Rules

How Rules Work

Rules are the heart of Mailgator. They define what your email client is allowed to do through the proxy. Every IMAP and SMTP operation is checked against your rules before it reaches the upstream server.

Two key principles:

  • First match wins. Mailgator evaluates rules top to bottom and uses the first rule that matches. Once a match is found, no further rules are checked.
  • Default deny. If no rule matches, the operation is denied. You do not need a catch-all deny rule, but adding one makes your config more readable.
# Rules are checked top-to-bottom. First match wins.

[[rules]]
name = "Allow reading inbox"
folders = ["INBOX"]
action = "allow"
operations = ["read"]

[[rules]]
name = "Deny everything else"
action = "deny"

Rule Structure

Every rule is a [[rules]] block in your config. Here are all available fields:

[[rules]]
name = "My rule"              # Required. Descriptive name (shown in logs)
folders = ["INBOX", "Sent"       ]
from = "*@example.com"        # Optional. Sender email glob
to = "*@company.com"          # Optional. Recipient email glob
cc = "*@team.com"             # Optional. CC email glob
bcc = "*@secret.com"          # Optional. BCC email glob
subject = "*urgent*"          # Optional. Subject line glob
has_attachment = true          # Optional. Filter by attachment presence
action = "allow"              # Required. "allow", "deny", or "ask"
operations = ["read", "write"       ]
ask_groups = ["admins"             ]

If a match field is omitted, it matches everything. For example, a rule without folders applies to all folders. A rule without from applies regardless of the sender.

You can also use the singular form folder instead of folders, and operation instead of operations -- they work the same way.

Match Fields

folders

A list of glob patterns matched against the mailbox folder name. Mailgator normalizes all folder hierarchy delimiters to /, so you can use forward slashes regardless of your server's native delimiter.

folders = ["INBOX"                  ]
folders = ["Archive/*"                ]
folders = ["Archive/**"                ]
folders = ["INBOX", "Sent", "Drafts"     ]

from, to, cc, bcc

Glob patterns matched against email addresses. All matching is case-insensitive.

from = "*@company.com"         # Any sender from company.com
to = "ceo@company.com"         # Specific recipient
from = "newsletter@*"          # Any newsletter sender
to = "*"                       # Any recipient (useful for ask rules)

subject

A glob pattern matched against the email subject line. Case-insensitive.

subject = "*confidential*"     # Subject contains "confidential"
subject = "Invoice *"          # Subject starts with "Invoice"

has_attachment

A boolean that filters based on whether the email has attachments.

has_attachment = true           # Only emails with attachments
has_attachment = false          # Only emails without attachments

Glob Patterns

Mailgator uses glob patterns (similar to file path matching) for flexible matching:

Pattern Meaning
* Matches any characters within a single level (does not cross / in folder names, or @ in emails when used as a standalone segment).
** Matches across levels, including nested subfolders. Must be used as a standalone path segment (e.g. Archive/**).
? Matches any single character.

All pattern matching is case-insensitive. *@Company.com matches user@company.COM.

Operations

Operations define what actions the rule applies to. You can use granular operations or shorthand aliases.

Granular Operations

Operation Description
folder:read List and open folders
folder:create Create new folders
folder:delete Delete folders
folder:rename Rename folders
mail:read Fetch and read email contents
mail:update Update email flags (read/unread, starred, etc.)
mail:delete Delete emails
mail:copy Copy emails between folders
mail:move Move emails between folders
mail:send Send outgoing emails (SMTP)

Shorthand Aliases

Shorthand aliases expand to multiple granular operations, saving you from listing them individually:

Shorthand Expands To
read mail:read + folder:read
write mail:update + mail:copy + folder:create + folder:rename
delete mail:delete + folder:delete
move mail:copy + mail:delete + mail:move
all Every operation (folder:read, folder:create, folder:delete, folder:rename, mail:read, mail:update, mail:delete, mail:copy, mail:move, mail:send)

Actions

Every rule must have one of three actions:

Action Description
allow Let the operation through to the upstream server.
deny Block the operation. The email client sees an error or the content is hidden.
ask Buffer the email and send a notification to an approval group. Only works with mail:send. See Ask & Approval.

deny rules do not require operations -- they block everything that matches. allow and ask rules must specify at least one operation.

Examples

Read-only access to INBOX

[[rules]]
name = "Read-only INBOX"
folders = ["INBOX"]
action = "allow"
operations = ["read"]

[[rules]]
name = "Deny everything else"
action = "deny"

Full access to specific folders, read-only elsewhere

[[rules]]
name = "Full access to workspace"
folders = ["Projects/**", "Archive/**"]
action = "allow"
operations = ["all"]

[[rules]]
name = "Read everything else"
action = "allow"
operations = ["read"]

[[rules]]
name = "Deny the rest"
action = "deny"

Allow sending only to your company

[[rules]]
name = "Read all emails"
action = "allow"
operations = ["read"]

[[rules]]
name = "Send to company only"
to = "*@mycompany.com"
action = "allow"
operations = ["mail:send"]

[[rules]]
name = "Deny external sends and everything else"
action = "deny"

Human approval for external emails

[[rules]]
name = "Read all"
action = "allow"
operations = ["read"]

[[rules]]
name = "Send internally without approval"
to = "*@mycompany.com"
action = "allow"
operations = ["mail:send"]

[[rules]]
name = "Ask for external sends"
action = "ask"
operations = ["mail:send"]
ask_groups = ["managers"]

[[rules]]
name = "Deny everything else"
action = "deny"

Filter by sender and attachment

[[rules]]
name = "Read emails from boss"
from = "boss@company.com"
action = "allow"
operations = ["read"]

[[rules]]
name = "Read emails with attachments in shared folder"
folders = ["Shared/**"]
has_attachment = true
action = "allow"
operations = ["read"]

[[rules]]
name = "Deny the rest"
action = "deny"

Tips

  • Order matters. Put your most specific rules first and general catch-alls last. The first matching rule wins.
  • Always end with a deny rule. While Mailgator denies unmatched operations by default, an explicit deny at the end makes your config self-documenting.
  • Use mailgator config validate to check your rules for syntax errors before starting the proxy.
  • Keep it simple. Start with a few broad rules and refine as needed. You can always check the logs to see which rules are matching.
  • The ask action only works with mail:send. You cannot use it for read or folder operations.