Why Dotenvx Uses Git, .env, and secp256k1 for Secrets

Updated

Dotenvx combines three existing primitives instead of inventing a new secrets system: Git distributes the encrypted .env file alongside your code, .env remains the standard way apps load environment variables, and secp256k1 (the elliptic curve Bitcoin has used for years) makes the values unreadable without your private key. The practical result is that you commit ciphertext, set one private key on your infrastructure, and Dotenvx decrypts and injects the values just-in-time when the app runs. This design fits teams that already deploy code through Git and want secrets to travel the same path without a separate secrets service.

The three primitives and what each one does

The design page on dotenvx.com describes the system as built entirely from primitives developers already understand and infrastructure they already use. Each piece has a narrow job:

Primitive Role in Dotenvx Why it was chosen
Git Delivers the encrypted .env file with the code Described as the best way to deliver digital goods — "the container ship of the digital world"
.env Defines how the app consumes secrets as environment variables The open standard for loading secrets into code, consistent with twelve-factor config
secp256k1 Encrypts the values so only the private key can unlock them A proven, simple asymmetric standard with small keys, battle-tested by Bitcoin

The key separation is deliberate: encryption lets the values sit next to the code in Git, while the decryption key stays on the environment (infrastructure) rather than in the repository. That keeps the twelve-factor principle of separating config from code intact.

Why Git instead of a dedicated secrets service

The stated reasoning is that code already travels through Git, so secrets should use the same channel rather than a purpose-built delivery mechanism. The design page puts it directly: why invent an inferior secrets delivery mechanism when a world-class one is already at hand. In practice this means:

  • One distribution path. git add .env and git commit put the encrypted file in the same history as the code that reads it.
  • Sharing through Git. Because the committed values are ciphertext, secrets can be shared through the repository safely.
  • No parallel system to operate. There is no separate secrets store to keep in sync with deployments.

This is a design argument, not a guarantee for every team. If your organization already runs a secrets manager with audit logging and rotation workflows, the trade-off is between that operational tooling and the simplicity of shipping secrets with code.

Why .env and secp256k1 specifically

.env was chosen because it is the open standard for injecting environment variables at runtime — the core primitive all secrets end up in. Keeping that format means existing apps and frameworks load variables the same way they always have; only the file's contents change from plaintext to ciphertext.

For encryption, the requirements were a proven, simple asymmetric standard with small keys. secp256k1 met all three: it is asymmetric (so the private key can stay off the code path), its keys are small, and it has a long track record through Bitcoin. The page frames cryptography as an opinionated choice made so developers don't have to pick an algorithm themselves.

What the single private key changes about key management

The design's stated payoff is operational: all of this works by setting a single private key on your infrastructure. The page contrasts that with "risky async coordination of secrets" and "centralized downtime risk," and says your secrets are always just there with your code.

Concretely, the workflow is:

  1. Encrypt: dotenvx encrypt turns the values in .env into ciphertext.
  2. Commit: git add .env and git commit -m "encrypt .env" store the encrypted file with your code.
  3. Run: dotenvx run -- node index.js decrypts with the private key and injects the variables — the page's example shows injected env (2) from .env.

The thing to verify before adopting this: the single private key becomes the one thing that must be present and protected on every environment that runs the app. The design removes coordination between a secrets service and your deployments, but it concentrates trust in that key. How you store and distribute it is your responsibility, and the page does not describe a key-rotation or recovery process.

When this design fits

Choose the Git + .env + secp256k1 approach when your deployments already flow through Git, your apps read environment variables from .env, and you want secrets to ship with code without running a separate secrets service. Look elsewhere, or plan additional controls, if you need centralized audit trails, automated rotation, or per-secret access policies — none of which the design page claims to provide.