Edge key proxy
Ship the token.Keep the key.
KeyVault Edge swaps your real API key for a token bound to the origins, endpoints, rate and spend you allow. The token is what lands in your bundle, your repo and your .env. The real key is injected at the edge, on requests that pass every check.
A stolen token is not a usable credential. It is a request for permission that we decline.
Try to get a stolen token past the edge
Same checks, same order, same responses as the live worker.
The policy block is what an attacker cannot see or change — it is sealed inside the encrypted payload. It is shown here so you can watch which rule refuses the request.
- Upstream target
X-KV-Target must be a public https origin (SSRF guard)
- Token signature
HMAC-SHA-256 verify over the token body, before any decrypt
- Envelope decrypt
AES-256-GCM unwraps the per-key DEK, DEK decrypts the payload
- Host binding
Request origin matched against allowed_hosts (wildcards supported)
- Expiry
expires_at compared against request time
- Endpoint scope
Method + path matched against allowed_endpoints
- Rate limit
Sliding minute/hour/day windows in a Durable Object
- Spend cap
Month-to-date estimated cost against monthly_cost_cap_micros
The real key was injected into the provider's auth header inside the worker. X-KV-* and CF-* headers are stripped before the request leaves.
Why we built this
Rotation is a fire drill you run after the damage.
Our own OpenAI key ended up in a public commit and was exploited eleven minutes later. Scanners caught it. The alert was accurate. It was also too late — by the time we rotated, the key had already been used.
Detection tells you a secret escaped. It cannot make the escaped secret useless. That gap is the entire reason this product exists, and it is the only thing it tries to close.
So we stopped trying to keep keys out of the places they leak, and made the thing that leaks worthless instead.
Six places a key gets out
- Client bundles
- A key inlined at build time ships to every visitor who opens devtools.
- Git history
- Removed from HEAD, still sitting in an earlier commit — and in every fork.
- CI logs
- One set -x, one verbose curl, and the key is in a build log with broad read access.
- Error trackers
- Request headers attached to an exception and forwarded to a third party.
- AI assistants
- Whole files pasted into a prompt, keys included, to debug something unrelated.
- Screenshots
- A terminal or .env on screen during a demo, a PR review, or a support ticket.
None of these are exotic. Every one of them is a normal Tuesday on a team that is shipping, which is why “be more careful” has never worked as a control.
Architecture
One boundary, and the secret only exists on one side of it.
The proxy is not a vault you fetch from — nothing hands a decrypted key back to your application. Your app holds a token, the edge holds the ability to use it, and those two facts never swap places.
Holds a restricted token
kve_hb_7f3a…c21This is what ships in your bundle, your repo, and your .env. It is not the credential — it is a policy-bound reference to one.
- 01
Verify signature
HMAC-SHA-256, before any decrypt
- 02
Unwrap envelope
AES-256-GCM: master key → DEK → payload
- 03
Match origin
allowed_hosts, wildcards supported
- 04
Check expiry + scope
expires_at, allowed_endpoints
- 05
Meter budget
rate window, then monthly spend cap
- 06
Inject real key
provider auth header, in worker memory
The real key is decrypted into worker memory for the life of one request. Any stage can refuse, and a refusal never reaches your provider — so it never costs you anything.
Receives an ordinary request
Authorization: Bearer sk-proj-…OpenAI, Stripe, GitHub — whoever it is, they see the real key in their own header format. Nothing about your provider relationship changes.
The response streams straight back with X-KV-Edge and X-KV-Latency attached. Usage and cost are metered after the response is already on its way, never in front of it.
What a token is allowed to do
The policy travels inside the token, encrypted.
Whoever holds the token cannot read its policy or widen it. The restrictions are sealed into the payload, so the only thing an attacker learns from a stolen token is that it did not work.
| Control | Token field | Behaviour |
|---|---|---|
| Origin | allowed_hosts | Exact hosts, or a leading wildcard for subdomains. Checked against the request origin. |
| Endpoint | allowed_endpoints | Method + path patterns. An empty list means unrestricted. |
| Lifetime | expires_at | Absolute expiry, compared at request time. |
| Throughput | rate_limit | Separate per-minute, per-hour and per-day windows. |
| Spend | monthly_cost_cap_micros | Hard month-to-date ceiling in USD micros. |
Scope is checked before the rate limit, so a request to an endpoint the token does not cover is refused without spending any of its budget.
Integration
Change the host. Keep the call.
There is no KeyVault SDK to adopt and no wrapper around your provider's client. You point the base URL at the proxy and pass a token where the key used to go.
// Point the SDK's baseURL at the proxy and pass your token// where the real key used to go. Nothing else changes.import OpenAI from "openai"; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY, // kve_hb_[YOUR_TOKEN] baseURL: "https://openai.keyvaultedge.com/v1",}); const res = await openai.chat.completions.create({ model: "gpt-4o-mini", messages: [{ role: "user", content: "Hello from the edge" }],});Compatible with your stack
Anything reachable over HTTPS with a header-based credential works, including OpenAI, Anthropic, Stripe, GitHub, AWS, Twilio, SendGrid, Supabase and Pinecone. These are APIs we proxy — not customers, partners or endorsements. Per-provider setup →
Receipts
Claims worth making are claims worth checking.
A security product that asks to sit in your request path should show its work. Here is what we assert, who it comes from, and where to verify it — including the parts that are not finished.
Runs on Cloudflare's edge network
Cloudflare's footprint, not ours
The proxy is a Cloudflare Worker, so it executes in Cloudflare's points of presence. The scale of that network is Cloudflare's claim to make; ours is only that we deploy to it.
How we deploy →Latency overhead, per region
Measured, not modelled — and not live yet
We publish p50/p95/p99 overhead per region from probes every five minutes, measured as proxy time minus a direct upstream call. The methodology is pinned. The probes are not running yet, and the table says so.
Benchmark + method →Uptime and incidents
Our record, published either way
We sit in your request path, which makes our availability your problem too. The status page and incident history are public, including the incidents that were our fault.
Status and history →Where we actually are
KeyVault Edge is early. We are working with a small number of engineering teams to prove the model in production, and we would rather tell you that than dress up a logo wall. There is no customer list on this page because we are not going to imply relationships we do not have.
What we can offer instead is inspectability: the architecture, the threat model, the benchmark methodology, the incident log, and a disclosure process for when you find something we missed.
Before you put us in your request path
The questions a security reviewer asks.
Where does the real key live, and is it encrypted at rest?
It is encrypted with AES-256-GCM under a per-key data encryption key, and that DEK is itself wrapped before anything is stored. A full compromise of our database yields ciphertext. The key exists in plaintext only inside worker memory, for the duration of a single request.
Who controls the encryption keys?
By default we hold the key-encryption key. On Enterprise you point us at your own AWS KMS, GCP Cloud KMS, or Azure Key Vault key, and it wraps every DEK instead — at which point we no longer hold anything capable of unwrapping your keys, and you can revoke our access at your KMS without asking us.
Can the edge ever hand the original secret back to my client?
No. The key is written into the upstream request's own auth header inside the worker and the response is streamed back untouched. There is no API that returns a decrypted key, and the proxy strips its own X-KV-* headers plus Cloudflare's CF-* headers before forwarding.
What happens when a check fails?
The request is refused at the edge and never reaches your provider, so a rejected request costs you nothing upstream. Signature and origin failures return 403, expiry 401, a throughput breach 429 with Retry-After, and a spend-cap hit 402. Everything except the spend cap is written to your breach log with the attempted origin, IP and geography.
Does it fail open if something breaks?
It fails closed. A token that cannot be verified is not forwarded — there is no bypass path that would send a request upstream unvalidated. The trade-off is honest: the proxy sits in your request path, so our availability becomes part of yours. That is the right question to ask us, and /status is where we answer it.
What are the limits of the spend cap?
Cost is metered after the response is already streaming, so the counter is eventually consistent. A burst of concurrent requests can overshoot the cap slightly before requests start failing. Streaming responses are not meterable at all and are recorded as zero cost — so treat the cap as a tight guard rail, not an accounting ledger.
Question not here? The vendor checklist covers procurement detail, and security@keyvaultedge.com reaches an engineer.
Pricing
Priced on tokens and requests.
No setup fee, and the limits below are the actual enforced numbers rather than marketing rounding. Full pricing →