TEE verification and encrypted inference
Verify enclave evidence and per-request receipts, understand verification levels, and use opaque NEAR or Chutes E2EE.
AnonRouter exposes provider-neutral enclave attestation and request-signature services. Provider evidence is fetched by a credential-isolated worker, verified fail-closed, and returned to you so your client can independently repeat the verification.
TEE is not automatically hardware-verified
A route's privacy modality and its verification level are separate claims.
AnonRouter currently emits no hardware-verified result. The API never turns
a provider boolean, model suffix, or confidential-compute flag into silicon
proof.
Building an E2EE client?
Follow the dedicated E2EE client guide for the ticket sequence, provider wire formats, required headers, retry rules, and production checklist. This page remains the attestation and receipt reference.
Support matrix
| Provider | Maximum verification | AnonRouter modality | Per-request receipt |
|---|---|---|---|
| Chutes confidential text | provider-attested | Non-streaming ML-KEM whole-body e2ee | Not exposed by the provider; returns tee_signature_not_supported |
| Chutes confidential embeddings | provider-attested | tee | Not exposed by the provider |
| Tinfoil | sdk-verified | tee over TLS/JSON | Not exposed by the provider; returns tee_signature_not_supported |
| NEAR AI direct | provider-attested | Opaque e2ee for openai/gpt-oss-120b and z-ai/glm-5.2 | EIP-191 receipt with exact AnonRouter wire-hash binding for completed non-stream requests |
| NEAR AI attested-3p | No direct model-enclave attestation | tee | No receipt through the direct flow |
| Venice | provider-attested | e2ee | EIP-191 enclave receipt for completed non-stream and streaming requests |
Tinfoil documents EHBP/HPKE transport, but its model selector is encrypted and the documented outer headers do not bind that model to an AnonRouter ticket or reservation. AnonRouter fails closed rather than expose a proxy through which a caller could ticket one model and encrypt a request for another. Tinfoil routes are therefore not advertised as E2EE.
Verification levels
| Level | What the result proves |
|---|---|
hardware-verified | Quote signatures, certificate and revocation chains, acceptable TCB, GPU evidence, nonce and key bindings, debug state, and pinned measurements all passed to silicon-vendor trust roots. No current production route reaches this level. |
sdk-verified | The official provider SDK completed its required cryptographic verification and the result matched AnonRouter's pinned release policy. |
provider-attested | Required structure, freshness, nonce/key, route, certificate-possession, and pinned-measurement checks passed, but the complete silicon-vendor chain was not independently established. |
unverified | A required check, policy value, or evidence item was absent or failed. |
unsupported | The selected provider or route does not expose the requested capability. |
The Intel/NVIDIA chain port remains intentionally unwired. The currently
available path does not provide all collateral, trust-root, revocation, and TCB
handling needed to make the stronger claim. Incomplete evidence fails closed at
provider-attested or unverified.
Fetch fresh attestation evidence
Both public TEE endpoints require an API key with the inference scope. Use a
fresh random nonce containing 32 to 64 bytes, encoded as hexadecimal:
curl "$ANONROUTER_BASE_URL/tee/attestation?model=openai/gpt-oss-120b&provider=near-ai&nonce=$NONCE" \
-H "Authorization: Bearer $ANONROUTER_API_KEY"The response identifies the exact provider route and privacy modality and contains:
verification_leveland every individual check;- normalized measurements and public signing identities;
- the measurement-policy version and expiry;
- the exact raw provider evidence for independent client verification.
Attestation results are cached for five minutes without prompts, responses, private keys, or raw request bodies. A hostname or model name alone never earns a verification level.
Retrieve a request receipt
After a supported completion, use the provider's request ID returned with that completion:
curl "$ANONROUTER_BASE_URL/tee/signature/$PROVIDER_REQUEST_ID?model=openai/gpt-oss-120b&provider=near-ai" \
-H "Authorization: Bearer $ANONROUTER_API_KEY"Optional request_hash and response_hash query parameters are additional
client cross-checks. They never replace the content-free hashes calculated and
stored by AnonRouter.
NEAR exact-wire receipts
For a non-stream request, the credential worker hashes the exact JSON sent to the direct enclave and the exact raw response before parsing. Receipt lookup requires an unexpired route binding, a fresh matching attestation, exact hash equality, and successful EIP-191 recovery to the attested signing address.
For a verified NEAR receipt, hash_binding_checked: true means the signed
request and response hashes equal the exact bytes observed by AnonRouter. NEAR
streaming does not yet provide the completed-response binding needed for this
claim and fails with tee_signature_binding_unavailable.
Venice enclave receipts
Venice receipts are recovered with EIP-191 against the secp256k1 key committed
to the earlier TDX attestation. The signed statement, completion ID, model, and
request.received/response.returned event hashes must agree.
Venice signs an enclave-internal ingress/egress representation rather than the
exact public API wire bytes. A valid receipt therefore normally returns
verified: true, verification_level: "provider-attested", and
hash_binding_checked: false. The response exposes both bound_* provider
hashes and gateway_* wire hashes instead of claiming equality Venice did not
sign.
Completed Venice streams are supported. Receipt metadata crosses the worker boundary in a private sideband that is never emitted as a customer SSE event. Aborted or incomplete streams produce no signature binding.
Unsupported is not a broken TEE route
Chutes and Tinfoil inference and public attestation work normally. They do not
expose a compatible per-completion receipt, so signature lookup returns the
structured 501 tee_signature_not_supported response. AnonRouter never
fabricates a substitute gateway signature.
NEAR v2 opaque E2EE
NEAR direct routes expose the provider-neutral v2 field-encryption modality. Request a nonce-bound attestation ticket for the exact direct route, then send ciphertext with this validated header set:
X-AnonRouter-E2EE-Provider: near-ai
X-Signing-Algo: ed25519
X-Client-Pub-Key: <32-byte Ed25519 public key as 64 lowercase hex chars>
X-Encryption-Version: 2Do not send X-Model-Pub-Key. That field belongs to NEAR's cloud gateway;
AnonRouter obtains the model key from the direct enclave's attestation.
For every encrypted field, the client uses ephemeral X25519 ECDH and
HKDF-SHA256 with info = "ed25519_encryption", then encodes this lowercase-hex
wire value:
[ephemeral X25519 public key: 32 bytes]
[XChaCha20-Poly1305 nonce: 24 bytes]
[ciphertext + authentication tag]Encryption and decryption stay client-side. AnonRouter forwards only the validated headers and opaque ciphertext, does not parse message fields as plaintext, and never receives either private key.
Endpoint discovery must exactly match the reviewed direct enclave domain.
Missing or mismatched discovery fails with
e2ee_enclave_endpoint_unavailable; an E2EE request never falls back to the
cloud gateway, a plaintext route, or another provider.
Chutes ML-KEM whole-body E2EE
Confidential Chutes text routes are ciphertext-only through AnonRouter. First,
use the normal model-bound attestation-ticket flow. The returned raw evidence
contains e2e_instances: instance UUIDs, ML-KEM-768 public keys, and short-lived
single-use nonces. Accept a key only after verifying the response and its
SHA256(caller nonce || ML-KEM key) TDX report-data commitment.
Encrypt with Chutes' official transport format, then submit the exact bytes:
curl "$ANONROUTER_BASE_URL/e2ee/chat/completions" \
-X POST \
-H "Content-Type: application/octet-stream" \
-H "X-AnonRouter-Ticket: $INFERENCE_TICKET" \
-H "X-AnonRouter-E2EE-Provider: chutes" \
-H "X-Chutes-Instance-Id: $ATTESTED_INSTANCE_ID" \
-H "X-Chutes-E2E-Nonce: $SINGLE_USE_NONCE" \
--data-binary @encrypted-request.bin \
--output encrypted-response.binThe credential worker resolves the ticket-bound model to its live chute_id,
requires confidential_compute: true, overwrites the chute, path, and streaming
headers, and adds the Chutes credential. Only the two validated instance/nonce
values cross from the client. Request and response bodies remain byte-for-byte
opaque to AnonRouter, and there is no provider fallback.
This first endpoint is non-streaming. Chutes keeps its non-stream token usage
inside the encrypted response, so the ticket must reserve the model's full output
ceiling. AnonRouter reserves the full context at the most expensive token rate
and conservatively captures it after success; it never estimates plaintext usage
from compressed ciphertext length. The ticket-mint request must therefore set
max_tokens to the model's published maximum.
The opt-in live suite performs a real ML-KEM-768 request/response round trip and decrypts only in the test client; the relay receives only the encrypted blobs.
What each provider check establishes
Chutes
AnonRouter checks every returned instance: TDX v4 structure and debug state,
pinned MRTD/RTMR0-3 measurements, the nonce plus ML-KEM key commitment, the
certificate SPKI commitment, RSA possession of the decoded attested body,
inner/outer quote and GPU equality, certificate validity, and complete instance
key discovery. The missing complete Intel/NVIDIA vendor chain keeps the result
at provider-attested. For an e2ee result, the verified ML-KEM key commitment
also has to pass; the route never claims hardware-verified.
Tinfoil
The credential worker runs the official tinfoil@1.2.1 verifier. An
sdk-verified result requires securityVerified === true, all five SDK
verification steps, the selected endpoint, and exact pinned release digest,
code fingerprint, enclave fingerprint, and TLS key. A missing SDK or document
never defaults to success.
NEAR direct
AnonRouter checks TDX v4 structure and debug state, NVIDIA evidence, the
nonce/key/TLS commitment, exact model and direct endpoint, mr_config_id, the
serialized app_compose hash, and pinned MRTD/RTMR0-3 measurements for that
model. Current evidence does not independently prove the model-weight digest or
complete silicon chain, so the maximum remains provider-attested.
Venice
AnonRouter checks TDX v4 structure and debug state, caller nonce and model,
NVIDIA evidence, nested report-data equality, and a secp256k1 public key whose
derived address matches the signer committed into TDX report data. Venice's own
verified boolean is not accepted as proof.
Service-level comparison
AnonRouter provides the core public operations documented by NanoGPT's TEE verification and signature APIs: fresh authenticated evidence, raw evidence for client verification, measurements and signing identities, and provider receipt lookup. AnonRouter also enforces explicit verification-strength levels, pinned measurement policies, route bindings, server-side EIP-191 recovery, and exact wire-hash checks where the provider signs those bytes.
The distinction is capability-specific: NEAR direct and Venice expose cryptographically verifiable request receipts, while Chutes and Tinfoil expose attestation without a compatible per-request receipt.
Trust boundaries
- Provider credentials stay on their provider-specific worker.
- Control and relay receive only content-free verification metadata and hashes.
- Raw prompts, responses, API keys, decrypted E2EE content, and unsafe upstream bodies are never written to verification caches or logs.
- The dispatch fence still runs immediately before billable provider work.
- Measurement-policy changes require reviewed immutable pins rather than trusting a live provider assertion in place.
See the E2EE client guide, models and privacy labels, intelligent routing, and the complete privacy architecture for how these capabilities affect route selection and the rest of the request lifecycle.