Encryption and security

How Backup protects database credentials, destination credentials, and the backup archives themselves.

Not verified yet

Backup handles three pieces of sensitive data: your database credentials, the credentials of BYO storage destinations, and the backup archives (your data, dumped). All are encrypted at rest; plaintext exists only in memory, inside short-lived scopes.

Credential storage (envelope encryption)

Database credentials and BYO destination credentials are protected the same way:

  1. A random 32-byte data encryption key (DEK) is generated via AWS KMS.
  2. The credentials are encrypted with AES-256-GCM using the DEK.
  3. The DEK itself is wrapped by a KMS key, bound to an encryption context{organization, datasource} for database credentials, {organization, destination} for destination credentials.
  4. Only the ciphertext, the wrapped DEK, and the key reference are stored. The plaintext and the DEK are wiped from memory immediately after sealing.

The encryption context matters: KMS refuses to unwrap a DEK unless the caller presents the exact same context, so ciphertext copied to a different organization or resource is undecryptable — a database leak alone yields nothing usable.

Credentials are write-only through the product: no dashboard screen or API response ever returns them.

How credentials reach the backup worker

When a job runs:

  1. The control plane assembles a one-job work order (job spec) containing the still-encrypted credential envelope and the destination details, and stores it encrypted, readable only via a short-lived presigned link.
  2. An isolated worker container is launched with just two inputs: the presigned link to its job spec and a callback URL for status reporting.
  3. The worker downloads the spec, calls KMS to unwrap the DEK (KMS validates the encryption context), decrypts the connection string in memory, and runs pg_dump / mongodump.

Credentials live in worker memory for the duration of the job; the container is destroyed afterwards. Nothing persists between jobs.

Worker authentication (the webhook token)

The worker reports status back with a single-use opaque token minted for that one job: 48 random bytes, of which the control plane stores only a hash. Callbacks are verified with a constant-time hash comparison plus an HMAC signature over the payload, and the token's first use is recorded to prevent replay. A stolen token is useless for any other job — and can't read anything, only report status for its own.

Archive encryption

  • In transit — the worker streams dump output to storage over HTTPS, always.
  • At rest, managed storage — archives are stored with server-side encryption in Norcube's bucket.
  • At rest, BYO destinations — per-destination setting: sse-s3 (the bucket's default encryption; R2, B2, Wasabi, and MinIO all encrypt at rest by default) or sse-kms (AWS S3 with a customer-managed KMS key). Set when creating the destination.

Connection security to your database

The worker connects to your database over the public internet from the static egress IP 18.196.207.101 — see Network access. TLS options in your connection string (sslmode=require, tls=true) are honoured end-to-end. The dump role should be read-only.

Worker isolation

  • Each backup runs in its own container — one job, one container, destroyed on exit. Nothing carries over between jobs.
  • Containers run as a non-root user with minimal cloud permissions: fetch the job spec, unwrap the DEK, write to the one destination.
  • Dump output streams straight to storage — no local disk, no temp files.
  • Error reporting is classified: the raw pg_dump/mongodump stderr is reduced to a human-readable summary ("authentication failed", "disk full") before it's stored, so connection-string fragments can't leak into job records.

Auditability

Every sensitive operation writes an audit log entry — with deliberate redaction: credential saves record only a success flag; download-link generation records size and expiry but never the URL (the URL is the capability). Audit entries are kept for one year; the retention deletion trail (what was deleted, when, why, bytes freed) is kept permanently.

On this page