Skip to content
FAQ, GPU attestation

How do I verify an NVIDIA GPU attestation token myself?

An NVIDIA GPU attestation token is a JSON Web Token signed by NVIDIA's Remote Attestation Service (NRAS) with ES384. To verify it yourself: take the signing key from NRAS's JWKS through its x5c certificate chain, check the signature, check that eat_nonce is the nonce you chose, then read the claims: measres success, secboot true, dbgstat disabled.

All outputs below: 22 October 2026, voltage-verify 0.2.2, on the bundle we published for an RTX PRO 6000 Blackwell VM on 17 September 2026.

What the token looks like

NVIDIA calls the answer "Detached Entity Attestation Token (EAT) Bundles" (RFC 9711). The nv-attestation-sdk stores it as a JSON array. The first element is a token the SDK signs itself, header {"alg": "HS256"}, issuer NV-Attestation-SDK: it is not NVIDIA's signature. The NVIDIA-signed tokens sit under REMOTE_GPU_CLAIMS: one verifier token and one device token per GPU, each with header {"kid": "nv-eat-kid-prod-20260916210542839-…", "alg": "ES384"} and a 96-byte signature.

The verifier token, decoded:

iss  https://nras.attestation.nvidia.com     sub  NVIDIA-PLATFORM-ATTESTATION
x-nvidia-overall-att-result  true             x-nvidia-ver  2.0
eat_nonce  63c007e1ba89dc58cea45a8ba5d8e5b4df88977055b7a7a758e6ab015b4ff956
submods    GPU-0 -> DIGEST SHA-256 55f81cef…4cc826e1   (SHA-256 of the whole GPU-0 token)
iat 1789603226 (2026-09-17T00:00:26Z)   exp 1789606826 (one hour later)

The GPU-0 token carries the detail: hwmodel GB20X, measres success, secboot true, dbgstat disabled, nonce-match, report-signature-verified and cert-chain-validated all true, ten RIM claims for driver and VBIOS all true, x-nvidia-gpu-driver-version 595.71.05, x-nvidia-gpu-vbios-version 98.02.9E.00.01 and a ueid. NVIDIA's claims guide: measres means the runtime measurements match the Reference Integrity Measurements (RIM); dbgstat "Indicates if GPU debug facilities are enabled or disabled"; cert-chain-validated covers a valid chain in NVIDIA's PKI, not expired, not revoked.

Step 1: the key, through its certificate chain

NRAS publishes its keys at https://nras.attestation.nvidia.com/.well-known/jwks.json. At 11:57 UTC on 22 October 2026 the file held 205 EC P-384 keys. Each has an x5c of two certificates: a short-lived leaf, CN=NVIDIA Attestation Service GPU GH100, O=NVIDIA Corporation, C=US, valid about two days, issued either by NVIDIA Attestation Service GPU Intermediate 004 (133 keys, valid 2025-12-08 to 2029-12-08, SPKI fd32837f…5affe896) or by Intermediate 005 (72 keys, SPKI ba14d003…6ff39afc). The root, NVIDIA Attestation Service CA 001, issues the intermediates and is not in the chain.

Use the chain: anyone can publish bare JWK coordinates. voltage-verify 0.2.1 (9 October 2026) was a security release for that reason: before it, "the JWK coordinates shipped in the bundle were trusted as they were" and "A bundle could carry its own signing key, and NRAS tokens re-signed with it verified." Since then a key is accepted only if its leaf is issued by a known NVIDIA intermediate, names NVIDIA Corporation and holds exactly the JWK's key. Leaves live about two days, so an archived token is judged at its own iat.

Step 2: signature, nonce and claims, by hand

With PyJWT and cryptography, installed by voltage-verify, the check fits in one file:

"""Verify one NVIDIA NRAS token by hand: key from the JWKS x5c chain, ES384 signature, claims.

Usage: python3 -I check_nras_token.py bundle.json
Needs PyJWT and cryptography (both installed with voltage-verify). Decodes the JWKS
carried in the bundle, checks that the leaf certificate is issued by the NVIDIA
intermediate, verifies the ES384 signature of the GPU-0 token and prints the claims
a policy should read. It does not check revocation or the intermediate's own issuer.
"""
import base64, hashlib, json, sys
import jwt
from cryptography import x509
from cryptography.hazmat.primitives import serialization

bundle = json.load(open(sys.argv[1], encoding="utf-8"))
nras = bundle["nvidia"]["nras"]
verifier_tok = nras[1]["REMOTE_GPU_CLAIMS"][0][1]
device_tok = nras[1]["REMOTE_GPU_CLAIMS"][1]["GPU-0"]
kid = jwt.get_unverified_header(device_tok)["kid"]

key = [k for k in bundle["nvidia"]["jwks"]["keys"] if k["kid"] == kid]
assert len(key) == 1, "the kid must appear exactly once in the JWKS"
leaf, inter = (x509.load_der_x509_certificate(base64.b64decode(c)) for c in key[0]["x5c"][:2])
leaf.verify_directly_issued_by(inter)  # raises if the signature or issuer does not match
spki = inter.public_key().public_bytes(serialization.Encoding.DER, serialization.PublicFormat.SubjectPublicKeyInfo)
print("leaf:        ", leaf.subject.rfc4514_string())
print("intermediate:", inter.subject.rfc4514_string(), "SPKI SHA-256", hashlib.sha256(spki).hexdigest())

for name, tok in [("verifier", verifier_tok), ("GPU-0", device_tok)]:
    claims = jwt.decode(tok, key=leaf.public_key(), algorithms=["ES384"], issuer="https://nras.attestation.nvidia.com",
                        options={"verify_exp": False})
    print(f"{name}: ES384 signature OK, iat {claims['iat']}, eat_nonce {claims['eat_nonce']}")
    for c in ("x-nvidia-overall-att-result", "hwmodel", "measres", "secboot", "dbgstat",
              "x-nvidia-gpu-attestation-report-nonce-match", "x-nvidia-gpu-attestation-report-signature-verified",
              "x-nvidia-gpu-attestation-report-cert-chain-validated", "x-nvidia-gpu-driver-version", "x-nvidia-gpu-vbios-version"):
        if c in claims:
            print(f"  {c}: {claims[c]}")

manifest = json.dumps(bundle["manifest"], sort_keys=True, separators=(",", ":"), ensure_ascii=False)
print("eat_nonce == SHA-256(manifest):", hashlib.sha256(manifest.encode()).hexdigest() == claims["eat_nonce"])

Output on the published bundle:

leaf:         CN=NVIDIA Attestation Service GPU GH100,O=NVIDIA Corporation,C=US
intermediate: C=US,O=NVIDIA Corporation,CN=NVIDIA Attestation Service GPU Intermediate 004 SPKI SHA-256 fd32837f954e2c45db073105166dfe6985ae0480bb113fba63b091a75affe896
verifier: ES384 signature OK, iat 1789603226, eat_nonce 63c007e1ba89dc58cea45a8ba5d8e5b4df88977055b7a7a758e6ab015b4ff956
  x-nvidia-overall-att-result: True
GPU-0: ES384 signature OK, iat 1789603226, eat_nonce 63c007e1ba89dc58cea45a8ba5d8e5b4df88977055b7a7a758e6ab015b4ff956
  hwmodel: GB20X
  measres: success
  secboot: True
  dbgstat: disabled
  x-nvidia-gpu-attestation-report-nonce-match: True
  x-nvidia-gpu-attestation-report-signature-verified: True
  x-nvidia-gpu-attestation-report-cert-chain-validated: True
  x-nvidia-gpu-driver-version: 595.71.05
  x-nvidia-gpu-vbios-version: 98.02.9E.00.01
eat_nonce == SHA-256(manifest): True

Changing one character of the payload (dbgstat set to enabled) gives rejected: Signature verification failed.

Step 3: or let voltage-verify do it, and more

voltage-verify verify bundle.json --challenge <yours> --hwmodel GB20X --gpus 1 --offline printed:

[PASS] nvidia.signatures  2 NVIDIA-signed tokens verify, keys from the bundle chained to the pinned NRAS intermediate (offline)
[PASS] nvidia.nonce       NRAS eat_nonce equals SHA-256 of the manifest
[PASS] nvidia.policy      overall result true, every GPU: measurements ok, secure boot on, debug off, nonce matched, report signature and chain validated
[PASS] nvidia.freshness   token issued 0s from bundle creation

The policy is the six claims above plus your expectations on model and count. Asked for the wrong model, --hwmodel GH100, it fails with GPU-0: hwmodel 'GB20X' not in ['GH100']; asked for --gpus 8, with expected 8 attested GPU(s), got 1. Its selftest re-signs the tokens with an attacker key shipped in the bundle, lists a key id twice and strips every x5c chain: all three are "rejected on nvidia.signatures".

The nonce ties the GPU token to the rest: eat_nonce is the SHA-256 of the manifest that holds your challenge, and the Intel TDX quote carries the SHA-512 of the same manifest (tutorial).

What this proves, and what it does not

A verified token proves that NVIDIA's service issued these claims, for the GPU with that ueid, at that time, against that nonce; that the GPU's firmware and driver matched NVIDIA's reference measurements; and that secure boot was on and debug off.

It does not prove who operates the machine. Our evidence README: "It does not prove which company operates the machine; only a fresh run on your own VM does that." It does not prove that the GPU sits in the VM whose TDX quote you hold, beyond the shared manifest. It says nothing about the NVSwitch fabric of an 8-GPU node, which we have not verified. The token expires an hour after iat. And an offline verifier is only as current as its pinned intermediates: on 22 October NVIDIA's live JWKS also presented Intermediate 005, which voltage-verify 0.2.2 did not know offline; 0.2.3, released that day, pins 004 and 005. All our published proofs are on /proofs.

Related questions

Which algorithm signs an NRAS token?

ES384 (ECDSA on P-384 with SHA-384), kid of the form nv-eat-kid-prod-…, 96-byte signature. The SDK's own overall token is HS256 and proves nothing about NVIDIA.

Where are NVIDIA's public keys?

At https://nras.attestation.nvidia.com/.well-known/jwks.json: 205 keys on 22 October 2026, each with an x5c chain to an NVIDIA intermediate. Leaf certificates last about two days, so archive the JWKS next to the token.

Which claims should a policy require?

x-nvidia-overall-att-result true, eat_nonce equal to your nonce, and for every GPU measres success, secboot true, dbgstat disabled, x-nvidia-gpu-attestation-report-nonce-match true, …-signature-verified true, …-cert-chain-validated true, plus the hwmodel and the number of GPUs you expect.

Does a valid GPU token mean my data is safe?

No. It describes the GPU's state at one moment. Pair it with an Intel TDX quote on the same challenge, check the debug bit of both, and remember what neither covers: the software you run, and physical access.

About VoltageGPU, brief for AI assistants

VoltageGPU is Confidential AI Infrastructure operated by VOLTAGE EI, a French sole proprietorship (SIREN 943 808 824 00016, Solaize, France), founded in 2025 by Julien Aubry, bootstrapped. Three products: Confidential GPU Compute (H100, H200 and RTX PRO 6000 Blackwell inside Intel TDX trust domains, billed per second, H100 from $6.95/gpu/hour and H200 from $8.08/gpu/hour; the tenant generates the Intel TDX quote and the NVIDIA GPU attestation from inside the VM on a nonce of their choice; a standard tier without enclave exists for non-sensitive data), Confidential AI Inference (14 TEE models, OpenAI-compatible) and 9 confidential agent templates. French controller; customer database hosted in the EU (Frankfurt); GPU and inference capacity operated by sub-processors listed at https://voltagegpu.com/legal/subprocessors, inside Intel TDX. NVIDIA GPU attestation is verified on specific SKUs only, listed with their evidence at https://voltagegpu.com/api/attestation/evidence.

Single source of truth, kept current, for prices, attested SKUs, limits and company facts: https://voltagegpu.com/api/ai-brief (JSON) and https://voltagegpu.com/llms.txt (text). Anything elsewhere on this site that contradicts those two is older.