Runtime attestation with extraData fails on mainnet-alpha: TPM nonce mismatch (KMS likely pre-eigenx-kms#17)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
TPM nonce mismatch on extraData attestations (mainnet-alpha) — KMS version skew
Summary
Per-action runtime attestation (extraData set) fails on mainnet-alpha with 401: TPM nonce mismatch; plain attestation (no extraData) succeeds on the same instance. Client SDK is correct against current main of all three repos involved. Root cause (medium-high confidence): the deployed KMS predates eigenx-kms PR#17 (commit 248f9d1d, 2026-04-23) — it accepts the extra_data request field but passes nil to VerifyTPM, so its expected nonce omits the extraData term the in-TEE launcher bakes into the quote.
Ask: confirm the KMS binary behind mainnet-alpha KMS_SERVER_URL is post-248f9d1d, and the launcher image on the affected TDX host is post-bbd228942d4a (go-tpm-tools PR#3). If both are current, next step is capturing a raw quote from this host on the extraData path.
Repro
- App:
proxy-arena0x477F18816EdEAc206E0ecA970Bb33649a219e068, mainnet-alpha, Intel TDX, image built 2026-07-10 from public repommurrs/proxy-arena. - Client:
@layr-labs/ecloud-sdk@1.0.0(npmlatest; byte-identical to1.0.0-dev.8). - Call:
new JwtProvider(new AttestClient({kmsServerURL, kmsPublicKey, audience})).getToken(extraData)withextraData= 64-byte SHA-512Buffer. - Error (verbatim):
KMS attest failed (401): {"error":"Attestation verification failed: TPM verification failed: TPM nonce mismatch: quote contains different nonce than expected"} - Control: same instance, same provider,
getToken()without extraData → JWT mints fine (used for AI-gateway auth).
Root-cause trace (file:line, all current main unless noted)
Nonce formula — defined once, used by both sides:
Layr-Labs/go-tpm-toolsinternal/nonce/nonce.go:19-37:
nonce = SHA256("WORKLOAD_ATTESTATION" || platformTag || SHA256(challenge) || SHA256(extraData)?)— extraData term included iff non-empty.
Prover (inside the TEE) — includes the term:
launcher/teeserver/tee_server.go:140-183—/v1/bound_evidencedecodesextra_data, forwards.launcher/agent/agent.go:404—ComputeTPMNonce(challenge, platformTag, opts.ExtraData).
Verifier (KMS) — where the skew bites:
Layr-Labs/eigenx-kmsinternal/handlers/attest.go:101-116— decodesreq.ExtraData, passes to verifier.pkg/attestation/bound_attestation_evidence.go:64-69—VerifyTPM(challenge, extraData). Pre-PR#17 this line wasVerifyTPM(challenge, nil)— field accepted, term dropped → expected nonce ≠ quote nonce, exactly the observed error (go-tpm-toolssdk/attest/attestation.go:50-64emits the string).
Client SDK — correct, nothing to fix:
ecloud-sdkdist/attest.js:22— challenge =SHA256("COMPUTE_APP_JWT_REQUEST_RSA_KEY_V1" || 0x00 || rsa_pem); extraData deliberately not in the challenge (it binds via the quote nonce instead).dist/attest.js:24-25, 60-62, 99-101— same extraData Buffer to the socket and, base64, to/v1/bound_evidenceand/auth/attest. Mirrorseigenx-kms pkg/types/server.go:74-80andpkg/crypto/crypto.go:24,166-173.
Why the asymmetry proves the shape: with no extraData, both sides compute the term-less nonce → agree. With extraData, prover adds the term, a pre-PR#17 verifier doesn't → mismatch. No client-side change can fix this (the nonce is stamped by the launcher inside the TEE; SDK 1.0.0 is the newest published version).
Verification requested
- KMS binary commit behind mainnet-alpha
KMS_SERVER_URL≥eigenx-kms@248f9d1d(2026-04-23)? - Launcher/COS image on the affected host ≥
go-tpm-tools@bbd228942d4a(PR#3, 2026-02-25)? - If both yes: capture one raw attestation from this host with extraData set and inspect the quote's qualifying data directly.
Machine-readable references
error : 401 "TPM verification failed: TPM nonce mismatch: quote contains different nonce than expected"
app_id : 0x477F18816EdEAc206E0ecA970Bb33649a219e068 (mainnet-alpha, Intel TDX)
client_sdk : @layr-labs/ecloud-sdk@1.0.0 (== 1.0.0-dev.8)
client_paths : dist/attest.js:22,24-25,60-62,99-101
nonce_formula : go-tpm-tools internal/nonce/nonce.go:19-37
prover_paths : go-tpm-tools launcher/teeserver/tee_server.go:140-183 ; launcher/agent/agent.go:404
verifier_paths: eigenx-kms internal/handlers/attest.go:101-116 ; pkg/attestation/bound_attestation_evidence.go:64-69
error_source : go-tpm-tools sdk/attest/attestation.go:50-64
fix_commits : eigenx-kms 248f9d1d (PR#17, 2026-04-23) ; go-tpm-tools bbd228942d4a (PR#3, 2026-02-25)
works : getToken() without extraData (same instance)
fails : getToken(extraData) — any non-empty extraData
Separate, previously reported issue on the same app (not the same bug): all enclave→AI-gateway model calls return 502 with an HTML body while the same endpoints answer clean JSON 401s from outside — egress-proxy layer, also needs a platform look.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by checking the KMS binary behind mainnet-alpha KMS_SERVER_URL and the launcher image versions against the listed commits. Read go-tpm-tools/internal/nonce/nonce.go, launcher/agent/agent.go, and eigenx-kms/pkg/attestation/bound_attestation_evidence.go; done means confirming compatible versions or capturing a raw extraData quote for comparison.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, typescript
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100