Package Exports
- vaulter
- vaulter/load
- vaulter/loader
- vaulter/package.json
Readme
๐ vaulter
Multi-Backend Environment & Secrets Manager
One CLI to manage all your environment variables.
Quick Start
npm install -g vaulter# Initialize project
vaulter init
# Set some secrets
vaulter set DATABASE_URL "postgres://localhost/mydb" -e dev
vaulter set API_KEY "sk-secret-key" -e dev
# Export to shell
eval $(vaulter export -e dev)
# Deploy to Kubernetes
vaulter k8s:secret -e prd | kubectl apply -f -Store secrets anywhere: AWS S3, MinIO, R2, Spaces, B2, or local filesystem.
AES-256-GCM encryption. Native K8s, Helm & Terraform integration.
MCP server for Claude AI. Zero config for dev, production-ready.
What's Inside
| Category | Features |
|---|---|
| Backends | AWS S3, MinIO, Cloudflare R2, DigitalOcean Spaces, Backblaze B2, FileSystem, Memory |
| Encryption | AES-256-GCM via s3db.js, field-level encryption, key rotation |
| Environments | dev, stg, prd, sbx, dr (fully customizable) |
| Integrations | Kubernetes Secret/ConfigMap, Helm values.yaml, Terraform tfvars |
| Monorepo | Service discovery, batch operations, config inheritance |
| MCP Server | Claude AI integration via Model Context Protocol |
| Unix Pipes | Full stdin/stdout support for scripting |
| Dotenv | Drop-in compatible: import 'vaulter/load' |
Highlights
Multi-Backend with Fallback
Configure multiple backends - vaulter tries each until one succeeds:
backend:
urls:
- s3://bucket/envs?region=us-east-1 # Primary (CI/CD)
- file:///home/user/.vaulter-store # Fallback (local dev)Native Integrations
# Kubernetes - deploy secrets directly
vaulter k8s:secret -e prd | kubectl apply -f -
# Helm - generate values file
vaulter helm:values -e prd | helm upgrade myapp ./chart -f -
# Terraform - export as tfvars
vaulter tf:vars -e prd > terraform.tfvarsUnix Pipes
# Import from Vault
vault kv get -format=json secret/app | \
jq -r '.data.data | to_entries | .[] | "\(.key)=\(.value)"' | \
vaulter sync -e prd
# Export to kubectl
vaulter export -e prd --format=env | \
kubectl create secret generic myapp --from-env-file=/dev/stdinMCP Server for Claude
# Start MCP server
vaulter mcp{
"mcpServers": {
"vaulter": {
"command": "npx",
"args": ["vaulter", "mcp"]
}
}
}Dotenv Compatible
Drop-in replacement for dotenv - works with your existing setup:
// Auto-load .env into process.env
import 'vaulter/load'
// Or programmatically with options
import { loader } from 'vaulter'
loader({ path: '.env.local', override: true })Commands
Core
| Command | Description | Example |
|---|---|---|
init |
Initialize project | vaulter init |
get <key> |
Get a variable | vaulter get DATABASE_URL -e prd |
set <key> <value> |
Set a variable | vaulter set API_KEY "sk-..." -e prd |
delete <key> |
Delete a variable | vaulter delete OLD_KEY -e dev |
list |
List all variables | vaulter list -e prd |
export |
Export for shell | eval $(vaulter export -e dev) |
Sync
| Command | Description | Example |
|---|---|---|
sync |
Merge local .env and backend | vaulter sync -f .env.local -e dev |
pull |
Download to .env | vaulter pull -e prd -o .env.prd |
push |
Upload from .env | vaulter push -f .env.local -e dev |
Integrations
| Command | Description | Example |
|---|---|---|
k8s:secret |
Kubernetes Secret | vaulter k8s:secret -e prd | kubectl apply -f - |
k8s:configmap |
Kubernetes ConfigMap | vaulter k8s:configmap -e prd |
helm:values |
Helm values.yaml | vaulter helm:values -e prd |
tf:vars |
Terraform .tfvars | vaulter tf:vars -e prd > terraform.tfvars |
tf:json |
Terraform JSON | vaulter tf:json -e prd |
Utilities
| Command | Description | Example |
|---|---|---|
key generate |
Generate encryption key | vaulter key generate |
services |
List monorepo services | vaulter services |
mcp |
Start MCP server | vaulter mcp |
Global Options
-p, --project <name> Project name
-s, --service <name> Service name (monorepos)
-e, --env <env> Environment: dev, stg, prd, sbx, dr
-b, --backend <url> Backend URL override
-k, --key <path|value> Encryption key file path or raw key
-v, --verbose Verbose output
--all All services (monorepo batch)
--dry-run Preview without applying
--json JSON output
--force Skip confirmationsConfiguration
Basic Config
# .vaulter/config.yaml
version: "1"
project: my-project
service: api # optional
backend:
# Single URL
url: s3://bucket/envs?region=us-east-1
# Or multiple with fallback
urls:
- s3://bucket/envs?region=us-east-1
- file:///home/user/.vaulter-store
encryption:
key_source:
- env: VAULTER_KEY # 1. Environment variable
- file: .vaulter/.key # 2. Local file
- s3: s3://keys/vaulter.key # 3. Remote S3
environments:
- dev
- stg
- prd
default_environment: devSync Settings
Sync merges local and remote variables. Conflicts are resolved by sync.conflict.
sync:
conflict: local # local | remote | prompt | error
ignore:
- "PUBLIC_*"
required:
dev:
- DATABASE_URLNotes:
promptanderrorwill stop the sync if conflicts are detected.- When reading from stdin, sync only updates the backend (local file is not changed).
Hooks
hooks:
pre_sync: "echo pre sync"
post_sync: "echo post sync"
pre_pull: "echo pre pull"
post_pull: "echo post pull"Environment Variable Expansion
Config values support ${VAR}, ${VAR:-default}, and $VAR:
backend:
url: s3://${AWS_ACCESS_KEY_ID}:${AWS_SECRET_ACCESS_KEY}@bucket/envs
# Or
url: ${VAULTER_BACKEND_URL}Local Override (config.local.yaml)
For credentials that should never be committed:
# .vaulter/config.local.yaml (gitignored)
backend:
url: s3://real-key:real-secret@bucket/envs?region=us-east-1Backend URLs
| Provider | URL Format |
|---|---|
| AWS S3 | s3://bucket/path?region=us-east-1 |
| AWS S3 + Profile | s3://bucket/path?region=us-east-1&profile=myprofile |
| AWS S3 + Credentials | s3://${KEY}:${SECRET}@bucket/path |
| MinIO | http://${KEY}:${SECRET}@localhost:9000/bucket |
| Cloudflare R2 | https://${KEY}:${SECRET}@${ACCOUNT}.r2.cloudflarestorage.com/bucket |
| DigitalOcean Spaces | https://${KEY}:${SECRET}@nyc3.digitaloceanspaces.com/bucket |
| Backblaze B2 | https://${KEY}:${SECRET}@s3.us-west-002.backblazeb2.com/bucket |
| FileSystem | file:///path/to/storage |
| Memory | memory://bucket-name |
Encryption
All secrets are encrypted with AES-256-GCM before storage.
Key Sources
# 1. Environment variable (CI/CD)
export VAULTER_KEY="base64-encoded-32-byte-key"
vaulter export -e prd
# 2. Local file (development)
vaulter key generate -o .vaulter/.key
# 3. Remote S3 (production)
# Configured in config.yamlYou can also pass a key directly:
vaulter list -e prd --key .vaulter/.keySecurity Settings
security:
paranoid: true # Fail if no encryption key is found
auto_encrypt:
patterns:
- "*_KEY"
- "*_SECRET"
- "DATABASE_URL"auto_encrypt.patterns is used to classify secrets for integrations (K8s/Helm).
Monorepo Support
Vaulter auto-discovers services with .vaulter/ directories and supports config inheritance.
NX Monorepo
my-nx-workspace/
โโโ .vaulter/
โ โโโ config.yaml # Shared config (backend, encryption)
โ โโโ environments/
โ โโโ dev.env # Shared dev vars
โโโ apps/
โ โโโ web/
โ โ โโโ .vaulter/
โ โ โโโ config.yaml # extends: ../../../.vaulter/config.yaml
โ โ โโโ environments/
โ โ โโโ dev.env # App-specific vars
โ โโโ api/
โ โโโ .vaulter/
โ โโโ config.yaml
โ โโโ environments/
โโโ libs/ # No .vaulter needed for libs
โโโ nx.json
โโโ package.json# From workspace root
vaulter services # List: web, api
# Sync all apps
vaulter sync -e dev --all
# Sync single app (from root or app dir)
vaulter sync -e dev -s api
cd apps/api && vaulter sync -e dev
# NX run with env vars
eval $(vaulter export -e dev -s api) && nx serve apiTurborepo
my-turbo-monorepo/
โโโ .vaulter/
โ โโโ config.yaml # Root config
โ โโโ environments/
โโโ apps/
โ โโโ web/
โ โ โโโ .vaulter/
โ โ โ โโโ config.yaml # extends: ../../../.vaulter/config.yaml
โ โ โ โโโ environments/
โ โ โโโ package.json
โ โโโ docs/
โ โโโ .vaulter/
โโโ packages/ # Shared packages (no .vaulter)
โโโ turbo.json
โโโ package.json# List discovered services
vaulter services
# Batch sync before turbo build
vaulter sync -e prd --all && turbo build
# Export for specific app
cd apps/web && eval $(vaulter export -e dev)
# Turbo with env passthrough (turbo.json)
# { "pipeline": { "build": { "env": ["DATABASE_URL", "API_KEY"] } } }
vaulter export -e prd -s web --format=shell >> apps/web/.env
turbo build --filter=webService Config Inheritance
# apps/api/.vaulter/config.yaml
extends: ../../../.vaulter/config.yaml # Inherit root config
service: api # Override service name
# Override or add service-specific settings
sync:
required:
prd:
- DATABASE_URL
- REDIS_URLCommands
# List services
vaulter services
# Sync all services
vaulter sync -e dev --all
# Sync specific services (glob supported)
vaulter sync -e dev -s api,worker
vaulter sync -e dev -s "svc-*"
# Batch export
vaulter export -e prd --all --format=jsonMCP Tools
| Tool | Description |
|---|---|
vaulter_get |
Get a single variable |
vaulter_set |
Set a variable |
vaulter_delete |
Delete a variable |
vaulter_list |
List all variables |
vaulter_export |
Export in various formats |
vaulter_sync |
Sync with .env file |
CI/CD
GitHub Actions
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy secrets
env:
VAULTER_KEY: ${{ secrets.VAULTER_KEY }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
npx vaulter k8s:secret -e prd | kubectl apply -f -GitLab CI
deploy:
script:
- npx vaulter k8s:secret -e prd | kubectl apply -f -
variables:
VAULTER_KEY: $VAULTER_KEYSecurity Best Practices
| Practice | How |
|---|---|
| Never commit credentials | Use config.local.yaml or env vars |
| Never commit encryption keys | Add .vaulter/.key to .gitignore |
| Use env var expansion | ${AWS_ACCESS_KEY_ID} instead of hardcoding |
| Use AWS credential chain | No credentials in URL, use IAM roles |
| Separate keys per environment | Different keys for dev/stg/prd |
| Restrict S3 bucket access | IAM policies to limit readers |
Files to .gitignore
.vaulter/.key
.vaulter/config.local.yaml
**/config.local.yaml
.env
.env.*API Usage
import { VaulterClient, loadConfig } from 'vaulter'
const config = loadConfig()
const client = new VaulterClient({ config })
await client.connect()
// Get
const value = await client.get('DATABASE_URL', 'my-project', 'prd')
// Set
await client.set({
key: 'API_KEY',
value: 'sk-secret',
project: 'my-project',
environment: 'prd'
})
// List
const vars = await client.list({
project: 'my-project',
environment: 'prd'
})
// Export
const envVars = await client.export('my-project', 'prd')
await client.disconnect()Comparison
| Feature | vaulter | dotenv | doppler | vault |
|---|---|---|---|---|
| Multi-backend | โ | โ | โ | โ |
| Encryption | AES-256-GCM | โ | โ | โ |
| K8s integration | Native | โ | Plugin | Plugin |
| Self-hosted | โ | N/A | โ | โ |
| Monorepo | Native | โ | Limited | โ |
| MCP/AI | โ | โ | โ | โ |
| Complexity | Low | Low | Medium | High |
Numbers
| Metric | Value |
|---|---|
| Backends | 7 (S3, MinIO, R2, Spaces, B2, FileSystem, Memory) |
| Environments | 5 (dev, stg, prd, sbx, dr) |
| Export Formats | 5 (shell, json, yaml, env, tfvars) |
| MCP Tools | 6 |
| Integrations | 5 (K8s Secret, K8s ConfigMap, Helm, Terraform, tfvars) |
Pre-built Binaries
Download from Releases:
| Platform | Binary |
|---|---|
| Linux x64 | vaulter-linux |
| Linux ARM64 | vaulter-linux-arm64 |
| macOS x64 | vaulter-macos |
| macOS ARM64 | vaulter-macos-arm64 |
| Windows | vaulter-win.exe |
License
MIT ยฉ Forattini
Documentation ยท Issues ยท Releases