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.
Store secrets anywhere: AWS S3, MinIO, R2, Spaces, B2, or local filesystem.
AES-256-GCM encryption. RSA/EC hybrid encryption. Native K8s, Helm & Terraform integration.
Quick Start ยท Security ยท CI/CD ยท Commands
Installation
# One-liner (recommended)
curl -fsSL https://raw.githubusercontent.com/forattini-dev/vaulter/main/install.sh | sh
# Or via npm/pnpm
npm install -g vaulter
pnpm add -g vaulterQuick Start
# Initialize project
vaulter init
# Set secrets (encrypted, synced to backend)
vaulter set DATABASE_URL="postgres://localhost/mydb" -e dev
# Export to shell
eval $(vaulter export -e dev)
# Deploy to Kubernetes
vaulter k8s:secret -e prd | kubectl apply -f -Table of Contents
- Why Vaulter?
- Security
- Daily Use
- Audit & Compliance
- Secret Rotation
- CI/CD
- Configuration
- Integrations
- Monorepo Support
- API Usage
- MCP Server
Why Vaulter?
The Problem
Environment variables and secrets are scattered across .env files, CI/CD settings, cloud consoles, and team Slack messages. This creates:
- Security gaps: Secrets in plaintext files, git history, or shared docs
- Sync issues: "Works on my machine" because
.envfiles differ - Deploy friction: Manual copy-paste between environments
- Audit blindness: No idea who changed what, when
The Solution
Vaulter centralizes all environment variables in encrypted storage (S3-compatible) while maintaining the simplicity of .env files:
| Traditional | With Vaulter |
|---|---|
Secrets in plaintext .env |
Encrypted at rest (AES-256-GCM) |
| Manual sync between devs | vaulter pull / vaulter push |
| Copy-paste to CI/CD | eval $(vaulter export -e prd) |
| No audit trail | Full history via S3 versioning |
| Different files per machine | Single source of truth |
Why Trust Vaulter?
- Open source: All code is auditable
- No lock-in: Your data lives in YOUR storage (S3, MinIO, R2, filesystem)
- Standard encryption: AES-256-GCM, the same used by AWS, Google, and banks
- Zero external dependencies: No SaaS, no API keys, no third-party services
- Offline capable: Works with local filesystem backend
Security
Encryption Model
Every secret is encrypted before leaving your machine using AES-256-GCM:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Machine โ
โ โ
โ .env file โโโบ vaulter encrypt โโโบ encrypted blob โโโบ S3 โ
โ (AES-256-GCM) (unreadable) โ
โ โ
โ S3 โโโบ encrypted blob โโโบ vaulter decrypt โโโบ .env file โ
โ (unreadable) (AES-256-GCM) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโWhat this means:
- The backend (S3, MinIO, etc.) only sees encrypted data
- Even with S3 access, secrets are unreadable without the key
- Each value is encrypted individually (field-level encryption)
- Authenticated encryption prevents tampering (GCM mode)
Key Management
Vaulter stores keys in ~/.vaulter/ directory (outside project) for security:
~/.vaulter/
โโโ projects/
โ โโโ <project-name>/
โ โโโ keys/
โ โโโ master # Private key (mode 600)
โ โโโ master.pub # Public key (mode 644)
โโโ global/
โโโ keys/ # Shared across all projects
โโโ shared
โโโ shared.pubKey Commands
# Generate keys
vaulter key generate --name master # Symmetric key
vaulter key generate --name master --asymmetric # RSA-4096 key pair
vaulter key generate --name master --asym --alg ec-p256 # EC P-256 key pair
vaulter key generate --name shared --global # Global key (all projects)
# List and show keys
vaulter key list # List all keys (project + global)
vaulter key show --name master # Show key details
# Export/import for deployment
vaulter key export --name master -o keys.enc # Export encrypted bundle
vaulter key import -f keys.enc # Import on another machine
# Set VAULTER_EXPORT_PASSPHRASE to encrypt the bundle with custom passphraseConfiguration with key_name
The simplest way to use keys is via key_name resolution:
# .vaulter/config.yaml
encryption:
mode: asymmetric
asymmetric:
algorithm: rsa-4096
key_name: master # โ ~/.vaulter/projects/<project>/keys/master[.pub]
# Or for global key:
# key_name: global:master # โ ~/.vaulter/global/keys/master[.pub]Legacy Key Sources (still supported)
You can also specify explicit key sources:
encryption:
key_source:
- env: VAULTER_KEY # 1. Environment variable (CI/CD)
- file: .vaulter/.key # 2. Local file (development)
- s3: s3://keys/vaulter.key # 3. Remote S3 (shared teams)Option 1: Environment Variable (Recommended for CI/CD)
# Generate a key
vaulter key generate --name master
# Set in CI/CD secrets from the generated key
export VAULTER_KEY=$(cat ~/.vaulter/projects/myproject/keys/master)Pros: Key never in project directory, rotates easily via CI/CD secret rotation Use case: GitHub Actions, GitLab CI, Jenkins
Option 2: key_name Resolution (Recommended for Development)
encryption:
mode: asymmetric
asymmetric:
key_name: master # Auto-resolves to ~/.vaulter/projects/<project>/keys/Pros: Simple, keys stored securely outside project Use case: Local development, team workflows
Option 3: Remote S3 (Team Shared)
encryption:
key_source:
- s3: s3://company-keys/vaulter/project.key?region=us-east-1Pros: Centralized key management, IAM-controlled access Use case: Teams, multiple developers needing same key
Asymmetric Key Encryption (RSA/EC)
For enhanced security with separate encrypt/decrypt permissions, Vaulter supports hybrid encryption using RSA or Elliptic Curve key pairs.
How It Works
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Hybrid Encryption โ
โ โ
โ Your secret โโโบ AES-256-GCM โโโบ Encrypted data โ
โ โ โ
โ โ (random AES key) โ
โ โผ โ
โ Public key โโโบ RSA/EC encrypt โโโบ Encrypted AES key โ
โ โ
โ Stored: { encrypted_key + encrypted_data + metadata } โ
โ โ
โ Decryption requires: Private key + Encrypted blob โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโBenefits:
- Separation of duties: Public key can only encrypt, private key can decrypt
- CI/CD security: Give CI/CD only the public key - it can write but not read secrets
- Production isolation: Only production has the private key for decryption
Generate Key Pair
# RSA 4096-bit (default, most compatible)
vaulter key generate --name master --asymmetric
# RSA 2048-bit (faster, less secure)
vaulter key generate --name master --asym --algorithm rsa-2048
# Elliptic Curve P-256 (modern, fast)
vaulter key generate --name master --asym --alg ec-p256
# Elliptic Curve P-384 (stronger EC)
vaulter key generate --name master --asym --alg ec-p384
# Global key (shared across all projects)
vaulter key generate --name shared --global --asymmetricOutput:
โ Generated rsa-4096 key pair: master
Private: ~/.vaulter/projects/my-project/keys/master (mode 600 - keep secret!)
Public: ~/.vaulter/projects/my-project/keys/master.pub (mode 644)
To use these keys in config.yaml:
encryption:
mode: asymmetric
asymmetric:
algorithm: rsa-4096
key_name: masterConfiguration
# .vaulter/config.yaml
encryption:
mode: asymmetric # Enable asymmetric mode
asymmetric:
algorithm: rsa-4096 # or rsa-2048, ec-p256, ec-p384
key_name: master # Uses ~/.vaulter/projects/<project>/keys/master[.pub]
# Or for global keys:
# key_name: global:master # Uses ~/.vaulter/global/keys/master[.pub]
# Alternative: explicit key sources (for CI/CD or custom paths)
# encryption:
# mode: asymmetric
# asymmetric:
# algorithm: rsa-4096
# public_key:
# - file: /path/to/master.pub
# - env: VAULTER_PUBLIC_KEY
# private_key:
# - file: /path/to/master
# - env: VAULTER_PRIVATE_KEYSupported Algorithms
| Algorithm | Key Size | Performance | Use Case |
|---|---|---|---|
rsa-4096 |
4096 bits | Slower | Maximum security, wide compatibility |
rsa-2048 |
2048 bits | Medium | Good balance, legacy systems |
ec-p256 |
256 bits | Fast | Modern systems, smaller keys |
ec-p384 |
384 bits | Medium | Higher security EC |
Use Case: Secure CI/CD Pipeline
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Development โ
โ Developers have BOTH keys โ can read and write secrets โ
โ vaulter set API_KEY="..." -e dev โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CI/CD (GitHub Actions, Jenkins, etc.) โ
โ Only PUBLIC key โ can write NEW secrets, cannot read โ
โ Useful for automated secret rotation scripts โ
โ โ
โ env: โ
โ VAULTER_PUBLIC_KEY: ${{ secrets.VAULTER_PUBLIC_KEY }} โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Production โ
โ Only PRIVATE key โ can read secrets at runtime โ
โ โ
โ env: โ
โ VAULTER_PRIVATE_KEY: ${{ secrets.VAULTER_PRIVATE_KEY }} โ
โ โ
โ # Application reads secrets at startup โ
โ eval $(vaulter export -e prd) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโEnvironment Variables
| Variable | Purpose |
|---|---|
VAULTER_PUBLIC_KEY |
Public key PEM content (for encryption) |
VAULTER_PRIVATE_KEY |
Private key PEM content (for decryption) |
Advanced Security Configurations
AWS KMS Integration (Planned)
For enterprises requiring HSM-backed keys:
encryption:
kms:
key_id: arn:aws:kms:us-east-1:123456789:key/abc-123
# Key never leaves AWS KMS
# Envelope encryption: KMS encrypts the data keyHow it works:
- Vaulter generates a data encryption key (DEK)
- DEK encrypts your secrets locally
- AWS KMS encrypts the DEK (envelope encryption)
- Only encrypted DEK + encrypted secrets are stored
- Decryption requires both KMS access AND S3 access
Threat Model
| Threat | Protection |
|---|---|
| S3 bucket breach | Data encrypted, key required |
| Key file leaked | Rotate key, re-encrypt |
| Man-in-middle | TLS + authenticated encryption |
| Malicious insider | Audit logs via S3 versioning |
| Accidental git commit | Secrets encrypted in .env |
Security Best Practices
# โ
DO
vaulter key generate # Random 256-bit key
echo ".vaulter/.key" >> .gitignore # Never commit keys
export VAULTER_KEY="${{ secrets.KEY }}" # CI/CD secrets
# โ DON'T
echo "password123" > .vaulter/.key # Weak key
git add .vaulter/.key # Exposed key
vaulter set KEY=val --key "hardcoded" # Key in command historyDaily Use
Workflow Overview
# Morning: sync with team's changes
vaulter pull -e dev
# During development: add new variable
vaulter set NEW_API_KEY="sk-xxx" -e dev
# End of day: push changes
vaulter push -e dev
# Deploy: export to production
vaulter k8s:secret -e prd | kubectl apply -f -Commands Reference
Core Commands
| Command | Description | Example |
|---|---|---|
init |
Initialize project | vaulter init |
get <key> |
Get a variable | vaulter get DATABASE_URL -e prd |
set KEY=val |
Set secrets (batch) | vaulter set A=1 B=2 -e prd |
set KEY::val |
Set configs (plain) | vaulter set PORT::3000 -e dev |
delete <key> |
Delete a variable | vaulter delete OLD_KEY -e dev |
list |
List all variables | vaulter list -e prd |
list --all-envs |
List across all envs | vaulter list --all-envs |
export |
Export for shell | eval $(vaulter export -e dev) |
Sync Commands
| Command | Description | Example |
|---|---|---|
sync |
Merge local and backend | vaulter sync -e dev |
pull |
Download from backend | vaulter pull -e prd |
push |
Upload to backend | vaulter push -e dev |
Integration Commands
| Command | Description | Example |
|---|---|---|
k8s:secret |
Kubernetes Secret | vaulter k8s:secret -e prd |
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 |
scan |
Scan monorepo | vaulter scan |
Audit Commands
| Command | Description | Example |
|---|---|---|
audit list |
List audit entries | vaulter audit list -e prd |
audit show |
Show entry details | vaulter audit show <id> |
audit stats |
Show statistics | vaulter audit stats -e prd |
audit cleanup |
Delete old entries | vaulter audit cleanup --retention 30 |
Rotation Commands
| Command | Description | Example |
|---|---|---|
rotation list |
Show rotation status | vaulter rotation list -e prd |
rotation run |
Run rotation check | vaulter rotation run -e prd --clear |
Set Command Syntax
# Secrets (encrypted, synced to backend)
vaulter set KEY=value # Single secret
vaulter set A=1 B=2 C=3 -e dev # Batch secrets
vaulter set KEY:=123 # Typed (number/boolean)
# Configs (plain text in split mode)
vaulter set PORT::3000 HOST::localhost # Configs| Separator | Type | Backend Sync | Encrypted |
|---|---|---|---|
= |
Secret | โ | โ |
:= |
Secret (typed) | โ | โ |
:: |
Config | Split: โ / Unified: โ | โ |
Global Options
-p, --project <name> Project name
-s, --service <name> Service name (monorepos)
-e, --env <env> Environment name (as defined in config)
-b, --backend <url> Backend URL override
-k, --key <path|value> Encryption key
-f, --file <path> Input file path
-o, --output <path> Output file path
-n, --namespace <name> Kubernetes namespace
--format <fmt> Output format (shell/json/yaml/env/tfvars/docker-args)
-v, --verbose Verbose output (shows values)
--dry-run Preview without applying
--json JSON output
--force Skip confirmations
--all Apply to all services in monorepoFlexible Environment Names
Vaulter lets you define your own environment names. Use whatever convention fits your workflow:
# Short names (default)
environments: [dev, stg, prd]
# Full names
environments: [development, staging, production]
# Custom names
environments: [local, homolog, qa, uat, prod]
# Brazilian pattern
environments: [dev, homolog, prd]All commands use -e with your custom names:
vaulter list -e homolog
vaulter pull -e development
vaulter k8s:secret -e uat | kubectl apply -f -Audit & Compliance
Vaulter includes built-in audit logging to track every change to your secrets. Essential for compliance (SOC2, HIPAA, PCI-DSS) and debugging "who changed what, when".
Why Audit?
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Without Audit Logging โ
โ โ
โ Developer: "Who deleted the API_KEY in production?" โ
โ Team: ๐คท "No idea, check git blame? It's not in the repo..." โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ With Vaulter Audit โ
โ โ
โ $ vaulter audit list -e prd --pattern "API_KEY" โ
โ โ
โ TIMESTAMP USER OP KEY ENV SRC โ
โ 2025-01-15 14:32:01 john delete API_KEY prd cli โ
โ 2025-01-10 09:15:22 jane set API_KEY prd sync โ
โ 2025-01-05 11:00:00 deploy set API_KEY prd ci โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโConfiguration
# .vaulter/config.yaml
audit:
enabled: true # Enable audit logging (default: true)
retention_days: 90 # Auto-cleanup entries older than N days
mask_values: true # Mask values in logs (show: sk-1234****5678)
include_values: false # Include actual values (โ ๏ธ security risk)| Option | Default | Description |
|---|---|---|
enabled |
true |
Enable/disable audit logging |
retention_days |
90 |
Auto-cleanup old entries |
mask_values |
true |
Mask sensitive values in logs |
include_values |
false |
Store full values (โ ๏ธ use with caution) |
Commands
List Audit Entries
# List recent entries (default: 50)
vaulter audit list -e prd
# Filter by user
vaulter audit list -e prd --user john
# Filter by operation
vaulter audit list -e prd --operation delete
# Filter by key pattern (supports wildcards)
vaulter audit list -e prd --pattern "DATABASE_*"
# Filter by date range
vaulter audit list -e prd --since "2025-01-01" --until "2025-01-15"
# Filter by source
vaulter audit list -e prd --source ci
# Show all environments
vaulter audit list --all-envs
# JSON output for scripting
vaulter audit list -e prd --json
# Combine filters
vaulter audit list -e prd --user deploy --operation set --limit 100Output:
TIMESTAMP USER OP KEY ENV SRC
2025-01-15 14:32:01 john delete API_KEY prd cli
2025-01-15 14:30:00 jane set DATABASE_URL prd cli
2025-01-15 10:00:00 github-ci push * prd ci
2025-01-14 16:45:22 jane sync * prd cli
Showing 4 entriesShow Entry Details
# Get full details of a specific entry
vaulter audit show <entry-id>Output:
ID: abc123def456
Timestamp: 2025-01-15 14:32:01
User: john
Operation: delete
Key: API_KEY
Project: my-project
Environment: prd
Source: cli
Previous: sk-1234****5678
Metadata: {"reason": "rotating key"}Audit Statistics
# View summary statistics
vaulter audit stats -e prdOutput:
Audit Statistics for my-project/prd
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Total entries: 1,247
Date range: 2024-10-15 09:00:00 to 2025-01-15 14:32:01
By Operation:
set 892
delete 124
sync 156
push 75
By User:
jane 456
john 321
github-ci 470
By Source:
cli 645
ci 470
sync 132Cleanup Old Entries
# Cleanup entries older than retention_days (from config)
vaulter audit cleanup
# Override retention period
vaulter audit cleanup --retention 30
# Dry-run to see what would be deleted
vaulter audit cleanup --retention 30 --dry-runAutomatic Audit Logging
Audit entries are created automatically for all write operations:
| Operation | Logged Info |
|---|---|
set |
Key, previous value (masked), new value (masked) |
delete |
Key, previous value (masked) |
sync |
Keys added, updated, deleted |
push |
Keys added, updated, deleted |
deleteAll |
All deleted keys |
Sources
The source field indicates where the operation originated:
| Source | Description |
|---|---|
cli |
Manual CLI command |
ci |
CI/CD pipeline |
sync |
Bidirectional sync operation |
api |
Programmatic API call |
mcp |
MCP server (AI assistant) |
Compliance Tips
# Export audit log for compliance review
vaulter audit list --all-envs --json > audit-report-$(date +%Y%m).json
# Monitor production changes
vaulter audit list -e prd --since "$(date -d 'yesterday' +%Y-%m-%d)"
# Alert on deletions
vaulter audit list -e prd --operation delete --json | jq '.entries | length'Secret Rotation
Regular secret rotation is a security best practice. Vaulter tracks rotation schedules and helps you identify secrets that need attention.
Why Rotate?
- Limit exposure: If a key is compromised, damage is time-limited
- Compliance: Many standards require periodic rotation (PCI-DSS: 90 days)
- Access control: Rotated keys invalidate old access
- Audit trail: Clear history of when credentials changed
How It Works
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Rotation Workflow โ
โ โ
โ 1. vaulter rotation list โ See what needs rotation โ
โ โ
โ KEY ENV LAST ROTATED ROTATE AFTER STATUS โ
โ DATABASE_URL prd 45 days ago 90 days โ OK โ
โ API_KEY prd 120 days ago 90 days โ OVERDUE โ
โ JWT_SECRET prd never 90 days โ OVERDUE โ
โ โ
โ 2. Manually rotate the credential in the external service โ
โ โ
โ 3. vaulter set API_KEY="new-value" -e prd โ
โ โ Automatically updates rotatedAt timestamp โ
โ โ
โ 4. vaulter rotation run -e prd --clear โ
โ โ Clears rotateAfter for updated keys (fresh start) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโConfiguration
# .vaulter/config.yaml
encryption:
rotation:
enabled: true # Enable rotation tracking
interval_days: 90 # Default rotation interval
patterns: # Keys that should be rotated
- "*_KEY"
- "*_SECRET"
- "*_TOKEN"
- "*_PASSWORD"
- "DATABASE_URL"
- "REDIS_URL"| Option | Default | Description |
|---|---|---|
enabled |
true |
Enable rotation tracking |
interval_days |
90 |
Default rotation period |
patterns |
["*_KEY", "*_SECRET", ...] |
Keys to track (glob patterns) |
Commands
List Rotation Status
# Show rotation status for all secrets
vaulter rotation list -e prd
# Check all environments
vaulter rotation list --all-envs
# Filter overdue only
vaulter rotation list -e prd --overdue
# Custom interval check
vaulter rotation list -e prd --days 30
# JSON output
vaulter rotation list -e prd --jsonOutput:
Rotation Status for my-project/prd (default: 90 days)
KEY LAST ROTATED ROTATE AFTER STATUS
DATABASE_URL 2024-12-01 2025-03-01 โ OK (45 days)
API_KEY 2024-09-15 2024-12-14 โ OVERDUE (32 days)
JWT_SECRET never โ โ NEVER ROTATED
REDIS_URL 2024-11-20 2025-02-18 โ OK (34 days)
Summary: 4 secrets, 2 overdue, 1 never rotatedRun Rotation Check
# Interactive rotation workflow
vaulter rotation run -e prd
# Clear rotation schedule for already-rotated keys
vaulter rotation run -e prd --clear
# Set new interval
vaulter rotation run -e prd --interval 60
# Dry-run
vaulter rotation run -e prd --dry-runInteractive Output:
Checking rotation status for my-project/prd...
โ Found 2 secrets needing rotation:
API_KEY (overdue by 32 days)
Last rotated: 2024-09-15
Rotate after: 2024-12-14
JWT_SECRET (never rotated)
Set a rotation schedule? [Y/n]: y
Rotation interval (days) [90]: 90
โ Scheduled rotation for 2025-04-15
To update a rotated secret:
vaulter set API_KEY="new-value" -e prd
After rotating, clear the schedule:
vaulter rotation run -e prd --clearSchedule Rotation
When you set a new value, Vaulter automatically tracks when it was last changed:
# Set new value (automatically updates rotatedAt)
vaulter set API_KEY="sk-new-rotated-key" -e prd
# Verify rotation was tracked
vaulter rotation list -e prd --pattern "API_KEY"Output:
KEY LAST ROTATED ROTATE AFTER STATUS
API_KEY just now 2025-04-15 โ OK (90 days)Rotation Metadata
Each secret tracks rotation metadata:
| Field | Description |
|---|---|
rotatedAt |
ISO timestamp of last rotation |
rotateAfter |
ISO timestamp when rotation is due |
View with:
vaulter get API_KEY -e prd --json | jq '.metadata'CI/CD Integration
# GitHub Actions - Weekly rotation check
name: Secret Rotation Check
on:
schedule:
- cron: '0 9 * * 1' # Every Monday at 9am
jobs:
check-rotation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check for overdue secrets
env:
VAULTER_KEY: ${{ secrets.VAULTER_KEY }}
run: |
OVERDUE=$(npx vaulter rotation list -e prd --json | jq '.overdue')
if [ "$OVERDUE" -gt 0 ]; then
echo ":โ ๏ธ:$OVERDUE secrets are overdue for rotation!"
npx vaulter rotation list -e prd
exit 1
fi
echo "โ All secrets are within rotation policy"Compliance Matrix
| Standard | Requirement | Vaulter Config |
|---|---|---|
| PCI-DSS | 90 days | interval_days: 90 |
| SOC2 | Regular rotation | interval_days: 90 |
| HIPAA | Periodic | interval_days: 180 |
| Internal | Custom | interval_days: N |
CI/CD
GitHub Actions (Quick Start)
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy secrets to Kubernetes
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 -GitHub Actions (Complete Example)
name: Deploy to Kubernetes
on:
push:
branches: [main, develop]
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'dev'
type: choice
options: [dev, stg, prd]
env:
VAULTER_VERSION: '1.0.1'
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'prd') || 'dev' }}
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
- name: Install Vaulter
run: npm install -g vaulter@${{ env.VAULTER_VERSION }}
- name: Configure kubectl
uses: azure/k8s-set-context@v4
with:
kubeconfig: ${{ secrets.KUBECONFIG }}
- 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: |
ENV=${{ github.event.inputs.environment || (github.ref == 'refs/heads/main' && 'prd') || 'dev' }}
# Deploy K8s Secret
vaulter k8s:secret -e $ENV -n my-namespace | kubectl apply -f -
# Deploy ConfigMap (non-sensitive config)
vaulter k8s:configmap -e $ENV -n my-namespace | kubectl apply -f -
# Verify deployment
kubectl get secret,configmap -n my-namespace
- name: Restart Deployment
run: |
kubectl rollout restart deployment/my-app -n my-namespace
kubectl rollout status deployment/my-app -n my-namespace --timeout=120sGitHub Actions (Monorepo with Services)
name: Deploy Service
on:
push:
branches: [main]
paths:
- 'apps/svc-*/**'
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
services: ${{ steps.changes.outputs.services }}
steps:
- uses: actions/checkout@v4
- id: changes
run: |
# Detect which services changed
SERVICES=$(git diff --name-only HEAD~1 | grep '^apps/svc-' | cut -d'/' -f2 | sort -u | jq -R -s -c 'split("\n")[:-1]')
echo "services=$SERVICES" >> $GITHUB_OUTPUT
deploy:
needs: detect-changes
runs-on: ubuntu-latest
strategy:
matrix:
service: ${{ fromJson(needs.detect-changes.outputs.services) }}
steps:
- uses: actions/checkout@v4
- name: Deploy ${{ matrix.service }}
env:
VAULTER_KEY: ${{ secrets.VAULTER_KEY }}
run: |
# Deploy secrets for specific service
vaulter k8s:secret -e prd -s ${{ matrix.service }} | kubectl apply -f -GitHub Actions (Using Binary for Speed)
name: Deploy (Fast)
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download Vaulter Binary
run: |
curl -sL https://github.com/forattini-dev/vaulter/releases/latest/download/vaulter-linux -o vaulter
chmod +x vaulter
sudo mv vaulter /usr/local/bin/
- name: Deploy
env:
VAULTER_KEY: ${{ secrets.VAULTER_KEY }}
run: |
vaulter k8s:secret -e prd | kubectl apply -f -GitHub Actions (Matrix Deploy)
name: Deploy All Environments
on:
workflow_dispatch:
inputs:
environment:
type: choice
options: [dev, stg, prd]
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- uses: actions/checkout@v4
- name: Deploy secrets
env:
VAULTER_KEY: ${{ secrets.VAULTER_KEY }}
run: |
npx vaulter k8s:secret -e ${{ inputs.environment }} | kubectl apply -f -
- name: Deploy configmaps
run: |
npx vaulter k8s:configmap -e ${{ inputs.environment }} | kubectl apply -f -GitLab CI
stages:
- deploy
deploy-secrets:
stage: deploy
image: node:22-alpine
script:
- npx vaulter k8s:secret -e ${CI_ENVIRONMENT_NAME} | kubectl apply -f -
environment:
name: $CI_COMMIT_REF_NAME
rules:
- if: $CI_COMMIT_BRANCH == "main"
variables:
CI_ENVIRONMENT_NAME: prd
- if: $CI_COMMIT_BRANCH == "develop"
variables:
CI_ENVIRONMENT_NAME: devJenkins Pipeline
pipeline {
agent any
environment {
VAULTER_KEY = credentials('vaulter-key')
AWS_ACCESS_KEY_ID = credentials('aws-access-key')
AWS_SECRET_ACCESS_KEY = credentials('aws-secret-key')
}
stages {
stage('Deploy Secrets') {
steps {
sh 'npx vaulter k8s:secret -e prd | kubectl apply -f -'
}
}
}
}Docker Integration
# Recommended: Use --env-file for production (handles all values safely)
vaulter export -e prd --format=env > .env.prd
docker run --env-file .env.prd myapp
# For simple values only: command substitution (no spaces/newlines in values)
docker run $(vaulter export -e prd --format=docker-args) myappNote: The
docker-argsformat outputs-e "KEY=VALUE"flags. Due to shell word-splitting, values containing spaces or special characters won't work correctly with$(...)substitution. Use--env-filefor complex values or production deployments.
For docker build with build args, use shell format:
# Export to shell and use in build
eval $(vaulter export -e prd)
docker build \
--build-arg DATABASE_URL="$DATABASE_URL" \
--build-arg API_KEY="$API_KEY" \
-t myapp .Terraform Integration
# Generate tfvars
vaulter tf:vars -e prd > secrets.auto.tfvars
# Or inline
terraform plan -var-file=<(vaulter tf:vars -e prd)Helm Integration
# Upgrade with secrets as values
vaulter helm:values -e prd | helm upgrade myapp ./chart -f -
# Or save to file
vaulter helm:values -e prd > values.secrets.yaml
helm upgrade myapp ./chart -f values.yaml -f values.secrets.yamlShell Aliases (Development)
# Add to ~/.bashrc or ~/.zshrc
alias vdev='eval $(vaulter export -e dev)'
alias vstg='eval $(vaulter export -e stg)'
alias vprd='eval $(vaulter export -e prd)'
# Usage
vdev npm run dev
vstg npm run test:integrationConfiguration
Basic Config
# .vaulter/config.yaml
version: "1"
project: my-project
service: api # optional, for monorepos
backend:
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
- file: .vaulter/.key
# Secret rotation settings
rotation:
enabled: true
interval_days: 90
patterns:
- "*_KEY"
- "*_SECRET"
- "*_TOKEN"
# Audit logging
audit:
enabled: true
retention_days: 90
mask_values: true
environments:
- dev
- stg
- prd
default_environment: devDirectory Modes
Unified Mode (Default)
my-project/
โโโ .vaulter/
โ โโโ config.yaml
โ โโโ environments/
โ โโโ dev.env
โ โโโ stg.env
โ โโโ prd.envSplit Mode
Separates configs (committable) from secrets (gitignored):
my-project/
โโโ .vaulter/config.yaml
โโโ deploy/
โโโ configs/ # โ
Committable (PORT, HOST, LOG_LEVEL)
โ โโโ dev.env
โ โโโ prd.env
โโโ secrets/ # โ Gitignored (DATABASE_URL, API_KEY)
โโโ dev.env
โโโ prd.envdirectories:
mode: split
configs: deploy/configs
secrets: deploy/secretsInitialize with: vaulter init --split
Backend URLs
| Provider | URL Format |
|---|---|
| AWS S3 | s3://bucket/path?region=us-east-1 |
| AWS S3 + Profile | s3://bucket/path?profile=myprofile |
| 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 |
Integrations
Kubernetes
# Deploy Secret
vaulter k8s:secret -e prd -n my-namespace | kubectl apply -f -
# Deploy ConfigMap
vaulter k8s:configmap -e prd | kubectl apply -f -Note: Custom secret/configmap names are configured in .vaulter/config.yaml:
integrations:
kubernetes:
secret_name: my-app-secrets
configmap_name: my-app-configHelm
# Pass as values
vaulter helm:values -e prd | helm upgrade myapp ./chart -f -
# Save to file
vaulter helm:values -e prd > values.secrets.yamlTerraform
# Generate tfvars
vaulter tf:vars -e prd > terraform.tfvars
# Generate JSON
vaulter tf:json -e prd > terraform.tfvars.jsonMonorepo Support
Vaulter auto-detects all major monorepo tools:
| Tool | Detection File | Workspace Config |
|---|---|---|
| NX | nx.json |
workspaceLayout |
| Turborepo | turbo.json |
Uses pnpm/yarn workspaces |
| Lerna | lerna.json |
packages array |
| pnpm | pnpm-workspace.yaml |
packages array |
| Yarn | package.json |
workspaces field |
| Rush | rush.json |
projects[].projectFolder |
Scan Command
# Discover all packages
vaulter scan
# Output:
# Monorepo: NX
# Found 17 package(s):
# โ Initialized: 3
# โ Not initialized: 14
# ๐ With .env files: 11Batch Operations
# Sync all services
vaulter sync -e dev --all
# Sync specific services
vaulter sync -e dev -s api,workerAPI Usage
import { VaulterClient, loadConfig } from 'vaulter'
const config = loadConfig()
const client = new VaulterClient({ config })
await client.connect()
// CRUD operations
const value = await client.get('DATABASE_URL', 'my-project', 'prd')
await client.set({ key: 'API_KEY', value: 'sk-xxx', project: 'my-project', environment: 'prd' })
const vars = await client.list({ project: 'my-project', environment: 'prd' })
await client.disconnect()Dotenv Compatible
// Auto-load .env into process.env
import 'vaulter/load'
// Or with options
import { loader } from 'vaulter'
loader({ path: '.env.local', override: true })MCP Server
Vaulter includes a Model Context Protocol (MCP) server for AI assistant integration.
Setup
# Start server
vaulter mcp
# Test with MCP Inspector
npx @anthropic-ai/mcp-inspector vaulter mcpClaude Desktop Config
{
"mcpServers": {
"vaulter": {
"command": "vaulter",
"args": ["mcp"]
}
}
}Available Tools (21)
Core Operations
| Tool | Description |
|---|---|
vaulter_get |
Get a variable |
vaulter_set |
Set a variable |
vaulter_delete |
Delete a variable |
vaulter_list |
List variables |
vaulter_export |
Export in various formats (shell, env, json, yaml, tfvars, docker-args) |
vaulter_sync |
Bidirectional sync |
vaulter_pull |
Download from backend |
vaulter_push |
Upload to backend |
Discovery & Analysis
| Tool | Description |
|---|---|
vaulter_compare |
Compare environments |
vaulter_search |
Search by pattern |
vaulter_scan |
Scan monorepo |
vaulter_services |
List services |
vaulter_init |
Initialize project |
Integrations
| Tool | Description |
|---|---|
vaulter_k8s_secret |
Generate K8s Secret |
vaulter_k8s_configmap |
Generate K8s ConfigMap |
vaulter_helm_values |
Generate Helm values.yaml |
vaulter_tf_vars |
Generate Terraform .tfvars |
Key Management
| Tool | Description |
|---|---|
vaulter_key_generate |
Generate encryption key (symmetric or asymmetric) |
vaulter_key_list |
List all keys (project + global) |
vaulter_key_show |
Show key details |
vaulter_key_export |
Export key to encrypted bundle |
Resources (8)
| URI Pattern | Description |
|---|---|
vaulter://config |
Project configuration |
vaulter://services |
Monorepo services |
vaulter://keys |
List all encryption keys |
vaulter://keys/<name> |
Specific key details |
vaulter://keys/global/<name> |
Global key details |
vaulter://project/env |
Environment variables |
vaulter://project/env/service |
Service-specific vars |
vaulter://compare/env1/env2 |
Environment diff |
Prompts (5)
setup_projectโ Initialize a new projectmigrate_dotenvโ Migrate existing .envdeploy_secretsโ Deploy to Kubernetescompare_environmentsโ Compare two environmentssecurity_auditโ Audit for security issues
Pre-built Binaries
Download from Releases:
| Platform | Binary |
|---|---|
| Linux x64 | vaulter-linux-x64 |
| Linux ARM64 | vaulter-linux-arm64 |
| macOS x64 | vaulter-macos-x64 |
| macOS ARM64 | vaulter-macos-arm64 |
| Windows x64 | vaulter-win-x64.exe |
License
MIT ยฉ Forattini