Skip to main content
Venice offers privacy-enhanced models that run in Trusted Execution Environments (TEE) and support End-to-End Encryption (E2EE). These models provide cryptographic guarantees that your data remains private—even from Venice.

Understanding the Privacy Levels

E2EE models include TEE protection plus client-side encryption. TEE models provide enclave security without requiring client-side encryption.

Available Models

Loading…
Check the Models page for the full list with pricing and context limits.

TEE Models

TEE models run inside hardware-secured enclaves (Intel TDX, NVIDIA Confidential Computing). The model weights and your data are protected from the host system—including Venice’s infrastructure.

Basic Usage

TEE models work exactly like regular models:

Verifying TEE Attestation

You can cryptographically verify that a model is running in a genuine TEE by fetching its attestation report:
The attestation response includes:
For production use, verify the attestation client-side by parsing the Intel TDX quote and checking the NVIDIA attestation.
For plain TEE model verification, signing_address and server-side verification fields are sufficient for baseline attestation checks. A signing_key is required when you need client-side E2EE key agreement and strict key-binding checks.

Response Signatures

TEE models can sign their responses, proving the output came from the attested enclave:

E2EE Models

E2EE models add client-side encryption on top of TEE protection. Your prompts are encrypted before leaving your device, and only the TEE can decrypt them. Venice E2EE uses:
  • ECDH (Elliptic Curve Diffie-Hellman) on secp256k1 for key exchange
  • HKDF-SHA256 for key derivation
  • AES-256-GCM for symmetric encryption
  • TEE attestation to verify the model runs in a secure enclave
E2EE requires client-side implementation. The examples below show the complete protocol.

How E2EE Works

1

Generate Ephemeral Key Pair

Client generates a secp256k1 key pair for this session.
2

Fetch TEE Attestation

Client requests /api/v1/tee/attestation and receives the model’s public key, attestation evidence, and nonce.
3

Verify Attestation

Client checks nonce match, debug mode disabled, and attestation validity.
4

Encrypt Messages

Client encrypts prompts using ECDH shared secret → HKDF → AES-GCM.
5

Send Request

Client sends request with E2EE headers (X-Venice-TEE-Client-Pub-Key, X-Venice-TEE-Model-Pub-Key, X-Venice-TEE-Signing-Algo).
6

TEE Processing

TEE decrypts request, processes it, and encrypts the response.
7

Decrypt Response

Client receives encrypted chunks and decrypts with private key.

Prerequisites

JavaScript (Node.js ESM):
Python:

Step 1: Check Model E2EE Support

First, verify the model supports E2EE by checking the /models endpoint.

Step 2: Generate Ephemeral Key Pair

Generate a new key pair for each session. The private key should be kept in memory only and securely zeroed after use.

Validation Helpers

Use these helper functions to validate keys and encrypted content before sending requests.

Step 3: Fetch and Verify TEE Attestation

The attestation proves the model is running in a genuine TEE. Always verify the attestation before trusting the model’s public key.
Important: Nonce Length - The client nonce must be 32 bytes (64 hex characters). Some TEE providers require exactly 32 bytes and will reject shorter nonces.

Step 4: Encrypt Messages

Encrypt user and system messages before sending. Only user and system role messages need encryption.
When E2EE headers are present, all user and system role messages must be encrypted. Sending any plaintext content in these roles will result in an “Encrypted field is not valid hex” error.

Step 5: Send Request with E2EE Headers

Include the required headers to enable E2EE processing.

Step 6: Decrypt Response Chunks

Responses from E2EE models are hex-encoded encrypted chunks. Decrypt each chunk using your private key.

Complete Working Example

E2EE Limitations

E2EE has some constraints due to the encryption requirements:

Security Best Practices

  1. Generate new key pairs per session - Don’t reuse ephemeral keys
  2. Zero-fill private keys - Clear private key bytes from memory when done
  3. Verify attestation - Always check verified: true and nonce match
  4. Check for debug mode - Reject attestations from debug enclaves
  5. Use streaming - E2EE requires streaming for proper encryption chunking
  6. Handle errors gracefully - Don’t expose decryption errors to users
  7. Use 32-byte nonces - TEE providers require exactly 32 bytes

Best Practices

Don’t just trust the verified: true response. Parse the Intel TDX quote client-side and verify the measurements match expected values. For NVIDIA GPUs, check the attestation via NVIDIA’s verification service.
Always generate a new random nonce for each attestation request. This prevents replay attacks where an attacker could serve a stale attestation.
The signing key should be bound to the TDX REPORTDATA field. This proves the key was generated inside the enclave.
Verify the TDX attestation doesn’t have debug flags set. A debug enclave can be inspected and should not be trusted for production.
E2EE requires careful cryptographic implementation. Use our official SDKs rather than implementing the protocol yourself.

Checking Model Capabilities

You can check if a model supports TEE or E2EE via the models endpoint:

Error Handling

Troubleshooting

The nonce length is incorrect. TEE providers require exactly 32 bytes (64 hex characters).
  • Use crypto.randomBytes(32).toString('hex') (JS) or secrets.token_hex(32) (Python)
  • Common mistake: secrets.token_hex(16) produces 32 hex chars (16 bytes), not 32 bytes
  • Check that the model supports E2EE (supportsE2EE: true)
  • Verify your API key is valid and has access to the requested model
  • Verify network connectivity to Venice API
  • Ensure you’re using the same private key that generated the public key sent in headers
  • Check that the response content is actually hex-encoded (E2EE active)
  • Verify the model public key matches what was used for encryption
  • All user and system role messages must be encrypted when E2EE headers are present
  • Verify your encrypted content passes the isValidEncrypted() validation (minimum 186 hex characters)
  • Check that encryption output is lowercase hex without any prefixes
  • Client public key must be exactly 130 hex characters starting with 04
  • Use the validateClientPubkey() helper to verify format before sending
  • Ensure you’re using uncompressed public key format (65 bytes = 130 hex chars)
  • Verify the model ID is correct and the model supports E2EE
  • Use the /models endpoint to verify available E2EE models

Resources