TINFOIL_API_KEY on your backend — exposing it to client browsers would let anyone use your API quota. At the same time, you want prompts and completions encrypted end-to-end to the attested enclave, not just to your server.
A proxy server running on your backend solves this. It sits between your client and the Tinfoil enclave, adding your API key, authenticating users, tracking usage, or applying rate limiting — while the Encrypted HTTP Body Protocol (EHBP) ensures request and response bodies stay encrypted end-to-end. EHBP encrypts at the application layer using HPKE, completely separate from TLS, so your proxy can read and modify HTTP headers without ever seeing the plaintext data. The JavaScript SDK also automatically verifies that the HPKE key comes from an attested secure enclave.
Client Setup
First, install the Tinfoil SDK:Proxy support with
SecureClient is available in the JavaScript SDK (Node.js and browsers).baseURL and attestationBundleURL.
This routes all traffic — including attestation — through your proxy, so the client only needs to reach a single origin. The SDK still verifies the attestation bundle client-side regardless of where it was fetched from.
When the SDK sends requests through a proxy (i.e., baseURL differs from the enclave URL), it includes the enclave URL in the X-Tinfoil-Enclave-Url header. Your proxy should use this header to determine where to forward requests, ensuring the encrypted payload reaches the same enclave that the client verified.
Proxy Server Setup
Your proxy’s job is to preserve the EHBP protocol headers that coordinate encryption between client and enclave, add your authentication credentials, and forward the encrypted payload. No special cryptographic libraries are needed — the proxy never participates in encryption or decryption. While we provide an example implementation in Go below, the proxy pattern works with any language that can handle HTTP requests. The example repository provides a complete reference implementation with a Go proxy and a TypeScript client that you can adapt to Python, Node.js, Rust, or any other language.Required Endpoints
Your proxy needs to implement these endpoints:| Path | Method | Description |
|---|---|---|
/attestation | GET | Proxy to https://atc.tinfoil.sh/attestation |
/v1/chat/completions | POST | Forward to the enclave URL from the X-Tinfoil-Enclave-Url header |
/v1/responses | POST | Forward to the enclave URL from the X-Tinfoil-Enclave-Url header |
Required Headers to Preserve
The EHBP protocol uses specific headers to coordinate encryption keys between the client and enclave. Your proxy must forward these headers unchanged in both directions. For requests, you need to preserveEhbp-Encapsulated-Key (the HPKE encapsulated key, hex-encoded, 64 characters).
For responses, you need to preserve Ehbp-Response-Nonce (the 32-byte nonce used in response key derivation, hex-encoded, 64 characters).
Understanding the body framing format isn’t necessary for proxy implementation, but it helps explain why these headers are critical—they contain the cryptographic material needed for key derivation and decryption.
CORS Configuration
If your proxy will be called from browser-based applications, you’ll need to configure CORS headers to allow the browser to send and read the encryption headers. The key requirement is exposing the EHBP headers in both directions:Implementation Example
Usage Metrics for Billing
Since EHBP encrypts request and response bodies, your proxy cannot read token counts from the JSON. Tinfoil provides usage metrics via HTTP headers so you can track usage and bill your users. To enable this, add theX-Tinfoil-Request-Usage-Metrics: true header when forwarding requests to the enclave. Tinfoil returns token counts in the X-Tinfoil-Usage-Metrics response header for non-streaming requests, or as an HTTP trailer after the body completes for streaming requests. The format is:
Custom Headers
Beyond the required EHBP headers, you can use custom HTTP headers to build your own application-level protocols between the client and proxy. Since EHBP only encrypts bodies, headers remain visible to the proxy — which means you can authenticate users, track requests, implement rate limiting, or pass feature flags without any of that metadata reaching the enclave.Request Headers
Access-Control-Allow-Headers configuration so browsers can send them.
Response Headers
Your proxy can add custom headers to responses that the client can read. This is useful for communicating rate limit information, cost tracking, or request IDs for debugging:Access-Control-Expose-Headers configuration for browsers to access them.
Security Considerations
While EHBP encrypts the request and response bodies, the HTTP headers remain visible throughout the proxy chain. This design is intentional—it’s what allows proxies to route and manage requests—but it has important security implications.- Use HTTPS in production. While request and response bodies are encrypted at the application layer, HTTP headers (including custom headers like user IDs) are only protected by transport-layer encryption.
- Validate and sanitize custom headers from clients. Treat them as untrusted input — check formats, guard against injection attacks, and authenticate before trusting client-provided values.
- Always preserve and forward the EHBP headers (
Ehbp-Encapsulated-Keyfor requests,Ehbp-Response-Noncefor responses). Dropping or modifying them will cause decryption to fail.
How It Works
The data flow shows how encryption is maintained throughout the request lifecycle:Next Steps
For a complete working example, check out the encrypted-request-proxy-example repository. It includes a Go proxy implementation with streaming support, a TypeScript browser client demonstrating theSecureClient, and custom header handling examples.
Example Repository
Go proxy server with TypeScript browser client
Encrypted HTTP Body Protocol
Deep dive into the EHBP specification

