Agent Wranglers

Required

Hand mail to your sending service over TLS with a send-only key

Connect your app to its mail server with implicit TLS on port 465, or required STARTTLS on port 587, and check the certificate. Use a key that can only send.

Risk if broken

An account or system taken over

Applies when

The project it sends email.

How to do it

RFC 8314 prefers implicit TLS for mail submission, and requires clients to check the server certificate. Never let the mail library fall back to plain text when STARTTLS fails. Otherwise the password or API key crosses the network in readable form. A sending service's HTTPS API meets this rule too. Give the app a key that may only send from your own domains, with no right to read contacts, change settings or add users. Anyone holding the key can send phishing in your name. Alert when one day's volume passes twice the daily average of the last 30 days. Store the key as Keep secrets in a secrets store says.

Examples

Using these examples: they show one way to follow this rule. Keep the behaviour and the check, not the syntax. Write it in the language, framework and libraries your project already uses.

JavaScript example

import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({
  host: 'smtp.mailprovider.example',
  port: 465,
  secure: true,
  auth: { user: 'apikey', pass: process.env.MAIL_SEND_KEY },
});

Python example

import os, smtplib, ssl

with smtplib.SMTP_SSL("smtp.mailprovider.example", 465, context=ssl.create_default_context()) as smtp:
    smtp.login("apikey", os.environ["MAIL_SEND_KEY"])
    smtp.send_message(message)

How to check

The mail settings name port 465 with TLS, or port 587 with TLS required, and certificate checks are on. A test send to a server with a self-signed certificate fails. The provider's key page shows send rights only.

Sources

For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/email/email-security/submission-tls">Agent Wranglers email playbook</a>. In code you write, add a comment next to it with the same link.