New: one command to protect every key
The fastest way to get started is now:
npx @vaultproof/init
This scans your .env, Shamir-splits each key locally, and rewrites your environment with one vp-proj- project ID. Zero code changes.
VaultProof Documentation
Everything you need to store, protect, and proxy your API keys and secrets with split-key security.
What is VaultProof?
VaultProof is a security layer for API keys and secrets. It splits your keys, encrypts the shares separately, and reassembles them only briefly in memory during a proxied API call. Your raw API key is never stored whole at rest on any server.
It is built for developers who work with third-party API keys -- OpenAI, Anthropic, Google AI, Together.ai, and more. If you have ever committed a key to GitHub, emailed a key to a teammate, or stored a key in plaintext in a .env file on a server, VaultProof solves that problem.
The problem is real: In 2024, GitHub detected 39 million leaked secrets in public repositories. API keys are the number one attack vector for credential theft. One leaked OpenAI key can cost you thousands of dollars in minutes.
Split and encrypt API keys with split-key encryption. No one -- including us -- can see the full key.
Make API calls through VaultProof. The key is reconstructed briefly in memory, then destroyed.
Every proxied call is logged with timestamp, endpoint, status code, and latency. Full audit trail.
Quick Start
Three ways to use VaultProof. The Proxy URL is the fastest -- run npx @vaultproof/init and every SDK works.
| Tool | What it is | Use when | Install |
|---|---|---|---|
Proxy URL RECOMMENDED |
Change your base URL to route through VaultProof | Any app using OpenAI, Anthropic, Google, or any AI SDK | No install -- just change one line |
npx @vaultproof/init |
One command that scans your .env, splits every key, and rewrites your environment | Any project with a .env file containing API keys | No install -- just run with npx |
| Dashboard | Web UI at vaultproof.dev/app | Visual key management, usage monitoring, team settings | No install -- just open in browser |
All three tools do the same thing under the hood: split your key, encrypt both shares with different keys, and proxy API calls so the full key is only assembled briefly in memory. The difference is the interface.
Proxy URL -- 1-line change
The fastest way to use VaultProof. Keep your existing SDK, just change the base URL. All SDK features work -- streaming, retries, types, everything.
Setup (once)
- Run
npx @vaultproof/init-- it scans your .env, splits each key, and rewrites your environment - Your .env now has a
vp-proj-project ID and per-provider*_BASE_URLentries - Done -- your existing code works, key is protected
import OpenAI from 'openai' const client = new OpenAI({ apiKey: process.env.VAULTPROOF_PROJECT_ID, // vp-proj- project ID baseURL: 'https://init.vaultproof.dev/p/openai/v1' }) // Use normally -- all SDK features work (streaming, retries, types) const res = await client.chat.completions.create({ model: 'gpt-4', messages: [{ role: 'user', content: 'Hello' }] })
import Anthropic from '@anthropic-ai/sdk' const client = new Anthropic({ apiKey: process.env.VAULTPROOF_PROJECT_ID, baseURL: 'https://init.vaultproof.dev/p/anthropic' })
import openai client = openai.OpenAI( api_key="vp-proj-...", base_url="https://init.vaultproof.dev/p/openai/v1" )
import Groq from 'groq-sdk' const client = new Groq({ apiKey: process.env.VAULTPROOF_PROJECT_ID, baseURL: 'https://init.vaultproof.dev/p/groq/openai/v1' })
import OpenAI from 'openai' const client = new OpenAI({ apiKey: process.env.VAULTPROOF_PROJECT_ID, baseURL: 'https://init.vaultproof.dev/p/deepseek/v1' })
Init CLI -- one command, every SDK works
Run npx @vaultproof/init in any project. It scans your .env, splits each key, and adds per-provider *_BASE_URL entries for supported header-based providers. Your OpenAI-compatible and API-key SDKs can then route through VaultProof with their normal environment variables.
# Protect every key in your .env at once npx @vaultproof/init # Protect a custom/internal API key from .env npx @vaultproof/init custom # Protect vault-only runtime secrets from .env npx @vaultproof/init secrets add # Run with vault-only secrets injected into the child process npx @vaultproof/init run -- npm run dev # Protect Ansible/Terraform network automation secrets npx @vaultproof/init netops npx @vaultproof/init netops run -- ansible-playbook site.yml # Preview what will happen without making changes npx @vaultproof/init --dry-run # Check if you have any legacy vp_live_ references to clean up npx @vaultproof/init --check-legacy
Your existing SDKs work unchanged
After running npx @vaultproof/init, your .env contains per-provider *_BASE_URL entries that point at the VaultProof proxy. Most SDKs (OpenAI, Anthropic, Stripe, etc.) read their base URL from the environment, so your code works without any changes.
# Original keys have been split and stored securely VAULTPROOF_PROJECT_ID=vp-proj-a8Kj3mNp9xRt2wQz # Per-provider proxy URLs (SDKs read these automatically) OPENAI_BASE_URL=https://init.vaultproof.dev/p/openai/v1 OPENAI_API_KEY=vp-proj-a8Kj3mNp9xRt2wQz ANTHROPIC_BASE_URL=https://init.vaultproof.dev/p/anthropic ANTHROPIC_API_KEY=vp-proj-a8Kj3mNp9xRt2wQz
import OpenAI from 'openai' // The SDK reads OPENAI_BASE_URL and OPENAI_API_KEY from env const client = new OpenAI() const res = await client.chat.completions.create({ model: 'gpt-4', messages: [{ role: 'user', content: 'Hello!' }] })
CLI -- run from the command line
The CLI has a few focused commands. Run it from any project directory.
# Scan .env, split every key, rewrite environment $ npx @vaultproof/init # Add an unsupported or internal API key from .env $ npx @vaultproof/init custom # Store database URLs, JWT secrets, and webhook secrets $ npx @vaultproof/init secrets add # Start a process with vault-only secrets injected $ npx @vaultproof/init run -- npm run dev # Protect and run network automation secrets $ npx @vaultproof/init netops $ npx @vaultproof/init netops run -- ansible-playbook site.yml # Preview what will happen without making changes $ npx @vaultproof/init --dry-run # Check for legacy vp_live_ references in your project $ npx @vaultproof/init --check-legacy
Dashboard -- visual web interface
Use the dashboard to view your projects, monitor proxy usage, and manage settings.
- Go to vaultproof.dev/app and create an account or log in
- Run
npx @vaultproof/initin your project to create a project and protect your keys - Your
vp-proj-project ID and protected keys appear in the dashboard - Monitor proxy call logs, per-provider usage, and rate limit status
CI/CD + Kubernetes
VaultProof works well in pipelines and clusters because the runtime only needs a public vp-proj- identifier plus per-provider proxy URLs.
VAULTPROOF_PROJECT_ID=vp-proj-... OPENAI_API_KEY=vp-proj-... OPENAI_BASE_URL=https://init.vaultproof.dev/p/openai/v1
env: VAULTPROOF_PROJECT_ID: ${{ secrets.VAULTPROOF_PROJECT_ID }} OPENAI_API_KEY: ${{ secrets.VAULTPROOF_PROJECT_ID }} OPENAI_BASE_URL: https://init.vaultproof.dev/p/openai/v1
kubectl create secret generic app-env \ --from-literal=VAULTPROOF_PROJECT_ID=vp-proj-... \ --from-literal=OPENAI_API_KEY=vp-proj-... \ --from-literal=OPENAI_BASE_URL=https://init.vaultproof.dev/p/openai/v1
Server-side callers: if your jobs/pods do not send browser Origin headers, do not enable strict origin enforcement for that project.
How It Works
A deep dive into the cryptographic pipeline that protects your keys.
3.1 Key Storage Flow
When you run npx @vaultproof/init, here is exactly what happens for each key found in your .env:
The CLI reads .env, .env.local, .env.production, and .env.development. It identifies API keys by shape (prefix and length) against a growing provider catalog.
Each key is split into exactly 2 shares using Shamir's Secret Sharing over GF(256). Each share alone is mathematically useless — knowing one share reveals zero information about the original key. The splitting happens in your terminal; the plaintext key is never transmitted.
Share 1 is sent to the VaultProof worker over HTTPS. The worker encrypts it with AES-256-GCM using a key derived from the server-side master key via HKDF-SHA256. A unique salt and IV are generated per encryption. The encrypted ciphertext is stored in Supabase.
Share 2 is stored as a separate base64 blob in Supabase. Either share alone reveals nothing about the key — this is a mathematical guarantee of the Shamir scheme, not a software assumption.
The original key values in your .env are replaced with your vp-proj- project ID, and per-provider *_BASE_URL lines are added pointing at the VaultProof proxy. A timestamped backup of your original .env is created first.
You receive a single vp-proj- identifier. This is not a secret — it is safe to commit, share, and put in CI variables. It tells the proxy which stored shares to reconstruct for each provider.
Key point: The plaintext API key never leaves your machine. The VaultProof server receives only Shamir shares, which are mathematically useless individually. The server encrypts Share 1 with its own master key; Share 2 is stored separately. Reconstruction requires both.
3.2 Proxy Call Flow
When your SDK makes an API call through the VaultProof proxy (via the *_BASE_URL in your .env), the key is temporarily reconstructed:
Your OpenAI/Anthropic/Stripe SDK reads the *_BASE_URL from the environment and sends its request to init.vaultproof.dev/p/<provider>/... instead of the provider directly. Your vp-proj- project ID is in the Authorization: Bearer header.
The worker validates the project ID and checks rate limits via a strongly-consistent Durable Object counter. Invalid or rate-limited requests are rejected before any database work.
The worker fetches both encrypted shares from Supabase in a single query. Share 1 is decrypted with AES-256-GCM using the server-side master key. Share 2 is read as-is. Warm requests hit an in-memory cache (30s TTL) and skip the database round trip.
The two shares are combined using Lagrange interpolation over GF(256). The original API key now exists in worker memory. This takes less than 0.1ms.
The worker forwards your request to the real provider (OpenAI, Anthropic, Stripe, etc.) with the reconstructed key in the appropriate auth header. Streaming (SSE) is supported.
Immediately after the outbound request is issued, the reconstructed key buffer is overwritten with zeros. The key existed in RAM for the duration of one fetch() call — typically under 1ms. It never touches disk, logs, or persistent storage.
The provider's response is passed through to your application with an explicit allowlist of safe response headers. Upstream headers like Set-Cookie are stripped to prevent cross-domain attacks.
3.3 What Happens in a Breach
VaultProof is designed so that compromising any single component does not expose your API keys:
| Scenario | What Attacker Gets | Can They Reconstruct Keys? |
|---|---|---|
| Database breached | Encrypted Share 1 (AES-256-GCM ciphertext) + Share 2 (raw Shamir share). Without the server-side master key, Share 1 is indistinguishable from random data. Share 2 alone reveals nothing about the key. | No |
| Server master key leaked | Can decrypt Share 1. But without Share 2 (which lives in a separate database row), a single share reveals nothing. Shamir's scheme is information-theoretically secure: one share of a 2-of-2 split is pure noise. | No |
| Project ID leaked | The vp-proj- identifier is public by design. An attacker can make proxy calls against your rate limit (60/min) but cannot retrieve the shares or the reconstructed key. The proxy returns the provider's response, not the key. |
No |
| Database + server master key | Decrypted Share 1 + Share 2. Both shares available. | Yes — requires both |
Two independent secrets must both be compromised simultaneously to reconstruct any API key: (1) the database contents (both Share 1 and Share 2) and (2) the server-side encryption key (needed to decrypt Share 1). These are stored in different systems with different access controls.
3.4 Split-Key Encryption Explained
The simple version
Think of it like tearing a photo in half. Each half looks like random noise -- you cannot tell what the photo is from either piece alone. Only when you put both halves together do you see the picture. VaultProof tears your API key into two pieces of cryptographic noise. Each piece is then locked in a separate safe with a separate key. To see the photo again, you need to open both safes.
The technical version
VaultProof uses a cryptographic secret sharing scheme to split each API key into two shares. Each share is independently indistinguishable from random data -- possessing only one share gives an attacker zero information about the original key.
Reconstruction requires both shares. Without both, every possible value of the original key is equally likely. The splitting and reconstruction algorithms are implemented in the open-source @vaultproof/shamir package, which you can audit independently.
3.5 Cryptographic Proofs
For authorization, VaultProof uses cryptographic proofs that verify three things without revealing any sensitive data:
You own the key slot you are requesting access to. The proof verifies your vault commitment hash matches without revealing the key material.
The requesting application has been granted access to this key slot. The proof checks the app grant without exposing the grant chain.
The request is fresh and not replayed. Each proof includes a unique nullifier that is stored server-side. If the same nullifier appears twice, the request is rejected.
Note: When using the SDK, ZK proof generation is handled automatically. The SDK generates proofs client-side before each proxy call.
Packages
VaultProof ships 2 npm packages. Most developers only need @vaultproof/init.
@vaultproof/init
The only package most developers need
One command that scans your .env, splits every API key locally using split-key encryption, uploads encrypted shares, and rewrites your environment with a vp-proj- project ID and per-provider *_BASE_URL entries. No SDK import needed -- your existing SDKs read the new base URL from the environment and route through VaultProof automatically.
npx @vaultproof/init
@vaultproof/shamir
Internal -- rarely needed directly
The split-key encryption engine. Bundled inside @vaultproof/init. Only install this directly if you want raw key splitting without VaultProof infrastructure.
No SDK import needed. After running npx @vaultproof/init, your existing OpenAI, Anthropic, Stripe, and other SDKs work unchanged. They read the *_BASE_URL from your environment and route through VaultProof automatically.
Proxy URL Reference
The recommended way to use VaultProof. Route any AI SDK through VaultProof by changing one URL.
URL Pattern
https://init.vaultproof.dev/p/{provider}/{path}
Replace {provider} with the provider name and {path} with the original API path. VaultProof forwards the request exactly (method, body, headers, query string).
Supported Providers
The init catalog currently includes 250 provider signatures. Common proxy-ready examples:
| Provider | Proxy Base URL | Upstream |
|---|---|---|
openai |
https://init.vaultproof.dev/p/openai/v1 |
https://api.openai.com |
anthropic |
https://init.vaultproof.dev/p/anthropic |
https://api.anthropic.com |
google |
https://init.vaultproof.dev/p/google |
https://generativelanguage.googleapis.com |
minimax |
https://init.vaultproof.dev/p/minimax/v1 |
https://api.minimax.io |
voyage |
https://init.vaultproof.dev/p/voyage/v1 |
https://api.voyageai.com |
jina |
https://init.vaultproof.dev/p/jina |
https://api.jina.ai |
ai21 |
https://init.vaultproof.dev/p/ai21/studio/v1 |
https://api.ai21.com |
assemblyai |
https://init.vaultproof.dev/p/assemblyai |
https://api.assemblyai.com |
together |
https://init.vaultproof.dev/p/together/v1 |
https://api.together.xyz |
mistral |
https://init.vaultproof.dev/p/mistral/v1 |
https://api.mistral.ai |
cohere |
https://init.vaultproof.dev/p/cohere |
https://api.cohere.com |
groq |
https://init.vaultproof.dev/p/groq/openai/v1 |
https://api.groq.com |
perplexity |
https://init.vaultproof.dev/p/perplexity |
https://api.perplexity.ai |
fireworks |
https://init.vaultproof.dev/p/fireworks/inference/v1 |
https://api.fireworks.ai |
deepseek |
https://init.vaultproof.dev/p/deepseek/v1 |
https://api.deepseek.com |
deepl |
https://init.vaultproof.dev/p/deepl |
https://api-free.deepl.com |
deepl-pro |
https://init.vaultproof.dev/p/deepl-pro |
https://api.deepl.com |
replicate |
https://init.vaultproof.dev/p/replicate |
https://api.replicate.com |
gitlab |
https://init.vaultproof.dev/p/gitlab/api/v4 |
https://gitlab.com |
launchdarkly |
https://init.vaultproof.dev/p/launchdarkly/api/v2 |
https://app.launchdarkly.com |
snyk |
https://init.vaultproof.dev/p/snyk/rest |
https://api.snyk.io |
honeycomb |
https://init.vaultproof.dev/p/honeycomb |
https://api.honeycomb.io |
Providers with account-specific upstreams, like Weaviate and Grafana, are supported by init when their service URL is present in your .env. For unsupported or internal HTTP APIs, run npx @vaultproof/init custom.
How Authentication Works
- Send your
vp-proj-project ID inAuthorization: Beareror in the provider API-key header your SDK already uses - VaultProof identifies your project and finds the stored key for that provider
- The key is reconstructed from encrypted shares briefly in memory, used to call the upstream API, then zeroed
- The response (including SSE streaming) is forwarded back to you transparently
SSE streaming works transparently. The proxy forwards chunked responses as they arrive. Your SDK's streaming helpers, retry logic, and type safety all work exactly as they would against the real API.
Examples
curl https://init.vaultproof.dev/p/openai/v1/models \
-H "Authorization: Bearer vp-proj-..."
import OpenAI from 'openai' const client = new OpenAI({ apiKey: process.env.VAULTPROOF_PROJECT_ID, baseURL: 'https://init.vaultproof.dev/p/openai/v1' }) const res = await client.chat.completions.create({ model: 'gpt-4', messages: [{ role: 'user', content: 'Hello' }] })
import openai client = openai.OpenAI( api_key="vp-proj-...", base_url="https://init.vaultproof.dev/p/openai/v1" ) res = client.chat.completions.create( model="gpt-4", messages=[{"role": "user", "content": "Hello"}] )
Integration Reference
No SDK import needed. After running npx @vaultproof/init, your existing SDKs route through VaultProof automatically via environment variables.
How It Works
- Run
npx @vaultproof/init-- scans your .env, splits each key, rewrites the file - Your .env now contains a
vp-proj-project ID and per-provider*_BASE_URLentries - Your SDKs read the environment -- OpenAI, Anthropic, Stripe, and others all support
*_BASE_URLenv vars - API calls route through VaultProof -- the proxy authenticates via
Authorization: Bearer vp-proj-...or the provider API-key header, reconstructs your key briefly in memory, calls the provider, then zeros the key
VAULTPROOF_PROJECT_ID=vp-proj-a8Kj3mNp9xRt2wQz OPENAI_API_KEY=vp-proj-a8Kj3mNp9xRt2wQz OPENAI_BASE_URL=https://init.vaultproof.dev/p/openai/v1 ANTHROPIC_API_KEY=vp-proj-a8Kj3mNp9xRt2wQz ANTHROPIC_BASE_URL=https://init.vaultproof.dev/p/anthropic
Per-Key Limits
PUT /sdk/keys/:keyId/limits
Update per-key call limits. Set daily and monthly caps to control API usage. When a limit is reached, calls are either blocked (HTTP 429) or allowed with an alert email, depending on the blockOnLimit setting.
| Parameter | Type | Required | Description |
|---|---|---|---|
dailyLimit |
number | null |
No | Max calls per day. Set to null to remove the limit. |
monthlyLimit |
number | null |
No | Max calls per month. Set to null to remove the limit. |
blockOnLimit |
boolean |
No | If true, calls return 429 when limit is hit. If false, calls continue but an alert email is sent. |
Returns:
{ status: "updated", dailyLimit: 500, monthlyLimit: 10000, blockOnLimit: true }
Rate limit response (HTTP 429)
{ error: "Daily call limit reached", limit: 500, used: 500, resets: "midnight UTC" }
Supported Providers
The catalog includes 250 signatures. This table shows common proxy-ready providers and their auth style.
| Provider | Value | Base URL | Auth Header |
|---|---|---|---|
| OpenAI | 'openai' |
api.openai.com |
Authorization: Bearer |
| Azure OpenAI | 'azure-openai' |
AZURE_OPENAI_ENDPOINT |
api-key |
| Anthropic | 'anthropic' |
api.anthropic.com |
x-api-key + anthropic-version |
| Google AI | 'google' |
generativelanguage.googleapis.com |
x-goog-api-key |
| MiniMax | 'minimax' |
api.minimax.io |
Authorization: Bearer |
| Voyage AI | 'voyage' |
api.voyageai.com |
Authorization: Bearer |
| Jina AI | 'jina' |
api.jina.ai |
Authorization: Bearer |
| AI21 | 'ai21' |
api.ai21.com |
Authorization: Bearer |
| AssemblyAI | 'assemblyai' |
api.assemblyai.com |
Authorization |
| Together.ai | 'together' |
api.together.xyz |
Authorization: Bearer |
| Mistral | 'mistral' |
api.mistral.ai |
Authorization: Bearer |
| Cohere | 'cohere' |
api.cohere.com |
Authorization: Bearer |
| Groq | 'groq' |
api.groq.com |
Authorization: Bearer |
| Perplexity | 'perplexity' |
api.perplexity.ai |
Authorization: Bearer |
| Fireworks | 'fireworks' |
api.fireworks.ai |
Authorization: Bearer |
| DeepSeek | 'deepseek' |
api.deepseek.com |
Authorization: Bearer |
| DeepL API Free | 'deepl' |
api-free.deepl.com |
Authorization: DeepL-Auth-Key |
| DeepL API Pro | 'deepl-pro' |
api.deepl.com |
Authorization: DeepL-Auth-Key |
| DigitalOcean | 'digitalocean' |
api.digitalocean.com |
Authorization: Bearer |
| Netlify / Render / Heroku | 'netlify', 'render', 'heroku' |
platform APIs |
Authorization: Bearer |
| Fastly | 'fastly' |
api.fastly.com |
Fastly-Key |
| HCP Terraform / Pulumi | 'terraform-cloud', 'pulumi' |
IaC APIs |
Bearer / token |
| Jira / Zendesk / Freshdesk | 'jira', 'zendesk', 'freshdesk' |
account-specific URL |
Authorization: Basic |
| Twilio / Chargebee | 'twilio', 'chargebee' |
api.twilio.com / site URL |
Authorization: Basic |
| Adyen | 'adyen' |
ADYEN_API_URL |
X-API-Key |
| npm Registry | 'npm-registry' |
registry.npmjs.org |
Authorization: Bearer |
| Qdrant / Meilisearch / Typesense / Elasticsearch | 'qdrant', 'meilisearch', 'typesense', 'elasticsearch' |
account-specific URL |
API key header / Bearer / ApiKey |
| Railway / Fly.io | 'railway', 'fly' |
platform APIs |
Authorization: Bearer |
| CircleCI / Buildkite / Semgrep / SonarQube Cloud | 'circleci', 'buildkite', 'semgrep', 'sonarcloud' |
CI and code security APIs |
Bearer / service token header |
| Better Stack / LogSnag / Raygun / Doppler | 'betterstack', 'logsnag', 'raygun', 'doppler' |
observability and secret ops APIs |
Authorization: Bearer |
| Segment / Plausible / Webflow | 'segment', 'plausible', 'webflow' |
analytics and CMS APIs |
Basic / Bearer |
| Svix / Knock / Browserbase | 'svix', 'knock', 'browserbase' |
workflow and agent APIs |
Bearer / X-BB-API-Key |
| Hume AI / RunPod | 'hume', 'runpod' |
model and GPU APIs |
X-Hume-Api-Key / Bearer |
| Paystack / Lemon Squeezy | 'paystack', 'lemonsqueezy' |
payment APIs |
Authorization: Bearer |
| Okta / Stytch | 'okta', 'stytch' |
identity APIs |
SSWS / Basic |
| Replicate | 'replicate' |
api.replicate.com |
Authorization: Bearer |
| GitLab | 'gitlab' |
gitlab.com |
PRIVATE-TOKEN |
| LaunchDarkly | 'launchdarkly' |
app.launchdarkly.com |
Authorization |
| Snyk | 'snyk' |
api.snyk.io |
Authorization: token |
| Honeycomb | 'honeycomb' |
api.honeycomb.io |
X-Honeycomb-Team |
Providers with account-specific upstreams, like Azure OpenAI, Jira, Zendesk, Freshdesk, Qdrant, Meilisearch, Typesense, Elasticsearch, Weaviate, and Grafana, are supported by init when their service URL is present in your .env. For unsupported or internal HTTP APIs, run npx @vaultproof/init custom.
Which keys to store
| Key type | Store? | Notes |
|---|---|---|
| API secret keys | Yes | OpenAI, Anthropic, Stripe secret key, AWS secret access key, etc. |
| OAuth client secrets | Yes | Google OAuth, GitHub OAuth client secrets. Use the proxy at runtime. |
| Service account JSON | Yes | GCP service accounts, Firebase admin keys. Store the entire JSON string. |
| Database passwords | Yes | SMTP passwords, Redis auth tokens, database credentials. |
| PEM / SSH private keys | Yes | Multi-line keys work. The splitting algorithm handles newlines and special characters. |
| Publishable / public keys | No | Stripe publishable key, Supabase anon key, Firebase API key. These are public by design. |
| Short-lived OAuth tokens | No | User access tokens, JWTs, STS temporary credentials. These expire too quickly. |
Keys with IP restrictions
Some providers let you restrict API keys to specific IP addresses. How this interacts with VaultProof depends on which method you use:
- Proxy URL — The API call is routed through VaultProof's server. Remove the IP restriction on your provider key and rely on VaultProof's per-key rate limits and budget caps instead.
Connect Widget
Deprecated. The @vaultproof/connect React widget is no longer needed. The new system uses npx @vaultproof/init to protect keys at the environment level -- no widget required. Existing integrations will continue to work but new projects should use the init flow instead.
CLI Reference
One command to protect every API key in your project. No global install needed -- run with npx.
Commands
npx @vaultproof/init
PRIMARY
Scans your .env (and .env.local, .env.production, .env.development), identifies API keys by prefix and length against a growing provider catalog, splits each key locally using split-key encryption, uploads encrypted shares, and rewrites your environment with a vp-proj- project ID and per-provider *_BASE_URL entries. A timestamped backup of your original .env is created first.
$ npx @vaultproof/init Scanning .env... Found 3 API keys: openai, anthropic, stripe Splitting keys locally... Uploading encrypted shares... Rewriting .env... Done. Your .env now uses vp-proj-a8Kj3mNp9x Backup saved: .env.backup.1712345678
npx @vaultproof/init custom
Protect an unsupported or internal HTTP API key already present in your .env. The CLI prompts for the provider slug, upstream base URL, auth header name, and header template, then rewrites the selected key to use your vp-proj- project ID.
$ npx @vaultproof/init custom Possible custom/internal keys: 1. INTERNAL_API_KEY from .env Provider slug: internal Upstream base URL: https://api.example.com Auth header: Authorization Header template: Bearer {key} Done. INTERNAL_API_KEY now routes through https://init.vaultproof.dev/p/internal
npx @vaultproof/init secrets add
Protect runtime secrets that are not outbound HTTP API keys, including database URLs, Redis URLs, JWT/session secrets, encryption keys, OAuth client secrets, and webhook signing secrets. The CLI stores split shares and rewrites plaintext values to vaultproof:// placeholders.
$ npx @vaultproof/init secrets add Possible vault-only secrets: 1. DATABASE_URL from .env 2. JWT_SECRET from .env Done. Use npx @vaultproof/init run -- npm run dev
npx @vaultproof/init run -- <command>
Fetch vault-only secrets with your authenticated VaultProof session and inject them into a child process environment without writing plaintext back to .env.
$ npx @vaultproof/init run -- npm run dev
Injecting 2 vault-only secrets for vp-proj-a8Kj3mNp9xRt2wQz.
npx @vaultproof/init netops
Protect network automation secrets in Ansible inventories, group_vars, host_vars, .env, terraform.tfvars, and *.auto.tfvars. Ansible values are rewritten to lookup('env', ...); Terraform secrets are supplied through TF_VAR_....
$ npx @vaultproof/init netops $ npx @vaultproof/init netops run -- ansible-playbook site.yml
npx @vaultproof/init --dry-run
Preview what init will do without making any changes. Shows which keys would be split and what your .env would look like after.
$ npx @vaultproof/init --dry-run
Dry run -- no changes will be made
Would split: OPENAI_API_KEY (openai)
Would split: ANTHROPIC_API_KEY (anthropic)
Would split: STRIPE_SECRET_KEY (stripe)
Would add: OPENAI_BASE_URL, ANTHROPIC_BASE_URL, STRIPE_BASE_URL
Would set: VAULTPROOF_PROJECT_ID=vp-proj-...
npx @vaultproof/init --check-legacy
Scan your project for any remaining references to the old vp_live_ / vp_test_ system. Reports files and line numbers so you can clean them up.
$ npx @vaultproof/init --check-legacy
Checking for legacy references...
No legacy references found. You're all set.
Environment Variables
After running npx @vaultproof/init, your .env contains:
| Variable | Description |
|---|---|
VAULTPROOF_PROJECT_ID |
Your vp-proj- project ID. Public, safe to commit. Tells the proxy which stored shares to reconstruct. |
OPENAI_API_KEY |
Set to your vp-proj- ID (the OpenAI SDK reads this for auth). |
OPENAI_BASE_URL |
https://init.vaultproof.dev/p/openai/v1 -- routes SDK calls through the proxy. |
ANTHROPIC_BASE_URL |
https://init.vaultproof.dev/p/anthropic -- same pattern for each provider. |
The same pattern applies for every provider: {PROVIDER}_API_KEY is set to the project ID, and {PROVIDER}_BASE_URL points at the proxy.
Detected Providers
The init command automatically detects these env vars and splits the keys they contain:
| Provider | Env Variable |
|---|---|
openai | OPENAI_API_KEY |
anthropic | ANTHROPIC_API_KEY |
stripe | STRIPE_SECRET_KEY |
aws | AWS_SECRET_ACCESS_KEY |
google | GOOGLE_API_KEY |
groq | GROQ_API_KEY |
mistral | MISTRAL_API_KEY |
twilio | TWILIO_AUTH_TOKEN |
sendgrid | SENDGRID_API_KEY |
github | GITHUB_TOKEN |
Dashboard
Web interface for managing keys, viewing logs, and monitoring usage at vaultproof.dev/app.
Overview Page
Your home screen after login. At a glance you see:
- • Total keys stored -- active key count across all providers
- • API calls this month -- total proxied requests with trend indicator
- • Usage chart -- daily call volume for the past 30 days
- • Key health -- per-key error rates and last-used timestamps
- • Recent activity -- last 10 proxy calls with status
Keys Page
Full key management interface:
- • Add Key -- paste a key, select provider, add a label. Key splitting happens in-browser.
- • Test Key -- one-click test that makes a lightweight proxy call to verify the key works.
- • Rotate -- replace the stored shares with a new API key without changing the key slot ID.
- • Revoke -- permanently destroy both shares. Irreversible.
- • Code snippets -- copy-paste SDK and cURL examples for each key.
Logs Page
Complete audit trail of every proxied API call:
- • Search -- filter by key, provider, status code, date range
- • Details -- timestamp, endpoint, method, status, latency (ms)
- • Export CSV -- download logs for external analysis or compliance
Settings Page
Account and security configuration:
- • Profile -- email and account details
- • Password -- change password (requires current password)
- • Projects -- create, list, and manage
vp-proj-project IDs - • Plan -- view current tier (Free/Starter/Pro/Enterprise) and usage limits
API Reference
Base URL: https://init.vaultproof.dev
The current worker in this repo exposes project-management routes under /api/v1/init/projects and provider proxy routes under /p/:slug/*. Management routes return JSON. Proxy routes forward the upstream provider response body directly.
Health
/health
Simple worker health check.
{ "status": "ok", "service": "vaultproof-init" }
Projects
Authenticated with Authorization: Bearer <supabase jwt>.
/api/v1/init/projects
Create a new project and receive a public vp-proj-... identifier.
// Request { "name": "Production", "allowed_origins": "https://app.example.com,https://staging.example.com", "strict_origin": true } // Response (201) { "id": "uuid", "vp_proj_id": "vp-proj-abc123...", "name": "Production", "created_at": "2026-04-14T..." }
/api/v1/init/projects
List all projects for the current user.
/api/v1/init/projects/:id
Fetch one project by row ID.
/api/v1/init/projects/:id
Update project metadata and origin-lock settings.
{
"name": "Production",
"allowed_origins": "https://app.example.com",
"strict_origin": true
}
/api/v1/init/projects/:id
Soft-revoke a project and all keys under it.
/api/v1/init/projects/stats/overview
Return summary stats for projects, keys, and providers.
Project Keys
Keys are uploaded as Shamir shares. Share 1 is encrypted by the worker; Share 2 is stored separately.
/api/v1/init/projects/:id/keys
Store or update a provider key under a project.
{
"provider": "openai",
"slug": "openai",
"share1": "base64...",
"share2": "base64...",
"env_var": "OPENAI_API_KEY",
"upstream_base_url": "https://api.openai.com",
"auth_header_name": "Authorization",
"auth_header_template": "Bearer {key}",
"extra_headers": { "OpenAI-Beta": "assistants=v2" }
}
/api/v1/init/projects/:id/keys
List active keys under a project.
/api/v1/init/projects/:id/keys/:keyId
Revoke a specific stored key.
/api/v1/init/projects/:id/keys/:keyId/rotate
Rotate an existing key with a new pair of shares.
{
"share1": "base64...",
"share2": "base64..."
}
Proxy
Authenticated with Authorization: Bearer vp-proj-... or a supported provider API-key header. Responses are forwarded from the provider, not wrapped by VaultProof.
/p/:slug/*
Universal provider proxy. The worker looks up the stored upstream config for :slug, reconstructs the real key in memory, injects auth headers, and forwards the request upstream.
curl https://init.vaultproof.dev/p/openai/v1/chat/completions \ -H "Authorization: Bearer vp-proj-..." \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4.1-mini","messages":[{"role":"user","content":"Hello"}]}'
/v1/*
Stripe compatibility path. Requests to /v1/* are proxied through the stored stripe key configuration.
Common Error Codes
| Code | Meaning | Common Cause |
|---|---|---|
400 |
Bad Request | Invalid upstream config, missing required fields, or malformed JSON |
401 |
Unauthorized | Missing or invalid Supabase JWT, or invalid vp-proj-... token |
403 |
Forbidden | Origin lock rejected the request |
404 |
Not Found | Missing project, key, or route |
429 |
Rate Limited | Per-project, per-user, or per-IP limits were exceeded |
500 |
Internal Error | Share reconstruction failed or the upstream provider returned an unexpected failure |
Scanner
The init CLI includes a local env-file scanner as part of the migration flow.
Privacy: The init scanner runs locally on your machine. It reads env files, detects supported provider keys or selected custom keys, and only uploads encrypted Shamir shares after you confirm.
CLI Scanner
Run one of these commands from your project directory:
npx @vaultproof/init --dry-run npx @vaultproof/init custom npx @vaultproof/init secrets add npx @vaultproof/init run -- npm run dev npx @vaultproof/init netops npx @vaultproof/init netops run -- ansible-playbook site.yml npx @vaultproof/init --yes npx @vaultproof/init --check-legacy npx @vaultproof/init doctor
- ✓
.env,.env.local,.env.production, and.env.development - ✓ Provider-specific key patterns from the bundled provider catalog
- ✓ Custom/internal HTTP API keys when you run
custom - ✓ Vault-only runtime secrets like database URLs, JWT secrets, and webhook secrets when you run
secrets add - ✓ Ansible and Terraform network automation secrets when you run
netops - ✓ Legacy
vp_live_references when you run--check-legacy - ✓ Worker, auth, and proxy reachability when you run
doctor
Detection
The current init catalog covers providers such as:
Detection is driven by the provider catalog, not a broad source-code crawl. The init flow is intentionally focused on env-file migration and rewrite.
Current Scope
The init CLI currently focuses on env-file migration. It does not scan your full source tree, CI configs, or git history in this repo. The goal is to replace plaintext secrets in the files your app actually loads at runtime.
Dashboard Scanner
A separate hosted scanner is available in the dashboard at vaultproof.dev/app/scanner for remote repository workflows.
- ✓ Repo-level scanning workflows live separately from the init CLI
- ✓ Use the local init scanner when your priority is rewriting plaintext env secrets quickly
Frequently Asked Questions
Common questions from developers evaluating VaultProof.
"Can VaultProof see my API keys?"
No -- and this is by design, not by policy. Your API key is split into two shares before it is stored. Share 1 is encrypted with a server-side key. Share 2 is stored separately. Neither share alone contains any information about the original key. The full key is only assembled briefly in memory during a proxy call, then immediately wiped. There is no "admin mode" that can view stored keys.
"What if I lose my project ID?"
Project IDs (vp-proj-) are not secret -- they are safe to commit and share. You can find your project ID in the dashboard at any time. If you need a new one, run npx @vaultproof/init again. Your stored keys are tied to your account, not to a specific project ID.
"What if VaultProof goes down?"
If the VaultProof server is unavailable, proxied API calls will fail because the key cannot be reconstructed. However, your API keys at the provider (OpenAI, Anthropic, etc.) are completely unaffected. VaultProof does not modify, rotate, or delete your provider keys. You can always use your original API keys directly if needed. We recommend keeping a backup of critical keys in a secure location for disaster recovery.
"Is this open source?"
Parts of VaultProof are published in this repository and as npm packages, including the init CLI, worker, dashboard, and Shamir package. Check the repo and package metadata for the current licensing and availability of each component.
"What providers are supported?"
The current init catalog includes 250 provider signatures, including OpenAI, Azure OpenAI, Anthropic, Google/Gemini, DeepL, MiniMax, Voyage AI, Jina AI, AI21, AssemblyAI, Hume AI, RunPod, Browserbase, Stripe, Chargebee, Adyen, Twilio, Telnyx, Vonage, MessageBird, Plivo, Paystack, Lemon Squeezy, Groq, xAI, OpenRouter, DeepSeek, Mistral, Together, Fireworks, Resend, SendGrid, Linear, Notion, Figma, Asana, ClickUp, monday.com, Todoist, Coda, Shortcut, GitHub, GitLab, Bitbucket, Jira, Zendesk, Freshdesk, ActiveCampaign, Klaviyo, Iterable, Braze, OneSignal, Novu, Netlify, Render, Heroku, Railway, Fly.io, DigitalOcean, Linode, Vultr, Hetzner, Scaleway, Fastly, HCP Terraform, Pulumi, npm Registry, CircleCI, Buildkite, Semgrep, SonarQube Cloud, Qdrant, Turso, Meilisearch, Typesense, Elasticsearch, Directus, Strapi, Hygraph, DatoCMS, Contentstack, Storyblok, Better Stack, Grafana, Honeycomb, Raygun, LogSnag, Snyk, Doppler, HashiCorp Vault, 1Password Connect, Opsgenie, Statuspage, LaunchDarkly, Split.io, Flagsmith, Segment, Plausible, Webflow, Svix, Knock, Brave Search, Apify, fal.ai, Serper, Make, n8n, Axiom, InfluxDB, Rollbar, BugSnag, Codecov, BrowserStack, Auth0, FusionAuth, Aiven, CockroachDB Cloud, DataStax Astra, Redis Cloud, ClickHouse Cloud, Razorpay, Mollie, GoCardless, Mercado Pago, Wise, Shippo, EasyPost, ShipEngine, Front, Help Scout, Calendly, Typeform, Productboard, Dropbox, Box, Pinata, DeepInfra, Baseten, Cartesia, Unstructured, Luma AI, Portkey, Scale AI, Braintrust, Eden AI, VirusTotal, IPinfo, Apollo, Buttondown, Close, Greenhouse Harvest, Xendit, Midtrans, Coinbase Commerce, Lokalise, Crowdin, Sendbird, Mux, bunny.net, Prerender.io, ImageKit, SambaNova, NVIDIA NIM, FriendliAI, Hyperbolic, Vapi, Retell AI, Rev AI, Speechmatics, Gladia, Soniox, Resemble AI, Infobip, Mailchimp Marketing, Fauna, Zilliz Cloud, Pipedream, Attio, Recurly, Phrase Strings, Transifex, RevenueCat, Qovery, Northflank, Koyeb, Deno Deploy, Supabase, Neon, and more. For proxying, each stored key carries its own validated upstream URL and auth-header template, so the worker can support provider-specific routing without hardcoding every API path.
"How is this different from 1Password or HashiCorp Vault?"
1Password and HashiCorp Vault store secrets and give them back to you in plaintext when you need them. Your application then uses the key directly, meaning it exists in your app's memory, potentially in logs, and definitely in network traffic. VaultProof never gives you the key back. Instead, it makes the API call for you using the reconstructed key, which only exists briefly in VaultProof's memory during the call. Your application never touches the raw key after initial storage.
"What about HIPAA / SOC 2?"
Compliance certifications (SOC 2, HIPAA) are planned but not yet obtained. The current architecture (encryption at rest, TLS in transit, audit logging, access controls) is designed with compliance in mind. Contact us at team@vaultproof.dev for compliance inquiries.
"Does VaultProof add latency to my API calls?"
Yes, but it is minimal. The overhead is the time to decrypt both shares and reconstruct the key (a few milliseconds) plus one additional network hop (edge to backend). For most LLM API calls, which take 500ms-5s to complete, VaultProof adds less than 50ms of overhead -- typically under 2% of the total request time.
"Can I use VaultProof in production?"
Yes. VaultProof runs on a global edge network (330+ cities worldwide) with multi-region database replication. Use your vp-proj- project ID in both production and development -- the proxy handles routing to the correct stored keys for each provider.