Doppler is an established server-side secrets product. Their public security write-up describes a two-tier design: encryption operations run on infrastructure that is not exposed to the public internet, with secrets tokenized and ciphertext returned through the customer-facing tier. The design keeps raw plaintext off internet-facing servers.
Capy is built around a different choice. Capy’s CLI encrypts each value on the engineer’s machine before it reaches the service. For ordinary cloud and BYOC key files, the service stores ciphertext and needs a client-held inner key to decrypt it. Both designs are reasonable; they answer different questions about what a breach of stored service data exposes.
At a glance
What this looks like at the request path
Picture the same workflow under each product. An engineer adds a new value, STRIPE_SECRET_KEY. Under Doppler, the value goes over TLS to Doppler’s API, the encryption tier wraps it, and the ciphertext lands in the database tier. Under Capy, the value is encrypted on the engineer’s machine; only the ciphertext is uploaded to the service, which syncs it to teammates’ machines. In each case the value is available at runtime via a one-line invocation (doppler run -- ..., capy run -- ...); the difference is what the vendor’s infrastructure ever held.
The keep.lock manifest lives in your git repo as a committable list of hash references, so a code reviewer can see in a PR diff which secrets changed, without seeing the values. capy kick deletes a teammate’s membership, after which the service refuses future outer-wrap removal for ordinary key.enc files. That does not erase values or usable keys already copied from a compromised device; rotate or rekey the affected scope when needed.
When Doppler is a good fit
Teams whose buying criteria centers on a hosted dashboard for non-CLI stakeholders, many built-in integrations into a long list of SaaS targets, or compliance certifications obtained against a server-side architecture will find Doppler a good fit. The trusted-vendor model is widely accepted in regulated workloads where the vendor is already in scope, and Doppler has staffed for that.
When Capy is the better answer
If “the vendor cannot decrypt our secrets” needs to be a built-in property rather than a configuration setting (common for teams handling customer keys, sovereign data, or for teams that want a breach to come out as “ciphertext was exfiltrated, the attacker has bytes”), Capy’s request path is the answer. Likewise if your secret changes belong in code review (the keep.lock manifest makes that legible without exposing values), or if removing a teammate should be a one-command event rather than a rotate-everything ritual.
Client-side encryption keeps an exfiltrated .env as ciphertext. It does not contain an agent with user-level command access: an agent that can run Capy as you can invoke commands that decrypt values your account can use. The comparisons overview covers this distinction.
Pulling values out of Doppler when you migrate is straightforward: doppler secrets download --no-file --format json produces a JSON dump per config. Capy has no importer — you write each config’s values into a .env and run capy, which encrypts every value on your machine and uploads the ciphertext. Use capy checkout -b <branch> to give the next config its own Capy branch, then repeat. The whole exercise is usually an evening on a small project.
The deciding question, said plainly: what does a breach of your secrets vendor cost you? If “we’d rotate and survive” is acceptable, Doppler will serve. If there are values that must remain unreadable to the vendor (even encrypted, even at rest, even with separated infrastructure), the request-path difference is what you’re buying. Last modified on October 2, 2026