Docs/SDK/Client-side Decryption
JavaScript · Python · Go

Client-side Decryption SDK

For self-hosted deployments: decrypt a token in your own runtime instead of routing through a proxy. It needs the deployment's own master and HMAC keys, so it is not available on hosted plans, where those keys belong to KeyVault Edge and are never shared. The SDKs are not yet published.

Server-side only

The decrypt SDK requires MASTER_KEY and HMAC_KEY. These are your root encryption keys — never include them in browser bundles, mobile apps, or any code that reaches untrusted environments. If you need to use an API key in the browser, use Ephemeral Sessions instead.

When to use the decrypt SDK

Cloudflare Worker / Edge Runtime

Decrypt inline inside a Worker without a round-trip to another service. Web Crypto API is available natively.

Backend microservice

Your service stores tokens in a DB and needs to call an upstream API — decrypt at call time, never at rest.

CLI tools & scripts

Automate API calls using tokens stored in a secrets manager without hardcoding keys.

Custom proxy middleware

Build your own forwarding layer with full control over headers, retries, and observability.

Install

# Not yet published to npm. Included with self-hosted (Enterprise) deployments.

Usage

import { KeyVaultDecryptor } from "@keyvault-edge/sdk/decrypt"; // Server-side only, inside YOUR self-hosted deployment.// MASTER_KEY / HMAC_KEY are that deployment's own root keys.const kv = new KeyVaultDecryptor({  masterKey: process.env.KV_MASTER_KEY!,  hmacKey: process.env.KV_HMAC_KEY!,}); const { apiKey, authHeaderName, authPrefix } = await kv.decrypt(token, "api.yourdomain.com"); await fetch("https://api.openai.com/v1/chat/completions", {  method: "POST",  headers: { [authHeaderName]: `${authPrefix}${apiKey}`, "Content-Type": "application/json" },  body: JSON.stringify({ model: "gpt-4o-mini", messages: [{ role: "user", content: "hi" }] }),});

The host parameter must match one of the allowedHosts the token was bound to at creation time. A mismatch throws a HostBindingError.

What happens inside the SDK

internals.ts
// Full decrypt pipeline (what the SDK does internally)://// 1. Strip the kvt_ prefix and split body / signature// 2. Verify the HMAC-SHA256 signature (tampered tokens are rejected here)// 3. Unwrap the per-token DEK with the master key (AES-256-GCM)// 4. Decrypt the payload with the DEK (AES-256-GCM): provider key + policy// 5. Check the host against the token's allowed hosts// 6. Check the expiry timestamp// 7. Return the provider key and its auth header details // KeyVaultDecryptor.decrypt(token, host) runs exactly these steps.

There are no network calls: everything is local cryptography (Web Crypto in JavaScript, or the platform's equivalent).

Error types

ErrorCause
InvalidTokenErrorToken is malformed or not a valid kvt_ token
HMACVerificationErrorSignature mismatch — token was tampered with or wrong HMAC_KEY
TokenExpiredErrorToken has passed its expiry timestamp
HostBindingErrorProvided host is not in the token's allowedHosts list
DecryptionErrorAES-GCM decryption failed — wrong MASTER_KEY or corrupted payload

Decrypt SDK vs. proxy

Decrypt SDKProxy (hosted / BYOP)
Latency overhead~0 ms (local crypto)1–30 ms (network)
Requires MASTER_KEY at runtimeYesNo
Breach detectionYou implement itBuilt-in
Rate limitingYou implement itBuilt-in
Audit loggingYou implement itBuilt-in
Works in the browserNoVia ephemeral sessions

Related docs