Skip to main content
This guide walks through verifying one response end to end: confirm the gateway is an attested TEE workload, then confirm the signed receipt binds your exact request and response to it. You only need curl, jq, and openssl. Full TEE quote verification additionally needs a DCAP verifier library, noted where it applies. For the concepts behind each step, see How Confidential AI works.

Prerequisites

export API_KEY="your-redpill-api-key"
export BASE="https://api.redpill.ai"

1. Fetch the attestation report with a fresh nonce

export NONCE="$(openssl rand -hex 16)"
curl -s "$BASE/v1/aci/attestation?nonce=$NONCE" \
  -H "Authorization: Bearer $API_KEY" -o report.json

jq '{api_version, workload_id, workload_keyset_digest,
     signing_address,
     report_data: .attestation.report_data,
     stale_after: .attestation.freshness.stale_after,
     provenance: .attestation.source_provenance}' report.json
Check that:
  • api_version is aci/1.
  • attestation.freshness.stale_after is in the future.
  • attestation.report_data is derived from your NONCE and the keyset (a DCAP verifier confirms the quote and this binding). See Attestation report.
  • attestation.source_provenance matches the gateway release you trust.
Verifying attestation.evidence.quote against Intel DCAP collateral, and the keyset endorsement, requires a verifier library. The platform publishes verifier tooling; this guide covers the checks you can reproduce with shell tools. The workload_id, workload_keyset_digest, freshness, and signature checks below do not need DCAP.

2. Make a request and capture the receipt id

curl -s -D headers.txt "$BASE/v1/chat/completions" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"qwen/qwen3-30b-a3b-instruct-2507",
       "messages":[{"role":"user","content":"Explain attestation in one sentence."}]}' \
  -o response.json

export RECEIPT_ID="$(grep -i '^x-receipt-id' headers.txt | tr -d '\r' | awk '{print $2}')"
echo "receipt: $RECEIPT_ID"
Save response.json; its bytes are what the receipt commits to.

3. Fetch the signed receipt

GET /v1/aci/receipts/{id} returns the bare canonical receipt:
curl -s "$BASE/v1/aci/receipts/$RECEIPT_ID" \
  -H "Authorization: Bearer $API_KEY" -o receipt.json

jq '{receipt_id, workload_id, workload_keyset_digest, endpoint}' receipt.json

4. Confirm the receipt belongs to the attested gateway

The receipt must come from the same workload you attested in step 1:
test "$(jq -r .workload_id report.json)" = "$(jq -r .workload_id receipt.json)" \
  && test "$(jq -r .workload_keyset_digest report.json)" = "$(jq -r .workload_keyset_digest receipt.json)" \
  && echo "workload matches" || echo "MISMATCH"

5. Check the bound hashes

The event_log records the request and response hashes. Confirm the response hash matches the bytes you received:
RESP_HASH="sha256:$(sha256sum response.json | awk '{print $1}')"
RECEIPT_RESP_HASH="$(jq -r '.event_log[] | select(.type=="response.returned") | .wire_hash' receipt.json)"
echo "received: $RESP_HASH"
echo "receipt:  $RECEIPT_RESP_HASH"
These match when the response was not altered after the gateway signed it. The request.received.body_hash event records the gateway-observed request body (for an E2EE request, that is the decrypted body).

6. Verify the signature

The receipt’s signature covers the canonical receipt bytes. Verify it with the official verifier helper, which confirms the signature under a receipt_signing_keys entry from the attested keyset:
# Conceptual: use the published verifier to check the receipt signature
# against a receipt_signing_keys entry in the attested keyset from step 1.
A receipt signed by a key that the attested keyset does not endorse is not bound to the attested workload, and verification fails.

7. Read the upstream verification result

jq '.event_log[] | select(.type=="upstream.verified")
    | {provider, model_id, result, required, session_id}' receipt.json
  • Confidential model: result is verified, required is true, and session_id is present. The upstream enclave was verified and the channel bound before your prompt was forwarded.
  • Routed model: result is failed, required is false, and there is no session_id. The upstream was not attested.

What a passing verification proves

  • The gateway is a specific reviewed workload in a genuine TEE (steps 1, 4).
  • The response you received is exactly the response the gateway signed (step 5).
  • The receipt is signed by a key bound to that workload (step 6).
  • For a confidential model, the model ran on a verified, channel-bound upstream (step 7).

Attestation report

Receipts

GET /v1/aci/attestation

GET /v1/aci/receipts/{id}