backupd
Security

How your data is protected

How backupd encrypts backups, who can decrypt them, how database credentials are stored, and how connections are secured.

Backups are encrypted before they are stored

Every backup is compressed with zstd and encrypted with age (version 1, X25519 keys) as it streams from your database. Storage only ever holds the encrypted file. Each backup's manifest is encrypted the same way.

You can open any backup with the stock age tool. There is no proprietary format.

Who can decrypt a backup

Each file is encrypted to every key on your workspace at the time it is made:

  • backupd's key for your workspace. It is unique to your workspace and lets backupd run restores and restore tests for you. Its secret half is itself encrypted at rest, and is only used by backupd to restore and test your backups. You can see its public key in Settings โ†’ Encryption, under backupd's key.
  • Each key you add. Up to 3 keys, added in Settings โ†’ Encryption. backupd only ever has the public half. See Encryption keys.

There is no mode where only you can open a backup. If you need that, tell us at support@backupd.dev.

Until you add a key, only backupd can decrypt your backups. The Encryption page shows a warning while that is the case.

Database credentials

  • Connection strings, Convex keys and bucket keys are encrypted at rest with AES-256-GCM.
  • After you save a connection string, the app only shows its host.
  • Credentials are handed to the dump tools through environment variables or a private option file that is deleted after the run. They never appear on a command line.
  • Error messages are scrubbed of passwords before they are shown or sent as alerts.

Connections

  • TLS on every connection. Connection strings that turn TLS off are rejected, and modes that would fall back to plain text are upgraded to require TLS.
  • Public addresses only. backupd resolves your host once, connects to that address, and refuses private, loopback and link-local ranges, so a connection string can't be pointed at backupd's own network.
  • Read-only is enough. A user with read access is all a backup needs.
  • Uptime checks never log in. They only open a connection and close it. See Uptime monitoring.

Access to your workspace

  • Members have roles: Owner, Admin or Member. See Members and roles.
  • Sign in with a passkey, or with a password and two-factor codes. See Passkeys, two-factor and sessions.
  • Every action in the workspace, including denied attempts and downloads, is recorded in an audit log that nobody can edit, kept for a year.
  • When backupd support signs in as a member to help, it lasts at most an hour and the audit log shows backupd support for everything done.

Restore tests run on separate servers

Restore tests restore your backup into a temporary database on a sandbox server, never into your database, and drop it afterwards.

  • The sandbox servers sit on a network with no internet access and no route to backupd's app, its database or its keys.
  • PostgreSQL and MySQL backups are restored by a throwaway database user that owns only the temporary database, so functions, triggers and procedures in your dump never run as an administrator.

The app and the API

  • HTTPS everywhere, with HSTS. Pages can't be shown inside another site's frame.
  • Session cookies are HTTP-only, secure and same-site, and the API refuses changes sent from other sites.
  • Webhook URLs, uptime checks and custom bucket endpoints are refused when they point at private addresses.

Where it runs

The app, its database, the backup workers and the sandboxes run in Frankfurt, Germany. Backups are stored in the region your workspace picks. See GDPR and your data.

Report a vulnerability

Write to security@backupd.dev. See also backupd.dev/.well-known/security.txt.

On this page