Skip to content

Let auto TDX attestation follow the image, not guest RAM - #1200

Merged
kvinwang merged 1 commit into
nextfrom
fix/tdx-lite-auto-any-memory
Sep 10, 2026
Merged

kvinwang merged 1 commit into
nextfrom
fix/tdx-lite-auto-any-memory

Conversation

@kvinwang

Copy link
Copy Markdown
Collaborator

Why

tdx_attestation_variant = "auto" refused lite below 3 GiB, exempting exactly
2 GiB:

if memory_mib < Self::THREE_GIB_MIB && memory_mib != Self::TWO_GIB_MIB {
    TdxAttestationVariant::Legacy
} else if image_supports_lite { ... }

That came from QEMU's setup-header rewrite, which moves the initrd with guest
RAM and so makes the patched kernel Authenticode hash memory-dependent — see
tdx_kernel_hash_uses_precomputed_high_mem in dstack-mr/src/kernel.rs.

Images whose OVMF normalizes the setup header measure the shipped bzImage
instead, which no guest RAM size can move. That is every image the build system
can now produce: os/image/assemble.sh hardcodes kernel_header_normalized
and the OVMF build fails when the normalization patch does not apply.

So the heuristic now only costs deployments the cheaper verification path — a
1 GiB CVM on a current image got legacy despite carrying everything lite needs.

What changed

resolve follows image_supports_lite alone and no longer takes the memory
size; TWO_GIB_MIB and THREE_GIB_MIB are gone. The vmm.toml comment and
the field doc are updated to match.

Both tests that encoded the old behaviour are updated. The one in app.rs is
rewritten to assert the new outcome — 1 GiB with a lite-capable image now
resolves to lite — so the behaviour change is recorded positively rather than
by deletion.

The case this stops covering

A pre-normalization image below the threshold: the VMM now selects lite, and
the no-download verifier rejects it. That rejection names the required memory
sizes and tells the operator to re-emit the image, so it is an explicit failure
rather than a silent mismatch, and tdx_attestation_variant = "legacy" keeps
such an image running as is. The reasoning is recorded on resolve itself.

Keeping the guard for exactly that case is possible — it would mean threading
kernel_header_normalized into resolve — but it puts the memory rule back
for a class of image the build system can no longer emit.

Testing

cargo test -p dstack-vmm --all-features (128 passed), cargo fmt --all -- --check, cargo clippy -p dstack-vmm -- -D warnings --allow unused_variables.

Independent of #1199; the two do not touch the same code.

`auto` refused lite below 3 GiB, exempting exactly 2 GiB. That came from
QEMU's setup-header rewrite, which moves the initrd with guest RAM and so makes
the patched kernel Authenticode hash memory-dependent. Images whose OVMF
normalizes the setup header measure the shipped `bzImage` instead, which no
guest RAM size can move -- and that is every image the build system can now
produce: `os/image/assemble.sh` hardcodes `kernel_header_normalized` and the
OVMF build fails when the normalization patch does not apply.

So the heuristic now only costs deployments the cheaper verification path: a
1 GiB CVM on a current image got legacy despite carrying everything lite needs.
Drop it and follow `image_supports_lite` alone; `resolve` no longer takes the
memory size.

A pre-normalization image is the one case this stops covering. The no-download
verifier still rejects those below the threshold, with an error that names the
memory sizes and says to re-emit the image, so the failure is explicit rather
than a silent mismatch, and `tdx_attestation_variant = "legacy"` keeps one
running as is.
Copilot AI lite review requested due to automatic review settings September 10, 2026 07:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The behavior change is consistently implemented and covered by updated tests, with only a minor doc-clarity nit noted in review comments.

Pull request overview

This PR updates the VMM’s tdx_attestation_variant = "auto" policy to select the attestation scheme based solely on whether the OS image provides TDX lite measurement material, removing the previous guest-RAM-size heuristic. This aligns the runtime selection logic with current images produced by the build system (which normalize the kernel setup header), avoiding unnecessary fallback to legacy verification on small-memory CVMs.

Changes:

  • Simplified TdxAttestationVariantConfig::resolve to depend only on image_supports_lite, removing the 2/3 GiB memory thresholds.
  • Updated VMM config documentation (vmm.toml and Rust field docs) to reflect the new auto behavior and rationale.
  • Adjusted VMM config construction and tests to record the new outcome (e.g., 1 GiB + lite-capable image resolves to lite).
File summaries
File Description
dstack/vmm/vmm.toml Updates operator-facing description of the auto attestation policy to remove the RAM-size rule.
dstack/vmm/src/config.rs Changes auto resolution logic and updates in-code docs/tests to match the new behavior.
dstack/vmm/src/app.rs Updates the call site to the new resolve signature and revises tests to assert the new auto outcome.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread dstack/vmm/vmm.toml
@kvinwang
kvinwang merged commit 6922a09 into next Sep 10, 2026
19 checks passed
@kvinwang
kvinwang deleted the fix/tdx-lite-auto-any-memory branch September 10, 2026 07:57
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