Documentation
Mail rules cookbook
A collection of ready-to-use rules.toml patterns for common setups. Each
example shows the TOML block for rules.toml and the equivalent admin shell
command.
Start from the default rules — the built-in
inbox delivery and the recommended spam rule — and add the recipes you need.
For the full match reference, see Mail rules reference.
Shell note:
/mail rules createtakeskey=valuepairs, with the conditions inmatch=as the last argument.match=takes the rest of the line as an inline TOML value, so values with spaces, brackets and quotes work there exactly as inrules.toml.
Restrict outbound to specific recipient domains
Outbound rules decide where submitted mail may go. Who may submit at all is decided by Everlock access grants on the submission listener.
Block outbound to one domain:
[[rule]]
id = "rule-outbound-block-competitor"
priority = 1
direction = "outbound"
type = "reject"
match = { envelope = "receiver", part = "domain", is = "blocked.example" }
/mail rules create rule-outbound-block-competitor direction=outbound priority=1 type=reject match={ envelope = "receiver", part = "domain", is = "blocked.example" }
Allow outbound to one domain only, block everything else:
Use allow at priority 1 to pass the permitted domain through, then a
catch-all reject at a higher priority number to block the rest.
[[rule]]
id = "rule-outbound-allow-jens-dev"
priority = 1
direction = "outbound"
type = "allow"
match = { envelope = "receiver", part = "domain", is = "jens.dev" }
[[rule]]
id = "rule-outbound-block-all"
priority = 100
direction = "outbound"
type = "reject"
/mail rules create rule-outbound-allow-jens-dev direction=outbound priority=1 type=allow match={ envelope = "receiver", part = "domain", is = "jens.dev" }
/mail rules create rule-outbound-block-all direction=outbound priority=100 type=reject
Let one sender write to a set of domains:
[[rule]]
id = "rule-aenea-out-partners"
priority = 5
direction = "outbound"
type = "allow"
match.all = [
{ envelope = "sender", is = "aenea@jens.dev" },
{ envelope = "receiver", part = "domain", is = ["apimeister.com", "99active.com"] },
]
/mail rules create rule-aenea-out-partners direction=outbound priority=5 type=allow match={ all = [{ envelope = "sender", is = "aenea@jens.dev" }, { envelope = "receiver", part = "domain", is = ["apimeister.com", "99active.com"] }] }
Force all outbound through a relay address:
[[rule]]
id = "rule-outbound-relay"
priority = 100
direction = "outbound"
type = "forward"
address = "smarthost@relay.example.net"
/mail rules create rule-outbound-relay direction=outbound priority=100 type=forward address=smarthost@relay.example.net
Restrict inbound to a single domain
Everlock's hosted-domain model restricts inbound mail by itself: once you create a mail domain, Everlock accepts SMTP recipients for configured domains only.
/mail domains create example.com
For extra assurance at the rules layer, reject anything that reaches rules evaluation for an unexpected domain:
[[rule]]
id = "rule-inbound-reject-unexpected-domain"
priority = 1
direction = "inbound"
type = "reject"
match = { envelope = "receiver", part = "domain", is = "unexpected.example" }
/mail rules create rule-inbound-reject-unexpected-domain direction=inbound priority=1 type=reject match={ envelope = "receiver", part = "domain", is = "unexpected.example" }
Admin catch-all for a domain
Route all mail for a domain to a central admin mailbox. Useful to catch contact form submissions, typos, or old addresses.
[[rule]]
id = "rule-admin-catchall"
priority = 100
direction = "inbound"
type = "store_as"
mailbox = "admin@example.com"
folder = "catchall"
match = { envelope = "receiver", part = "domain", is = "example.com" }
/mail rules create rule-admin-catchall direction=inbound priority=100 type=store_as mailbox=admin@example.com folder=catchall match={ envelope = "receiver", part = "domain", is = "example.com" }
Put this at a high priority number so more specific rules run first.
Shared alias for a team inbox
Route all mail sent to support@example.com into a shared mailbox that the
whole team reads.
[[rule]]
id = "rule-support-alias"
priority = 5
direction = "inbound"
type = "store_as"
mailbox = "team@example.com"
folder = "support"
match = { envelope = "receiver", is = "support@example.com" }
/mail rules create rule-support-alias direction=inbound priority=5 type=store_as mailbox=team@example.com folder=support match={ envelope = "receiver", is = "support@example.com" }
Auto-forward to an external address
Forward a copy of all inbound mail for one address to an external mailbox, for example while someone is away or using a legacy address.
[[rule]]
id = "rule-forward-alice"
direction = "inbound"
type = "store_and_forward"
address = "alice@gmail.com"
folder = "inbox"
match = { envelope = "receiver", is = "alice@example.com" }
/mail rules create rule-forward-alice direction=inbound type=store_and_forward address=alice@gmail.com folder=inbox match={ envelope = "receiver", is = "alice@example.com" }
store_and_forward keeps a local copy. forward skips local storage:
[[rule]]
id = "rule-forward-alice-only"
direction = "inbound"
type = "forward"
address = "alice@gmail.com"
match = { envelope = "receiver", is = "alice@example.com" }
/mail rules create rule-forward-alice-only direction=inbound type=forward address=alice@gmail.com match={ envelope = "receiver", is = "alice@example.com" }
Send mailing list traffic to a folder
Any message that carries a List-Id header is a mailing list message. Route
them all to a dedicated folder.
[[rule]]
id = "rule-lists-folder"
priority = 20
direction = "inbound"
type = "put_in_folder"
folder = "lists"
match = { header = "List-Id", exists = true }
/mail rules create rule-lists-folder direction=inbound priority=20 type=put_in_folder folder=lists match={ header = "List-Id", exists = true }
A priority number above the spam rule's 10 lets spam sent through a list
still land in junk.
Mark newsletters as read automatically
Newsletters you subscribe to are usually not urgent. Accept them and mark them as already read so they stay out of your unread count.
[[rule]]
id = "rule-newsletter-seen"
priority = 21
direction = "inbound"
type = "set_flags"
seen = true
match = { header = "List-Unsubscribe", exists = true }
/mail rules create rule-newsletter-seen direction=inbound priority=21 type=set_flags seen=true match={ header = "List-Unsubscribe", exists = true }
The first matching rule decides: a message with both List-Id and
List-Unsubscribe goes to the list folder at priority 20, and a newsletter
with List-Unsubscribe alone lands in the inbox, marked as read.
File mail that fails DMARC as junk
DMARC fails when the From domain publishes a policy and the message is
neither SPF- nor DKIM-aligned with it — a typical sign of a forged sender.
[[rule]]
id = "rule-dmarc-fail-junk"
priority = 9
direction = "inbound"
type = "put_in_folder"
folder = "junk"
match = { auth = "dmarc", is = "fail" }
/mail rules create rule-dmarc-fail-junk direction=inbound priority=9 type=put_in_folder folder=junk match={ auth = "dmarc", is = "fail" }
Reject mail from a specific sender
Block a known bad sender before any storage or processing happens.
[[rule]]
id = "rule-block-spammer"
priority = 1
direction = "inbound"
type = "reject"
match = { envelope = "sender", part = "domain", is = "known-spam.example" }
/mail rules create rule-block-spammer direction=inbound priority=1 type=reject match={ envelope = "sender", part = "domain", is = "known-spam.example" }
drop accepts silently without bouncing — useful when the sender address is
likely forged and a bounce would only create backscatter:
[[rule]]
id = "rule-drop-spammer"
priority = 1
direction = "inbound"
type = "drop"
match = { envelope = "sender", part = "domain", is = "known-spam.example" }
/mail rules create rule-drop-spammer direction=inbound priority=1 type=drop match={ envelope = "sender", part = "domain", is = "known-spam.example" }
To test what the message itself claims, use the From header with a part:
{ header = "From", part = "domain", is = "known-spam.example" } compares
the address and leaves the display name aside.
Reject oversized messages
Block inbound messages over a size threshold to protect storage.
[[rule]]
id = "rule-reject-large-inbound"
priority = 1
direction = "inbound"
type = "reject"
match = { message = "size", gt = 26214400 }
/mail rules create rule-reject-large-inbound direction=inbound priority=1 type=reject match={ message = "size", gt = 26214400 }
The same for outbound:
[[rule]]
id = "rule-reject-large-outbound"
priority = 1
direction = "outbound"
type = "reject"
match = { message = "size", gt = 26214400 }
/mail rules create rule-reject-large-outbound direction=outbound priority=1 type=reject match={ message = "size", gt = 26214400 }
Route build and alert notifications
CI systems and monitoring tools usually send from a predictable address or use a subject prefix. Put them in their own folder.
By sender domain:
[[rule]]
id = "rule-monitoring-alerts"
priority = 3
direction = "inbound"
type = "put_in_folder"
folder = "alerts"
match = { envelope = "sender", part = "domain", is = "monitoring.example.com" }
/mail rules create rule-monitoring-alerts direction=inbound priority=3 type=put_in_folder folder=alerts match={ envelope = "sender", part = "domain", is = "monitoring.example.com" }
By subject prefix:
[[rule]]
id = "rule-ci-alerts"
priority = 3
direction = "inbound"
type = "put_in_folder"
folder = "ci"
match = { header = "Subject", matches = '^\[build\]' }
/mail rules create rule-ci-alerts direction=inbound priority=3 type=put_in_folder folder=ci match={ header = "Subject", matches = '^\[build\]' }
Everything except release notices:
[[rule]]
id = "rule-ci-noise"
priority = 4
direction = "inbound"
type = "put_in_folder"
folder = "ci"
match.all = [
{ envelope = "sender", part = "domain", is = "ci.example.com" },
{ not = { header = "Subject", contains = "release" } },
]
A complete minimal setup
A rules.toml for a single hosted domain: the
default rules plus the most common cases.
Create the domain first, then add the rules:
/mail domains create example.com
/mail rules create rule-reject-large direction=inbound priority=1 type=reject match={ message = "size", gt = 26214400 }
/mail rules create rule-support direction=inbound priority=5 type=store_as mailbox=admin@example.com folder=support match={ envelope = "receiver", is = "support@example.com" }
/mail rules create rule-lists direction=inbound priority=20 type=put_in_folder folder=lists match={ header = "List-Id", exists = true }
/mail rules create rule-outbound-size direction=outbound priority=1 type=reject match={ message = "size", gt = 26214400 }
Equivalent rules.toml, next to the spam rule from the defaults:
# Block oversized inbound
[[rule]]
id = "rule-reject-large"
priority = 1
direction = "inbound"
type = "reject"
match = { message = "size", gt = 26214400 }
# Route support to the shared mailbox
[[rule]]
id = "rule-support"
priority = 5
direction = "inbound"
type = "store_as"
mailbox = "admin@example.com"
folder = "support"
match = { envelope = "receiver", is = "support@example.com" }
# Route list traffic to a folder
[[rule]]
id = "rule-lists"
priority = 20
direction = "inbound"
type = "put_in_folder"
folder = "lists"
match = { header = "List-Id", exists = true }
# Block oversized outbound
[[rule]]
id = "rule-outbound-size"
priority = 1
direction = "outbound"
type = "reject"
match = { message = "size", gt = 26214400 }
Everything else lands in the recipient's inbox.