Documentation

Last updated: 2026-11-12

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 create takes key=value pairs, with the conditions in match= 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 in rules.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.


mail rules smtp