Security

Data protection

AdminUpdated Sep 11, 2026

How Atlas keeps data confidential, isolated between tenants, and recoverable.

Encryption at rest

Every secret Atlas stores is encrypted at the application layer with AES-256-GCM before it reaches the database — the database never sees plaintext secrets. Encryption uses envelope encryption: each instance has its own data key, and that data key is itself wrapped by a root key held outside the database (and, in managed deployments, backed by a KMS). Compromising a database dump does not compromise the secrets in it without the keys.

The secrets protected this way include:

  • Time-based one-time password (TOTP) shared secrets

  • Webhook signing secrets

  • OAuth provider tokens and client secrets held on behalf of a tenant

  • Per-instance JWT signing keys

  • The PKCE code verifier for in-flight OAuth flows

Each encrypted value is stored as a versioned envelope (a v1. prefix identifies the scheme), and an automated test asserts that these columns never contain plaintext.

One value is deliberately not envelope-encrypted: the OAuth state lookup key. It is the key the provider callback uses to find the pending attempt, so a random-IV encryption would make the lookup impossible. Instead it is protected the way a lookup key should be — high entropy, single use, and a short time-to-live — and this choice is documented in the code rather than left implicit.

Passwords are never stored in any recoverable form. They are hashed with Argon2id.

Encryption in transit

All traffic is served over TLS. For managed domains, certificates are issued and auto-renewed through Let's Encrypt, and HSTS is enabled at the edge (max-age one year, includeSubDomains, preload) with HTTP redirected to HTTPS. Self-hosted operators terminate TLS at their own edge and control their own certificate and header policy.

Tenant isolation

Atlas is multi-tenant, and isolation is enforced at the data (repository) layer, not left to individual route handlers to remember. Every query for tenant-owned data — users, emails, events, audit records, sessions — is scoped by instance_id at the repository, so no request can read across a tenant boundary.

A subtle but important detail: a request for a record that belongs to another tenant returns 404 Not Found, not 403 Forbidden. A 403 would confirm that the record exists; a 404 reveals nothing. This behavior is covered by automated tests for each tenant-scoped resource, so a regression fails the build rather than surfacing as a cross-tenant leak.

Data residency

  • Self-hosted: your data lives wherever you run Atlas — your cloud account, your region, your control. Nothing in Atlas keeps state outside your own Postgres and Redis.

  • Managed: the managed service currently runs in a single region. Region selection and multi-region residency are on the roadmap; because Atlas keeps no local state outside Postgres and Redis, multi-region is an operational rollout rather than an architectural change.

Backups & disaster recovery

For the managed service, Atlas takes daily automated backups that are shipped off-box (so the loss of the primary host does not take the backups with it), stored encrypted, and kept for a defined rolling retention window. Restore and incident procedures — database recovery, cache loss, provider outage, and signing-key rotation — are documented in internal runbooks.

We are candid about the current limits: managed Atlas today runs on a single primary database without automated failover. That is the one honest availability caveat, and automated high availability and multi-region failover are on the roadmap. Recovery today is a restore-from-backup operation, not an instantaneous failover. Self-hosted operators define their own backup, retention, and high-availability posture to match their requirements.

Key management & rotation

Signing keys are per-instance and rotate. When a JWT signing key rotates, the previous key stays published in the JWKS for 24 hours so tokens already issued keep verifying through the transition. The root key that wraps per-instance data keys is managed outside the database and can be rotated without re-encrypting tenant data one row at a time.

Was this page helpful?
Data protection