๐งช Vial
The centralized secret vault for vibe coders.
Store your API keys once. Pour them everywhere.
one-vial.org
The Problem
You're vibe coding. You've spun up 30 projects this month. Every single one needs some combination of OPENAI_API_KEY, STRIPE_SECRET_KEY, SUPABASE_URL, and a dozen more. You're copy-pasting from a password manager, a Notion doc, three old .env files, and that one Slack DM to yourself.
Then you rotate a key. Good luck updating all 30 projects.
The Fix
brew install cheesejaguar/tap/vial # use the tap; "brew install vial" is a different package
go install github.com/cheesejaguar/vial/cmd/vial@latest
vial init # create your encrypted vault
vial key set OPENAI_API_KEY
# โ paste value (hidden)
# โ โ Stored.
cd ~/projects/my-new-app
vial pour
# โ โ OPENAI_API_KEY โ matched from vault
# โ โ STRIPE_SECRET_KEY โ matched from vault
# โ โ NEXT_PUBLIC_SUPABASE_URL โ matched (prefix-stripped: SUPABASE_URL)
# โ โ DATABASE_URL โ not found in vault
# โ .env created with 3/4 keys populated
That's it. Your .env.example is the template. Your vault is the source of truth. Vial pours the secrets in.
๐ฎ Features
Encrypted Vault
Your secrets live in a single encrypted file. Argon2id key derivation โ AES-256-GCM per-value encryption. Key names stay readable for diffing; values are individually encrypted. Secured in memory with memguard.
๐ซ Pour
The core ritual. Reads your .env.example, matches each variable against your vault, and writes a .env. Handles conflicts intelligently โ prompts you when an existing value differs from the vault.
vial pour # populate .env from vault
vial pour --dry-run # preview without writing
vial pour --force # overwrite without asking
vial pour --all # pour every registered project at once
๐ง Smart Matching (5-Tier Engine)
Vial doesn't just do exact matches. It understands your keys.
| Tier |
Method |
Example |
| 1 |
Exact match |
OPENAI_API_KEY = OPENAI_API_KEY |
| 2 |
Normalize |
NEXT_PUBLIC_SUPABASE_URL โ SUPABASE_URL |
| 3 |
Alias & variants |
OPENAI_KEY โ OPENAI_API_KEY |
| 4 |
Comment-informed |
# Your Stripe secret key โ STRIPE_SECRET_KEY |
| 5 |
LLM-assisted |
Calls an inference API for truly ambiguous cases |
Framework prefixes like NEXT_PUBLIC_, VITE_, REACT_APP_ are automatically stripped. Common suffix variants (_KEY โ _API_KEY โ _SECRET_KEY) are auto-detected.
๐ท๏ธ Aliases
vial label set OPENAI_KEY=OPENAI_API_KEY
# Now any project asking for OPENAI_KEY gets your OPENAI_API_KEY
๐งช Distill
Already have secrets scattered in .env files? Import them.
vial distill .env # import keys from an existing .env
vial distill --overwrite # update existing vault keys
๐บ Brew
Run a command with secrets injected โ no .env file needed.
vial brew -- node server.js
vial brew -- python manage.py runserver
๐ Shelf (Project Registry)
Register projects for batch operations.
vial shelf add ~/projects/my-app
vial shelf add ~/projects/api-server
vial pour --all # pour every shelved project
๐ Key Rotation
Rotate once, propagate everywhere.
vial key set OPENAI_API_KEY # update the value
vial pour --all # re-pour all projects
# โ 12 projects updated
๐ Scaffold
Auto-generate .env.example from your source code.
vial scaffold # scan current project for env var references
vial scaffold ./my-project # scan specific directory
# โ Generates .env.example with all discovered variables
Detects env vars in JavaScript, TypeScript, Python, Go, Ruby, Rust, and PHP.
๐ Setup (Zero-Config Onboarding)
One command to set up a new project โ scan, scaffold, register, pour, and hook.
cd ~/projects/my-new-app
vial setup # does everything below in one step:
# โ Scans source code for env var references
# โก Generates .env.example if missing
# โข Registers project in shelf
# โฃ Pours secrets from vault
# โค Installs git pre-commit hook
๐ก๏ธ Secret Leak Prevention
Git pre-commit hook that scans staged files for leaked vault secrets.
vial hook install # install pre-commit hook
vial hook check --staged # manually check staged files
vial hook uninstall # remove the hook
Create a .vialignore file to suppress false positives.
๐ฉบ Secret Health
Track the age, rotation status, and health of your secrets.
vial health # show health report
vial health --set-rotation STRIPE_SECRET_KEY=90 # rotate every 90 days
vial health --json # machine-readable output
Model Context Protocol server for Claude Code, Cursor, and other AI coding tools.
vial mcp # start read-only MCP server
vial mcp --allow-writes # enable write operations
Configure in your MCP client (e.g. Claude Code settings.json):
{
"mcpServers": {
"vial": { "command": "vial", "args": ["mcp"] }
}
}
Export secrets in various formats for containers, CI/CD, and scripts.
vial export --confirm-plaintext --format=docker-env-file # Docker
vial export --confirm-plaintext --format=k8s-secret # Kubernetes
vial export --confirm-plaintext --format=github-actions # GitHub Actions
vial export --confirm-plaintext --format=shell # Shell exports
vial export --confirm-plaintext --format=json --keys="STRIPE_*" # Filtered
๐ฅ Import from External Sources
Import secrets from popular secret managers.
vial distill --from=json secrets.json # JSON file
vial distill --from=1password # 1Password CLI
vial distill --from=doppler # Doppler
vial distill --from=vercel # Vercel
๐ Secret Sharing
Create encrypted, time-limited secret bundles for teammates.
vial share OPENAI_API_KEY STRIPE_* # create a bundle
vial share --all --expires=1h # share everything, 1-hour expiry
vial share receive team-secrets.bundle # import from a bundle
๐ Audit Log
Track all vault activity.
vial audit # show last 20 entries
vial audit --limit 50 # show more
vial audit --csv # export for compliance
โก GitHub Actions
Use vial in CI/CD workflows with the included GitHub Action.
- uses: cheesejaguar/vial@v1
env:
VIAL_MASTER_KEY: ${{ secrets.VIAL_MASTER_KEY }}
๐ฅ๏ธ Dashboard
A local web UI for browsing your vault, managing aliases, and checking secret health.
vial dashboard
# โ Opens http://localhost:9876 in your browser
Dark-themed Svelte SPA with vault browser, alias management, project registry, and secret health indicators (age, rotation status, staleness).
๐ Sync
Keep your vault in sync across machines.
vial sync push --backend filesystem --remote ~/iCloud/vial/vault.json
vial sync pull --backend filesystem --remote ~/iCloud/vial/vault.json
vial sync status --backend filesystem --remote ~/iCloud/vial/vault.json
Supports filesystem sync (iCloud, Dropbox, any mounted path). Git-based sync is experimental.
๐ช Command Reference
Vial uses alchemical command names with standard aliases for the conventionally-minded.
| Command |
Alias |
Description |
vial init |
|
Create a new encrypted vault |
vial cork |
lock |
Lock the vault, clear session |
vial uncork |
unlock |
Unlock with master password |
vial key set NAME |
set |
Store a secret (value via stdin) |
vial key get NAME |
get |
Retrieve a secret |
vial key list |
list, ls |
List all stored key names |
vial key rm NAME |
rm |
Remove a secret |
vial pour |
|
Populate .env from vault |
vial distill [FILE] |
import |
Import keys from .env file or external source |
vial brew -- CMD |
run |
Run command with injected secrets |
vial diff |
|
Compare .env.example vs vault |
vial scaffold |
|
Auto-generate .env.example from source code |
vial setup |
|
Zero-config project onboarding |
vial health |
|
Secret health report & rotation policies |
vial hook install/uninstall/check |
|
Git pre-commit hook for leak prevention |
vial mcp |
|
Start MCP server for AI coding tools |
vial export |
|
Export secrets in various formats |
vial share |
|
Create encrypted secret bundles |
vial share receive |
|
Import from a shared bundle |
vial audit |
|
View vault audit log |
vial shelf add/list/rm |
project |
Manage project registry |
vial label set/list/rm |
alias |
Manage key aliases |
vial dashboard |
|
Launch web dashboard |
vial sync push/pull/status |
|
Sync vault to/from remote |
vial completion bash/zsh/fish |
|
Generate shell completions |
๐ Security Model
What we protect against:
- Disk theft without master password โ vault encrypted at rest with AES-256-GCM
- Shell history leaks โ secret values never accepted as CLI arguments
- Swap exposure โ
memguard uses mlock() to prevent secrets in swap
- Backup exposure โ vault file contains only ciphertext
What we don't protect against:
- Active malware with root access on a running system
- Plaintext
.env files (these are on you โ use .gitignore and full-disk encryption)
Encryption stack:
Master Password
โ Argon2id (64 MiB, 3 iterations, 1 parallelism)
โ 256-bit KEK
โ Encrypts randomly-generated DEK
โ DEK encrypts individual values via AES-256-GCM
Accepted trade-off: Reusing API keys across projects increases blast radius if the vault is compromised, in exchange for zero-friction deployment. This is the reality of solo developer workflows. Vial embraces it while providing the strongest practical encryption for the vault itself.
โ๏ธ Configuration
Config lives at ~/.config/vial/config.yaml:
vault_path: ~/.local/share/vial/vault.json
session_timeout: 4h
env_example: .env.example
log_level: warn
# LLM-assisted matching (optional)
# llm:
# provider: openrouter
# endpoint: https://openrouter.ai/api/v1
# model: anthropic/claude-sonnet-4-6
# vault_key_ref: OPENROUTER_API_KEY
Override with environment variables (VIAL_VAULT_PATH, VIAL_SESSION_TIMEOUT, etc.) or the --config flag.
CI/CD
Set VIAL_MASTER_KEY to unlock the vault non-interactively:
export VIAL_MASTER_KEY="your-master-password"
vial pour # no prompt needed
๐๏ธ Architecture
cmd/vial/main.go โ entry point
internal/
vault/ โ Argon2id KDF, AES-256-GCM, CRUD, atomic storage
parser/ โ .env parser (quotes, escapes, interpolation, multi-line)
matcher/ โ 5-tier matching engine
alias/ โ alias store, pattern rules, auto-detection
project/ โ project registry
llm/ โ LLM provider abstraction (OpenAI, Anthropic, OpenRouter)
scanner/ โ source code env var extraction (JS, Python, Go, Ruby, Rust, PHP)
dashboard/ โ embedded Svelte web dashboard
keyring/ โ OS keychain session caching
config/ โ YAML config via Viper
sync/ โ vault sync (filesystem, git)
web/ โ SvelteKit dashboard SPA
vscode/ โ VS Code extension (coming soon)
Single static binary. No runtime dependencies. ~9 MB with the embedded dashboard.
๐ License
MIT โ do whatever you want with it.
Potent secrets, safely contained.