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.jsonname (Node.js)
  • go.mod → full module path (Go)
  • Cargo.tomlpackage.name (Rust)
  • pyproject.tomlproject.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 environment
  • production - 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
Use Case: Use 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/.

Use Case: Single repository, team uses Git to share encrypted secrets.
# 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/.

Use Case: Share secrets across multiple projects in your organization.
# 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:

  1. Each machine has a unique RSA keypair
  2. Secrets are encrypted with a project master key
  3. The master key is wrapped (encrypted) for each authorized machine
  4. 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:

  1. Generate a new master key
  2. Re-encrypt all secrets with the new key
  3. Wrap the new key for all authorized machines
  4. Delete the old master key
⚠️ Warning: All machines will need to pull the updated vault after rotation.

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

  1. Generate project master key (32 bytes random)
  2. Encrypt each secret value with AES-256-GCM using master key
  3. Wrap master key for each machine using RSA-OAEP
  4. Store encrypted secrets and wrapped keys in vault

Decryption Flow

  1. Load machine's wrapped key from vault
  2. Decrypt wrapped key using machine's private RSA key
  3. Decrypt secret values using unwrapped master key
  4. 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.pem secure (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.pem to 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

  1. Vault is backed up via Git - just clone the repo
  2. Back up ~/.nvolt/private_key.pem separately (encrypted backup)
  3. Document machine management procedures

GitHub Actions

Setup

  1. Generate a CI machine keypair:
nvolt machine add ci-github-actions
  1. Copy the generated private key
  2. Add it as a GitHub secret: NVOLT_PRIVATE_KEY
  3. 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

  1. Generate a CI machine keypair:
nvolt machine add ci-gitlab
  1. Add the private key as a GitLab CI/CD variable: NVOLT_PRIVATE_KEY
  2. Mark it as "File" type
  3. 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