Help us shape the future of Go! Take the 2026 Go Developer Survey

doppler-backup

module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: MIT

README

doppler-backup

CI Release Go Reference

Emergency backup/restore for Doppler secrets.

Doppler keeps per-secret version history and an activity log, but it cannot recover a deleted project. doppler-backup is a local safety net: it snapshots every secret in every project/config into a SQLite database, encrypted at rest with AES-256-GCM under a passphrase you choose, and can restore any snapshot back into Doppler.

Who may need this?

Anyone using the 'developer' Doppler account for secrets management with applications (e.g. solo developers, very small teams). This application was developed against the features of a 'developer' Doppler account.

There may be features in a Doppler 'teams' or 'enterprise' account that may be suitable for inclusion in this type of application. I'm happy for this project to be cloned or forked in that regard for someone to add missing features for the 'teams' or 'enterprise' Doppler account types.

Prerequisites

  • The doppler CLI, version 3.76.0 or newer, installed and authenticated (doppler login) — doppler-backup shells out to it rather than talking to the Doppler API directly. backup and restore check the installed CLI's version up front and fail fast with a clear error if it's too old.
  • Go 1.26+ — only needed if building from source; skip it if you're using a prebuilt binary.

Install

Download a prebuilt binary

Each GitHub Release has binaries for Linux, macOS, and Windows attached. Download the asset that matches your OS/architecture, e.g. for release vX.Y.Z:

OS Architecture Asset
macOS Apple Silicon doppler-backup-vX.Y.Z-darwin-arm64
macOS Intel doppler-backup-vX.Y.Z-darwin-amd64
Linux amd64 doppler-backup-vX.Y.Z-linux-amd64
Linux arm64 doppler-backup-vX.Y.Z-linux-arm64
Windows amd64 doppler-backup-vX.Y.Z-windows-amd64.exe

On Linux/macOS, mark the download executable and move it onto your $PATH:

chmod +x doppler-backup-vX.Y.Z-<os>-<arch>
mv doppler-backup-vX.Y.Z-<os>-<arch> /usr/local/bin/doppler-backup
Build from source
git clone https://github.com/johndotmcgann/doppler-backup.git
cd doppler-backup
make build          # produces bin/doppler-backup
make install         # go install into $GOPATH/bin

Usage

All commands accept --db PATH to choose the SQLite database file (default ./doppler-backup.db). The database is created automatically on first use and locked down to owner-only (0600) permissions.

A passphrase is always required to encrypt or decrypt the backup database — there is no default and no environment-variable fallback. Pass it via --passphrase (or --old-passphrase/--new-passphrase for rotate), or omit the flag when running interactively to be prompted for it without the input being echoed back. Running non-interactively (e.g. from cron) without the flag is an error, so unattended use must always pass the flag explicitly.

Passphrases used to encrypt (backup, and rotate's --new-passphrase) must be at least 12 characters. Length, not character-class complexity, is what protects against offline brute force here — this passphrase feeds directly into scrypt and protects a static file an attacker with a copy can attack with no rate limiting — so a long random passphrase from a password manager, or a multi-word Diceware-style phrase, is both easier to type and stronger than a short "complex" one. Passphrases used only to decrypt existing data (restore, and rotate's --old-passphrase) are accepted as-is regardless of length, so databases created before this minimum was introduced remain restorable; run rotate to move such a database onto a compliant new passphrase.

Backup

Snapshot every project and config visible to your Doppler token:

doppler-backup backup --passphrase '<your passphrase>'

Limit to a single project:

doppler-backup backup --project my-project --passphrase '<your passphrase>'

A failure on one config (e.g. a locked or inaccessible config) is logged and skipped rather than aborting the whole run. The command exits non-zero only if every backup attempt failed.

List snapshots
doppler-backup list
doppler-backup list --project my-project

Shows snapshot id, project, config, and timestamp (no passphrase needed — listing doesn't decrypt anything).

Restore

Restore the most recent snapshot for a project/config:

doppler-backup restore --project my-project --config prd --passphrase '<your passphrase>'

Restore a specific snapshot by id (see doppler-backup list):

doppler-backup restore --project my-project --config prd --snapshot 12 --passphrase '<your passphrase>'

--project and --config must be given explicitly — there is no "restore everything" mode, since blindly overwriting every config at once is more dangerous than the problem this tool solves. Restoring into a brand-new project (e.g. after recreating one that was deleted) works the same way: create the project/config in Doppler first, then restore into it.

A wrong passphrase fails cleanly with incorrect passphrase or corrupted snapshot rather than silently writing garbage secrets.

Rotate passphrase

Re-encrypt every stored snapshot under a new passphrase, invalidating the old one:

doppler-backup rotate --old-passphrase '<current passphrase>' --new-passphrase '<new passphrase>'

This decrypts every snapshot with the old passphrase and re-encrypts it under a freshly generated salt and the new passphrase, all inside a single transaction — either everything is rotated or nothing is. Before making any changes it copies the database to <db>.bak-<unix timestamp> as a safety net; delete that copy once you've confirmed the new passphrase works.

How it works

  • Backup: enumerates projects (doppler projects) and configs (doppler configs), downloads each config's secrets (doppler secrets download --json), encrypts the JSON blob, and stores it as one row per project/config/timestamp.
  • Restore: decrypts the chosen snapshot, writes it to a temporary 0600 file, and uploads it with doppler secrets upload. The temp file is created in /dev/shm (tmpfs) when available, falling back to the OS default temp directory otherwise, and is removed as soon as the upload finishes. A SIGINT/SIGTERM handler also removes it if you interrupt a restore mid-flight. None of this protects against SIGKILL or a hard crash between the write and the cleanup — in that narrow window, decrypted secrets can be left on disk (or in tmpfs, which itself can be swapped to disk on memory pressure unless swap is disabled).
  • Encryption: a random salt is generated once per database and stored in a meta table. Every run derives a 32-byte key from your passphrase and that salt via scrypt, then encrypts each snapshot with AES-256-GCM and a fresh random nonce. Losing the passphrase means losing access to every snapshot in that database — there is no recovery mechanism.
  • Doppler's computed DOPPLER_PROJECT / DOPPLER_CONFIG / DOPPLER_ENVIRONMENT values are stripped before snapshotting since they describe the target config rather than being real secrets.

Notes

  • No built-in scheduling — run doppler-backup backup from cron or a similar scheduler for regular snapshots.

Directories

Path Synopsis
cmd
doppler-backup command
internal
crypto
Package crypto encrypts secret snapshots at rest using a passphrase-derived AES-256-GCM key, so the SQLite database never stores plaintext secrets.
Package crypto encrypts secret snapshots at rest using a passphrase-derived AES-256-GCM key, so the SQLite database never stores plaintext secrets.
doppler
Package doppler wraps the `doppler` CLI (assumed installed and authenticated on the host) rather than reimplementing Doppler's API.
Package doppler wraps the `doppler` CLI (assumed installed and authenticated on the host) rather than reimplementing Doppler's API.
store
Package store persists encrypted secret snapshots in SQLite.
Package store persists encrypted secret snapshots in SQLite.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL