nvolt Documentation
Learn how to securely manage your environment variables with nvolt.
Installation
macOS
brew install nvolt
Linux
curl -fsSL https://install.nvolt.io/latest/install.sh | bash
From Source
git clone https://github.com/iluxav/nvolt.git
cd nvolt
go build -o nvolt ./cmd/nvolt
sudo mv nvolt /usr/local/bin/
Verify Installation
nvolt --version
Quick Start
Get up and running with nvolt in under a minute:
1. Initialize a Vault
# Initialize in current directory (local mode)
nvolt init
# OR initialize with a GitHub repo (global mode)
nvolt init --repo my-org/nvolt-secrets
2. Push Your Secrets
# From a .env file
nvolt push -f .env.production -e production
# Or set secrets directly with -k flag
nvolt push -k DATABASE_URL=postgres://localhost:5432/mydb -k API_KEY=secret123
3. Pull Secrets
# View secrets
nvolt pull -e production
# Write to file
nvolt pull -e production > .env
4. Run Your Application
# Load secrets and run command
nvolt run -e production npm start
Core Concepts
Projects
A project represents your application. nvolt automatically detects the project name from:
package.json→name(Node.js)go.mod→ full module path (Go)Cargo.toml→package.name(Rust)pyproject.toml→project.name(Python)- Current directory name (fallback)
You can override the project name with -p my-project.
Environments
Environments separate secrets for different deployment stages:
default- Development (default)staging- Staging environmentproduction- Production environment- Custom environments as needed
Machines
Each device or CI server is a "machine" with its own RSA keypair:
- Private key stays on the machine (
~/.nvolt/private_key.pem) - Public key is stored in the vault (
.nvolt/machines/) - Machines must be granted access to decrypt secrets
Wrapped Keys
Secrets are encrypted with a master key. The master key is "wrapped" (encrypted) for each authorized machine using their public key. This allows:
- Per-machine access control
- Easy machine revocation
- Key rotation without re-encrypting all secrets
nvolt init
Initialize a new vault and generate machine keypair.
Usage
# Local mode - vault in current directory
nvolt init
# Global mode - vault in GitHub repo
nvolt init --repo org/repo-name
What it does
- Generates RSA-4096 keypair for this machine
- Stores private key at
~/.nvolt/private_key.pem - Creates vault structure at
.nvolt/or~/.nvolt/orgs/org/repo/ - In global mode: clones the repository if it doesn't exist
nvolt join
Join an existing vault and register this machine.
Usage
# Local mode - vault in current directory
nvolt join
# Global mode - vault in GitHub repo
nvolt join org/repo-name
# or
nvolt join --repo org/repo-name
What it does
- Generates RSA-4096 keypair for this machine (if not already present)
- Registers machine's public key to the existing vault
- In global mode: clones the repository if it doesn't exist locally
After Joining
After joining a vault, you'll need someone with push access to grant your machine access to specific environments:
# Someone with access runs:
nvolt machine grant your-machine-id -e production
nvolt join when connecting to an existing vault that was created by someone else. Use nvolt init when creating a new vault for the first time.
nvolt push
Encrypt and push secrets to the vault.
Usage
# From .env file
nvolt push -f .env.production -e production
# Set individual secrets with -k flag
nvolt push -k API_KEY=abc123 -k DB_PASSWORD=secret
# Multiple secrets and specify project name
nvolt push -k API_KEY=abc123 -k DB_SECRET=xyz789 -p my-backend -e staging
Flags
-f, --file- Path to .env file-k, --key- Key=value pairs (can be specified multiple times)-e, --env- Environment name (default: "default")-p, --project- Project name (auto-detected if not specified)
nvolt pull
Decrypt and retrieve secrets from the vault.
Usage
# Print secrets to stdout
nvolt pull -e production
# Write to file
nvolt pull -e production > .env.local
# Different project
nvolt pull -p my-backend -e staging
Flags
-e, --env- Environment name-p, --project- Project name
Output Format
Secrets are output in .env format:
DATABASE_URL=postgres://localhost:5432/mydb
API_KEY=abc123xyz
SECRET_TOKEN=super-secret
nvolt run
Load secrets into environment and run a command.
Usage
# Run npm start with production secrets
nvolt run -e production npm start
# Run Python script
nvolt run -e staging python app.py
# Run with custom project
nvolt run -p my-api -e production ./server
Flags
-e, --env- Environment name-p, --project- Project name-c, --command- Command to run (alternative to positional args)
Machine Management
Add a Machine
Generate a new keypair for another device or CI server:
nvolt machine add ci-github-actions
This generates a private key that you can copy to the new machine.
List Machines
nvolt machine list
Grant Access to a Machine
Grant a specific machine access to decrypt secrets in an environment:
# Grant access to default environment
nvolt machine grant ci-server
# Grant access to specific environment
nvolt machine grant ci-server -e production
# Grant access with project and environment
nvolt machine grant alice-laptop -p myproject -e staging
This wraps the master key for the specified machine, allowing it to decrypt secrets.
Remove a Machine
Revoke access for a machine:
nvolt machine rm ci-github-actions
This removes the machine's wrapped keys, preventing it from decrypting secrets.
Vault Commands
Show Vault Info
nvolt vault show
Displays:
- Registered machines
- Projects and environments
- Access permissions
Verify Vault Integrity
nvolt vault verify
Verifies:
- All encrypted files are readable
- Wrapped keys are valid
- No corruption in vault structure
Sync Vault
# Re-wrap keys after machine changes
nvolt sync
# Rotate master key
nvolt sync --rotate
Local vs Global Mode
Local Mode
Vault is stored in your project directory at .nvolt/.
# Initialize
cd my-project
nvolt init
# Vault is at ./nvolt/
# Commit to Git
git add .nvolt/
git commit -m "Add encrypted secrets"
git push
Git Management: You control all Git operations (add, commit, push).
Global Mode
Vault is stored in a dedicated GitHub repository at ~/.nvolt/orgs/org/repo/.
# Initialize with repo
nvolt init --repo my-org/nvolt-secrets
# Vault is at ~/.nvolt/orgs/my-org/nvolt-secrets/
# nvolt automatically handles Git operations
Git Management: nvolt automatically pulls before reads and pushes after writes.
Directory Structure Comparison
Local Mode
my-project/
├── .nvolt/
│ ├── machines/
│ ├── secrets/
│ │ └── default/
│ ├── wrapped_keys/
│ │ └── default/
│ └── keyinfo.json
├── src/
└── package.json
Global Mode
~/.nvolt/
├── private_key.pem
└── orgs/
└── my-org/
└── nvolt-secrets/
├── machines/
├── my-project/
│ ├── secrets/
│ │ ├── default/
│ │ └── production/
│ └── wrapped_keys/
└── another-project/
Environments
Separate secrets for different deployment stages.
Creating Environments
Environments are created automatically when you push secrets:
nvolt push -f .env.dev -e development
nvolt push -f .env.staging -e staging
nvolt push -f .env.prod -e production
Environment-Specific Access
You can grant machines access to specific environments:
# CI gets staging access
nvolt machine add ci-server
# Push staging secrets - CI can now decrypt them
nvolt push -f .env.staging -e staging
# Production servers get production access only
# They won't be able to decrypt staging secrets
Access Control
How It Works
Access control in nvolt is cryptographically enforced:
- Each machine has a unique RSA keypair
- Secrets are encrypted with a project master key
- The master key is wrapped (encrypted) for each authorized machine
- Only machines with a wrapped key can decrypt secrets
Granting Access
When you add a machine and push secrets, that machine automatically gets access:
# Add new machine
nvolt machine add laptop-alice
# Copy the generated private key to Alice's laptop
# at ~/.nvolt/private_key.pem
# Push or sync secrets - this wraps the master key for Alice
nvolt sync
Revoking Access
# Remove machine
nvolt machine rm laptop-alice
# Re-wrap keys for remaining machines
nvolt sync
Key Rotation
When to Rotate
- A machine's private key may be compromised
- Regular security policy (e.g., every 90 days)
- After removing a team member
Rotating Master Key
nvolt sync --rotate
This will:
- Generate a new master key
- Re-encrypt all secrets with the new key
- Wrap the new key for all authorized machines
- Delete the old master key
Cryptography
Algorithms Used
- RSA-4096 - Machine keypairs and key wrapping (OAEP with SHA256)
- AES-256-GCM - Secret encryption (authenticated encryption)
- SHA256 - Key fingerprints and OAEP padding
Encryption Flow
- Generate project master key (32 bytes random)
- Encrypt each secret value with AES-256-GCM using master key
- Wrap master key for each machine using RSA-OAEP
- Store encrypted secrets and wrapped keys in vault
Decryption Flow
- Load machine's wrapped key from vault
- Decrypt wrapped key using machine's private RSA key
- Decrypt secret values using unwrapped master key
- Load secrets into environment
Security Properties
- ✅ Confidentiality - Only authorized machines can decrypt
- ✅ Integrity - GCM authentication prevents tampering
- ✅ Forward Secrecy - Rotating master key protects past secrets
- ✅ No Network Trust - All crypto happens locally
Security Best Practices
✅ Do
- Keep
~/.nvolt/private_key.pemsecure (permissions: 0600) - Use separate environments for dev/staging/prod
- Rotate master keys regularly (e.g., every 90 days)
- Remove machines immediately when team members leave
- Use strong Git authentication (SSH keys, not HTTPS passwords)
- Enable Git repo access controls (private repos)
- Audit vault changes via Git history
❌ Don't
- Never commit
~/.nvolt/private_key.pemto Git - Never share private keys between machines
- Never store plaintext secrets in Git
- Don't use the same environment for dev and prod
- Don't skip machine removal when revoking access
Backup Strategy
- Vault is backed up via Git - just clone the repo
- Back up
~/.nvolt/private_key.pemseparately (encrypted backup) - Document machine management procedures
GitHub Actions
Setup
- Generate a CI machine keypair:
nvolt machine add ci-github-actions
- Copy the generated private key
- Add it as a GitHub secret:
NVOLT_PRIVATE_KEY - Push your secrets to the vault:
nvolt push -f .env.ci -e ci
nvolt sync # Wrap keys for the new CI machine
Workflow Example
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install nvolt
run: |
curl -fsSL https://install.nvolt.io/latest/install.sh | bash
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Setup nvolt private key
run: |
mkdir -p ~/.nvolt
echo "${{ secrets.NVOLT_PRIVATE_KEY }}" > ~/.nvolt/private_key.pem
chmod 600 ~/.nvolt/private_key.pem
- name: Clone vault
run: |
git clone [email protected]:my-org/nvolt-secrets.git ~/.nvolt/orgs/my-org/nvolt-secrets
- name: Run app with secrets
run: |
nvolt run -e ci npm test
GitLab CI
Setup
- Generate a CI machine keypair:
nvolt machine add ci-gitlab
- Add the private key as a GitLab CI/CD variable:
NVOLT_PRIVATE_KEY - Mark it as "File" type
- Push secrets and sync:
nvolt push -f .env.ci -e ci
nvolt sync
Pipeline Example
stages:
- test
- deploy
test:
stage: test
before_script:
- curl -fsSL https://install.nvolt.io/latest/install.sh | bash
- export PATH="$HOME/.local/bin:$PATH"
- mkdir -p ~/.nvolt
- cp $NVOLT_PRIVATE_KEY ~/.nvolt/private_key.pem
- chmod 600 ~/.nvolt/private_key.pem
- git clone [email protected]:my-org/nvolt-secrets.git ~/.nvolt/orgs/my-org/nvolt-secrets
script:
- nvolt run -e ci npm test