Documentation
Everything you need to get running.
Installation
macOS / Linux
curl -fsSL https://getenvv.com/envv | sh
Windows (PowerShell)
irm https://getenvv.com/install.ps1 | iex
Verify
envv --version
Update
envv upgrade
Quick Start
Four steps. That's the whole thing.
1. Register
# Create your account and generate your age key
$ envv auth register
Email: you@company.com
Password: ••••••••
Name: Your Name
✓ Key generated at ~/.config/sops/age/keys.txt
✓ Registered as you@company.com
2. Create Organization + Project
# Create your organization
$ envv org create --name="My Company"
✓ Created org: org_abc123
# Create a project
$ envv project create --org-id=org_abc123 --name="My App"
✓ Created project: proj_xyz789
# Initialize in your project directory
$ cd your-project
$ envv project init --org-id=org_abc123 --project-id=proj_xyz789
3. Push Your Secrets
# Push your existing .env file
$ envv push .env.production --env prod
✓ Encrypted for 1 team member
✓ Pushed to backend
4. Run
# Pulls, decrypts in memory, runs your command
$ envv run -- npm start
# Specify environment
$ envv run --env staging -- vercel dev
Zero plaintext on disk. Secrets are decrypted in memory and injected into your process. Nothing is ever written unencrypted.
Team Setup
Invite Team Members
# Invite by email
$ envv org invite --org-id=org_abc123 --email=alice@company.com --role=member
✓ Invitation sent
New Member Joins
# They install and register
$ curl -fsSL https://getenvv.com/envv | sh
$ envv auth register
# Clone and init
$ git clone your-repo && cd your-repo
$ envv project init --org-id=org_abc123 --project-id=proj_xyz789
# Pull and run
$ envv run -- npm start
When Someone Leaves
# Re-encrypt for updated team membership
$ envv rotate --env prod
✓ Re-encrypted for 3 team members
Service Accounts
CI runners, Docker containers, Kubernetes pods — they all need secrets. They get service accounts: users created by an admin, with keypairs managed externally.
Why not ephemeral keys? Secrets are encrypted for specific public keys. If CI generated a fresh key each run, an admin would need to re-encrypt secrets for that new key — breaking automation. Service accounts solve this: create once, encrypt once, run forever.
How It Works
A service account is a user like any other, but:
- An admin creates the keypair (not the machine itself)
- The private key is stored in your CI platform's secrets
- The public key is registered with envv
- The account gets read-only access to secrets
Create a Service Account
# Admin creates keypair and registers with envv
$ envv service-account create \
--name="ci-prod" \
--org-id=org_abc123 \
--role=reader
✓ Service account created: ci-prod
✓ Added to org with reader role
# Private key (save this to your CI secrets):
AGE-SECRET-KEY-1QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
# This is shown once. Copy it now.
Store the Private Key in CI
# GitHub: Settings → Secrets → Actions → New secret
# GitLab: Settings → CI/CD → Variables
# CircleCI: Project Settings → Environment Variables
Name: SOPS_AGE_KEY
Value: AGE-SECRET-KEY-1QQQQ... (the private key from above)
Re-encrypt Secrets
# Secrets must be re-encrypted to include the new recipient
$ envv push --env prod
✓ Encrypted for 3 team members + 1 service account
If compromised: Remove the service account and rotate secrets immediately.
Then create a new service account and update your CI secrets.
envv service-account remove ci-prod && envv rotate --env prodThen create a new service account and update your CI secrets.
Multiple Service Accounts
# One per environment or deployment target
$ envv service-account create --name="ci-staging" --org-id=... --role=reader
$ envv service-account create --name="ci-prod" --org-id=... --role=reader
$ envv service-account create --name="k8s-prod" --org-id=... --role=reader
# List service accounts
$ envv service-account list --org-id=org_abc123
NAME ROLE CREATED
ci-staging reader 2024-01-15
ci-prod reader 2024-01-15
k8s-prod reader 2024-01-20
Commands
Authentication
envv auth register # Create account + generate keys
envv auth login # Login
envv auth logout # Logout
envv auth whoami # Show current user
Organizations
envv org create --name=NAME # Create organization
envv org list # List your organizations
envv org invite --email=... # Invite member
Projects
envv project create # Create project
envv project init # Initialize current directory
envv project status # Show project configuration
envv project members # List project members
Secrets
envv push .env --env prod # Encrypt and push
envv pull --env prod # Download (stays encrypted)
envv pull --decrypt # Decrypt to .env for local dev
envv pull --stdout # Pipe decrypted vars to stdout
envv run -- CMD # Pull, decrypt in memory, run
envv rotate --env prod # Re-encrypt for team
Updating Secrets
envv secrets set KEY "value" -e prod # Add/update one secret
envv secrets unset KEY -e prod # Remove one secret
envv edit --env prod # Edit all secrets in $EDITOR
Two ways to update:
secrets set — surgical. Change one key without seeing the rest.edit — opens decrypted secrets in your editor. Save and quit to re-encrypt. No plaintext touches disk.
Local Dev Convenience
# Decrypt to .env for tools that expect it
envv pull --decrypt --env dev
✓ Decrypted to .env
# Pipe to any command
envv pull --stdout --env dev | grep DATABASE
Transition at your pace. Use
--decrypt during the switch. Keep .env in .gitignore. The encrypted .envv/ stays committed — CI stays secure.
Utilities
envv upgrade # Update to latest version
envv --version # Show version
CI/CD
CI needs a service account — a dedicated keypair that's registered with envv and stored in your CI system's secrets.
First: Create a service account for your CI environment. See Service Accounts above. Then come back here.
GitHub Actions
# .github/workflows/deploy.yml
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install envv
run: curl -fsSL https://getenvv.com/envv | sh
- name: Run tests with secrets
run: envv run --env test -- npm test
env:
SOPS_AGE_KEY: ${{ secrets.SOPS_AGE_KEY }}
GitLab CI
# .gitlab-ci.yml
test:
script:
- curl -fsSL https://getenvv.com/envv | sh
- envv run --env test -- npm test
variables:
SOPS_AGE_KEY: $SOPS_AGE_KEY # from CI/CD Variables
Any CI System
# 1. Set SOPS_AGE_KEY env var (from your CI's secrets)
# 2. Install and run
curl -fsSL https://getenvv.com/envv | sh
envv run --env production -- npm run build
Docker in CI
See the Docker guide for container-specific patterns: mounting keys at runtime, keeping secrets out of layers, and Kubernetes secrets.
Troubleshooting
Command not found: envv
The installer adds envv to
/usr/local/bin. Make sure it's in your PATH:
echo $PATH | grep -q /usr/local/bin || export PATH="/usr/local/bin:$PATH"
Failed to decrypt
Your private key must exist and you must be a project member:
# Check your key exists
cat ~/.config/sops/age/keys.txt
# If you're a new team member, ask admin to rotate
envv rotate --env development
Secrets not loading
Make sure you're using
envv run:
# Wrong - secrets not loaded
npm start
# Correct - secrets in memory
envv run -- npm start