Documentation

Last updated in git: 2026-06-11

Mail rules reference

rules.toml lives at the root of the mail store and controls how Everlock handles every message that passes through the system — inbound or outbound.

How rules work

Rules are evaluated in ascending priority order. The first rule that matches wins. When no rule matches, the backend default is to store the message in the recipient mailbox under inbox.

  • lower priority numbers run first
  • higher priority numbers run later
  • omitted priority defaults to 10
  • equal priorities preserve file order
  • priority = 0 is valid

Rules have a directioninbound or outbound. Inbound rules apply to mail arriving over SMTP. Outbound rules apply to mail sent through the submission listener. A rule only runs for its own direction; inbound rules never fire for outbound mail and vice versa.

Rule shape

Each rule is one [[rule]] TOML block:

[[rule]]
id = "rule-default-inbox"
name = "catch-all inbox delivery"
priority = 10
direction = "inbound"
receiver = "*"
type = "store"
folder = "inbox"

direction defaults to inbound when omitted.

Required field

FieldDescription
idUnique rule identifier. Must start with rule-.

Optional fields

FieldDefaultDescription
nameHuman-readable label. Not used by the rule engine.
priority10Evaluation order. Lower numbers run first.
directioninboundinbound or outbound.

Match fields

All match fields are optional. A rule with no match fields matches every message in its direction.

FieldTypeDescription
senderstringEnvelope sender address. Supports * wildcard. Case-insensitive.
receiverstringEnvelope recipient address. Supports * wildcard. Case-insensitive.
domainstringRecipient domain. Supports * wildcard. Case-insensitive.
local_partstringRecipient local part (before @). Supports * wildcard. Case-insensitive.
subject_containsstringSubject header substring. Case-sensitive.
message_idstringExact Message-ID header value.
header_from_containsstringFrom header substring. Case-sensitive.
header_to_containsstringTo header substring. Case-sensitive.
size_gtintegerMatches if message size in bytes is greater than this value.
size_ltintegerMatches if message size in bytes is less than this value.
has_headerstringMatches if the named header is present in the message.

Wildcard behavior:

  • * matches any sequence of characters including none
  • *@example.com matches any sender at that domain
  • alerts@* matches alerts at any domain
  • * alone matches everything

Actions

The action is written inline using the type key plus any action-specific fields. The type value matches the action name exactly.

allow

Explicitly permit the message and stop evaluating further rules. The message is handled as if no rule had matched — stored in the recipient mailbox for inbound, sent normally for outbound. Useful as a priority-1 allowlist entry before a lower-priority catch-all reject.

type = "allow"

reject

Reject the message with an SMTP error. The sender receives a permanent failure.

type = "reject"

drop

Accept the message but discard it silently. The sender sees a success reply.

type = "drop"

store

Store in the recipient mailbox. folder defaults to inbox when omitted.

type = "store"
folder = "inbox"

store_as

Store in a different mailbox than the envelope recipient. Useful for aliases and shared inboxes. folder defaults to inbox when omitted.

type = "store_as"
mailbox = "admin@example.com"
folder = "support"

put_in_folder

Store in the recipient mailbox but place the message in a specific folder. Use this when you want to route to a folder without changing the destination mailbox.

type = "put_in_folder"
folder = "alerts"

set_flags

Store in the recipient mailbox and set IMAP flags on the message. All flags are optional; omitted flags are left at their default (false).

type = "set_flags"
seen = true
flagged = true
answered = false
deleted = false

forward

Forward the message to another address without storing it locally. The original raw message is forwarded as-is. Uses MX lookup for delivery.

type = "forward"
address = "ops@example.net"

store_and_forward

Store locally and forward to another address. folder defaults to inbox when omitted.

type = "store_and_forward"
address = "ops@example.net"
folder = "sales"

Outbound rules

Outbound rules apply to mail sent through the submission listener. They use the same match fields as inbound rules.

Only four actions are allowed for outbound rules:

  • allow
  • reject
  • drop
  • forward

Using any other action on an outbound rule will fail validation when rules.toml is loaded. Everlock refuses to start with an invalid rules file.

Example: reject outbound mail over 10 MB:

[[rule]]
id = "rule-outbound-size-limit"
direction = "outbound"
size_gt = 10485760
type = "reject"

Example: redirect all outbound mail through a specific relay address:

[[rule]]
id = "rule-outbound-relay"
direction = "outbound"
sender = "*@example.com"
type = "forward"
address = "relay@outbound.example.net"

Example rules file

A complete rules.toml combining inbound and outbound rules:

# Drop list traffic before anything else
[[rule]]
id = "rule-drop-lists"
priority = 1
has_header = "List-Id"
type = "drop"

# Route alerts to a dedicated folder
[[rule]]
id = "rule-alerts"
priority = 5
receiver = "alerts@example.com"
type = "put_in_folder"
folder = "alerts"

# Route support tickets to the shared admin mailbox
[[rule]]
id = "rule-support"
priority = 5
receiver = "support@example.com"
type = "store_as"
mailbox = "admin@example.com"
folder = "support"

# Block oversized outbound messages
[[rule]]
id = "rule-outbound-no-large"
direction = "outbound"
size_gt = 10485760
type = "reject"

# Catch-all: store everything else in inbox
[[rule]]
id = "rule-default"
priority = 100
receiver = "*"
type = "store"
folder = "inbox"

Read next

mail rules smtp