FastAPI service for remote attestation of confidential VMs with Intel TDX and NVIDIA H200 GPUs. Runs inside the confidential VM and provides cryptographic proof of hardware integrity to external verifiers.
- Intel CPU with TDX (Trust Domain Extensions)
- NVIDIA H200 GPUs (8x) with Confidential Computing support
- TDX-enabled confidential VM
Provides two main API endpoints:
-
Remote Attestation (
/attestation): Generates attestation quotes from both CPU and GPU- CPU: Collects Intel TDX quote via TSM interface (
/sys/kernel/config/tsm/report) - GPU: Collects H200 attestation reports using NVIDIA Attestation SDK
- Output: Returns signed quotes with certificate chains for external verification
- CPU: Collects Intel TDX quote via TSM interface (
-
Confidential Completion (
/completion): Proxies LLM inference requests with cryptographic signing- Proxy: Forwards chat completion requests to local vLLM service
- Signing: Computes SHA-256 hashes of request/response and signs with ECDSA
- Output: Returns vLLM response with signature headers for verification
GET /ping
Health check endpoint. Returns service version and image digest for integrity verification.
Response:
{
"status": "ok",
"version": "1.0.0",
"image_digest": "sha256:..."
}POST /attestation
Request:
{
"nonce": "optional-hex-string" // Optional 32-byte hex (64 chars)
}Response:
{
"nonce": "used-nonce-hex",
"cpu": {
"quote": "hex-encoded-tdx-quote"
},
"gpu": {
"arch": "HOPPER",
"evidence_list": [
{
"evidence": "base64-attestation-report",
"certificate": "base64-certificate-chain"
}
]
},
"signing_address": "0x...",
"image_digest": "sha256:..."
}POST /completion
Proxy endpoint for vLLM chat completions with cryptographic signing. Forwards requests to a local vLLM service and returns signed responses.
Request:
{
"messages": [{"role": "user", "content": "Hello"}],
"model": "optional-model-name",
"temperature": 0.7,
"max_tokens": 100,
"stream": false,
"top_p": 1.0,
"frequency_penalty": 0.0,
"presence_penalty": 0.0,
"stop": null,
"n": 1,
"logprobs": false
}Response:
- Body: Standard OpenAI-compatible chat completion response from vLLM
- Headers:
text: Signing text in format{request_hash}:{response_hash}signature: ECDSA signature (hex-encoded)signing_address: Public key used for verificationsigning_algo:ecdsaimage_digest: Container image digest for integrity verification
For streaming responses (stream: true), the signature is sent as an SSE event before the final [DONE] message:
data: {"id":"chatcmpl-123","choices":[{"delta":{"content":"Hello"}}]}
event: signature
data: {"text": "...", "signature": "...", "signing_address": "...", "signing_algo": "ecdsa", "image_digest": "..."}
data: [DONE]
For /completion responses, vLLM provenance is also included:
vllm.image_digest: SHA256 digest of the vLLM container image (queried from Docker)vllm.model_id: Model loaded in vLLM
Environment Variables:
VLLM_API_KEY: API key for authenticating with local vLLM serviceVLLM_PORT: Port for vLLM API (default:8000)VLLM_CONTAINER_NAME: Name of vLLM container to query (default:vllm-server)
Note: The service expects a local vLLM server at http://localhost:8000/v1/chat/completions (configurable via VLLM_PORT). ECDSA signing keys are automatically generated on application startup. The public key is returned in the signing_address response header for verification.
pip install -r requirements-dev.txt
uvicorn main:app --host 0.0.0.0 --port 8001Container deployment provides tamperproof guarantees through immutable image digests.
# Download the deploy script
curl -fsSL -o deploy.sh https://github.com/ionet-official/cc-attestation-agent-api/releases/latest/download/deploy.sh
chmod +x deploy.sh
# Ensure SSL certificates exist
sudo mkdir -p /opt/ionet/cc-attestation-agent-api/certs
# Copy your cert.pem and key.pem to /opt/ionet/cc-attestation-agent-api/certs/
# Get the latest version and deploy
VERSION=$(curl -fsSL https://api.github.com/repos/ionet-official/cc-attestation-agent-api/releases/latest | grep -oP '"tag_name": "\K[^"]+')
sudo ./deploy.sh "$VERSION"The GitHub Actions workflow (.github/workflows/build-and-attest.yml) automatically:
- Builds container image with locked dependencies
- Pushes to GitHub Container Registry (ghcr.io)
- Signs the image using Sigstore/cosign
- Generates SBOM using Syft (CycloneDX format)
- Attests SBOM linking it to the image digest
- Generates SLSA provenance (Level 3)
- Scans for vulnerabilities using Grype
- Publishes release with image digest and verification instructions
IMAGE="ghcr.io/ionet-official/cc-attestation-agent-api@sha256:..."
# Verify image signature
cosign verify "$IMAGE" \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
# Verify SBOM attestation
cosign verify-attestation "$IMAGE" \
--type cyclonedx \
--certificate-identity-regexp ".*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
# Verify SLSA provenance
slsa-verifier verify-image "$IMAGE" \
--source-uri github.com/ionet-official/cc-attestation-agent-apiThe container runs with IMAGE_DIGEST environment variable set to the signed image digest. Remote verifiers can confirm the running container matches the signed image:
# Get expected digest from release
EXPECTED=$(curl -sL https://github.com/ionet-official/cc-attestation-agent-api/releases/download/v1.0.0/image-digest.txt)
# Get runtime digest from API (use -k for self-signed certs)
ACTUAL=$(curl -sk https://localhost/ping | jq -r '.image_digest')
# Compare
[ "$EXPECTED" = "$ACTUAL" ] && echo "Verified" || echo "TAMPERED"The image_digest is included in /ping, /attestation, and /completion responses.
The attestation API queries the Docker socket on startup to collect vLLM provenance:
- Container image digest: Queried directly from Docker (cannot be spoofed)
- Model ID: Queried from vLLM
/v1/modelsendpoint
Startup behavior:
- Retries 3 times at 30-second intervals waiting for vLLM
- Fails to start if vLLM is not available after all retries
- Ensures every
/completionresponse includes verified vLLM provenance
Requirements:
- vLLM container must be named
vllm-server(or setVLLM_CONTAINER_NAME) - Docker socket must be mounted (
-v /var/run/docker.sock:/var/run/docker.sock:ro) - vLLM API must be accessible at
http://localhost:8000(or setVLLM_PORT)
fastapi,uvicorn: Web framework and serverpyopenssl: Certificate handlingnv-attestation-sdk: NVIDIA GPU attestation
External clients send a nonce to prove freshness. Service returns cryptographically signed quotes that clients verify against Intel/NVIDIA roots of trust. This proves the workload runs on genuine confidential hardware before sending sensitive data.
| Verification | What It Proves |
|---|---|
| Sigstore signature | Image hasn't been tampered with since build |
| SBOM attestation | Exact dependencies at build time, linked to image |
| SLSA provenance | Built from specific commit, by specific workflow |
| Vulnerability scan | No critical CVEs in dependencies at deploy time |
| Image digest | Immutable container identity - cannot be modified after build |