Skip to content

Intel TDX support and a GCP confidential VM guide - #305

Merged
drasko merged 5 commits into
absmach:mainfrom
rodneyosodo:gcp-intel-tdx
Oct 6, 2026
Merged

drasko merged 5 commits into
absmach:mainfrom
rodneyosodo:gcp-intel-tdx

Conversation

@rodneyosodo

Copy link
Copy Markdown
Contributor

What type of PR is this?

This is a feature because it adds Intel TDX support to the Proplet guest stack, alongside the existing Azure AMD SEV-SNP path. It is also a documentation update, because it adds hal/gcp/README.md, and a dependency update, because it moves elastic-tee-hal to upstream main and compiles the tdx-attester in.

What does this do?

Adds a second confidential-computing platform to the guest stack. Until now Proplet could only attest against an Azure SEV-SNP vTPM, so the same binary could not run on a GCP confidential VM with Intel TDX. Three things change:

  • proplet/Cargo.toml compiles tdx-attester next to az-snp-vtpm-attester, and elastic-tee-hal with amd-sev + intel-tdx. One binary now serves both platforms: detect_tee_type() probes TDX first and falls through to the Azure vTPM, so the running host decides which attester is primary. Both attesters are compiled rather than selected by a cargo feature on purpose — a [features] entry is not target-scoped, so enabling attestation-agent/az-snp-vtpm-attester from there pulls tss-esapi-sys into the arm64 and riscv64 builds, which CI builds and which fail without the TPM2 TSS headers. Keeping the choice in the [target.'cfg(target_arch = "x86_64")'.dependencies] block leaves those builds alone.
  • examples/hal-runner moves to the same elastic-tee-hal revision. Its previous pin predated both TDX support and the Azure vTPM fix, so Part 6 of the guide would have reported type=AmdSev or nothing.
  • hal/gcp/README.md is a new end-to-end guide: Trustee on a separate GCE VM, the CoCo guest components inside a C3/C4 Intel TDX confidential VM. It mirrors hal/azure/README.md and opens with a table of where the two platforms differ, because those differences are the failure modes: the attester is tdx-attester rather than az-snp-vtpm-attester, evidence is a DCAP quote from the Linux TSM rather than a vTPM attestation, and the guest needs neither a vTPM for attestation nor Intel's DCAP headers. hal/azure/README.md and hal/ubuntu/README.md link to it.

Two claims in the guide were checked rather than copied from the Azure guide: GCP's default-allow-internal rule already permits the KBS port, so the firewall rule is presented as hardening rather than a requirement; and current Trustee already points trusted_certs_paths at the token-signing CA, so that step is a verification with a fallback rather than a blind rewrite.

Attestation-policy hardening is left as a follow-up section. GCP boots GRUB rather than the TDVF shim, so Trustee evaluates its other TDX branch and needs rtmr_* reference values that change whenever the guest kernel does.

Which issue(s) does this PR fix/relate to?

None

Have you included tests for your changes?

No new tests — this is a build-configuration, dependency and documentation change, and the attester behaviour it depends on is tested upstream in elasticproject-eu/wasmhal. Verified:

  • cargo check --bins and cargo build --release in proplet
  • cargo test --lib --bins — 207 passed
  • cargo fmt --check and cargo clippy --bins clean
  • cargo tree --target aarch64-unknown-linux-gnu / riscv64gc confirm those graphs are unchanged (no tss-esapi-sys), while x86_64 gains the TDX attester dependencies
  • exercised end to end on a GCP c3-standard-4 TDX instance: HAL reports IntelTdx, a DCAP quote is produced from /dev/tdx_guest, and an encrypted workload decrypts and runs

Did you document any new/modified features?

Yes

Notes

  • Depends on elasticproject-eu/wasmhal main, where the intel-tdx feature and the x86_64 scoping of the Azure vTPM dependencies have landed. elastic-tee-hal is pinned to main in both proplet and examples/hal-runner.
  • The guide documents GCP-specific traps that cost real time to find, each with the error string: --create-disk versus --image (one boot disk), --maintenance-policy=TERMINATE being valid on the CVM but rejected on a plain e2 host, Intel's DCAP apt repo being needed before the kbs-client build, the keyprovider's --kbs argument being the only source of its KBS URL, and KBS URL not configured / UnWrapKey API is unimplemented as wrong-branch symptoms in guest-components.
  • GCP credentials and identifiers are not committed; the guide uses <project-id> placeholders and $PROJECT / $ZONE.

The guest stack could only attest against an Azure SEV-SNP vTPM, so the same
proplet binary could not run on a GCP confidential VM with Intel TDX. Two
changes make one binary serve both:

- Compile the `tdx-attester` next to `az-snp-vtpm-attester`. Both attesters
  are compiled in rather than selected by a feature, because
  `detect_tee_type()` probes TDX first and falls through to the Azure vTPM,
  so the running platform decides which one is primary. A `[features]` entry
  cannot express this: features are not target-scoped, so enabling
  `attestation-agent/az-snp-vtpm-attester` from there pulls `tss-esapi-sys`
  into the arm64 and riscv64 builds, which CI builds and which fail without
  the TPM2 TSS headers.
- Point `elastic-tee-hal` at wasmhal's `intel-tdx` feature so the HAL can
  produce a real TDX DCAP quote from the Linux TSM, next to the existing
  Azure vTPM path.

The HAL is tracked on the fork branch because
elasticproject-eu/wasmhal#7 is still open; switch it back to `main` once that
lands.

Verified: `cargo check --bins`, `cargo test --lib --bins` (207 tests),
`cargo fmt --check` and `cargo clippy --bins` clean. `cargo tree --target`
confirms the arm64 and riscv64 graphs are unchanged (no `tss-esapi-sys`) while
x86_64 gains the TDX attester dependencies.
Mirrors hal/azure/README.md for the other confidential-VM platform we
support: Trustee on a separate GCE VM, the CoCo guest components inside a
C3/C4 Intel TDX confidential VM.

Parts 4-6 (publishing an encrypted image, running a workload, exercising the
HAL) follow the Azure guide. Parts 1-3 are TDX-specific and open with a
comparison table of where the two platforms differ, because the differences
are the failure modes: the attester is `tdx-attester` rather than
`az-snp-vtpm-attester`, evidence is a DCAP quote from the Linux TSM rather
than a vTPM attestation, and the guest needs neither a vTPM nor Intel's DCAP
headers.

Two claims are checked rather than copied from the Azure guide:

- The firewall section says KBS is already reachable in a default VPC
  (`default-allow-internal` allows all TCP from 10.128.0.0/9) and offers the
  explicit rule as hardening, instead of implying one is required.
- Trustee ships `trusted_certs_paths = [ca-cert.pem]`, which already is the
  token-signing CA, so the token-CA step is a verification with a documented
  fallback rather than a blind rewrite.

Attestation policy hardening is left as a follow-up section: GCP boots GRUB
rather than the TDVF shim, so evaluation takes Trustee's other TDX branch and
needs rtmr reference values that change whenever the guest kernel does.

hal-runner moves to the same wasmhal rev as proplet so Part 6 reports
IntelTdx; its previous pin predated both TDX support and the Azure vTPM fix.

Also cross-links the GCP guide from the Azure and QEMU guides.
Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
@drasko
drasko merged commit bfd9b83 into absmach:main Oct 6, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants