Add AWS EC2 NitroTPM attestation and guest OS support - #753
Conversation
d6fb1cd to
504e342
Compare
504e342 to
420ea41
Compare
420ea41 to
41f9b7e
Compare
41f9b7e to
41a4aa1
Compare
fe08404 to
4062083
Compare
Simplification pass (operator decisions)Rebased onto master (includes #777 empty TPM key-provider id) and applied:
Commit: Still follow-up as needed: Yocto UKI recipe stop embedding |
Follow-up commit
|
ca7909f to
c49b7cf
Compare
Add AWS EC2 NitroTPM as a first-class attestation platform under the account-admin-untrusted threat model, integrated like SEV-SNP rather than with AWS-specific auth surface. Measurement model (aligned with bare TDX): - Boot: PCR4/7/12 for AMI/UKI identity - Config: shared-disk MrConfigV3 measured into PCR8 (no UKI cmdline pin) - Events: all dstack events extend SHA384 PCR14 (RTMR3 analogue; no PCR23 launch/runtime split) - os_image_hash: prefer unified sha256(sha256sum.txt) via VmConfig.aws_measurement + reference PCR bind; legacy PCR-hash fallback - KMS GetAppKey: RA-TLS only (api_version=1); no recipient encryption - GetQuote/Attest: report_data only (no platform attestation_options) - check_kms / auth-simple: pin early mrAggregated only (boot-mr-done) Includes Yocto AWS kernel/image support, verifier/KMS paths, SDKs, docs, and release/smoke helpers. Empty TPM key-provider id (already on master) keeps early MR precomputable.
c49b7cf to
d8f4871
Compare
Local TPM sealing on AwsEc2 now binds only SHA384 PCR4/7/12 (boot/OS identity). PCR23 is unused after the single PCR14 event-lane model and is resettable, so it must not gate sealed app keys.
Local NitroTPM key-provider sealing now uses sha384:4,7,8,12,14 — boot path (4/7/12), shared-disk MrConfigV3 (8), and the dstack event lane at seal time (14). Seal runs after PCR8 measure and key-provider events, so reboot unseal matches the same intermediate PCR14 state.
Wire unified os_image_hash + aws_measurement end-to-end: - dstack-mr aws-measurement-cbor and assemble measurement.aws.cbor - guest quote embeds sys-config vm_config when aws_measurement binds attested PCR4/7/12 (legacy PCR-hash fallback otherwise) - dstack-cloud: platform=aws, prepare sys-config with aws_measurement, full EC2 lifecycle (AMI import, shared snapshot, run/stop/start/logs) - remove standalone aws-ec2-import/smoke/attach scripts; docs point to dstack-cloud. Keep image audit + release-manifest helpers only.
UKI assemble always precomputes NitroTPM PCR4/7/12 into measurement.aws.cbor and lists it in sha256sum.txt so digest.txt is fixed for the release. Host nitro-tpm-pcr-compute is preferred; Docker AL2023 is fallback; missing both fails the build. dstack-cloud prepare only embeds the release material and refuses packages that lack a checksum-committed measurement.aws.cbor.
AwsOsImageMeasurement now holds sha256(PCR4||PCR7||PCR12) instead of the three raw SHA384 PCR values, matching the legacy image-hash composition. hex encoding uses serde_human_bytes (hex_bytes alias). Verifier and guest quote compare digests; dstack-mr still takes PCR4/7/12 hex and folds them.
Drop panic from cbor_to_vec and the awkward context string parameter.
Callers attach context with .context("…") instead. to_cbor_vec,
from_cbor_slice, measurement_hash, from_measurement, decode_*, and
document verify now use anyhow::Result for a consistent error model.
4fe61c8 to
f6ed3c4
Compare
The pre-key-release check added no security guarantee: key release for an unauthorized compose is already blocked by KMS via the PCR14 event lane, and key use under a mismatched config is still rejected by the full mr_config check in verify_app before any key is used or persisted. The early check only duplicated the static-field validation for AWS, diverging from the other platforms. Remove it and let AWS follow the same single post-key verification path as TDX and SEV-SNP.
On the AWS EC2 platform the attestation mode must be NitroTPM only. Exposing TDX or SEV-SNP devices on an AWS instance must not silently switch the attestation mode away from the AWS platform path.
reuse policy_tcb_fields when filling VerificationDetails so details.tcb_status matches boot_info.tcbStatus (notably AWS NitroTPM, which is normalized to "UpToDate" for the auth gate but surfaced as null at the top level). also picks up the pending rustfmt import reorder that broke CI.
the "legacy paths without aws_measurement use the value directly" path no longer exists; aws_measurement is mandatory on AWS.
the KMS key-release pipeline gates non-SNP quotes through CvmVerifier::verify_os_image_hash; pin down that the AWS path rejects a vm_config without aws_measurement, accepts a unified vm_config bound to the quoted PCRs, and rejects a boot_pcr_digest mismatch.
- audit-aws-ec2-image-hardening.sh: a supplied --rootfs-squashfs with no unsquashfs available is now a FAIL instead of WARN + exit 0 - generate-aws-ec2-release-manifest.sh: capture the audit exit status explicitly so a failing audit prints its output instead of silently aborting the manifest run under set -e
hop limit 2 lets processes behind the docker bridge fetch IMDSv2 tokens, exposing instance-role credentials to app containers when iam_instance_profile is set. dstack itself never talks to IMDS, so default metadata_hop_limit to 1 and leave 2 as an explicit opt-in for deployments whose containers legitimately need the instance role.
generate_tpm_app_keys now fails closed on platforms whose TPM is not part of the platform trust model; document that in the app-compose key_provider field description.
drop the unpinned docker amazonlinux:2023 + dnf fallback from assemble.sh: the computed PCRs feed measurement.aws.cbor -> sha256sum.txt -> os_image_hash, i.e. the measurement the KMS and verifiers enforce, so only a version-pinned operator-installed nitro-tpm-pcr-compute may produce it.
release images and their evidence (sha256sum.txt, digest.txt, measurement.aws.cbor, aws-pcrs.json) are produced by the unified os/build.sh flow now, so drop generate-aws-ec2-release-manifest.sh and the reproducibility-manifest doc written around it. rework the production verifier runbook around the build.sh release package (reproducible rebuild + pinned host tools for reference measurements) and note the removal in the dated security evaluation. the hardening audit script stays.
Trim the superseded security evaluation to the live threat model and property table, document the actual UKI archive and PCR sidecar layout, and remove stale recipient/fallback claims. Also simplify the certificate output and build fragments referenced by the updated runbook.
Drop the write-only AppInfo.attestation field and its backend, simulator, SDK, and documentation plumbing. GetQuoteResponse.attestation remains the platform-agnostic evidence field.
Parameterize GCP/AWS vm-config generation, reuse one shared-disk builder with required-file checks, and remove dead config serialization and save helpers. Correct all project-file diagnostics to app.json.
Restore the established string-error measurement API while using or_panic for invariant-only CBOR encoding. Consolidate TCB and key-release policy helpers, move AWS image-binding tests to the verifier, and remove redundant tests, dead accessors, and unrelated TPM/NSM diff noise.
There was a problem hiding this comment.
Pull request overview
Adds end-to-end AWS EC2 NitroTPM support across the monorepo (guest OS build/measurement, attestation generation, verifier/KMS policy normalization, SDK surface updates, and operational documentation) under the account-admin-untrusted threat model.
Changes:
- Introduces AWS NitroTPM attestation collection/verification and AWS-specific OS-image binding (
aws_measurement, boot PCR digest) across attest/verifier/KMS. - Extends Yocto guest OS/kernel configuration and image assembly to produce AWS measurement artifacts and hardening audit tooling.
- Updates SDKs and docs to expose/use a platform-agnostic
attestationfield and to document AWS verification/operations.
Reviewed changes
Copilot reviewed 60 out of 62 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| sdk/python/src/dstack_sdk/dstack_client.py | Adds attestation field to quote response model. |
| sdk/js/src/index.ts | Adds attestation field to JS SDK quote response type. |
| sdk/go/dstack/client.go | Adds attestation field and decoding helper to Go SDK. |
| sdk/curl/api.md | Documents attestation in /GetQuote and cloud fields in /Info. |
| os/yocto/tools/README.md | Clarifies Yocto host tools scope and AWS tooling location. |
| os/yocto/tools/aws/audit-aws-ec2-image-hardening.sh | Adds AWS EC2 image hardening audit script. |
| os/yocto/layers/meta-dstack/recipes-kernel/linux/linux-yocto%.bbappend | Adds AWS kernel feature config sources and feature inclusion. |
| os/yocto/layers/meta-dstack/recipes-kernel/linux/files/dstack-aws.scc | Introduces Yocto kernel feature definition for AWS. |
| os/yocto/layers/meta-dstack/recipes-kernel/linux/files/dstack-aws.cfg | Adds kernel config needed for EC2 Nitro boot devices/console. |
| os/yocto/layers/meta-dstack/recipes-core/images/dstack-uki.bb | Documents AWS app/config binding expectations for UKI cmdline. |
| os/yocto/layers/meta-dstack/recipes-core/dstack-guest/dstack-guest.bb | Adds tpm2-tss build dependency for guest recipe. |
| os/image/README.md | Documents AWS measurement artifact and tool requirements. |
| os/image/assemble.sh | Generates and includes measurement.aws.cbor in image digest/tar flows. |
| dstack/vmm/src/app.rs | Initializes aws_measurement field in VM config assembly path. |
| dstack/verifier/src/verification.rs | Adds AWS NitroTPM OS-image verification and policy boot info construction. |
| dstack/verifier/src/types.rs | Adds PolicyBootInfo and includes it in verification details. |
| dstack/verifier/src/main.rs | Adds --verify-cert oneshot mode for RA-TLS cert verification. |
| dstack/verifier/src/lib.rs | Re-exports PolicyBootInfo and policy_tcb_fields. |
| dstack/verifier/README.md | Documents AWS mode, policy boot info, and --verify-cert workflow. |
| dstack/verifier/Cargo.toml | Gates binary build on binary feature (default-enabled). |
| dstack/tpm2/src/types.rs | Adds RSA EK template and configurable name algorithm for templates/NV. |
| dstack/tpm2/src/device.rs | Adds raw session command helpers and flexible auth-area builders. |
| dstack/tpm2/src/commands.rs | Adds raw execution, NV name read, auth NV read/write, capabilities helpers. |
| dstack/tpm-types/src/lib.rs | Adds SHA384 PCR selection helper. |
| dstack/tpm-qvl/src/lib.rs | Rejects AWS EC2 platform for GCP AK quote root retrieval. |
| dstack/tpm-attest/tests/tpm_quote_sample.README.md | Documents TPM quote parsing fixture semantics/provenance. |
| dstack/tpm-attest/src/lib.rs | Adds AWS NitroTPM PCR policy and single-PCR read helper. |
| dstack/ra-tls/src/attestation.rs | Adds RA-TLS cert verification APIs returning verified certificate evidence. |
| dstack/ra-tls/Cargo.toml | Adds tokio dev-dependency for async tests. |
| dstack/nsm-qvl/tests/nitro_attestation.README.md | Documents NSM attestation fixture capture/verification model. |
| dstack/nsm-qvl/src/lib.rs | Adds alias for NitroTPM PCR field name in attestation document. |
| dstack/kms/src/onboard_service.rs | Adds platform evidence mapping for AWS NitroTPM. |
| dstack/kms/src/main_service/upgrade_authority.rs | Reuses verifier’s canonical policy boot info and TCB normalization. |
| dstack/kms/src/main_service.rs | Adds AWS NitroTPM key-release gate and extensive AWS-specific tests. |
| dstack/kms/src/config.rs | Adds aws_nitro_tpm_key_release config flag. |
| dstack/kms/kms.toml | Documents and defaults AWS NitroTPM key-release gate to disabled. |
| dstack/kms/Cargo.toml | Adds cc-eventlog dev-dependency for AWS-related tests. |
| dstack/kms/auth-simple/README.md | Updates allowlisting guidance and adds AWS NitroTPM example. |
| dstack/kms/auth-simple/index.test.ts | Normalizes attestationMode casing and updates tests/messages. |
| dstack/kms/auth-simple/auth-config.example.json | Updates example KMS MR label to “early/boot-mr-done”. |
| dstack/dstack-util/src/system_setup/config_id_verifier.rs | Skips AWS PCR8 config-id cross-check (guest-measured). |
| dstack/dstack-util/src/system_setup.rs | Adds AWS instance binding and AWS-specific PCR measurements/policy. |
| dstack/dstack-util/src/main.rs | Allows emitting raw AWS NitroTPM attestation doc in quote command path. |
| dstack/dstack-util/src/host_api.rs | Skips host notify on AWS EC2 platform. |
| dstack/dstack-util/src/crypto.rs | Rejects all-zero X25519 shared secret during DH decrypt. |
| dstack/dstack-util/Cargo.toml | Adds tpm2 dependency to support AWS NitroTPM operations. |
| dstack/dstack-types/src/lib.rs | Adds AWS platform detection and AWS OS image measurement document types. |
| dstack/dstack-mr/src/main.rs | Adds AWS measurement encoding/inspection support. |
| dstack/dstack-attest/src/v1.rs | Adds AWS NitroTPM platform evidence variant. |
| dstack/dstack-attest/src/lib.rs | Extends measured-event emission to TPM PCRs (sha256/sha384) and adds PCR8 measure helper. |
| dstack/dstack-attest/src/aws_nitro_tpm.rs | Implements NitroTPM vendor-command flow to obtain attestation documents. |
| dstack/dstack-attest/src/attestation.rs | Adds AWS NitroTPM mode, quote/report verification, and MR derivation from PCRs. |
| dstack/dstack-attest/Cargo.toml | Adds AWS NitroTPM dependencies under quote feature. |
| dstack/Cargo.lock | Locks new dependencies for AWS NitroTPM functionality. |
| docs/verification.md | Adds platform-specific verification guidance including AWS NitroTPM. |
| docs/tutorials/attestation-verification.md | Clarifies TDX-specific flow and documents platform differences incl. AWS. |
| docs/security/security-model.md | Updates security model and measurement semantics for AWS NitroTPM mode. |
| docs/security/cvm-boundaries.md | Documents TPM key provider constraints and AWS measurement lane semantics. |
| docs/quickstart.md | Extends quickstart to include AWS NitroTPM option and config example. |
| docs/aws-ec2-production-verifier-runbook.md | New runbook for AWS EC2 NitroTPM production verification and ops. |
| docs/aws-attested-instance-security-evaluation.md | New AWS NitroTPM threat-model security evaluation document. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot resolve the merge conflicts in this pull request |
…tform-spec # Conflicts: # dstack/dstack-types/src/lib.rs
Resolved. The only true conflict was in
All other changes from master merged cleanly (tee-simulator, VMM networking, Cargo.lock, etc.). Merge commit: |
Summary
Adds the complete AWS EC2 NitroTPM platform path under the account-admin-untrusted threat model. This PR now combines the former dstack#753 implementation with the Yocto image changes from Dstack-TEE/meta-dstack#79.
Attestation and key release
Guest OS
dstack-awsYocto kernel feature with built-in NVMe, ENA, UEFI/GPT, serial-console, and TPM CRB support;tpm2-tssto the dstack guest recipe build dependencies;os/yocto/tools/aws/and formal documentation underdocs/.Operations and documentation
--repo) rather than separate dstack/meta-dstack checkouts.Validation
cargo test -p dstack-attest aws_nitro_tpmcargo test -p dstack-kms aws_nitro_tpmcargo test -p dstack-verifier awscargo test -p dstack-guest-agent -p dstack-guest-agent-simulator -p ra-tls -p tpm-attest -p tpm-qvlnpm run test:runandnpm run lintindstack/kms/auth-simplebash -n/shellcheckthroughprek run --all-filesreuse lintforge test --ffiwas not rerun locally because Foundry is not installed in this environment; CI covers the Foundry suite.