Overview
The attestation service is a FastAPI-based REST API that generates Intel TDX attestation quotes. It provides cryptographic proof that code is running inside a trusted execution environment (TEE) and implements TLS channel binding using Exported Keying Material (EKM) as defined in RFC 9266.Architecture
Technology Stack
- Framework: FastAPI 0.119 with async support
- Python: 3.11 - 3.13
- TEE Integration: dstack_sdk 0.5.3
- Dependencies: Pydantic 2.7 for validation
- Package Manager: uv for fast dependency resolution
Service Configuration
API Endpoints
Health Check
TDX Quote Generation
nonce_hex: Exactly 64 hexadecimal characters (32 bytes) of random data for freshness
Interactive API Documentation
- Swagger UI:
GET /docs - ReDoc:
GET /redoc
EKM Channel Binding
Overview
The attestation service implements TLS channel binding using Exported Keying Material (EKM) to prevent man-in-the-middle attacks and bind attestation quotes to specific TLS sessions.RFC 9266 Compliance
The implementation follows RFC 9266: Channel Bindings for TLS 1.3:- Uses
tls-exporterchannel binding type - Requires TLS 1.3 (enforced by nginx)
- Combines EKM with application-specific nonce
Architecture Flow
EKM Header Format
TheX-TLS-EKM-Channel-Binding header uses a signed format:
- ekm_hex: 64 hexadecimal characters (32 bytes of EKM material)
- hmac_hex: 64 hexadecimal characters (32 bytes of HMAC-SHA256)
- Total length: Exactly 129 characters (64 + 1 + 64)
HMAC Validation
The service validates the HMAC signature before trusting the EKM value:attestation_service.py:121-150
Report Data Computation
The attestation service combines the client nonce with the EKM to create the TDX report data:attestation_service.py:152-174
Properties:
- Freshness: Nonce prevents replay of old attestations
- Channel Binding: EKM ties attestation to current TLS session
- Verifiability: Client can independently compute expected report_data
- Size: SHA512 output (64 bytes) fits TDX report_data field
HMAC Key Derivation
Production: dstack TEE Derivation
In production, the HMAC key is derived deterministically from the TEE identity:attestation_service.py:94-116
Key Properties:
- Deterministic: Same compose hash + key path = same key
- TEE-Bound: Key never leaves the CVM
- Zero-Trust: Operator never sees the key value
- Synchronized: Both nginx and attestation service derive the same key
Development: Environment Variable Fallback
When dstack is unavailable (development mode withNO_TDX=true):
The
EKM_SHARED_SECRET must be at least 32 characters. The service will fail to start with a shorter secret.dstack SDK Integration
Async Client Initialization
The service uses an async dstack client initialized at startup:attestation_service.py:63-83
Concurrent Operations
The service fetches TDX quote and TCB info concurrently:attestation_service.py:239-243
Development and Testing
NO_TDX Development Mode
For development without TDX hardware:- Testing without dstack daemon
- Development on non-TDX hardware
- Mock attestation responses
Running Locally
Running Tests
Debug Endpoints
For integration testing, useattestation_service_with_debug.py:
GET /debug/ekm: Verify EKM header forwarding and HMAC validation
Docker Image
Building
Published Images
Images are published to GitHub Container Registry:Environment Variables
| Variable | Default | Description |
|---|---|---|
HOST | 0.0.0.0 | Bind address |
PORT | 8080 | Service port |
WORKERS | 8 | Number of worker processes |
EKM_SHARED_SECRET | - | HMAC key for dev mode (min 32 chars) |
LOG_LEVEL | INFO | Logging verbosity |
NO_TDX | false | Disable dstack integration |
Scaling Configuration
Process-Level Scaling
Use multiple worker processes:Container-Level Scaling
Use multiple container replicas:Choose one scaling approach (process or container level) for optimal performance. Using both simultaneously provides no additional benefit.
Security Considerations
Defense in Depth
The EKM validation provides multiple security layers:- Network Isolation: Attestation service only accessible from nginx
- HMAC Validation: Prevents header forgery even if proxy is compromised
- TEE Key Derivation: HMAC key never leaves the CVM
- Constant-Time Comparison: Prevents timing attacks on HMAC validation
Threat Model
Protection against:- Proxy Compromise: HMAC prevents forged EKM values
- Replay Attacks: Nonce provides freshness
- MITM Attacks: EKM binds to specific TLS session
- Timing Attacks: Constant-time HMAC comparison
Best Practices
- Never expose port 8080 externally
- Use dstack key derivation in production (not
EKM_SHARED_SECRET) - Ensure nginx and attestation service share the same dstack socket
- Monitor for HMAC validation failures (may indicate attacks)
Error Handling
Common Errors
| Status | Cause | Solution |
|---|---|---|
400 Bad Request | Missing EKM header | Check nginx configuration |
403 Forbidden | Invalid HMAC signature | Verify shared secret matches |
500 Internal Server Error | Dstack client not initialized | Check dstack socket mount |
422 Unprocessable Entity | Invalid nonce format | Ensure 64-character hex string |
Example Error Response
Monitoring
Key metrics to track:- Request rate to
/tdx_quote - HMAC validation failure rate
- TDX quote generation latency
- Dstack client errors
Next Steps
Auth Service
Implement token-based authentication
Certificate Manager
Configure nginx and TLS certificates
