Encryption in transit

Every endpoint we operate is served over TLS: the API at api.deadsimple.email (AWS API Gateway in front of Lambda), the dashboard at app.deadsimple.email, the identity provider at id.deadsimple.email, the hosted MCP server at api.deadsimple.email/mcp, and this site. Webhook destinations are validated at registration and must be https:// URLs; an http:// destination is rejected. The IMAP and SMTP credentials issued for each inbox use IMAP on port 993 (TLS) and SMTP submission on port 587 (STARTTLS). Outbound mail from the API to our relays and to Postmark is submitted over STARTTLS on port 587.

Data at rest

All customer data lives in AWS, region us-east-1.

  • DynamoDB holds accounts, inboxes, messages, API keys, webhooks, events and billing records. Tables are encrypted at rest with DynamoDB's default server-side encryption (AWS-owned keys). We do not currently use customer-managed KMS keys.
  • S3 holds two things: the raw MIME of each inbound email, and attachment bytes. Every object is written with server-side encryption (SSE-S3, AES-256) set on the request. The raw-email bucket has a lifecycle rule that expires objects after 30 days; the parsed message in DynamoDB is the record of truth and is kept for as long as your account holds it. Attachments are stored up to 25 MB each and served through an ownership-checked API endpoint, never a public URL.
  • Mail servers (the Dovecot and Postfix hosts behind the shared domain) run on EC2 in the same region. Mail spends time there in transit to the inbound pipeline; the pipeline hands it to S3 and DynamoDB as above.

Credentials and authentication

  • API keys are dse_-prefixed with a 128-bit random secret. Only the SHA-256 hash is stored; the raw key is shown once at creation. Keys can be revoked individually, and each key carries a granular permission set (for example guardrails.read) rather than a single all-or-nothing scope. Keys can be scoped to a workspace for multi-tenant isolation.
  • Dashboard passwords are hashed with bcrypt. Sessions are signed JWTs (HS256) that expire after 72 hours and carry a unique id so an individual session can be revoked. Signup and login are gated by Cloudflare Turnstile.
  • MCP OAuth 2.1: the hosted MCP server issues access tokens through an authorization-code flow with PKCE (S256), dynamic client registration (RFC 7591) and revocation (RFC 7009). The user approves the grant on the dashboard. Tokens are scoped to email operations only, with no billing or account administration, and are stored SHA-256 hashed like API keys. Access tokens live 7 days; refresh tokens live 90 days and rotate on every use.
  • Sign in with Dead Simple (the OpenID Connect provider) requires PKCE S256, signs id_tokens with ES256, keeps authorization codes single-use for five minutes, stores its access and refresh tokens as SHA-256 hashes, and never places the account owner's email in an id_token. Details are on the identity page.
  • Inbound pipeline: the endpoint that receives mail from our mail servers authenticates each delivery with a shared secret held in AWS SSM Parameter Store; unauthenticated posts are refused.

Authorization and inbox guardrails

Beyond per-key permissions and workspace scoping, each inbox can carry guardrails that the API enforces on every outbound action regardless of what the calling agent asks for: allowed_domains, blocked_domains, max_sends_per_hour, can_reply, can_forward, can_delete, require_draft_approval (all sends must go draft, approve, send) and max_attachment_size_mb. Team members have roles with a minimum-role check on administrative routes.

Webhook integrity

Each webhook has its own signing secret, derived from a master secret and the webhook id. Every delivery is signed with HMAC-SHA256 over "<timestamp>.<body>" and carries the signature in two headers, X-DSE-Webhook-Signature: sha256=<hex> and X-DSE-Signature: t=<timestamp>,v1=<hex>, plus X-DSE-Webhook-Id and X-DSE-Webhook-Timestamp. Including the timestamp in the signed content lets a receiver reject replays. Failed deliveries are retried on an exponential schedule (1s, 30s, 5m, 30m, 2h, 24h by default) and logged per webhook, with replay from the dashboard. Custom headers you attach to a webhook cannot override the signature headers.

Inbound mail: spam and prompt injection

Inbound mail passes through the mail server's spam filter (Rspamd) and arrives with is_spam and spam_score on the message. Separately, every inbound message is scanned for prompt-injection patterns aimed at an agent reading it and annotated with injection_risk and injection_score. Both are advisory: nothing is silently dropped, and your handler and guardrails decide what happens. Per-inbox allowlist and blocklist filters can reject senders before a message is stored; a rejected message emits a message.rejected event. Attachments are stored and, for PDF, XLSX, DOCX and CSV, extracted to text; they are not scanned for malware. Treat attachment bytes as untrusted.

Abuse controls

Because this is an email platform, the abuse we defend against most is the platform being used to send phishing. Controls in production:

  • Cloudflare Turnstile on signup and login, plus per-IP, per-subnet, per-day and platform-wide rate limits on account creation.
  • Signup rejection for disposable email domains and for domains whose MX points at a temp-mail provider.
  • Brand-impersonation checks on inbox addresses on the shared domain, so a stranger cannot create an inbox that reads as a well-known company.
  • Account-wide outbound caps keyed on account age for accounts with no payment method, and fan-out detection that counts distinct recipients: a young unpaid account that mails many strangers in a day is suspended automatically and the team is alerted.
  • Bounce and complaint feedback from our delivery providers is ingested and hard-bouncing addresses are suppressed automatically.

Suspension is reversible and keeps all data. A suspended account can still read through the API and the dashboard, but every request that sends, creates or changes something is refused with account_suspended. The Acceptable Use Policy sets out what leads to it.

Data deletion

Deleting an inbox removes it and its mailbox on the mail server. Permanent account deletion, run by us on request, removes users, workspaces, API keys, inboxes and their mailboxes, messages, attachment objects in S3, events, webhooks, domains and the smaller per-account records across every table. Before the purge runs, a JSON snapshot of the deleted records is written to a restricted internal archive bucket so that a mistaken deletion can be reversed; tell us if your requirements need that archive purged as well and we will arrange it. An account with an active Stripe subscription is not deleted until the subscription has been cancelled. Raw inbound MIME expires from S3 after 30 days on its own.

Subprocessors

These are the third parties that may process customer data as part of running the service.

SubprocessorPurposeData involved
Amazon Web Services (us-east-1)Hosting: Lambda, API Gateway, DynamoDB, S3, SQS, EC2 mail servers, SES for some outbound mail, Parameter Store for secretsAll customer data
StripeSubscription billing, invoices, pay-per-request card payments (MPP)Billing contact, payment details (held by Stripe, not by us)
PostmarkOutbound delivery for custom domains connected since September 2026; delivery and bounce webhooks back to usOutbound message content and recipients for those domains
Cloudflare TurnstileBot check on dashboard signup and loginBrowser signals at signup and login; no email content
VercelHosting for the dashboard at app.deadsimple.emailDashboard traffic; the dashboard reads and writes through our API
DynadotDomain registrar for domains purchased through Dead SimpleRegistrant contact details for purchased domains only
PayAIx402 payment facilitator for pay-per-request callsPayment payloads for x402 requests only; no email content

Reporting a vulnerability

If you believe you have found a security issue in Dead Simple Email, email security@deadsimple.email with enough detail to reproduce it. We read every report, we will acknowledge it, and we ask that you give us reasonable time to fix an issue before publishing. Please do not test against accounts or inboxes you do not own. We do not currently run a paid bug bounty.

Compliance

Dead Simple Email is not yet SOC 2 certified. We will update this page when that changes rather than imply it in the meantime. A completed security questionnaire, covering the controls on this page in the format most vendor assessments use, is available on request to support@deadsimple.email. Our Privacy Policy, Terms of Service and Acceptable Use Policy are public. Data is processed in the United States (AWS us-east-1); we do not currently offer other regions.

Last reviewed: September 17, 2026.

Need the questionnaire?

Send us the format your team uses and we will return it completed.

support@deadsimple.email Prompt-injection scanning