Smart .env vault β encrypt, sync, diff & manage your secrets.
Git-safe team sharing. Never leak secrets again.
Environment variables are critical but managing them is a mess:
- π«
.envfiles can't be committed to git (they contain secrets) - π° New team members ask "can you send me the .env file?"
- π€· No way to diff environments (dev vs prod)
- π Secrets leak into codebases constantly
Zink encrypts your .env files into a git-safe .env.vault file using AES-256-GCM encryption. Your team commits the vault, and each member decrypts with a shared password.
# Encrypt your .env β .env.vault (safe to commit!)
zink encrypt
# New team member clones the repo and decrypts
zink decrypt# Install globally
npm install -g zink-vault
# Initialize in your project
cd your-project
zink init
# Add some variables
zink set DATABASE_URL=postgres://localhost:5432/mydb
zink set API_KEY=sk_live_abc123
zink set JWT_SECRET=super-secret-token
# Encrypt into vault
zink encrypt
# Commit the vault (it's encrypted!)
git add .env.vault .zinkrc .env.example
git commit -m "Add encrypted environment vault"Initialize a new vault in your project.
zink init
zink init --env production # Set default environment
zink init --force # ReinitializeCreates .zinkrc (config) and .env.vault (encrypted store). Automatically updates .gitignore.
Encrypt your .env file into the vault.
zink encrypt # Encrypt default environment
zink encrypt -e production # Encrypt production
zink encrypt -e staging # Encrypt stagingEach environment is encrypted independently with its own salt and IV.
Decrypt the vault back to a .env file.
zink decrypt # Decrypt default environment
zink decrypt -e production # Decrypt production
zink decrypt --stdout # Print to stdout (for piping)
zink decrypt --force # Overwrite without confirmationSet one or more environment variables.
zink set DATABASE_URL=postgres://localhost:5432/db
zink set API_KEY=abc123 JWT_SECRET=xyz789 # Multiple at once
zink set PORT=3000 -e production # Set in specific environmentRetrieve a variable's value.
zink get DATABASE_URL
zink get API_KEY --raw # Raw value (for scripting)
zink get API_KEY --masked # Show masked valueScripting example:
export DB_URL=$(zink get DATABASE_URL --raw)List all variables in an environment.
zink ls # List with masked values
zink ls --show # Reveal actual values
zink ls -e production # List production varsRemove variable(s).
zink rm OLD_API_KEY
zink rm KEY1 KEY2 KEY3 # Remove multiple
zink rm KEY --force # Skip confirmationCompare variables between two environments.
zink diff development production
zink diff staging production --values # Show value differencesShows which keys are missing, added, or have different values.
Check your .env file for common issues.
zink validate
zink validate -e productionChecks for:
- β Duplicate keys
- β Invalid key names
β οΈ Empty valuesβ οΈ Placeholder values (TODO,CHANGE_ME, etc.)β οΈ Short secretsβ οΈ Localhost in productionβ οΈ Missing keys from.env.example
Generate a .env.example template (safe to commit).
zink template # Generate from default env
zink template -e production # From production
zink template --output .env.sample # Custom filename
zink template --bare # Without description commentsAuto-generates human-readable descriptions for common variable names.
Scan your codebase for leaked secrets.
zink scan # Scan current directory
zink scan --path ./src # Scan specific directory
zink scan --strict # Exit with error if secrets found (for CI)Detects:
- AWS keys & secrets
- GitHub tokens
- Stripe keys
- Google API keys
- Private keys
- Database URLs
- JWT tokens
- Generic secrets & passwords
- And more...
Export variables to other formats.
zink export --format json # Export as JSON
zink export --format yaml # Export as YAML
zink export --format docker # Docker env-file format
zink export --stdout # Print to stdout
zink export -o config.json # Custom output fileImport variables from external formats.
zink import config.json # Import from JSON
zink import env.yaml # Import from YAML
zink import .env.backup # Import from .env file
zink import config.json --merge # Merge with existing vars
zink import config.json -e staging # Import into specific envZink uses industry-standard encryption:
| Feature | Detail |
|---|---|
| Algorithm | AES-256-GCM (authenticated encryption) |
| Key Derivation | PBKDF2 with SHA-512 |
| Iterations | 100,000 |
| Salt | 32 bytes, unique per environment |
| IV | 16 bytes, unique per encryption |
| Auth Tag | 16-byte tamper detection |
The .env.vault file is safe to commit β without the master password, the data is cryptographically secure.
| File | Purpose | Git? |
|---|---|---|
.env |
Your actual secrets | β Never commit |
.env.vault |
Encrypted vault | β Safe to commit |
.zinkrc |
Zink configuration | β Commit this |
.env.example |
Template (no values) | β Commit this |
Developer A Developer B
βββββββββββββ βββββββββββββ
1. zink set KEY=VALUE
2. zink encrypt
3. git push β 4. git pull
5. zink decrypt
6. Has all the secrets! π
Share the master password securely (password manager, in-person, etc.) β never in git or chat.
# GitHub Actions example
- name: Decrypt secrets
run: |
npm install -g zink-vault
echo "$VAULT_PASSWORD" | zink decrypt --force
env:
VAULT_PASSWORD: ${{ secrets.VAULT_PASSWORD }}Use zink scan --strict in CI to prevent secret leaks:
- name: Scan for secrets
run: zink scan --strict- Node.js β₯ 18.0.0
- npm β₯ 8
MIT β see LICENSE for details.