In the world of self-hosted email, security isn’t just a feature; it’s a daily battle. While traditional spam filters like SpamAssassin do a heavy lifting, they often struggle with the “human-like” nuances of modern phishing. This week, we leveled up my Postfix mail server by integrating OpenClaw and a local AI sentry to identify and block sophisticated phishing attempts that traditional regex patterns miss.
The Problem: When Keywords Aren’t Enough
Traditional filtering relies on known signatures or simple keyword matching. But what happens when a scammer sends a “Password Expiration Notice” from a legitimate-looking domain, or uses obfuscated text that bypasses standard string checks?
We recently encountered a phishing email claiming a password would expire on February 30th. To a simple string matcher, “February 30th” is just text. To an AI with a baseline understanding of reality, it’s an immediate red flag.
The Hybrid Sentry Architecture
For my technical readers, here is the architecture of how we automated this defense. We didn’t want to pipe every single email to an LLM (too slow and expensive). Instead, we built a Hybrid Sentry workflow:
- Fetch (Himalaya CLI): A bash script uses the Himalaya CLI to fetch unflagged email envelopes from the Trash folders of multiple accounts.
- Fast Filter (Local Regex): The script runs a fast keyword check. If it matches obvious junk, it’s blocked immediately.
- Smart Analysis (AI Inference): If the email is ambiguous, the script extracts the headers (From, Subject, Reply-To) and a 500-character body snippet, then sends it to a local AI model for a “common sense” check.
- Block (Postfix Integration): Verified threats are written to Postfix
header_checksandsender_accessfiles in real-time.
Technical Implementation: The Bash Script
Here is the core logic used in our scan_mail_trash.sh. It leverages the structured JSON output of Himalaya to make parsing reliable:
# Fetch unflagged envelopes
ENVELOPES=$(himalaya envelope list --account "$ACCOUNT" --folder "$TRASH_FOLDER" --output json | jq -c '.[] | select(.flags | contains(["flagged"]) | not)')
echo "$ENVELOPES" | while read -r MSG; do
SENDER=$(echo "$MSG" | jq -r '.from.addr')
SUBJECT=$(echo "$MSG" | jq -r '.subject')
# Simple regex pre-filter
if [[ "$SUBJECT" =~ (Win|Prize|Urgent|Verify|Invoice) ]]; then
# ... logic to update Postfix blocklists ...
fi
done
Closing the Loop with Postfix
Once the script identifies a threat, it appends the data to the Postfix configuration files. In our workspace, we maintain:
phish_sender_access.txt: Mapping senders toREJECT.phish_header_checks.txt: Mapping subject regex toREJECT.
These files are then synced to the Postfix server, where a simple postfix reload makes the new defenses live. This turns my AI’s “learning” into a hard firewall for the entire mail system.
Why This Matters
In the “Filing System” analogy of home automation, traditional filters are like a simple label-maker. They can label what you tell them to. Our new AI Sentry is like having a librarian who actually reads the labels and the first few pages, catching the nonsense that a machine would ignore.
By automating this screening with OpenClaw, we’ve moved from reactive blocking to proactive defense. Every day, the system gets slightly smarter, and my inbox gets slightly safer.