Docs/ Privacy & security

Encryption & key handling

Secrets envelope-encrypted; bring your own AI key if you prefer.

Every secret Aiemaily holds on your behalf — OAuth tokens, IMAP passwords, BYOK keys — is envelope-encrypted and decrypted only in an isolated worker at the moment it’s needed. Nothing sensitive is stored inline, written to logs, or accessible to application code.

Encryption in transit and at rest

All traffic between your device and Aiemaily’s servers travels over TLS 1.2+ with modern cipher suites. Connections that fall back to older TLS versions are rejected at the load balancer.

Data at rest — message bodies, metadata, summaries — is encrypted using AES-256 at the storage layer. Object storage blobs (message bodies) carry an additional per-object encryption key managed by a KMS, so a compromised storage layer cannot yield plaintext without also compromising the KMS.

Envelope encryption for all credentials

OAuth tokens, IMAP/SMTP credentials, and BYOK keys are wrapped with a per-user data encryption key (DEK), which is itself encrypted by a key encryption key (KEK) held in a dedicated KMS. The DEK is never stored alongside the ciphertext it protects. Plaintext credentials never touch application logs, error reports, or analytics pipelines.

Least-privilege everywhere

Aiemaily requests the minimum OAuth scopes needed for each mail provider. For Gmail this means read + send + label management; we never request contacts export, Drive access, or admin APIs. Scope grants are surfaced in the connection UI so you can see exactly what you’ve authorised.

Every database row, object storage blob, and function invocation carries an owner ID. Requests that don’t present a matching JWT are rejected at the data layer, not just the API layer. This object-level authorisation means a bug in the API routing cannot leak one user’s data to another.

Request authorisation flow (simplified)
1Client sends JWT in Authorization: Bearer …
2API gateway verifies signature + expiry
3Function extracts userId from verified claims
4DB query includes WHERE owner_id = :userId
5Object storage policy rejects cross-user blob reads
6Result returned — no cross-account data possible

Webhooks, CORS, and CSP

Inbound webhooks from Stripe, Gmail Push Notifications, and Microsoft Graph are validated with HMAC signatures before any payload is processed. Replayed or tampered webhooks are silently dropped and logged.

The web app ships with a strict Content Security Policy that blocks inline scripts, restricts fetch targets to our own domains and known API hosts, and disallows framing from third-party origins. CORS is configured per-route to allow only the production and staging origins.

Idempotency and safe retries

Every mutating API call — send, archive, label, delegate — accepts an idempotency key so that network retries can’t duplicate actions. This is especially important for send: if a connection drops after the server accepts the request, a retry with the same key is a no-op, not a duplicate send.

PCI compliance via Stripe

Card data never touches Aiemaily servers. Billing flows use Stripe’s hosted checkout and Elements; we store only the Stripe customer ID and subscription status.

Frequently asked

Feature overview

AI Drafting

Ready to try it?

Start free