Security
Last updated: April 20, 2026
MailSink handles email traffic for real test suites and agent runs. That's sensitive by default — an inbox may catch a signup OTP, a password reset link, or content you'd rather not leak. This page documents what we do about that.
Transport
-
All HTTP traffic terminates on Cloudflare's edge with TLS 1.3. HSTS
is enforced on
api.mailsink.devandmailsink.dev. - Inbound email rides Cloudflare Email Routing. Cloudflare's MX frontends advertise STARTTLS; delivery from major providers (Gmail, Outlook, Sendgrid, Postmark) is encrypted in transit.
Storage
-
Raw
.emlbytes and parsed JSON are written to Cloudflare R2. Metadata (sender, subject, extracted code/link, size) lives in Cloudflare D1. - Both are encrypted at rest by Cloudflare. We don't manage our own encryption keys — we rely on Cloudflare's default encryption for R2 and D1.
- Emails expire and are hard-deleted on the TTL you set when you create the inbox (max 1h Free, 24h Pro, 7d Team). A cron job runs hourly and removes expired rows from D1 and objects from R2. Burning an inbox manually deletes immediately.
Authentication
-
Sign-in uses GitHub OAuth. We request only
read:useranduser:emailscopes. -
API access uses bearer tokens prefixed
msk_. Tokens are hashed with SHA-256 before storage — we can't recover a token after you dismiss the one-time reveal. -
Rate limits are enforced per-key in Cloudflare KV: 60/min Free,
600/min Pro, 3000/min Team. Clients see the window via
X-RateLimit-LimitandX-RateLimit-Remaining.
Access model
-
An API key scopes to a single account. There's no cross-account read
path in the API. Inboxes, messages, and keys are filtered by
account_idon every query. -
Internal-only endpoints (ingest, domain verification) require a
separate
INTERNAL_SECRETthat never leaves the Worker boundary.
Subprocessors
We share data with the following third parties only as required:
- Cloudflare — compute (Workers), storage (D1, R2, KV), DNS, email routing, CDN.
- Stripe — billing. Payment card data is entered directly into Stripe's hosted Checkout. We store only a Stripe customer ID and subscription status.
- GitHub — OAuth identity provider. We store your GitHub user ID, username, and primary email.
Responsible disclosure
If you find a vulnerability, please email security@mailsink.dev before sharing details publicly. We'll acknowledge within 72 hours and work with you on a fix timeline.
Please don't run active exploitation against production (automated scanners are fine against your own inboxes; denial-of-service probes are not). We don't currently run a paid bounty program, but we'll credit reporters in the changelog unless you'd rather stay anonymous.
What we don't claim
- No SOC 2, no ISO 27001. MailSink is an indie-run service. If your compliance regime requires either, we're not the right fit yet.
- No data residency guarantees beyond what Cloudflare provides. Email content may land in any Cloudflare region.
Contact
General security questions: security@mailsink.dev.