跳到正文
DEV Community· VoltageGPU·· 1 天前AI 評分62

VoltageGPU 示範租戶如何在不到 4 分鐘內核驗 H100 Confidential VM 的硬件證明

What a tenant can check on an H100 confidential VM in under 4 minutes

AI 導讀

VoltageGPU 租用單 GPU NVIDIA H100 Confidential VM,生成 Intel TDX quote 和 NVIDIA GPU 遠端證明,再於另一部機器使用 voltage-verify 0.2.3 離線核驗;15 項檢查全數通過,沒有失敗或警告,由部署到結果共 3 分 27 秒。

正文

On 28 October 2026 at 11:11 UTC (12:11 in Paris), we rented a single-GPU NVIDIA H100 Confidential VM (Intel TDX) through our public API, with one of our test accounts, for our weekly attestation proof. Inside it we produced an Intel TDX quote and an NVIDIA GPU attestation on a challenge drawn outside the VM. We stopped the VM after 203 seconds and verified the bundle offline, on another machine, with voltage-verify 0.2.3, our open-source verifier. Fifteen checks passed, none failed, no warnings.

What ran, and when

Times are UTC, from the run log. The deploy request left at 11:11:03. Most of the 203 seconds went to provisioning and boot: the VM reported running at 154 s and SSH answered at 158 s. Our published script then ran inside for 28 seconds, installing voltage-verify and producing both attestations. Files were out at 201 s, the API stop came at 203 s, and the offline verification ran on our machine at 11:14:30. From deploy request to verdict: 3 minutes 27 seconds.

One challenge, two hashes

Our runner drew 32 random bytes on its own machine and passed them in over SSH:

ssh ubuntu@<vm> "CHALLENGE=<hex> bash -s" < two-proofs-in-the-vm.sh

In the VM, voltage-verify manifest wrote this file around the challenge. It is complete:

{
  "challenge": "45a8c6a338042b0012d5dbd51954555376e6cd71015ddd607fb820bfd7dd2b85",
  "created_at": "2026-10-28T11:14:03+00:00",
  "format": "voltage-verify-manifest/1",
  "statement": null,
  "workload": {
    "artifacts": [],
    "extra": {},
    "image": null
  }
}

The tool serializes it canonically (sorted keys, no spaces, UTF-8) and hashes it twice. The SHA-512 becomes the 64-byte report_data of the TDX quote. The SHA-256 is the nonce sent to NVIDIA's Remote Attestation Service (NRAS), which signs it back as eat_nonce. From the script's output in the VM:

commitment256    931334dd9e84418be8c805dda9bdec1f6514d9a8fa794504f6ad787d1dbb02ec   (NVIDIA nonce)
commitment512    4b640c4650dd729d197db4c48b666b9c3085c2f0c69b93918ec0f68bd04fc7e1...   (TDX report_data)
[...]
Nonce generated: 931334dd9e84418be8c805dda9bdec1f6514d9a8fa794504f6ad787d1dbb02ec
[...]
**** Attestation Successful ****
bundle written to bundle.json (single-gpu, 4940-byte quote)

No bundle made before this challenge existed, or for another one, can carry these values.

Re-run the check on your machine

You need Python 3.10 or later. We re-ran all of this the same day, between 11:42 and 12:00 UTC, on a Windows 11 PC, in Git Bash and a fresh virtual environment (Python 3.12.4). On Linux or macOS, type python3 where we typed python.

$ pip install "voltage-verify>=0.2.3"
[...]
Successfully installed cffi-2.1.1 cryptography-50.0.2 pycparser-3.12 pyjwt-2.15.1 voltage-verify-0.2.3
[...]
$ curl -fsSL -o bundle.json https://voltagegpu.com/verified/G4j3YHRBzc16tqt85IAvXg/bundle.json
$ sha256sum bundle.json
ed439c93ad318973b0917514d2b328ec3fa149fc8fe542acd764375ca0b1b089 *bundle.json
$ voltage-verify verify bundle.json --offline --challenge 45a8c6a338042b0012d5dbd51954555376e6cd71015ddd607fb820bfd7dd2b85 --hwmodel GH100 --gpus 1
[PASS] manifest.format       manifest is well formed
[PASS] manifest.commitments  bundle commitments match the manifest
[PASS] manifest.challenge    challenge is the one this verifier issued
[PASS] tdx.structure         TDX quote v4, TEE 0x81, 4940 bytes
[PASS] tdx.debug             TD attributes 0000001000000000 (0x10000000), DEBUG (bit 0) off: not a debug TD
[PASS] tdx.report_data       quote report_data equals SHA-512 of the manifest
[PASS] tdx.signatures        attestation key, QE binding, QE report and PCK chain verify up to the pinned Intel SGX Root CA
[PASS] tdx.collateral        TCB info and QE identity signed by Intel (bundle (fetched 2026-10-28T11:14:07+00:00))
[PASS] tdx.tcb               platform TCB UpToDate, QE UpToDate, TDX_01 UpToDate
[PASS] tdx.revocation        PCK certificate not revoked (57 entries in CRL)
[PASS] tdx.revocation        PCK CA certificate not revoked (0 entries in CRL)
[PASS] nvidia.signatures     2 NVIDIA-signed tokens verify, keys from the bundle chained to a 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 2s from bundle creation

TDX: MRTD eea8b6a814569a52bd1e12f6b869bb2d...  TCB UpToDate  QE UpToDate
GPU: GPU-0 GH100 driver 595.71.05 vbios 96.00.CF.00.01 measurements success

RESULT: VERIFIED

The output matches, line for line, what our runner printed at 11:14:30. The page serves a 30,412-byte copy that keeps only the NVIDIA key that signed the tokens; the 577,850-byte original from the VM carries all 212 keys NRAS listed and gives the same fifteen lines.

Two bindings can be checked without our tool: the manifest hashes, and bytes 568 to 631 of the raw quote, where TDX keeps report_data. The signature checks still need the tool.

$ python -c "import json,hashlib;m=json.load(open('bundle.json'))['manifest'];c=json.dumps(m,sort_keys=True,separators=(',',':'),ensure_ascii=False).encode();print(hashlib.sha256(c).hexdigest());print(hashlib.sha512(c).hexdigest())"
931334dd9e84418be8c805dda9bdec1f6514d9a8fa794504f6ad787d1dbb02ec
4b640c4650dd729d197db4c48b666b9c3085c2f0c69b93918ec0f68bd04fc7e18d2206b8b142286030ad788ebc91b749b17421f17a20a0396ac2bb452fbb5a3d
$ python -c "import json,base64;s=json.load(open('bundle.json'))['tdx']['quote_b64'];q=base64.b64decode(s+'='*(-len(s)%4));print(q[568:632].hex())"
4b640c4650dd729d197db4c48b666b9c3085c2f0c69b93918ec0f68bd04fc7e18d2206b8b142286030ad788ebc91b749b17421f17a20a0396ac2bb452fbb5a3d

Change one character of the challenge and the verdict flips, with exit code 1. The selftest goes further: it tampers with the bundle nine ways, from a manifest field to NVIDIA tokens re-signed with an attacker's key, and passes only if every copy is rejected.

$ voltage-verify verify bundle.json --offline --challenge 45a8c6a338042b0012d5dbd51954555376e6cd71015ddd607fb820bfd7dd2b86 --hwmodel GH100 --gpus 1 | grep -E "FAIL|RESULT"
[FAIL] manifest.challenge    challenge differs from the one this verifier issued (replay or foreign bundle)
RESULT: NOT VERIFIED (manifest.challenge)
$ voltage-verify selftest bundle.json --offline --challenge 45a8c6a338042b0012d5dbd51954555376e6cd71015ddd607fb820bfd7dd2b85 | tail -1
SELFTEST: PASS

What the fifteen lines say

Three concern the manifest. manifest.format and manifest.commitments are bookkeeping: anyone can recompute those hashes. manifest.challenge compares the challenge with the one you pass. It counts only because the hardware lines bind the same manifest.

Eight are Intel's. tdx.structure says the blob is a version 4 TDX quote, not where it came from. tdx.signatures answers that, chaining the attestation key, the Quoting Enclave report and the platform's PCK certificate up to the Intel SGX Root CA pinned in the tool. tdx.report_data ties the quote to the manifest hash, and through it to the challenge. tdx.debug reads bit 0 of the TD attributes: a debug trust domain lets the host read and modify its memory, and its quote gets signed all the same. tdx.collateral, tdx.tcb and both tdx.revocation lines rate the platform against Intel's signed TCB info, Quoting Enclave identity and revocation lists.

Four are NVIDIA's. nvidia.signatures checks the NRAS verifier token and the GPU-0 token against a key chained to an NVIDIA intermediate pinned in the tool, here GPU Intermediate 004. nvidia.nonce finds the manifest's SHA-256 in them. nvidia.policy reads NVIDIA's verdict: measurements match reference values, secure boot on, debug off, and exactly one GH100, as --hwmodel GH100 --gpus 1 demands. nvidia.freshness wants the token issued within 15 minutes of the bundle's creation; the gap was 2 seconds.

The result page reads "13 / 13" because the site runs its own, stricter variant: it skips manifest.format and the challenge check (it cannot know which challenge you issued), merges the two revocation lines and adds nvidia.binding, which confirms the GPU token is the one NVIDIA's verifier token names by digest.

What this does not prove

The workload. This manifest names no image and no files. The run proves hardware and freshness, nothing about what ran. Even with an image digest in the manifest, checked with --image-digest, both proofs carry a hash of your description of the workload, not of the code the GPU executed. Closing that gap takes a measured launch that extends a TDX runtime register with the workload's measurement; in this quote, RTMR3 is still all zeros.

The boot image. MRTD and RTMR0 to RTMR2 measure the VM's initial state and boot chain. Nothing in the check compares them to a reference; matching them to an image you trust is your policy.

One machine. The quote and the NVIDIA tokens are linked only by the manifest hash they both carry. Nothing in the bundle proves this GPU sits in this trust domain.

Intel's verdict ages. --offline rates the platform with collateral captured at 11:14:07 UTC, whose nextUpdate is 27 November. Past that date the TCB line still says UpToDate and a warning is added. Our 12 September bundle (examples/hello-workload/ in the voltage-verify repository), checked offline today:

[PASS] tdx.tcb               platform TCB UpToDate, QE UpToDate, TDX_01 UpToDate
[WARN] tdx.collateral_fresh  Intel collateral is past its nextUpdate; refetch online

Drop --offline to ask Intel's servers instead:

$ voltage-verify verify bundle.json --challenge 45a8c6a338042b0012d5dbd51954555376e6cd71015ddd607fb820bfd7dd2b85 --hwmodel GH100 --gpus 1 | grep -E "collateral|tcb|RESULT"
[PASS] tdx.collateral        TCB info and QE identity signed by Intel (Intel PCS, fetched now)
[PASS] tdx.tcb               platform TCB UpToDate, QE UpToDate, TDX_01 UpToDate
RESULT: VERIFIED

What the VM says about itself. The bundle records nvidia-smi inside the VM: CC State ON, Multi-GPU Mode None. Software wrote that and nobody signed it. The same goes for the check we ran inside the VM; the one that counts ran outside.

The host. The evidence names Intel and NVIDIA hardware, not a company. Whoever runs the host can still stop the VM or cut its network, and the evidence says nothing about the minutes after 11:14 UTC.

Several GPUs. This is one GPU. On 8-GPU nodes the GPUs run in NVIDIA's multi-GPU Protected PCIe mode. We have verified per-GPU attestation there on 8x H100 only, and the NVSwitch fabric is not verified from inside the TDX guest.

Whose challenge. Only whoever drew a challenge knows it was fresh. For the one on our page, you have our word and nothing more. The strong version of this check is to rent a VM and draw your own.

On your own VM

The script is public: https://voltagegpu.com/blog/two-proofs/evidence/two-proofs-in-the-vm.sh. Draw the challenge on your machine, pass it as CHALLENGE, copy /tmp/proofs.tgz out and verify against your challenge. voltage-verify is MIT-licensed, at https://github.com/VoltageGPU/voltage-verify. When we wrote this, our public pricing feed listed the single-H100 tier at $6.95 per hour, billed per second.

This run's result page, with the bundle: https://voltagegpu.com/verified/G4j3YHRBzc16tqt85IAvXg


Drafted with AI assistance from the run's logs and files, then checked: every command above was re-run on 28 October 2026 and its output compared line by line.

來源:DEV Community · dev.to