Tenant isolation is enforced by the database
Every table that belongs to a customer carries an account id and is covered by a PostgreSQL row-level security policy keyed on it, with FORCE enabled so the policy applies to the table owner too. The application connects as a role that cannot bypass those policies.
This matters because it makes isolation a property of the database rather than of every query we will ever write. A developer who forgets a WHERE account_id = … gets no rows, not somebody else’s.
Signing keys are encrypted at rest
Each sending domain gets its own 2048-bit DKIM key pair, generated by us. The private half is encrypted with AES-256-GCM under a key held outside the database and mounted at runtime, never baked into a container image or committed to a repository.
The reason is specific: a database dump alone must not let anyone sign mail as one of our customers. That would let them forge DMARC-passing mail from a domain we vouch for, which is worse than leaking the data itself.
API keys are never stored
We store an HMAC of the secret under a server-side pepper, not the secret. A key is shown once, at creation. If it is lost it is rotated, not recovered — and a stolen database gives an attacker nothing they can authenticate with.
The delivery record is append-only
Message events are written to a log that cannot be updated or deleted, and each entry is hash-linked to the one before it. The chain is computed inside the database, in the same transaction as the insert, so two concurrent writers cannot fork it.
The practical effect is that the record is tamper-evident: removing or editing an event breaks the chain from that point onward, and you can verify it yourself rather than taking our word for it.
Webhooks are signed and replay-resistant
Every webhook carries a timestamped HMAC signature over the raw body. Verify it with a constant-time comparison and reject anything outside your tolerance window — the docs show exactly how, including the mistake of parsing the JSON before verifying the bytes.
Deliveries are retried with backoff and carry an idempotency key that stays the same across retries, so a redelivery can never be mistaken for a second event.
In transit
The API is HTTPS only. Outbound mail uses opportunistic TLS: we negotiate STARTTLS with the receiving server whenever it offers it, which is the overwhelming majority of mail. Where a receiver offers no TLS the alternative is not delivering at all, so we deliver and record exactly what happened — the connection details are in the message’s record.
What we do not claim
We are not SOC 2 or ISO 27001 certified. We do not have a formal bug bounty. We are not going to imply otherwise on a marketing page — if you need an audited provider today, we are not it yet, and we would rather tell you now than during procurement.
Reporting a vulnerability
Email [email protected] with enough detail to reproduce the issue. We will acknowledge within three working days and keep you updated until it is resolved.
Please do not run automated scanners against production, do not access or modify data that is not yours, and give us a reasonable window to fix things before disclosing publicly. We will not pursue legal action against anyone acting in good faith under those terms.
- Security contact
- [email protected]
- Abuse reports
- [email protected]
- Data protection
- [email protected], and the data processing terms