← All posts

Zero-Knowledge Secret Manager — What It Is and Why It Matters for AI Agents

A zero-knowledge secret manager means the server cannot decrypt your secrets. Here's why that architecture matters — especially when AI coding agents are in the loop.

A zero-knowledge secret manager is one where the service provider — the company running the server — cannot decrypt your secrets. Not “we promise not to look.” Cannot. Architecturally, mathematically, cannot.

This property matters in any secrets management context. When AI coding agents enter the workflow, it becomes essential.

What zero-knowledge means precisely

In a conventional secrets manager, your secrets are stored encrypted, but the service holds the keys. The provider could, in principle, decrypt any secret you store. More practically: a server compromise, a rogue employee, or a law enforcement request could all result in your secrets being decrypted without your consent.

Zero-knowledge architecture removes this capability entirely. Encryption happens on the client, before anything is sent to the server. The server stores and retrieves ciphertext but has no access to the keys that would let it decrypt that ciphertext.

The client — your machine — holds the key material. The server holds the ciphertext. Neither is useful without the other, and the server never receives the key material.

How OpaqueVault implements zero-knowledge

The encryption chain has three layers:

Layer 1: Master password → Key Encryption Key

master_password → Argon2id(time=1, mem=64MB, threads=4) → KEK (32 bytes)

Your master password is processed through Argon2id, the winner of the Password Hashing Competition and the current state-of-the-art for password-based key derivation. The resulting 32-byte Key Encryption Key (KEK) is never transmitted anywhere. It lives only in your memory and, during an active session, in the memory of the local ov mcp serve process.

The Argon2id parameters are hardcoded client-side. The server cannot suggest weaker parameters. There is no “forgot my master password” flow because there is no server-side recovery — the server doesn’t have anything to recover with.

Layer 2: KEK + random DEK → encrypted DEK

KEK + random_bytes(32) → AES-256-GCM → encrypted_DEK

Each secret gets a unique Data Encryption Key (DEK). The DEK is generated with crypto/rand (cryptographically secure), wrapped with the KEK using AES-256-GCM, and the resulting encrypted_DEK is stored on the server. The server stores the wrapped key but cannot unwrap it without the KEK it doesn’t have.

Layer 3: DEK + plaintext → ciphertext

DEK + plaintext_secret → AES-256-GCM → ciphertext

The actual secret value is encrypted with the DEK using AES-256-GCM with a fresh random nonce for every encryption operation. The ciphertext is stored on the server alongside the encrypted DEK.

What the server stores:

Field Value on server
App slug Plaintext (routing metadata)
Environment slug Plaintext (routing metadata)
Secret name AES-256-GCM ciphertext, indexed by an HMAC lookup token
Secret value AES-256-GCM ciphertext
Data Encryption Key AES-256-GCM wrapped with a key derived from the KEK

The server can neither return the name of your STRIPE_SECRET_KEY nor its value — there is no plaintext name column in the schema. It looks secrets up by an HMAC token computed client-side from a key derived from your KEK, which reveals nothing about the name itself.

App and environment slugs are the exception: those stay in plaintext, because the server routes on them. So the server knows you have an app called payments-api with a production environment, and it knows how many secrets live there and when they’re read — it just doesn’t know what any of them are called or what they contain.

Post-quantum transport: ML-KEM-768 + X25519

Zero-knowledge protects your secrets at rest. Transport security protects them in motion — specifically, when the client sends ciphertext to the server for storage and retrieves it for decryption.

OpaqueVault’s traffic runs over TLS 1.3 negotiating the X25519MLKEM768 hybrid group, which combines X25519 (the current standard) and ML-KEM-768 (the NIST-selected post-quantum algorithm). The hybrid approach means:

  • If X25519 is broken by a quantum adversary, ML-KEM-768 still holds
  • If ML-KEM-768 has an undiscovered vulnerability, X25519 still holds
  • Both would have to be broken simultaneously for the transport to be compromised

“Harvest now, decrypt later” is a real attack model: adversaries record encrypted traffic today, planning to decrypt it when quantum computers become viable. The hybrid PQC approach ensures your secret traffic is safe against this even if you’re creating secrets today that need to stay secret for decades.

Why zero-knowledge matters specifically for AI agents

Every conventional reason to prefer zero-knowledge architecture — server compromise, insider threats, legal demands — still applies. AI coding agents add a new dimension.

When Claude Code or Cursor is helping you build, there’s a third party with access to your development context: the AI model and the infrastructure behind it. Your conversation context, the files the AI reads, and the outputs of tools the AI calls all flow through external infrastructure.

In a non-zero-knowledge architecture, your secrets could be compromised at two points:

  1. At the secrets server (the conventional threat model)
  2. Via the AI’s context window, if the secrets manager naively returns values to the AI

Zero-knowledge handles threat #1 by ensuring the server has nothing to compromise. OpaqueVault’s MCP design — specifically the absence of a get_secret tool — handles threat #2 by ensuring the AI never receives plaintext values in the first place.

The result is a system where:

  • The remote server cannot decrypt your secrets
  • The AI cannot read your secrets
  • Secrets are only ever decrypted locally, in memory, for the duration of a subprocess execution

Comparison: zero-knowledge vs. conventional secrets managers

Property Conventional Zero-Knowledge
Provider can decrypt Yes No
Server compromise risk High Ciphertext only
“Forgot password” recovery Usually yes No (by design)
Key location Server Client only
AI context exposure Possible Defense-in-depth (significantly reduced attack surface)
Audit log sensitivity Can contain secret names HMAC-hashed references

The tradeoffs are real. Zero-knowledge means no server-side recovery. If you lose your master password, your secrets are gone — the server cannot help you. This is the correct tradeoff for a secrets manager, where the security guarantee is more important than the recovery convenience.

Verifying the zero-knowledge property

OpaqueVault is source-available under the Business Source License 1.1, which converts to Apache 2.0 in 2030. BSL 1.1 is not an OSI-approved open-source license, and the repository is not public today — so we won’t tell you to go read the code and check. What you can check is the shape of the API, which accepts only ciphertext and exposes no decryption endpoint:

  • POST /secrets — accepts encrypted_value (ciphertext), encrypted_dek (wrapped DEK)
  • GET /secrets/{id} — returns encrypted_value, encrypted_dek
  • There is no decrypt endpoint

The server is a blob store that speaks HTTPS. There is no server-side secret processing to trust or distrust. This guarantee holds as long as (a) the client-side code has not been tampered with and (b) the user’s master password has not been compromised — standard dependencies for any zero-knowledge system.

Getting started

Terminal window
# Install
brew install opaquevault-brew/tap/ov
# Authenticate (derives KEK from your master password, locally)
ov auth login
# Store a secret (encrypted client-side before sending)
ov secret set DATABASE_URL
# Configure as MCP server for Claude Code
# Add to ~/.claude.json or project .mcp.json:
# { "mcpServers": { "opaquevault": { "command": "ov", "args": ["mcp", "serve"] } } }

From that point forward: your secrets are encrypted with keys only you hold, the server stores ciphertext it cannot read, and Claude Code can use your credentials to run authenticated commands without ever seeing the values.

That’s zero-knowledge secrets management. Not a promise — an architecture.


OpaqueVault is a zero-knowledge, MCP-native secret manager for AI coding agents. Get started free →

Related: MCP Secret Manager — How OpaqueVault Works · MCP Server Secrets Management — The Complete Guide


Corrections (April 2026):

  • Changed “architecturally prevented” to “defense-in-depth” for AI context exposure — vault_run output is observable by the agent, and prompt injection remains a vector. The design minimizes attack surface rather than eliminating it.
  • Added standard zero-knowledge dependency caveats: client-side code integrity and master password hygiene.

Zero-knowledge secrets for AI agents

Keep credentials out of Claude's context window.

OpaqueVault encrypts secrets client-side and injects them into subprocesses — your AI agent never sees the plaintext value.

Get started free →← More posts