x/tee_attest Real (skeleton)
On-chain verification of hardware TEE attestation quotes. Three vendor paths: Intel TDX, AMD SEV-SNP, and NVIDIA NRAS-JWT. Quote bodies stay off-chain; only the verification result and content hash live on-chain.
Three verification paths
| Vendor | Library (Phase 1) | Roots | TCB enforcement |
|---|---|---|---|
| Intel TDX | github.com/google/go-tdx-guest v0.3.1 | embedded SGX provisioning roots | per-FMSPC governance minimum |
| AMD SEV-SNP | github.com/google/go-sev-guest v0.14.1 | embedded ARK + ASK | per-chip-family minimum (VLEK supported) |
| NVIDIA NRAS | github.com/golang-jwt/jwt/v5 + pinned NVIDIA JWKS | NRAS JWKS pinned in TrustRoots | per-architecture minimum |
NVIDIA gets a Phase-2 follow-up: full local NRAS verifier port (4-6 weeks of engineering) drops the JWKS-pinning dependency entirely.
Determinism rules
- NO system clock - keeper reads only
ctx.BlockHeight,ctx.BlockTime,ctx.HeaderHash. - NO network calls - no PCS / OCSP / NRAS HTTP fetches inside the keeper.
- Vendor crypto libraries are called with
Getter: nil,GetCollateral: falseso they cannot reach the network even if accidentally invoked.
The MsgVerifyAttestation wire format
| Field | Type | Notes |
|---|---|---|
host_addr | bech32 | operator address (signer) |
tee_kind | enum | NVIDIA_NRAS / INTEL_TDX / AMD_SEV_SNP |
evidence_hash | 32 B | sha256 of full quote |
nonce | 32 B | chain-issued epoch nonce (must match) |
bound_pubkey | 32-256 B | session key bound in REPORTDATA |
quote_blob | 5-20 KB | NOT permanently stored on-chain |
cert_chain | 0-16 KB | vendor cert chain (Intel/AMD); empty for NRAS |
quote_height | int64 | block height included in nonce derivation |
da_uri | string | off-chain DA pointer (ipfs://, ar://, ...) |
REPORTDATA binding
REPORTDATA = sha256( chain_id || host_addr || epoch_nonce || session_pubkey )
Each vendor's quote body has its own REPORTDATA / userdata field; the per-vendor verifier extracts it and compares to this digest. Quotes that do not bind session_pubkey this way are rejected.
Attestation ID
attestation_id = hex(sha256(quote_blob))
Epoch nonce derivation
nonce_next = sha256( ctx.BlockHeight() (BE 8B) || ctx.HeaderHash() )
Rotated every Params.EpochNonceRotationBlocks blocks (~10 minutes default). Fully deterministic across all validators.
Storage strategy
Quote bodies are stored OFF-CHAIN (Celestia, IPFS, Arweave). The keeper persists ~250 B per record:
attestation_id sha256(quote) hex tee_kind vendor enum mrtd_or_measurement_digest TDX MRTD / SNP MEASUREMENT / NRAS measurement bound_pubkey session key valid_until block height host_addr bech32 accepted_at_height block height da_uri off-chain DA pointer status ACCEPTED / CHALLENGED / REVOKED
TCB update flow
- Vendor publishes a TCB recovery (Intel) / firmware bump (AMD) / JWKS change (NVIDIA).
- Off-chain security working group verifies the publication's signature and posts a gov proposal carrying
MsgRegisterTrustRootand / orMsgUpdateTcbInfo. - Validators vote. On pass,
x/govcalls the keeper handlers. - From the next block onward, every
MsgVerifyAttestationchecks the new minimum / root set. Older records remain ACCEPTED untilvalid_untilexpires.
Other messages
MsgRegisterTrustRoot // gov-only; add or revoke a TCB root MsgUpdateTcbInfo // gov-only; update per-(tee_kind, platform_id) minimum MsgEvidenceChallenge // anyone; challenges a stored result, posts bond
Queries
ParamsAttestationByID(id)AttestationsByHost(host_addr, pagination)TrustRoots(tee_kind?)TcbInfo(tee_kind?)EpochNonce- the current epoch nonce hosts must use in REPORTDATA
ABCI++ vote extensions
x/pouw consumes attestation results via vote extensions. The wire format:
VoteExtension = proto.Marshal(VoteExt{
Receipts: []ReceiptCommitWithAttestation{
{commit_hash, host_addr, attestation_id}
}
})
What's wired today
Real Module wiring, params, KV layout (with host index + expiry index), trust-root and TCB-info registry CRUD (gov-only), all read queries, MsgVerifyAttestation dispatch, MsgEvidenceChallenge bond escrow, deterministic epoch-nonce rotation, IsAttestationValid (the surface x/pouw consumes).
Phase 1 Per-vendor verifier bodies (TDX, SEV-SNP, NRAS), REPORTDATA extraction from parsed quotes, EndBlock pruning of expired records, challenge re-verification with bond settlement, ABCI++ ExtendVote / VerifyVoteExtension bodies.
See also
- x/pouw consumes
IsAttestationValid - SPUR-IC spec for the receipt format that wraps the attestation in transit
- Source: x/tee_attest/