Skip to content

chore(attestation): gate azure generation on the target, not the feature alone - #94

Open
samlaf wants to merge 1 commit into
flashbots:mainfrom
SeismicSystems:upstream/azure-attester-target-gate
Open

chore(attestation): gate azure generation on the target, not the feature alone#94
samlaf wants to merge 1 commit into
flashbots:mainfrom
SeismicSystems:upstream/azure-attester-target-gate

Conversation

@samlaf

@samlaf samlaf commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

This is just a nice to have, but it's been annoying me. I open a bunch of related repos in vscode, and turn on all-features on rust-analyzer because that's the only easy way that vscode workspaces can configure features (they don't read repo-specific settings.json file when inside a workspace).

But even without the vscode workspace issue, I think generally this is a nice to have cleanup as it makes it more obvious by the build.rs injected feature name that its x86 linux only.

LLM Summary

cargo check --all-features, and anything else that turned on azure-attester, failed to build on any host that is not x86_64 linux. Two dependencies of the generation path do not compile elsewhere: tss-esapi-sys ships pregenerated bindings for a fixed list of target tuples that omits aarch64-darwin and panics on anything outside it, and az-tdx-vtpm takes az-cvm-vtpm with default features, whose verifier turns on sev/openssl and so rdrand 0.8, which has no non-x86 support (virtee/sev#369). That put a whole-crate build failure in front of anyone on an Apple Silicon or aarch64 machine running a feature-complete check, rust-analyzer and cargo doc included.

Gating on the feature alone was the mistake: a feature records what the caller asked for, not what the target can provide. So declare az-tdx-vtpm and tss-esapi in a
cfg(all(target_os = "linux", target_arch = "x86_64")) dependency table, and have build.rs derive an azure_attester_x86_64_linux cfg from the feature and those same two target values. The generation code moves from cfg(feature = "azure-attester") onto that cfg. Both halves are load bearing: the feature keeps the native tpm2-tss stack opt-in so verification never links it, which a build script cannot do since it can neither add nor remove a dependency, while the cfg is what asserts the code compiles here. The cfg carries the platform in its name so the gate sites need not each repeat the condition, and so that reading one makes clear it is not the feature.

Enabling azure-attester off x86_64 linux is now a no-op rather than an error. Cargo still reports the feature as enabled; its two dependencies are simply absent from the graph and build.rs withholds the cfg, leaving the compiled surface equal to azure-verifier on its own: detect() never reports AzureTdx, and generation returns AttestationTypeNotSupported. Verification is untouched and still needs no TPM stack anywhere.

Narrowing to x86_64 is not a workaround waiting on those upstream fixes. TDX is an Intel technology and the vTPM is read through a linux device, so an Azure TDX CVM is x86_64 linux by construction and the gate is permanent; the sev issue is linked as evidence for anyone who later tries to widen it. The upstream fix that would let us delete code is kinvolk/azure-cvm-tooling#95, so tpm_quote's retirement note now names it.

The macOS CI job gains a cargo check -p attestation --all-features step, which is what would have caught this. The crate readme claimed it was impossible to compile with azure-attester on macOS, and now describes the no-op instead.

One hazard when editing either file: the platform condition lives in both Cargo.toml's target table and build.rs, and nothing enforces that the two agree. A build.rs broader than the table fails the build outright; a narrower one silently drops the generation code. Comments in both places say so.

…ure alone

`cargo check --all-features`, and anything else that turned on
`azure-attester`, failed to build on any host that is not x86_64 linux.
Two dependencies of the generation path do not compile elsewhere:
tss-esapi-sys ships pregenerated bindings for a fixed list of target
tuples that omits aarch64-darwin and panics on anything outside it, and
az-tdx-vtpm takes az-cvm-vtpm with default features, whose `verifier`
turns on `sev/openssl` and so rdrand 0.8, which has no non-x86 support
(virtee/sev#369). That put a whole-crate build failure in front of
anyone on an Apple Silicon or aarch64 machine running a feature-complete
check, rust-analyzer and cargo doc included.

Gating on the feature alone was the mistake: a feature records what the
caller asked for, not what the target can provide. So declare
az-tdx-vtpm and tss-esapi in a
cfg(all(target_os = "linux", target_arch = "x86_64")) dependency table,
and have build.rs derive an `azure_attester_x86_64_linux` cfg from the
feature and those same two target values. The generation code moves from
`cfg(feature = "azure-attester")` onto that cfg. Both halves are load
bearing: the feature keeps the native tpm2-tss stack opt-in so
verification never links it, which a build script cannot do since it can
neither add nor remove a dependency, while the cfg is what asserts the
code compiles here. The cfg carries the platform in its name so the gate
sites need not each repeat the condition, and so that reading one makes
clear it is not the feature.

Enabling `azure-attester` off x86_64 linux is now a no-op rather than an
error. Cargo still reports the feature as enabled; its two dependencies
are simply absent from the graph and build.rs withholds the cfg, leaving
the compiled surface equal to `azure-verifier` on its own: detect() never
reports AzureTdx, and generation returns AttestationTypeNotSupported.
Verification is untouched and still needs no TPM stack anywhere.

Narrowing to x86_64 is not a workaround waiting on those upstream fixes.
TDX is an Intel technology and the vTPM is read through a linux device, so
an Azure TDX CVM is x86_64 linux by construction and the gate is
permanent; the sev issue is linked as evidence for anyone who later tries
to widen it. The upstream fix that would let us delete code is
kinvolk/azure-cvm-tooling#95, so tpm_quote's retirement note now names it.

The macOS CI job gains a `cargo check -p attestation --all-features` step,
which is what would have caught this. The crate readme claimed it was
impossible to compile with `azure-attester` on macOS, and now describes
the no-op instead.

One hazard when editing either file: the platform condition lives in both
Cargo.toml's target table and build.rs, and nothing enforces that the two
agree. A build.rs broader than the table fails the build outright; a
narrower one silently drops the generation code. Comments in both places
say so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant