Now in public beta

Your .env file,
but it's a vault.

Drop-in replacement for dotenv. One key in your environment, everything else encrypted remotely. AES-256-GCM. Per-device secrets. Hot reload. Zero config migration.

terminal
# Install (drop-in — same API as dotenv)
$ pip install vault-env
# Before (dotenv)
.env — 14 secrets on every machine
DATABASE_URL=postgresql://user:s3cret@...
STRIPE_KEY=sk_live_4eC39H...
AWS_SECRET=wJalrXUtnFEMI/K7...
...
# After (vault-env)
.env — one key, that's it
VAULT_KEY=vk_proj123_a1b2c3d4e5...

Three steps. No config files.

If you know dotenv, you know vault-env. The migration takes about 90 seconds.

01

Replace one import

Swap load_dotenv() for load_vault(). Same API, same behavior. Your code doesn't change.

# Before
from dotenv import load_dotenv
load_dotenv()

# After
from vaultdotenv import load_vault
load_vault()
02

Push your secrets

Your existing .env gets encrypted with AES-256-GCM and stored remotely. The .env file becomes a single VAULT_KEY.

$ vault-env push
Encrypting 14 secrets...
Pushed to production (v1)

$ cat .env
VAULT_KEY=vk_proj123_a1b2c3...
03

Deploy with one key

Set VAULT_KEY in your environment. Secrets are pulled and decrypted at boot. Each device gets its own encryption layer.

$ vault-env register-device
Device "web-01" registered.
Secret saved to ~/.vault/proj123.key

# That's it. App boots, secrets load.
04

Watch for changes

Rotate a key, update a connection string — running processes pick up the change in seconds. No redeploy, no restart.

import vaultdotenv

vaultdotenv.load_vault()

vaultdotenv.watch(
    interval=30,
    on_change=lambda changed, all:
        print("Rotated:", list(changed.keys())),
)

Security without the ceremony

Everything you need to stop committing secrets. Nothing you don't.

AES-256-GCM encryption

Secrets are encrypted before they leave your machine. The vault server never sees plaintext.

Per-device secrets

Each machine gets a unique device key. Revoke a laptop without rotating every secret.

HMAC-signed requests

Every API call is signed with a time-stamped HMAC. No bearer tokens flying around.

Hot reload

Change a secret in the dashboard, it propagates to running processes. No redeploys.

Encrypted cache

Secrets are cached locally with AES-256-GCM. If the vault is unreachable, your app still boots.

Zero config migration

Run vault-env push. Your .env becomes a VAULT_KEY. That's the entire migration.

Live updates

Change a secret.
Skip the redeploy.

vault-env watches for changes and updates process.env in-place. Rotate an API key from the dashboard and every running process picks it up within seconds. No restart, no downtime.

  • Lightweight polling — only checks a version number, no secrets transferred until something changes
  • onChange callback with the diff — reconnect databases, refresh tokens, whatever you need
  • Background thread (Python) or unref'd timer (Node.js) — won't keep your process alive
Node.js
const vault = require('vault-env');

await vault.config();

vault.watch({
  interval: 30000,
  onChange(changed, allSecrets) {
    console.log('Updated:', Object.keys(changed));
    // Reconnect DB, refresh tokens, etc.
  },
});
Python
import vaultdotenv

vaultdotenv.load_vault()

vaultdotenv.watch(
    interval=30.0,
    on_change=lambda changed, all:
        print("Updated:", list(changed.keys())),
)

Simple, honest pricing

No per-seat charges. No request metering. No surprises.

Free

Enough to ship something real.

$0forever
  • 10 secrets
  • 2 environments
  • 1 project
  • 2 devices
  • Encrypted cache
  • Community support
Start free
Most popular

Pro

For solo devs and small teams.

$4.95/mo
  • 30 secrets
  • 3 environments
  • 3 projects
  • 5 devices
  • Hot reload
  • Version history
  • Email support
Start free trial

Team

For teams who ship to prod.

$9.95/mo
  • Unlimited secrets
  • Unlimited environments
  • 10 projects
  • Unlimited devices
  • Hot reload
  • Version history
  • Audit log
  • Priority support
Start free trial