Security fixes are applied to the current main release. Self-hosters should run a reviewed revision and keep Bun, Python rollback dependencies, container images, the TLS proxy, and the host patched.
Report suspected vulnerabilities privately through GitHub private vulnerability reporting. Do not open a public issue, test against other users, access unrelated data, or disrupt a service. Include the affected revision, impact, and reproduction steps. An acknowledgement is expected within seven days; no bounty is promised.
- Email/password signup and login work without OAuth. WorkOS AuthKit is optional account authentication; it does not grant mailbox access.
- Gmail delivery supports App Passwords over SMTP only. SendPlug does not request Gmail OAuth/API scopes. App Passwords cross the API over operator-provided HTTPS, are decrypted in API/worker memory when needed, and are encrypted at rest. This is not end-to-end encryption.
- API tokens are sender-scoped, revocable, shown once, and stored as keyed hashes. A raw token remains a bearer credential.
- PostgreSQL stores account and delivery state. Redis stores queues, auth/rate-limit state, and worker heartbeats. The VM operator, reverse proxy, databases, mounted secrets, logs, process memory, and backups are trusted boundaries.
- Compose publishes only the API on loopback. A maintained reverse proxy must terminate TLS, overwrite
X-Real-IP, and must not expose PostgreSQL or Redis. - Redis
noevictionprevents silent queue eviction, but exhaustion can make sends unavailable. Persistent volumes are not backups. sentmeans Gmail accepted the SMTP transaction, not inbox delivery, opening, or reading.
- Rotate API tokens manually with overlap: create and deploy a replacement, verify its use, then revoke the old token.
- Revoke an exposed Gmail App Password at Google, replace it in SendPlug, and test the sender.
- Rotate recovery and session secrets during maintenance; a session-secret change signs users out.
- A token-pepper change invalidates every existing API token; plan downtime and reissue them all.
- There is no online credential-key re-encryption. Replacing it makes stored sender ciphertext unreadable until credentials are re-entered. If the key and database leaked together, revoke every App Password.
- Preserve evidence, determine the exposure window, and fix the cause before restoration.
See the cutover runbook for backups, rollback, and reconciliation.