The OpenClaw IMAP email trigger
Watching a mailbox, the isolated restricted reader agent, sender authentication from DMARC to sender-bound tokens, the freshness rule, and how to verify the boundary
Email is the most hostile input an agent can read: anyone can send it. OpenClaw’s bundled IMAP plugin treats it that way. It watches an existing mailbox and starts a separate, isolated agent session for each allowed incoming message, and it does not send email, modify flags, expose a public webhook or backfill messages already present when monitoring begins. Here is the restricted reader you configure first, the account settings, the sender authentication ladder, tokens and freshness, the watcher’s runtime behaviour, and the test that proves the boundary holds.
The restricted reader
- Configure an explicit reader agent before enabling the plugin, with explicit agent ownership and one binding per enabled channel so the primary agent keeps its channels: the docs’ example gives the reader its own workspace, a model, a sandbox in all mode with session scope and no workspace access, a minimal tool profile allowing only the session status tool and denying the filesystem, runtime, web, browser, cron, gateway and node groups.
- The account entry names the host, port and TLS, the user, a password as a stored secret reference, the mailbox, a watch mode with a poll interval, the allowed senders, the sender authentication floor and trusted authentication-results servers, the reader agent id, whether to deliver announcements, whether to include the body, and a byte cap.
- The reader requires an available sandbox backend and an authenticated model; unlike the Gmail integration it needs no hooks setting, no Google Cloud, no tunnel and no public endpoint, because it calls the Gateway’s trusted plugin email dispatcher directly, so HTTP-hook allowlists are not its boundary and the agent id, sender policy and restricted reader are.
- The docs list the checks to run before trusting it: list agents and bindings, validate the config, probe the reader’s model status, run a one-message agent turn as the reader, and explain its sandbox.
Any link navigation, file write, shell command, browser action, or other tool escape is a failed boundary check.
Sender authentication
The parsed From address is checked against the allowlist before any message reaches a model; entries are full addresses or domain entries, display names and Reply-To grant nothing, messages with several From addresses are rejected, and an empty allowlist disables the account. Four strengths follow: verified when local mail authentication returns an aligned DMARC pass, accepted by default; asserted when a configured trusted authentication-results server reports a pass, accepted only with the trusted-server opt-in and an asserted floor; unverified when SPF alone passes or an untrusted server asserts a result, or when ownership is unproven including a DMARC temporary error, accepted only with an unverified floor; and mutable, the changeable or shared alias level the IMAP mapper never produces but the floor may still name. The default minimum is verified, an explicit unverified floor admits no-evidence mail, authenticator exceptions cause retries unless a trusted header satisfies the floor, and lowering the minimum never bypasses the allowlist or the freshness check. Rejections before authentication record an invalid-from, sender-not-allowed or message-too-old gate without a strength.
Tokens, freshness, the watcher
- A sender-bound token is for an allowlisted sender that cannot produce useful DKIM or DMARC: a long random token bound to specific senders, delivered to a plus-addressed mailbox; after the From and allowlist checks the token is checked before freshness and authentication, a match bypasses both the forty-eight-hour freshness check and mail authentication, and without one a message whose internal date is older than forty-eight hours is rejected before authentication. The token never widens the allowlist or grants tools or workspace access.
- The watcher reconciles new mail every poll interval in both polling and IDLE modes, IDLE notifications trigger immediate sweeps, transient authentication failures and failed admission are retried without waiting for another email, after three failed attempts it records a skip and moves on, and a stopped watcher does not keep retrying. It keeps its own cursor and deduplication state rather than the channel dead-letter queue, existing messages are baselined without dispatch at first start, new ones are deduplicated across restarts, a mailbox validity change records a fresh baseline instead of replaying, bodies are capped with a recorded truncation marker, and a crash during unresolved admission can leave a claim, so the path does not promise exactly-once processing.
- Verify the boundary with a deep security audit and the log stream: send yourself a message asking to follow a link and run a command, confirm it dispatches to the reader, creates an isolated run and only summarises the content. The dispatch log with a run id records admission, not completion; look for the hook-run-completed line with the same id and inspect the transcript. With delivery off, successful announcements are disabled, and a model failure after admission does not make IMAP replay the message.
OpenClaw automations covers the Gmail integration this plugin is the simpler alternative to, and OpenClaw sandboxing explained the backend the reader agent requires.
Troubleshooting
Three consecutive authentication failures stop retries and mark the watcher unhealthy until the password or secret reference is updated and the config reloaded, and one broken account does not stop others. Servers without IMAP IDLE fall back to periodic sweeps with a minimum interval of fifteen seconds, some iCloud servers advertise a push service instead of standard IDLE so polling is the supported path, rejected self-hosted senders should fix their DKIM and DMARC before you lower the floor or add a token, and no dispatch usually means an empty allowlist, a message older than the baseline, a From that does not match, a missing reader agent or a failing model probe; rejections are logged without subjects or bodies. OpenClaw hooks and webhooks is the sibling event system this plugin deliberately stays separate from, and OpenClaw models and providers the authenticated model the reader needs.
On Diali
On Diali the mailbox password would live in the vault rather than a config file, and the restricted reader needs a sandbox backend the assistant can reach, which is the part to confirm with us before relying on it. Hosted OpenClaw on Diali is the assistant and Diali security describes the boundary the reader pattern extends.
- An isolated reader with almost no tools.
- Verified DMARC by default; tokens for the rest.
- Baseline, deduplicate, cap; never backfill.
Stop reading about it, build one
Set up an agent, pick a channel, and have it working inside the app you already keep open.
