Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.redpill.ai/llms.txt

Use this file to discover all available pages before exploring further.

TEE Verification

Verify that your API requests are processed in genuine TEE hardware. This guide covers programmatic verification for production systems.

Quick Start

Use this path when you want to verify a real API response:
git clone https://github.com/redpill-ai/redpill-verifier.git
cd redpill-verifier
pip install requests eth-account

export API_KEY=YOUR_REDPILL_API_KEY
python3 signature_verifier.py --model phala/qwen-2.5-7b-instruct
That command makes a chat completion, fetches /v1/signature/{request_id}, fetches /v1/attestation/report with the returned signing_address, and verifies that the response signature is bound to genuine TEE hardware. Use this path when you only want to verify that a model server is currently attested:
git clone https://github.com/redpill-ai/redpill-verifier.git
cd redpill-verifier/js
npm install && npm run build
# Verify attestation (no API key needed)
npx redpill-verifier attestation --model phala/gpt-oss-120b

Verify Your Chat Response

The primary use case: you’re using RedPill as an OpenAI alternative, and want to verify the response came from a real TEE.
import OpenAI from 'openai'
import { verify } from '@redpill-ai/verifier'

// Use RedPill as OpenAI drop-in
const openai = new OpenAI({
  baseURL: 'https://api.redpill.ai/v1',
  apiKey: process.env.REDPILL_API_KEY,
})

const response = await openai.chat.completions.create({
  model: 'phala/gpt-oss-120b',
  messages: [{ role: 'user', content: 'Hello!' }],
})

// Verify the response
const proof = await verify(response.id, {
  model: 'phala/gpt-oss-120b',
  apiKey: process.env.REDPILL_API_KEY,
})

if (proof.verified && proof.signature.valid) {
  console.log('Response is cryptographically verified from TEE')
  console.log('Provider:', proof.provider)        // "near-ai"
  console.log('Hardware:', proof.hardware)         // ["INTEL_TDX", "NVIDIA_CC"]
  console.log('Signer:', proof.signingAddress)     // "0x56d070..."
}

Verification Paths

PathAPIs usedUse when
Model attestationGET /v1/attestation/report?model=...&nonce=...You want proof that a model endpoint is running in genuine TEE hardware
Response signatureGET /v1/signature/{request_id}?model=...You want proof that your specific response was signed by the TEE key
End-to-end response verificationBoth endpoints togetherYou want production-grade proof that your exact request and response are bound to an attested TEE signer
Do not stop after fetching an attestation if your goal is to verify a specific API response. Attestation proves the environment; the signature proves the request and response. Use signing_address to bind the two.

Attestation API

Get Attestation Report

Fetch a fresh attestation report with your nonce:
# Generate nonce (must be 32-byte hex)
NONCE=$(openssl rand -hex 32)

# Request attestation (no auth required)
curl "https://api.redpill.ai/v1/attestation/report?model=phala/gpt-oss-120b&nonce=$NONCE"
Response format depends on provider:
{
  "gateway_attestation": {
    "signing_address": "0x...",
    "signing_algo": "ecdsa",
    "intel_quote": "hex-encoded-tdx-quote",
    "event_log": [...],
    "info": { "vm_config": "..." }
  },
  "model_attestations": [{
    "signing_address": "0x...",
    "intel_quote": "hex-encoded-tdx-quote",
    "nvidia_payload": "{...}",
    "event_log": [...],
    "info": { "tcb_info": "{...}", "vm_config": "..." }
  }]
}

Verify Attestation (TypeScript)

import { verifyModel } from '@redpill-ai/verifier'

// Light mode (default) — no Docker needed
const result = await verifyModel({ model: 'phala/gpt-oss-120b' })

console.log(result.verified)                         // true
console.log(result.provider)                         // "near-ai" (auto-detected)
console.log(result.light.tdx.verified)               // true
console.log(result.light.reportData.bindsAddress)    // true
console.log(result.light.gpu?.verdict)               // "true"
console.log(result.light.compose?.hashMatches)       // true

// Deep mode — QEMU-based replay (requires Docker)
const deep = await verifyModel({ model: 'phala/qwen-2.5-7b-instruct', deep: true })
console.log(deep.deep.allValid)                      // true
console.log(deep.deep.components)                    // [{name: "model", ...}, {name: "kms", ...}, {name: "gateway", ...}]

Signature API

Get Request Signature

After making a chat completion, get the cryptographic signature:
curl "https://api.redpill.ai/v1/signature/{chat_id}?model=phala/gpt-oss-120b" \
  -H "Authorization: Bearer $REDPILL_API_KEY"
Response:
{
  "text": "model_name:request_hash:response_hash",
  "signature": "0xe56dcf782ec610e4...",
  "signing_address": "0x56d070df1c6be444b007839ef9cf67cec7c12b8b",
  "signing_algo": "ecdsa"
}

Verify Signature (TypeScript)

import { recoverSigner, fetchSignature, sha256 } from '@redpill-ai/verifier'

// Fetch signature for an existing chat
const sig = await fetchSignature(chatId, model, apiKey)

// Recover the Ethereum address that signed the response
const recovered = await recoverSigner(sig.text, sig.signature)
console.log(recovered === sig.signing_address) // true

// Optionally check response hash
const parts = sig.text.split(':')
const respHash = parts.length === 3 ? parts[2] : parts[1]
console.log(await sha256(responseText) === respHash) // true

End-to-End API Flow

This is the flow most applications should implement:
1

Make the chat completion

Store the exact JSON string you sent and the exact response body you received. Hashes are byte-sensitive, so production verifiers should hash the same serialized request body that was sent on the wire.
2

Fetch the request signature

Call GET /v1/signature/{chat_id}?model=... and read text, signature, signing_address, and signing_algo.
3

Verify the signed hashes

Parse text as either request_hash:response_hash or model:request_hash:response_hash, compute SHA-256 for your request and response, and confirm both hashes match.
4

Verify the signature signer

Recover the signer from the signature and assert it equals signing_address.
5

Fetch fresh attestation for the signer

Generate nonce=$(openssl rand -hex 32) and call /v1/attestation/report?model=...&nonce=...&signing_address=....
6

Verify signer binding

Verify the Intel TDX quote, NVIDIA GPU attestation, nonce, and report-data binding. The report data must contain the same signing address that signed your response.

On-Chain Verification

Verify the TDX quote trustlessly via Ethereum smart contracts:
import { verifyModel } from '@redpill-ai/verifier'

// On-chain DCAP verification (free view call, no wallet needed)
const result = await verifyModel({
  model: 'phala/gpt-oss-120b',
  network: 'sepolia',  // or 'automata-mainnet'
})

console.log(result.onchain?.verified) // true — verified by smart contract

Store Proof Permanently

import { storeProof, lookupProof } from '@redpill-ai/verifier'

// Store (requires wallet + gas)
const tx = await storeProof(intelQuote, signingAddress, proofStoreAddr, privateKey, 'sepolia')
console.log(tx.txHash) // permanent on-chain record

// Look up later (free)
const record = await lookupProof(quoteHash, proofStoreAddr, 'sepolia')
NetworkRedpillProofStore Contract
Sepolia0x83541AD3f380De2b28E0108d4Da934236342B02b

Provider-Specific Verification

The verifier auto-detects the provider and applies specific checks:
ProviderSpecific Checks
PhalaCompose manifest hash vs mr_config, Sigstore provenance, deep mode (model+KMS+gateway)
NearAIGateway + model attestation, deep mode (gateway+model)
ChutesAnti-tamper binding (SHA256(nonce + e2e_pubkey) vs report_data), debug mode disabled
TinfoilHardware policy (MR_SEAM, XFAM, TdAttributes), Sigstore golden values (RTMR1/RTMR2), hw profile matching

What You’re Verifying

CheckWhat It Proves
Intel TDX quoteCode runs in genuine Intel TDX CPU enclave
AMD SEV-SNP quoteCode runs in genuine AMD SEV-SNP enclave
NVIDIA attestationGPU is genuine H100/H200 with confidential computing
Report data binds addressSigning key was generated inside TEE
Nonce embeddedAttestation is fresh, not replayed
Compose hash matches mr_configRunning code matches published Docker compose
Sigstore provenanceContainer images have verified build chain
On-chain DCAPTDX quote verified by Ethereum smart contract (trustless)
Request/response hashYour exact request was signed
Signature validResponse came from the claimed signing address

Available Models

GPU TEE models currently available through RedPill:
# Chutes
z-ai/glm-5.1
moonshotai/kimi-k2.6
qwen/qwen3.5-397b-a17b
qwen/qwen3-coder-next
minimax/minimax-m2.5
xiaomi/mimo-v2-flash
deepseek/deepseek-v3.2
moonshotai/kimi-k2.5

# Near AI
z-ai/glm-5
deepseek/deepseek-chat-v3.1
openai/gpt-oss-120b
qwen/qwen3-30b-a3b-instruct-2507
z-ai/glm-4.7

# Phala Network
phala/qwen3.5-27b
phala/qwen3-vl-30b-a3b-instruct
qwen/qwen3-embedding-8b
phala/gemma-3-27b-it
phala/glm-4.7-flash
phala/gpt-oss-20b
phala/qwen-2.5-7b-instruct
phala/qwen2.5-vl-72b-instruct
phala/uncensored-24b
sentence-transformers/all-minilm-l6-v2
Call GET /v1/models for the live catalog. Phala, Near AI, and Chutes models currently return supported attestation formats from /v1/attestation/report. Tinfoil models are listed as GPU TEE models, but RedPill’s attestation endpoint currently returns provider errors for the Tinfoil catalog entries, so verify Tinfoil support live before building against it.

CI/CD Integration

# .github/workflows/verify-tee.yml
name: Verify TEE Attestation

on:
  schedule:
    - cron: '0 * * * *'  # Hourly
  workflow_dispatch:

jobs:
  verify:
    runs-on: ubuntu-latest
    steps:
      - name: Setup verifier
        run: |
          git clone https://github.com/redpill-ai/redpill-verifier.git
          cd redpill-verifier/js && npm install && npm run build

      - name: Verify models
        run: |
          cd redpill-verifier/js
          npx redpill-verifier attestation --model phala/gpt-oss-120b --light --skip-onchain

Troubleshooting

Cause: The model’s backend may be temporarily unavailable.Action: Try a different model from the same provider, or retry in a few minutes. Chutes models can take up to 2 minutes to respond.
Cause: Quote validation failed against Intel certificates.Action: Retry. If persistent, report to security@redpill.ai.
Cause: The TEE gateway rewrites the model name internally (e.g., phala/gpt-oss-120bopenai/gpt-oss-120b). The TEE signs what it actually processes.Action: This is expected behavior. The response hash should still match. The signature is valid — verify with ECDSA ecrecover.
Cause: Docker is not running or dstack-verifier is not started.Action: Run docker compose up -d from the repo root, or use --light to skip deep verification.

API Reference

Attestation Endpoint

Full attestation API reference

Signature Endpoint

Full signature API reference