Skip to content
MailHaap
[01]Security

Security is not a feature here. It is the licence to operate.

We hold other people's email — password resets, invoices, contracts, medical appointments. Here is exactly how it is isolated, encrypted, accessed and audited.

Four independent isolation layers

Application: every handler resolves the workspace from the verified credential and never from user input. Database: row-level security with FORCE, so a query missing its tenant clause returns nothing. Cryptographic: a per-workspace key bound by additional authenticated data, so a ciphertext moved between workspaces fails to decrypt. Provider: separate sending containers and separate DKIM keys per customer domain.

Object storage holds ciphertext only

Message bodies and attachments are encrypted before they touch storage, with a per-object key derived from the workspace key, which is itself wrapped by a root key held at a different provider. Possession of the object plus the storage credential is not sufficient to read anything.

Crypto-shredding

Deleting a workspace destroys its key. Every object belonging to it becomes permanently unreadable in the same instant, including copies in backups and replicas — a verifiable answer to “delete all my data” that object-by-object deletion cannot give.

No standing access

There is no standing production database access for anyone. Human access requires a stated reason, a second approver, a time-boxed credential and a session recording. Every decryption is written to an immutable audit entry with who, what, when and from where.

The vulnerability classes we design against

Every outbound fetch of a user-supplied URL goes through a guarded client that resolves DNS itself and rejects private, link-local, loopback and metadata ranges — including IPv6 and IPv4-mapped forms — re-checking after each redirect. The click redirector resolves destinations from server-side state, never from the URL. Header values are CR/LF-stripped before MIME assembly. The template evaluator has no file access, no network access and no arbitrary property traversal.

Tested, not asserted

For every resource type there is a test asserting that workspace B receives a 404 — never a 403 — for workspace A's object, via the API, via the download service, and via a direct database query under B's role. These tests block merges. So do the attachment tests: reading a raw object yields unparseable bytes, a download ticket cannot be redeemed twice, and a tampered ciphertext fails rather than returning partial data.

[02]Threat model

Who we are defending against, and with what.

Adversaries, their goal, and the primary defences
AdversaryGoalPrimary defences
Opportunistic attackerCredential stuffing, relay abuseMandatory 2FA, rate limits, no open relay, breached-password checks
Spammer or abuserUse us as a sending platformKYC tiers, warm-up ladder, content scanning, thresholds below the provider's
Competitor or scraperEnumerate customers and listsOpaque prefixed ids, row-level security, no enumeration endpoints
Targeted attackerRead one specific customer's mailEnvelope encryption, no standing access, audit, hardware-key MFA
Compromised customer accountSend spam, exfiltrate contactsAnomaly detection, per-mailbox caps, export limits, session invalidation
Malicious insiderBulk data accessBreak-glass with dual approval, immutable audit, key-service rate limits
Supply chainMalicious dependencyPinned dependencies, SBOM per release, signed images, restricted egress
Compelled or breached providerRead stored contentCiphertext only; the root key is held at a different provider entirely
[03]Mail-specific

We must be the most correctly configured domain we host.

  • mailhaap.com publishes DMARC at p=reject, MTA-STS and TLS-RPT.
  • No open relay, ever. Submission always requires authentication, and automated relay tests run hourly against our own hosts.
  • TLS is mandatory for submission and IMAP. Inbound MX is opportunistic with MTA-STS offered — refusing plaintext inbound would silently drop legitimate mail from misconfigured senders.
  • DKIM keys are 2048-bit, one per customer domain, stored envelope-encrypted, rotated annually with a 14-day overlap.
  • SPF, DKIM, DMARC and ARC are verified on every inbound message, and the results are surfaced in the interface rather than hidden in the spam score.
  • [email protected] is monitored with an SLA and feeds directly into the abuse workflow.
[04]Compliance

Where we are, and when.

Compliance roadmap
MilestoneTiming
Security page, DPA, sub-processor listGate 2
External penetration test, full scopeBefore general availability
Private bug bounty, then publicGate 4
SOC 2 Type IGate 5
SOC 2 Type IIGate 5 + 6 months
ISO 27001Evaluated at Gate 6

Restore drills run monthly, timed, into a scratch environment — an untested backup is not a backup. Target recovery time is four hours; target recovery point is fifteen minutes.

Found something? Tell us before you tell anyone else.

Report vulnerabilities to [email protected]. We acknowledge within one working day, we do not threaten researchers, and we credit you in the fix unless you ask us not to.