SECURITY · POLICY

Security practices.

LAST UPDATED · 2026-04-20

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.dev and mailsink.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 .eml bytes 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:user and user:email scopes.
  • 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-Limit and X-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_id on every query.
  • Internal-only endpoints (ingest, domain verification) require a separate INTERNAL_SECRET that 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 [email protected] 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: [email protected].