Ask & Approval Flow
What Is the Ask Action?
The ask action adds human oversight to outgoing emails. Instead of immediately sending an email, Mailgator buffers it and notifies a group of approvers. The email is only sent after someone approves it -- or it expires if nobody responds.
This is especially useful when an AI agent or automated tool sends emails on your behalf. You stay in control of what actually reaches the recipient.
When to Use It
The ask action only works with the mail:send operation. Common scenarios:
- An AI agent sends customer replies -- you want a human to approve each one before it goes out
- A shared mailbox where external emails need manager approval
- A compliance workflow where certain recipients require sign-off
- Internal emails go through automatically, but external emails need review
How It Works
Here is the step-by-step flow when an email matches an ask rule:
- Email client sends the email through Mailgator's SMTP proxy.
- Mailgator matches an ask rule. Instead of forwarding to the upstream server, it buffers the email.
- The email body and sender credentials are encrypted (AES-256-GCM) and stored in a local SQLite database.
- Notification emails are sent to all recipients in the configured ask groups. Each notification includes an approval link and a preview of the email.
- An approver reviews the email and clicks Approve or Deny (via web UI or email reply).
- If approved: Mailgator replays the original email through the upstream SMTP server using the stored credentials. The email is sent as if the original sender sent it directly.
- If denied or expired: The email is discarded. Stored credentials are cleared.
The email client sees a successful send immediately (step 2). The actual delivery depends on the approval decision.
Configuration
Using ask rules requires several config sections. Here is what you need:
1. Database
A SQLite database to store pending approval requests. Mailgator creates it automatically.
[database] path = "mailgator.db"
2. Web Server
A web server that hosts the approval pages. Approvers visit these pages to review and approve/deny emails.
[web] listen_addr = "0.0.0.0:8080"
3. Ask Settings
General settings for the approval flow.
[ask] timeout_in_minutes = 30 retention_days = 30 base_url = "https://mailgator.example.com" reply_domain = "approve.example.com"
| Option | Description |
|---|---|
| timeout_in_minutes | How long an email waits for approval before expiring. Default: 30 minutes. |
| retention_days | How long resolved (approved/denied/expired) requests are kept in the database. Default: 30 days. |
| base_url | The public URL of your Mailgator web server. Used in approval links in notification emails. |
| reply_domain | Domain used for email-based approval replies. The notification sets a Reply-To address like approve-TOKEN@reply_domain. |
4. Approval Groups
Define named groups of email addresses that receive approval notifications.
[ask.groups.managers] recipients = ["alice@company.com", "bob@company.com"] [ask.groups.security] recipients = ["security@company.com"]
5. Ask Rules
Rules that trigger the ask flow. They reference the approval groups defined above.
[[rules]] name = "Ask before sending externally" action = "ask" operations = ["mail:send"] ask_groups = ["managers"]
Complete Config Example
Here is a full config that allows internal sends automatically but requires approval for external emails:
[smtp] upstream_addr = "smtp.company.com:587" listen_addr = "127.0.0.1:1587" [imap] upstream_addr = "imap.company.com:993" listen_addr = "127.0.0.1:1993" [[rules]] name = "Read all emails" action = "allow" operations = ["read"] [[rules]] name = "Send internally" to = "*@company.com" action = "allow" operations = ["mail:send"] [[rules]] name = "Ask before external sends" action = "ask" operations = ["mail:send"] ask_groups = ["managers"] [[rules]] name = "Deny everything else" action = "deny" [database] path = "mailgator.db" [web] listen_addr = "0.0.0.0:8080" [ask] timeout_in_minutes = 60 retention_days = 90 base_url = "https://mailgator.company.com" reply_domain = "approve.company.com" [ask.groups.managers] recipients = ["alice@company.com", "bob@company.com"]
Approving via Web UI
When an email is pending approval, the notification includes a link like:
https://mailgator.company.com/decide/abc123...
The approval page shows:
- Who is sending the email (From)
- Who it is addressed to (To)
- The subject line
- A preview of the email body
- When the request expires
Click Approve to send the email, or Deny to discard it. Once a decision is made, the page shows a confirmation message. If the request has already been decided or has expired, the page shows the appropriate status.
Approving via Email Reply
You can also respond to the notification email directly:
- To approve: Reply to the notification email. The Reply-To address is set to
approve-TOKEN@reply_domain. The reply content does not matter -- only the address matters. - To deny: Send an email to
deny-TOKEN@reply_domain. (This address is included in the notification body.)
For email-based approval to work, you need to configure the reply_domain to route incoming emails to Mailgator's SMTP proxy. This typically requires MX records pointing to your Mailgator instance.
Timeout and Retention
Two settings control the lifecycle of pending emails:
- timeout_in_minutes (default: 30) -- If nobody approves or denies the email within this window, it expires automatically. Expired emails are never sent. The stored credentials are cleared when an email expires.
- retention_days (default: 30) -- After an email has been approved, denied, or expired, the record stays in the database for this many days. This allows you to review past decisions. After the retention period, records are cleaned up automatically.
[ask] timeout_in_minutes = 60 # 1 hour to decide retention_days = 90 # Keep records for 3 months
Security Notes
- Credential encryption. The sender's SMTP credentials (username and password) are captured during the send attempt and encrypted with AES-256-GCM before being stored in the database. The encryption key is auto-generated and saved in the secrets file.
- Credentials are cleared after use. Once an email is approved and replayed (or denied/expired), the encrypted credentials are deleted from the database.
- Back up the secrets file. If you lose
mailgator-config-secrets.toml, any currently pending emails cannot be replayed because the credentials cannot be decrypted. - Approval tokens are unique. Each pending email gets a cryptographically random token. The token is required to approve or deny the email.
- Origin checking. The web UI checks the Origin/Referer header against the configured
base_urlto prevent cross-site request forgery on the approve/deny endpoints. - All data stays local. The database, credentials, and email content never leave your server. Mailgator does not send email content to any external service.