Skip to main content
Frontier uses SMTP (Simple Mail Transfer Protocol) to send emails for authentication (OTPs, magic links), invitations, and notifications. This guide covers configuring Frontier’s mailer service.

Overview

The mailer service supports:
  • One-time password (OTP) delivery
  • Magic link authentication
  • Organization invitations
  • User notifications
  • Custom email templates

Configuration

Basic Settings

app.mailer.smtp_host
string
required
SMTP server hostname or IP address.
app:
  mailer:
    smtp_host: smtp.gmail.com
app.mailer.smtp_port
integer
required
SMTP server port number.Common ports:
  • 587 - STARTTLS (recommended)
  • 465 - SSL/TLS
  • 25 - Unencrypted (not recommended)
app:
  mailer:
    smtp_port: 587
app.mailer.smtp_username
string
required
Username for SMTP authentication.
app:
  mailer:
    smtp_username: "[email protected]"
app.mailer.smtp_password
string
required
Password or app-specific password for SMTP authentication.
app:
  mailer:
    smtp_password: "your-smtp-password"
Use environment variables for sensitive credentials. Never commit passwords to version control.
app.mailer.smtp_insecure
boolean
default:"true"
Skip TLS certificate verification. Set to false for production.
app:
  mailer:
    smtp_insecure: false  # Verify TLS certificates in production
app.mailer.smtp_tls_policy
string
default:"mandatory"
TLS policy for SMTP connection.Options:
  • mandatory - Always use STARTTLS (recommended)
  • opportunistic - Use STARTTLS if available, otherwise unencrypted
  • none - Never use STARTTLS (not recommended)
app:
  mailer:
    smtp_tls_policy: "mandatory"

Email Headers

app.mailer.headers
object
required
Email headers including sender information.
app:
  mailer:
    headers:
      from: "[email protected]"
      # Optional additional headers:
      reply-to: "[email protected]"
      x-mailer: "Frontier"
The from header is required and must be an email address authorized by your SMTP provider.

Provider-Specific Configuration

Gmail / Google Workspace

For Gmail or Google Workspace SMTP:
app:
  mailer:
    smtp_host: smtp.gmail.com
    smtp_port: 587
    smtp_username: "[email protected]"
    smtp_password: "your-app-password"  # Not your regular password
    smtp_insecure: false
    smtp_tls_policy: "mandatory"
    headers:
      from: "[email protected]"
Setup Steps:
  1. Enable 2-factor authentication on your Google account
  2. Generate an App Password
  3. Use the app password in your Frontier configuration
Google Workspace SMTP Relay: For Google Workspace, you can use SMTP relay which doesn’t require authentication:
  1. Go to Google Admin Console → Apps → Google Workspace → Gmail → Routing
  2. Configure SMTP relay service
  3. Allow your application’s IP addresses
  4. Use smtp_username and smtp_password as empty strings or omit them
Reference: Google Workspace SMTP Guide

Amazon SES

For AWS Simple Email Service:
app:
  mailer:
    smtp_host: email-smtp.us-east-1.amazonaws.com
    smtp_port: 587
    smtp_username: "AKIAIOSFODNN7EXAMPLE"  # SMTP username from SES
    smtp_password: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"  # SMTP password
    smtp_insecure: false
    smtp_tls_policy: "mandatory"
    headers:
      from: "[email protected]"
Setup Steps:
  1. Verify your domain or email address in SES
  2. Request production access (remove sandbox limitations)
  3. Create SMTP credentials in SES console
  4. Use the region-specific SMTP endpoint
Available Regions:
  • email-smtp.us-east-1.amazonaws.com (N. Virginia)
  • email-smtp.us-west-2.amazonaws.com (Oregon)
  • email-smtp.eu-west-1.amazonaws.com (Ireland)
  • See AWS SES Regions
Reference: Amazon SES SMTP Guide

Mailgun

For Mailgun SMTP:
Mailgun
app:
  mailer:
    smtp_host: smtp.mailgun.org
    smtp_port: 587
    smtp_username: "[email protected]"
    smtp_password: "your-mailgun-smtp-password"
    smtp_insecure: false
    smtp_tls_policy: "mandatory"
    headers:
      from: "[email protected]"
Setup Steps:
  1. Add and verify your domain in Mailgun
  2. Get SMTP credentials from Mailgun dashboard
  3. Use the SMTP credentials (not API key) in configuration
Reference: Mailgun SMTP Guide

Postmark

For Postmark SMTP:
Postmark
app:
  mailer:
    smtp_host: smtp.postmarkapp.com
    smtp_port: 587
    smtp_username: "your-server-api-token"  # Use your Server API Token
    smtp_password: "your-server-api-token"  # Same as username
    smtp_insecure: false
    smtp_tls_policy: "mandatory"
    headers:
      from: "[email protected]"
Setup Steps:
  1. Create a server in Postmark
  2. Verify your sender signature or domain
  3. Use your Server API Token as both username and password
Reference: Postmark SMTP Guide

SendGrid

For SendGrid SMTP:
SendGrid
app:
  mailer:
    smtp_host: smtp.sendgrid.net
    smtp_port: 587
    smtp_username: "apikey"  # Literal string "apikey"
    smtp_password: "SG.xxxxxxxxxxxxxxxxxxxx"  # Your SendGrid API key
    smtp_insecure: false
    smtp_tls_policy: "mandatory"
    headers:
      from: "[email protected]"
Setup Steps:
  1. Verify your sender identity in SendGrid
  2. Create an API key with “Mail Send” permissions
  3. Use the literal string "apikey" as username
  4. Use your API key as password

Custom SMTP Server

For self-hosted or custom SMTP servers:
Custom SMTP
app:
  mailer:
    smtp_host: mail.example.com
    smtp_port: 587
    smtp_username: "[email protected]"
    smtp_password: "your-password"
    smtp_insecure: false
    smtp_tls_policy: "mandatory"
    headers:
      from: "[email protected]"

Complete Examples

app:
  mailer:
    smtp_host: smtp.gmail.com
    smtp_port: 587
    smtp_username: "[email protected]"
    smtp_password: "${SMTP_PASSWORD}"  # From environment
    smtp_insecure: false
    smtp_tls_policy: "mandatory"
    headers:
      from: "[email protected]"
      reply-to: "[email protected]"

Testing Email Configuration

After configuring SMTP, test email delivery:

Using Frontier API

Trigger a test email by initiating authentication:
# Request OTP
curl -X POST http://localhost:8000/v1beta1/auth/otp \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]"
  }'

Using Development Tools

For development, use local SMTP testing tools: MailHog (captures emails locally):
# Run MailHog
docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog

# Configure Frontier to use MailHog
app:
  mailer:
    smtp_host: localhost
    smtp_port: 1025
    smtp_username: ""
    smtp_password: ""
    smtp_insecure: true
    smtp_tls_policy: "none"

# View emails at http://localhost:8025
Mailtrap (email testing service):
app:
  mailer:
    smtp_host: smtp.mailtrap.io
    smtp_port: 587
    smtp_username: "your-mailtrap-username"
    smtp_password: "your-mailtrap-password"
    smtp_tls_policy: "mandatory"

Email Templates

Email templates are configured in the authentication section:

OTP Email Template

app:
  authentication:
    mail_otp:
      subject: "Your Login Code - Acme Corp"
      body: |
        <html>
        <body>
          <h1>Login Code</h1>
          <p>Use this code to login:</p>
          <h2 style="color: #007bff;">{{.Otp}}</h2>
          <p>This code expires in 15 minutes.</p>
        </body>
        </html>
      validity: "15m"
app:
  authentication:
    mail_link:
      subject: "Your Login Link - Acme Corp"
      body: |
        <html>
        <body>
          <h1>Login Link</h1>
          <p>Click the button below to login:</p>
          <a href="{{.Link}}" style="background-color: #007bff; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px;">Login</a>
          <p>Or copy this link: {{.Link}}</p>
          <p>This link expires in 15 minutes.</p>
        </body>
        </html>
      validity: "15m"

Invitation Email Template

app:
  authentication:
    # Configure via preferences
    # See Platform Preferences documentation
Invitation templates are managed through Preferences.

Troubleshooting

Common Issues

Problem: connection refused
Solution:
- Verify smtp_host and smtp_port are correct
- Check firewall rules allow outbound connections
- Test connectivity: telnet smtp.example.com 587
Problem: authentication failed
Solution:
- Verify smtp_username and smtp_password are correct
- For Gmail: ensure you're using App Password, not regular password
- Check if your account requires 2FA
- Verify SMTP credentials haven't expired
Problem: certificate verification failed
Solution:
- Set smtp_insecure: false and smtp_tls_policy: "mandatory"
- Verify your system's CA certificates are up to date
- Check if SMTP server certificate is valid
Problem: recipient rejected or from address not verified
Solution:
- Verify sender email in your SMTP provider (SES, SendGrid, etc.)
- Check SPF/DKIM records are configured
- Ensure 'from' address matches verified domain
- For SES: request production access to remove sandbox
Problem: Emails going to spam
Solution:
- Configure SPF, DKIM, and DMARC records
- Use verified domain in 'from' address
- Add proper reply-to header
- Avoid spam trigger words in subject/body
- Monitor sender reputation

Debug SMTP Connection

Test SMTP connection manually:
# Test connection
openssl s_client -connect smtp.gmail.com:587 -starttls smtp

# Or using telnet
telnet smtp.gmail.com 587

# Expected response:
220 smtp.gmail.com ESMTP ...

Enable Debug Logging

Increase log level to debug SMTP issues:
log:
  level: debug
Then check logs for detailed SMTP communication.

Security Best Practices

  1. Use App-Specific Passwords
    • Generate app passwords for Gmail/Google Workspace
    • Don’t use main account passwords
  2. Store Credentials Securely
    app:
      mailer:
        smtp_password: "${SMTP_PASSWORD}"  # From environment
    
  3. Enable TLS
    app:
      mailer:
        smtp_tls_policy: "mandatory"
        smtp_insecure: false
    
  4. Verify Certificates
    • Never use smtp_insecure: true in production
    • Keep system CA certificates updated
  5. Configure SPF/DKIM
    • Add SPF record to your DNS
    • Configure DKIM signing with your provider
    • Implement DMARC policy
  6. Rate Limiting
    • Configure rate limits in your SMTP provider
    • Monitor email sending quotas
    • Implement application-level rate limiting
  7. Monitor Bounce Rates
    • Track email delivery failures
    • Remove invalid addresses
    • Monitor spam complaints

See Also

Build docs developers (and LLMs) love