Skip to main content
End-to-end encryption (E2EE) adds field-level encryption between your client and the attested gateway, on top of TLS. TLS still protects the HTTP connection. E2EE additionally encrypts selected request and response fields to a public key that comes from the gateway’s verified attestation report. E2EE is useful when you want the encryption key itself to be cryptographically tied to the TEE workload you verified.
E2EE decrypts inside the attested gateway so the gateway can process the request. It proves the decryption key belongs to the verified gateway; it does not hide plaintext from that gateway. Use confidential models when the upstream model provider must also be attested.

Get the Gateway E2EE Key

Fetch and verify the gateway attestation report, then read the E2EE key from the attested keyset:
curl -s "https://inference.phala.com/v1/aci/attestation?nonce=$(openssl rand -hex 16)" \
  -H "Authorization: Bearer $API_KEY" \
  | jq -r '.attestation.workload_keyset.e2ee_public_keys[] | select(.key_id=="dstack-kms-e2ee-v1") | .public_key'
The key algorithm is secp256k1-aes-256-gcm-hkdf-sha256. The gateway advertises supported E2EE versions in service_capabilities.supported_e2ee_versions.

Request Headers

Include these headers when sending an E2EE request:
HeaderValue
X-E2EE-Version2
X-Client-Pub-KeyYour secp256k1 public key, hex encoded.
X-Model-Pub-KeyThe gateway E2EE public key from the attested keyset.
X-E2EE-NonceUnique per-request nonce.
X-E2EE-TimestampUnix seconds, close to gateway time.
Do not send X-Signing-Algo with E2EE. That header selects the legacy signature compatibility path.

Ciphertext Format

Each encrypted field is lowercase hex encoding of:
ephemeral_uncompressed_secp256k1_public_key || aes_gcm_nonce || ciphertext_tag
The AEAD associated data binds ciphertext to the protocol version, direction, algorithm, model, field path, nonce, timestamp, and response identity. If any of those values change, decryption fails.
Do not build this manually unless you are implementing a client library. Use official client or verifier helpers when available, because AAD construction and field selection must match the gateway exactly.

Receipts with E2EE

Receipts work the same way for E2EE requests. The response still includes x-receipt-id, and you still verify the receipt with Get Receipt. For E2EE, request.received.body_hash is the hash of the gateway-observed decrypted body, not the encrypted wire body. Compare it with the decrypted request body your client holds.

Trust Boundary

Verify a Response