Dotenvx: Encrypted Environment Variables for Modern Deployments
Environment variables have become the standard way to configure applications. Database credentials, API keys, third-party service tokens — they all live in .env files during development. But here's the problem: these plaintext files are a security liability.
If your .env file gets exposed — through a misconfigured server, a leaked backup, or a compromised developer machine — every secret inside is immediately compromised. And yet, we've been using them this way for over a decade.
Dotenvx changes that.
What is Dotenvx?
Dotenvx is a secure evolution of the original dotenv library, created by the same author (Scott Motte). It adds encryption to your .env files, allowing you to safely commit them to version control while keeping your secrets protected.
The key innovation is cryptographic separation: your encrypted secrets live in your codebase, but the decryption key is stored separately. An attacker would need both to access your secrets.
Why Encryption Matters
Consider what happens in a typical breach scenario with plaintext .env files versus encrypted ones:
Git repository exposed — With plaintext files, all secrets are immediately leaked. With dotenvx, attackers get an encrypted blob that's useless without the separate decryption key.
Server compromise — Plaintext secrets are readable the moment an attacker gains access. With dotenvx, they'd also need access to wherever you store the private key (typically a different system entirely).
CI/CD breach — If your CI/CD platform is compromised, plaintext environment variables stored there are stolen directly. With dotenvx, only the encrypted files exist in your codebase.
Backup leak — Database dumps, server snapshots, or repository backups containing plaintext .env files expose everything. Encrypted files remain protected.
The CircleCI breach in early 2023 is a perfect example. Attackers accessed environment variables stored in the CI/CD platform but couldn't access codebases. With dotenvx, even if they had accessed both, the encrypted .env files would have been useless without the private decryption keys stored elsewhere.
How Dotenvx Works
Dotenvx uses Elliptic Curve Integrated Encryption Scheme (ECIES) with AES-256 encryption. Here's the simplified flow:
- Initialization: When you encrypt a
.envfile, dotenvx generates a key pair:
- `DOTENV_PUBLIC_KEY` — used to encrypt secrets (safe to commit)
- `DOTENV_PRIVATE_KEY` — used to decrypt secrets (never commit)
Encryption: Each secret value is encrypted individually using a unique ephemeral key, then that key is encrypted with the public key.
Decryption: At runtime, dotenvx uses the private key to decrypt secrets and inject them as environment variables.
Installation
# macOS/Linux
curl -sfS https://dotenvx.sh/install.sh | sh
# Or via npm
npm install @dotenvx/dotenvx --save
# Or via Homebrew
brew install dotenvx/brew/dotenvx
Basic Usage
Step 1: Create your .env file
echo "DATABASE_URL=postgres://user:password@localhost/myapp" > .env
echo "API_SECRET=sk_live_abc123xyz" >> .env
Step 2: Encrypt it
dotenvx encrypt
Your .env file now looks like this:
#/-------------------[DOTENV_PUBLIC_KEY]--------------------/
#/ public-key encryption for .env files /
#/----------------------------------------------------------/
DOTENV_PUBLIC_KEY="02a5c9..."
DATABASE_URL="encrypted:BGVh3..."
API_SECRET="encrypted:BKrt5..."
And a new .env.keys file is created:
#/------------------!DOTENV_PRIVATE_KEYS!-------------------/
#/ private decryption keys. DO NOT commit to source control /
#/----------------------------------------------------------/
DOTENV_PRIVATE_KEY="a1b2c3d4..."
Step 3: Add .env.keys to .gitignore
echo ".env.keys" >> .gitignore
Step 4: Commit your encrypted .env
git add .env
git commit -m "Add encrypted environment configuration"
Step 5: Run your application
# Locally (dotenvx reads from .env.keys automatically)
dotenvx run -- node app.js
# In production (set the private key as an env var)
DOTENV_PRIVATE_KEY="a1b2c3d4..." dotenvx run -- node app.js
Multiple Environments
Dotenvx supports environment-specific files with a naming convention:
.env # Default/development
.env.staging # Staging environment
.env.production # Production environment
.env.ci # CI/CD pipelines
Each file gets its own key pair:
dotenvx encrypt -f .env.production
dotenvx encrypt -f .env.staging
Your .env.keys will contain multiple keys:
DOTENV_PRIVATE_KEY="..."
DOTENV_PRIVATE_KEY_STAGING="..."
DOTENV_PRIVATE_KEY_PRODUCTION="..."
At runtime, the key suffix determines which file to decrypt:
# Decrypts .env.production
DOTENV_PRIVATE_KEY_PRODUCTION="..." dotenvx run -- php artisan serve
# Decrypts both .env and .env.production (production values override)
DOTENV_PRIVATE_KEY="..." DOTENV_PRIVATE_KEY_PRODUCTION="..." dotenvx run -- php artisan serve
Language Support
Dotenvx works as a CLI wrapper, so it's language-agnostic:
# Node.js
dotenvx run -- node app.js
# Python
dotenvx run -- python main.py
# Ruby
dotenvx run -- bundle exec rails server
# PHP
dotenvx run -- php artisan serve
# Go
dotenvx run -- go run main.go
# Any command
dotenvx run -- ./your-binary
Key Security Practices
- Never commit
.env.keys— Add it to.gitignoreimmediately - Store private keys in your deployment platform — Use your hosting provider's secrets management
- Rotate keys periodically — Generate new keys and re-encrypt when team members leave
- Use environment-specific keys — Don't use the same private key across all environments
- Limit key access — Only production servers should have production keys
When to Use Dotenvx
Dotenvx is ideal when:
- You want encrypted secrets in version control
- Multiple developers need access to the same configuration
- You deploy to multiple environments (staging, production, etc.)
- You want to avoid third-party secrets management services
- You need a simple, auditable secrets workflow
It's a straightforward upgrade from plaintext .env files that dramatically reduces your attack surface without adding operational complexity.
Dotenvx is open source and free to use. For team features like syncing, access controls, and audit logs, see Dotenvx Ops.