Security

The server cannot
read your secrets.

Not "we promise not to look." Not "protected by our privacy policy." Mathematically cannot — by design. Here's how it works.

Encryption

AES-256-GCM

Key derivation

HKDF-SHA256

IV size

12 bytes / push

Auth tag

128 bits

Encryption

How your secrets are encrypted.

01

A 256-bit master key is generated on your machine

When you push to a new repository for the first time, boltenv generates a cryptographically random 256-bit (32-byte) master key using the operating system's CSPRNG. This key never leaves your machine during this step — it is stored at ~/.boltenv/keys/{owner}/{repo}.key with 0600 file permissions.

02

HKDF-SHA256 derives purpose-specific subkeys

The master key is never used directly for encryption. Instead, boltenv uses HKDF (HMAC-based Key Derivation Function, RFC 5869) with SHA-256 to derive two independent subkeys from the master key:

  • Encryption subkey — derived with info label boltenv-v1-encrypt
  • HMAC subkey — derived with info label boltenv-v1-hmac
Key separation ensures that even if one subkey is somehow compromised, the other remains secure.

03

AES-256-GCM encrypts with a fresh random IV

Your .env file is encrypted using AES-256-GCM (Advanced Encryption Standard with Galois/Counter Mode) with the derived encryption subkey. A fresh 12-byte random IV (Initialization Vector) is generated for every single push — this means encrypting identical content twice produces completely different ciphertext each time. The GCM authentication tag (16 bytes, 128 bits) provides cryptographic tamper detection.

04

Only ciphertext is transmitted to boltenv cloud

The encrypted envelope { version, iv, authTag, ciphertext } is transmitted over TLS to boltenv cloud. The master key and the derived encryption subkey are never transmitted. Key names from your .env file are stored as HMAC-SHA256 hashes, not in plaintext — the server cannot determine what variables you have stored.

05

On pull, the key is fetched and decryption happens locally

When a teammate pulls, the server verifies their GitHub permissions, releases the encrypted master key (wrapped server-side with a separate KMS key), and sends the ciphertext. The master key is decrypted locally, the subkey is derived locally, and the .env file is decrypted locally. The server decrypts nothing.

Access Control

GitHub as the trust anchor.

boltenv does not operate its own identity system. GitHub repository write access is the access control list for secrets. This has several important properties:

Real-time enforcement

The GitHub API is called on every push and pull. There is no cached permission state. The moment you remove someone from the GitHub repo, their next push or pull is rejected — even if they still have the CLI installed and authenticated.

Principle of least privilege

boltenv requests only the repo OAuth scope from GitHub — the minimum needed to verify write access. It does not request access to your GitHub Actions, org membership, billing, or any other data.

No new attack surface

Your team's GitHub account is already a target. Adding boltenv doesn't add a new credentials system to protect — it leverages the authentication infrastructure you already have and manage.

Auditability

GitHub's audit log records every access change to the repository. You have a complete, tamper-evident record of who had access to your repository (and therefore your secrets) and when.

Threat Model

What we protect against. And what we don't.

Every security tool has limits. We publish ours explicitly so you can make an informed decision about whether boltenv fits your threat model.

Protected against

  • Accidental .env commit to a public GitHub repo
  • Secrets shared via Slack, email, or Discord
  • Compromised boltenv server database (ciphertext only)
  • Man-in-the-middle attacks (TLS + GCM auth tag)
  • Stale access after a teammate is removed from GitHub
  • Insider threat at boltenv (server never sees plaintext)
  • Secrets in CI/CD logs (pull writes a file, not stdout by default)
  • Replay attacks (fresh IV per push, auth tag per envelope)
  • Partial file writes (atomic temp-file-then-rename writes)
  • Insecure file permissions (.env written with 0600)

Not protected against

  • Full server compromise with both database + BOLTENV_KEY_WRAPPER env var
  • Supply-chain attack on the @boltenv.dev/cli npm package
  • Authorized but malicious teammate (has the key)
  • Secrets already stored in plaintext elsewhere (Slack history, etc.)
  • Compromised GitHub account of a repo member
  • Secrets visible in shell history if passed as CLI args
  • Memory scraping on the local machine during encryption/decryption
  • Legal process served on boltenv (metadata is accessible)

Data Handling

What we store. And what we don't.

We store

  • ·Encrypted ciphertext (AES-256-GCM)
  • ·IV and authentication tag
  • ·HMAC-SHA256 key name hashes
  • ·Key fingerprints (not the key itself)
  • ·GitHub username of pusher
  • ·Push timestamp and version metadata
  • ·Encrypted master key (KMS-wrapped)

We never store

  • ·Your .env values in plaintext
  • ·Your master encryption key
  • ·Your derived encryption subkey
  • ·Variable names in plaintext
  • ·GitHub access tokens
  • ·BOLTENV_KEY values
  • ·Decrypted data of any kind

Data is stored in encrypted databases. All API traffic is over TLS 1.3. We use separate KMS keys for key wrapping and data encryption. Audit logs are retained for 90 days on the Team plan.

Responsible Disclosure

Found a vulnerability?

We take security reports seriously. If you've found a security vulnerability in boltenv, please report it privately before disclosing publicly. We commit to responding within 24 hours and to working with you on a coordinated disclosure timeline.

In scope

  • · Authentication bypass
  • · Key material exposure
  • · Authorization flaws in push/pull
  • · Cryptographic weaknesses
  • · Data leakage via API endpoints

Out of scope

  • · Rate limiting on non-sensitive endpoints
  • · Denial of service attacks
  • · Social engineering
  • · Physical attacks