Skip to main content
E2EE encrypts selected request and response fields between your client and the attested gateway. TLS still protects the connection; E2EE adds field-level encryption whose public key comes from the gateway’s attested keyset. This guide shows how to send an E2EE request. For the trust model and what E2EE does and does not protect, read End-to-end encryption.
E2EE is decrypted inside the attested gateway so it can process your request. It proves the decryption key belongs to the attested workload; it does not hide the request from that workload. For the upstream to be attested too, use a confidential model.

When to use it

Use E2EE when you want field-level encryption bound to a key you can trace to the attestation report, in addition to TLS. If TLS is sufficient for your threat model, you can call the API normally without these headers.

1. Get the gateway E2EE key

Fetch the attestation report and read the E2EE public key from the attested keyset. Verify the report first (see Verify a response) so you know the key is bound to a genuine TEE.
curl -s "https://api.redpill.ai/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 matching key uses the secp256k1-aes-256-gcm-hkdf-sha256 algorithm.

2. Send E2EE headers

Include these headers on your request. Do not send X-Signing-Algo; that selects the legacy path.
HeaderValue
X-E2EE-Version2
X-Client-Pub-KeyYour secp256k1 public key, hex encoded.
X-Model-Pub-KeyThe gateway E2EE public key from step 1.
X-E2EE-NonceA unique per-request nonce.
X-E2EE-TimestampUnix seconds, close to gateway time.

3. Encrypt the selected fields

Each encrypted field is the lowercase hex encoding of:
ephemeral_uncompressed_secp256k1_public_key || aes_gcm_nonce || ciphertext_tag
The AEAD associated data binds the ciphertext to the protocol version, direction, algorithm, model, field path, nonce, and timestamp. Any mismatch fails decryption.
Assembling the ciphertext and AAD by hand is error-prone. Use the official client or verifier helpers, which implement the key exchange, AAD construction, and field selection for you.

Receipts with E2EE

The response still carries an x-receipt-id. For an E2EE request, request.received.body_hash is the hash of the gateway-observed decrypted body. When you verify, compare request hashes against the decrypted body your client holds, not the encrypted bytes you sent. See Receipts.

E2EE concept

Verify a response