Browser-Encrypted Private Mode on Bitcoin.com AI
Bitcoin.com AI now supports Private Mode for a first set of TEE-backed text models.
This is different from ordinary TEE routing. In a normal hosted chat request, Bitcoin.com AI receives your chat body as regular JSON, then routes it to a model. With Private Mode, the request and response body are encrypted on your device before Bitcoin.com AI receives them.
That means Bitcoin.com AI can authenticate, route, and bill the request, but cannot read the prompt or completion body for supported Private Mode requests.
What Private Mode does
Private Mode creates a stricter privacy boundary for supported models:
your browser or local proxy -> encrypted request body -> Bitcoin.com AI -> verified TEE target
verified TEE target -> encrypted response body -> Bitcoin.com AI -> your browser or local proxy
The plaintext exists where it has to exist:
- in your browser or local proxy
- inside the verified TEE target that runs the model
Bitcoin.com AI sees routing and account metadata, but not the encrypted request or response body.
What Bitcoin.com AI can and cannot see
For supported Private Mode requests, the encrypted body includes:
- messages
- system and developer instructions
- text conversation history sent to the model
- supported model settings and reasoning controls
- the model response body
Bitcoin.com AI can still see the parts needed to run the service:
- your Bitcoin.com AI account or API key identity
- the selected Private Mode model
- request timing, sizes, status, and usage metadata
- the selected TEE target metadata
The TEE target can see the plaintext prompt and completion because the model has to process them.
Using Private Mode in the web app
In the Bitcoin.com AI web app, choose an eligible TEE model and use the Private Mode control in the model picker.
If a model does not show the Private Mode control, that model is not currently supported through the browser-encrypted Private Mode path. This is so far only working with Tinfoil models - we're working with other providers to be able to do this for more models and providers.
The web app encrypts the chat-completions body in the browser with the Tinfoil client before Bitcoin.com AI receives it. Bitcoin.com AI forwards the encrypted body and returns the encrypted response. Your browser decrypts the response locally.
Private Mode in the web app is intentionally narrower than normal chat. It supports text chat, conversation history, model settings, streaming, and supported reasoning modes. Features that require Bitcoin.com AI to inspect or add plaintext before the request is encrypted are disabled for Private Mode turns.
Verification receipts
After a completed Private Mode response, Bitcoin.com AI shows a verification receipt.
The receipt includes:
- whether browser-side verification succeeded
- the TEE target and enclave host
- verifier step statuses
- expected and runtime measurement fingerprints
- attestation bundle hash when available
- verification document hash
- request and response encryption flags
- timestamp and model information
This receipt is meant to be copied, saved, and checked independently.
To verify a copied receipt locally:
npx @nanogpt/private-mode verify receipt.json
You can also pipe the receipt JSON on stdin:
cat receipt.json | npx @nanogpt/private-mode verify
The verifier fetches fresh attestation material for the receipt's TEE target, verifies it locally, and checks the measurements, release digest, and HPKE key against the copied receipt.
The right interpretation is specific: this individual Private Mode request used browser-side attestation verification and encrypted request/response bodies for a supported TEE target.
Using Private Mode through the API
For API clients, CLIs, agents, and OpenAI-compatible tools, use the local Bitcoin.com AI Private Mode proxy:
NANOGPT_API_KEY=sk-your-key npx @nanogpt/private-mode
It starts an OpenAI-compatible local server:
http://127.0.0.1:8787/v1
Then point your OpenAI-compatible client at that local base URL:
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "http://127.0.0.1:8787/v1",
apiKey: "unused",
});
const response = await client.chat.completions.create({
model: "private/kimi-k2-6",
messages: [{ role: "user", content: "Hello" }],
});
The local proxy verifies Tinfoil attestation, encrypts request bodies, sends ciphertext through Bitcoin.com AI, decrypts encrypted responses locally, and returns normal OpenAI-compatible responses to your app.
You can inspect the local proxy status with:
GET http://127.0.0.1:8787/v1/models
GET http://127.0.0.1:8787/v1/private-mode/status
GET http://127.0.0.1:8787/v1/private-mode/attestation
The local proxy preserves normal OpenAI chat semantics. Omit stream for a single JSON response, or set stream: true for server-sent events.
Why the local proxy exists
Direct API calls to Bitcoin.com AI's normal /v1/chat/completions endpoint send ordinary JSON to Bitcoin.com AI. That is the right path for normal Bitcoin.com AI API usage, but it is not the Private Mode privacy boundary.
Private Mode needs encryption before the request body leaves your machine. The local proxy gives OpenAI-compatible apps that boundary without requiring every app to implement attestation verification and encrypted transport itself.
Current scope
Private Mode is currently available for supported Tinfoil-backed text models.
That first scope is deliberate. We only want to show the Private Mode label for models where the request body can be encrypted before Bitcoin.com AI receives it, the client can verify the TEE target, and Bitcoin.com AI can still settle usage without decrypting the prompt or completion.
We will expand this when we can make the same claim for more models and providers.