Skip to content

ionet-official/cc-attestation-agent-api

Remote Attestation Service

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.

Hardware Requirements

  • Intel CPU with TDX (Trust Domain Extensions)
  • NVIDIA H200 GPUs (8x) with Confidential Computing support
  • TDX-enabled confidential VM

What It Does

Provides two main API endpoints:

  1. 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
  2. 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

API

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 verification
    • signing_algo: ecdsa
    • image_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 service
  • VLLM_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.

Local Development

pip install -r requirements-dev.txt
uvicorn main:app --host 0.0.0.0 --port 8001

Production Deployment

Container deployment provides tamperproof guarantees through immutable image digests.

Quick Install

# 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"

Build Pipeline

The GitHub Actions workflow (.github/workflows/build-and-attest.yml) automatically:

  1. Builds container image with locked dependencies
  2. Pushes to GitHub Container Registry (ghcr.io)
  3. Signs the image using Sigstore/cosign
  4. Generates SBOM using Syft (CycloneDX format)
  5. Attests SBOM linking it to the image digest
  6. Generates SLSA provenance (Level 3)
  7. Scans for vulnerabilities using Grype
  8. Publishes release with image digest and verification instructions

Image Verification

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-api

Runtime Image Digest Verification

The 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.

vLLM Provenance

The attestation API queries the Docker socket on startup to collect vLLM provenance:

  1. Container image digest: Queried directly from Docker (cannot be spoofed)
  2. Model ID: Queried from vLLM /v1/models endpoint

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 /completion response includes verified vLLM provenance

Requirements:

  • vLLM container must be named vllm-server (or set VLLM_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 set VLLM_PORT)

Dependencies

  • fastapi, uvicorn: Web framework and server
  • pyopenssl: Certificate handling
  • nv-attestation-sdk: NVIDIA GPU attestation

Use Case

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.

Security

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

About

FastAPI remote attestation service for Intel TDX and NVIDIA H200 confidential VMs

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors