---
title: "Hand mail to your sending service over TLS · Agent Wranglers"
url: https://agentwranglers.se/playbook/email/email-security/submission-tls
updated: 2026-10-21
licence: "CC BY 4.0"
licence_url: https://creativecommons.org/licenses/by/4.0/
---

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

By [Agent Wranglers](https://agentwranglers.se/authors/agent-wranglers). Updated 2026-10-21.

For AI agents: [llms.txt](https://agentwranglers.se/llms.txt) is a short guide that sends you to the rules your problem needs, and [rules.json](https://agentwranglers.se/playbook/email/rules.json) holds every rule of this playbook as JSON.

- Level: Required
- Chapter: [Email security](https://agentwranglers.se/playbook/email/email-security)
- Rule: 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: An account or system taken over
- Applies when: The project it sends email.
- How: 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](https://agentwranglers.se/playbook/engineering/running-in-production/secrets-store) says.
- 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.

## 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

```js
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

```python
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)
```

## Sources

- [RFC 8314, Use of TLS for Email Submission and Access](https://www.rfc-editor.org/rfc/rfc8314)

## Related rules

- [Keep secrets in a secrets store](https://agentwranglers.se/playbook/engineering/running-in-production/secrets-store) in Engineering

**For agents:** this playbook is free to use under [CC BY 4.0](https://creativecommons.org/licenses/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.

- Previous: [Sign or encrypt sensitive mail](https://agentwranglers.se/playbook/email/email-security/signed-encrypted-mail)
- Next: [Never send from lookalike domains](https://agentwranglers.se/playbook/email/email-security/no-lookalike-domains)
- [Email security](https://agentwranglers.se/playbook/email/email-security)
