Skip to content

Email Notifications

Rack Gateway sends email notifications for security events, user management actions, and system alerts using Postmark.

  • Security Alerts: New CLI logins, failed logins, MFA failures, rate limits
  • User Notifications: Welcome emails, API tokens created for you, account locks and unlocks
  • Admin Alerts: Users added, API tokens created, rack parameter changes, rate limits
  • Async Processing: Background job queue for reliable delivery
  1. Sign up at https://postmarkapp.com
  2. Create a new server for Rack Gateway
  3. Copy the Server API Token
  4. Verify your sender domain
Terminal window
# Required to send email
POSTMARK_API_TOKEN=your-server-api-token
# Optional
POSTMARK_FROM=gateway@yourdomain.com # Default: no-reply@<GOOGLE_ALLOWED_DOMAIN>
POSTMARK_STREAM=outbound # Default: outbound

The gateway doesn’t log which sender it chose. To check delivery, add a user (they get a welcome email) or create an API token, then look at Postmark’s activity log. Without POSTMARK_API_TOKEN the gateway sends nothing.

Every email names the gateway that sent it, so you can tell racks apart when one person gets email from several gateways. The subject starts with Rack Gateway (<RACK_DISPLAY_NAME>): , for example Rack Gateway (Staging): New CLI Login, and the email ends with a footer giving the gateway’s name and URL. The subjects below are shown without that prefix.

Sent to the user whenever a CLI session is created for their account.

FieldContent
SubjectNew CLI Login
ToUser email
ContentTime, device, IP address, user agent

Sent to the user when MFA verification fails.

FieldContent
SubjectFailed MFA Verification Attempt
ToUser email
ContentTime, IP address, user agent

Sent to the address that tried when a login fails after Google (for example an address that isn’t a gateway user).

FieldContent
SubjectFailed Login Attempt
ToUser email
ContentTime, channel, status, IP, user agent

Sent when a request is rate limited: to the signed-in user (if any), and to every admin who isn’t locked (looked up when it’s sent, at most once per client IP in 15 minutes).

To User:

FieldContent
SubjectRate Limit Exceeded
ToUser email
ContentPath, time, IP address

To Admins:

FieldContent
SubjectRate Limit Exceeded - User {email}
ToAll admin users
ContentUser info, path, time, IP

The same security email isn’t sent again to the same recipient within 15 minutes (the admin alert, per client IP), so a burst of failures produces one email.

Sent when a new user is added.

FieldContent
SubjectWelcome
ToNew user email
ContentRoles, inviter, gateway URL
Hello Alice,
You have been added to the Production Rack Gateway by admin@example.com.
Your assigned roles: deployer, viewer
You can access the gateway at:
https://gateway.example.com
Please log in with your Google Workspace account to get started.
If you have any questions, please contact your administrator.
Welcome aboard!

Sent to all admins when a user is added.

FieldContent
SubjectNew user added: {email}
ToAll admin users (BCC)
ContentUser info, roles, creator, time

Sent when a user account is locked.

FieldContent
SubjectAccount Locked
ToLocked user email
ContentReason, contact instructions
FieldContent
SubjectAccount Unlocked
ToUnlocked user email

Sent when an account is locked automatically after 5 failed MFA attempts in 5 minutes. The lock is recorded in the audit log as user.lock by system.

FieldContent
SubjectAccount Locked - Multiple Failed Login Attempts
ToLocked user email
ContentReason, contact instructions

Every admin who isn’t locked also gets User locked: {email}, asking them to check with the user before unlocking the account.

When an API token is created, its owner gets New API token created (the token’s name and who created it), and every other admin gets API token created for {email}.

When rack parameters are changed through the gateway, every admin gets {email} changed rack parameters. It names the changed parameters but never their values, which can hold credentials.

Email notifications use River for async processing:

Job KindDescription
email:send:single / email:send:manyEmails built by request handlers (API tokens, account locks and unlocks, MFA auto-lock, rack parameter changes)
email:security:new_cli_sessionNew CLI login notification
email:security:failed_mfaFailed MFA notification
email:security:failed_loginFailed login notification
email:security:rate_limit_userRate limit user alert
email:security:rate_limit_adminRate limit admin alert
email:user:welcomeWelcome email
email:user:added_adminAdmin notification

A failed email job is retried with River’s backoff (attempt⁴ seconds: 1s, 16s, 81s, about 4 minutes, 10 minutes and so on), up to 11 attempts over about 7 hours, then discarded.

Each failed attempt is logged with the job’s kind, ID and attempt count (and reported to Sentry when configured):

[ERROR] job email:user:welcome failed: postmark send failed: 401 Unauthorized (id 1234, attempt 3 of 11)

Without a Postmark token, emails can be logged instead of dropped:

Terminal window
DEV_EMAIL_LOG=true
# or, in a development (testbypass) build
DEV_MODE=true

They’re logged at debug level under the email.summary and email.body topics, so also set LOG_LEVEL=debug and DEBUG_TOPICS=email.summary,email.body:

[DEBUG email.summary] to=alice@example.com subject="Rack Gateway (Production): Welcome"
[DEBUG email.body] text=... html=...
VariableRequiredDefaultDescription
POSTMARK_API_TOKENTo send email-Postmark server API token
POSTMARK_FROMNono-reply@<GOOGLE_ALLOWED_DOMAIN>Verified sender email
POSTMARK_STREAMNooutboundMessage stream name
DEV_EMAIL_LOGNofalseLog emails instead of sending

The gateway selects email sender based on configuration:

SenderBehavior
PostmarkSends via Postmark API
LoggerLogs to stdout (development)
NoopDoes nothing (silent)
  1. Verify configuration

    • Check POSTMARK_API_TOKEN is set
    • Check POSTMARK_FROM (or the no-reply@ default) is a verified sender
    • Restart gateway after changes
  2. Check Postmark

    • Verify domain is verified
    • Check API token is valid
    • Review Postmark activity log
  3. Check gateway logs

    • Look for email job errors
    • Check for Postmark API errors

Causes:

  • Invalid API token
  • Token doesn’t match server
  • Server disabled

Resolution:

  • Regenerate Postmark API token
  • Verify using correct server token (not account token)

Causes:

  • Recipient email bounced previously
  • Recipient marked as complaint

Resolution:

  • Check Postmark suppressions list
  • Contact recipient to verify email

Resolution:

  • Verify sender domain with SPF/DKIM/DMARC
  • Use consistent “From” address
  • Avoid spam trigger words
  • Always verify your sender domain in Postmark
  • Configure SPF, DKIM, and DMARC records
  • Use a dedicated subdomain for gateway emails
  • Emails never contain tokens, secrets or env var values; rack parameter emails name the parameters only
  • Names and other user-supplied values are escaped in HTML emails
  • Repeated security emails to the same recipient are suppressed for 15 minutes
  • Use a verified production domain
  • Monitor Postmark delivery rates
  • Set up Postmark alerts for bounces
  • Review suppression list regularly
  • Keep admin notification list current
  • Review security email patterns
  • Test email delivery regularly
  • Archive emails for compliance if required