From 27cc12d7f391a76b4a31fe6aa79ce91d382e849c Mon Sep 17 00:00:00 2001 From: Kevin Wang Date: Tue, 21 Jul 2026 18:57:12 -0700 Subject: [PATCH] refactor(api): rename attestation mode to tee variant --- docs/aws-ec2-production-verifier-runbook.md | 8 ++++---- dstack/crates/dstack-auth/src/main.rs | 2 +- dstack/dstack-attest/src/attestation.rs | 20 +++++++++---------- dstack/dstack-util/src/main.rs | 4 ++-- dstack/kms/auth-simple/README.md | 2 +- dstack/kms/auth-simple/index.test.ts | 4 ++-- dstack/kms/auth-simple/index.ts | 2 +- dstack/kms/rpc/proto/kms_rpc.proto | 4 ++-- dstack/kms/src/main_service.rs | 14 ++++++------- dstack/kms/src/main_service/amd_attest.rs | 4 ++-- .../kms/src/main_service/upgrade_authority.rs | 4 ++-- dstack/kms/src/onboard_service.rs | 10 +++++----- dstack/kms/src/www/onboard.html | 4 ++-- dstack/tests/docs/kms-self-authorization.md | 2 +- dstack/verifier/README.md | 10 +++++----- dstack/verifier/src/main.rs | 2 +- dstack/verifier/src/types.rs | 12 +++++------ dstack/verifier/src/verification.rs | 15 +++++++++----- 18 files changed, 64 insertions(+), 59 deletions(-) diff --git a/docs/aws-ec2-production-verifier-runbook.md b/docs/aws-ec2-production-verifier-runbook.md index 77e6098cb..5b9f4ab98 100644 --- a/docs/aws-ec2-production-verifier-runbook.md +++ b/docs/aws-ec2-production-verifier-runbook.md @@ -181,7 +181,7 @@ jq -e \ .is_valid == true and .details.quote_verified == true and .details.report_data == $expected_report_data and - .details.boot_info.attestationMode == "dstack-aws-nitro-tpm" and + .details.boot_info.teeVariant == "dstack-aws-nitro-tpm" and .details.boot_info.tcbStatus == "UpToDate" and .details.boot_info.osImageHash == $expected_os_image_hash ' request.json.verification.json @@ -226,9 +226,9 @@ key_provider_id })` and compare it to PCR8. dstack's own verifier and KMS do **not** check PCR8 — they rely on PCR14 replay — so it is not part of the required policy above. -The `attestationMode` field is carried in the verified boot info for +The `teeVariant` field is carried in the verified boot info for observability; a relying party may additionally assert -`attestationMode == "dstack-aws-nitro-tpm"` against the verifier output, but the +`teeVariant == "dstack-aws-nitro-tpm"` against the verifier output, but the authorization contract itself keys on the standard fields above. Same-account AWS KMS is not a trusted secret authority in this threat model if @@ -261,7 +261,7 @@ Require the generated `endpoint-cert.pem.ratls-verification.json` to contain: ```bash jq -e ' .is_valid == true and - .details.attestation_mode == "dstack-aws-nitro-tpm" and + .details.tee_variant == "dstack-aws-nitro-tpm" and .details.app_info.os_image_hash_verified == true ' endpoint-cert.pem.ratls-verification.json ``` diff --git a/dstack/crates/dstack-auth/src/main.rs b/dstack/crates/dstack-auth/src/main.rs index 217d92947..2a752e4b0 100644 --- a/dstack/crates/dstack-auth/src/main.rs +++ b/dstack/crates/dstack-auth/src/main.rs @@ -291,7 +291,7 @@ mod tests { #[test] fn deserializes_the_kms_bootinfo_wire_contract() { let wire = r#"{ - "attestationMode": "dstack", + "teeVariant": "dstack", "mrAggregated": "0xAABB", "osImageHash": "0xC2AA", "mrSystem": "0xdead", diff --git a/dstack/dstack-attest/src/attestation.rs b/dstack/dstack-attest/src/attestation.rs index 1ba9a435b..7e75d0ba6 100644 --- a/dstack/dstack-attest/src/attestation.rs +++ b/dstack/dstack-attest/src/attestation.rs @@ -450,7 +450,7 @@ fn has_sev_snp_tsm_provider() -> bool { false } -fn choose_dstack_attestation_mode(has_tdx: bool, has_sev_snp: bool) -> Result { +fn choose_dstack_tee_variant(has_tdx: bool, has_sev_snp: bool) -> Result { if has_tdx { return Ok(TeeVariant::DstackTdx); } @@ -468,7 +468,7 @@ pub fn detect_tee_variant() -> Result { // First, try to detect platform from DMI product name let platform = Platform::detect_or_dstack(); match platform { - Platform::Dstack => choose_dstack_attestation_mode(has_tdx, has_sev_snp), + Platform::Dstack => choose_dstack_tee_variant(has_tdx, has_sev_snp), Platform::Gcp => { // GCP platform: TDX + TPM dual mode if has_tdx { @@ -1286,7 +1286,7 @@ pub enum AttestationQuote { } impl AttestationQuote { - pub fn mode(&self) -> TeeVariant { + pub fn variant(&self) -> TeeVariant { match self { AttestationQuote::DstackTdx(_) => TeeVariant::DstackTdx, AttestationQuote::DstackAmdSevSnp(_) => TeeVariant::DstackAmdSevSnp, @@ -1303,7 +1303,7 @@ mod compatibility_tests { use scale::Encode; #[test] - fn attestation_mode_scale_discriminants_preserve_existing_wire_values() { + fn tee_variant_scale_discriminants_preserve_existing_wire_values() { assert_eq!(TeeVariant::DstackTdx.encode(), vec![0]); assert_eq!(TeeVariant::DstackGcpTdx.encode(), vec![1]); assert_eq!(TeeVariant::DstackNitroEnclave.encode(), vec![2]); @@ -1312,7 +1312,7 @@ mod compatibility_tests { } #[test] - fn attestation_mode_deserializes_canonical_names() { + fn tee_variant_deserializes_canonical_names() { let parse = |value| serde_json::from_str::(value).unwrap(); assert_eq!(parse(r#""dstack-tdx""#), TeeVariant::DstackTdx); assert_eq!(parse(r#""dstack-gcp-tdx""#), TeeVariant::DstackGcpTdx); @@ -1360,17 +1360,17 @@ mod compatibility_tests { } #[test] - fn dstack_attestation_mode_prefers_tdx_when_both_tdx_and_tsm_exist() { + fn dstack_tee_variant_prefers_tdx_when_both_tdx_and_tsm_exist() { assert_eq!( - choose_dstack_attestation_mode(true, true).unwrap(), + choose_dstack_tee_variant(true, true).unwrap(), TeeVariant::DstackTdx ); } #[test] - fn dstack_attestation_mode_uses_snp_when_only_snp_exists() { + fn dstack_tee_variant_uses_snp_when_only_snp_exists() { assert_eq!( - choose_dstack_attestation_mode(false, true).unwrap(), + choose_dstack_tee_variant(false, true).unwrap(), TeeVariant::DstackAmdSevSnp ); } @@ -2365,7 +2365,7 @@ impl Attestation { let report = verifier.gcp_tpm.fetch_and_verify(quote).await?; let pcr_ind = self .quote - .mode() + .variant() .tpm_event_pcr_and_bank() .map(|(pcr, _)| pcr) .context("Failed to get event PCR no")?; diff --git a/dstack/dstack-util/src/main.rs b/dstack/dstack-util/src/main.rs index a61a0a1f6..9c16465fe 100644 --- a/dstack/dstack-util/src/main.rs +++ b/dstack/dstack-util/src/main.rs @@ -450,7 +450,7 @@ fn cmd_attest_info(args: AttestInfoArgs) -> Result<()> { match attestation { VersionedAttestation::V0 { attestation } => { println!("version: V0"); - println!("mode: {:?}", attestation.quote.mode()); + println!("mode: {:?}", attestation.quote.variant()); println!("config_bytes: {}", attestation.config.len()); match attestation.tdx_quote() { Some(tdx) => { @@ -495,7 +495,7 @@ fn cmd_attest_json(args: AttestJsonArgs) -> Result<()> { let json = match attestation { VersionedAttestation::V0 { attestation } => { - let mode = attestation.quote.mode().as_str(); + let mode = attestation.quote.variant().as_str(); let tdx_quote = match attestation.tdx_quote() { Some(tdx) => serde_json::json!({ "quote": hex::encode(&tdx.quote), diff --git a/dstack/kms/auth-simple/README.md b/dstack/kms/auth-simple/README.md index f7c826e8f..6857122d1 100644 --- a/dstack/kms/auth-simple/README.md +++ b/dstack/kms/auth-simple/README.md @@ -171,7 +171,7 @@ App boot authorization. **Request:** ```json { - "attestationMode": "dstack-tdx", + "teeVariant": "dstack-tdx", "mrAggregated": "0x...", "osImageHash": "0x...", "appId": "0x...", diff --git a/dstack/kms/auth-simple/index.test.ts b/dstack/kms/auth-simple/index.test.ts index 0d5da07d0..32ad06772 100644 --- a/dstack/kms/auth-simple/index.test.ts +++ b/dstack/kms/auth-simple/index.test.ts @@ -9,7 +9,7 @@ import app from './index'; const TEST_CONFIG_PATH = './test-auth-config.json'; const baseBootInfo = { - attestationMode: 'dstack-tdx', + teeVariant: 'dstack-tdx', mrAggregated: '0xabc123', osImageHash: '0x1fbb0cf9cc6cfbf23d6b779776fabad2c5403d643badb9e5e238615e4960a78a', appId: '0xapp123', @@ -106,7 +106,7 @@ describe('auth-simple', () => { const sevSnpBootInfo = { ...baseBootInfo, - attestationMode: 'dstack-amd-sev-snp', + teeVariant: 'dstack-amd-sev-snp', tcbStatus: 'OutOfDate' }; const denied = await app.fetch(new Request('http://localhost/bootAuth/kms', { diff --git a/dstack/kms/auth-simple/index.ts b/dstack/kms/auth-simple/index.ts index b8d8c86c2..4a833d1ec 100644 --- a/dstack/kms/auth-simple/index.ts +++ b/dstack/kms/auth-simple/index.ts @@ -9,7 +9,7 @@ import { readFileSync, existsSync } from 'fs'; // zod schemas for validation - compatible with auth-eth implementation const BootInfoSchema = z.object({ - attestationMode: z.string().optional().default(''), + teeVariant: z.string().optional().default(''), mrAggregated: z.string().describe('aggregated MR measurement'), osImageHash: z.string().describe('OS Image hash'), appId: z.string().describe('application ID'), diff --git a/dstack/kms/rpc/proto/kms_rpc.proto b/dstack/kms/rpc/proto/kms_rpc.proto index cb135da38..de44e28a0 100644 --- a/dstack/kms/rpc/proto/kms_rpc.proto +++ b/dstack/kms/rpc/proto/kms_rpc.proto @@ -149,8 +149,8 @@ message AttestationInfoResponse { bytes mr_aggregated = 2; // OS image hash bytes os_image_hash = 3; - // Attestation mode (e.g. "dstack-tdx", "dstack-gcp-tdx") - string attestation_mode = 4; + // TEE variant (e.g. "dstack-tdx", "dstack-gcp-tdx") + string tee_variant = 4; // Custom site name for display string site_name = 5; // Ethereum RPC URL from auth API diff --git a/dstack/kms/src/main_service.rs b/dstack/kms/src/main_service.rs index bf2618924..df51d48c0 100644 --- a/dstack/kms/src/main_service.rs +++ b/dstack/kms/src/main_service.rs @@ -216,7 +216,7 @@ fn ensure_key_release_allowed( snp_enabled: bool, aws_nitro_tpm_enabled: bool, ) -> Result<()> { - match boot_info.attestation_mode { + match boot_info.tee_variant { TeeVariant::DstackAmdSevSnp if !snp_enabled => { bail!("amd sev-snp key release is not enabled") } @@ -320,7 +320,7 @@ impl RpcHandler { // SNP rootfs/app/config binding is handled by the SNP launch-measurement // helper above. The legacy OS-image verifier is TDX-oriented and still // rejects SNP quotes; keep SNP on the explicit fail-closed helper path. - if boot_info.attestation_mode != TeeVariant::DstackAmdSevSnp { + if boot_info.tee_variant != TeeVariant::DstackAmdSevSnp { self.verify_os_image_hash(vm_config_str.into(), att) .await .context("Failed to verify os image hash")?; @@ -875,7 +875,7 @@ mod tests { .expect("aws nitrotpm attestation should produce KMS boot info"); let pcrs = verified_aws_nitro_tpm_pcrs(&attestation); - assert_eq!(boot_info.attestation_mode, TeeVariant::DstackAwsNitroTpm); + assert_eq!(boot_info.tee_variant, TeeVariant::DstackAwsNitroTpm); assert_eq!(boot_info.tcb_status, "UpToDate"); assert!(boot_info.advisory_ids.is_empty()); assert_eq!(boot_info.app_id, vec![0x11; 20]); @@ -930,7 +930,7 @@ mod tests { ensure_key_release_allowed(&boot_info, false, true).unwrap(); // A TDX boot info is unaffected by the AWS gate even when it is disabled. - boot_info.attestation_mode = TeeVariant::DstackTdx; + boot_info.tee_variant = TeeVariant::DstackTdx; ensure_key_release_allowed(&boot_info, false, false).unwrap(); } @@ -1023,7 +1023,7 @@ mod tests { let boot_info = build_boot_info_for_attestation(&attestation, false, &vm_config) .expect("snp attestation should build boot info through vm_config path"); - assert_eq!(boot_info.attestation_mode, TeeVariant::DstackAmdSevSnp); + assert_eq!(boot_info.tee_variant, TeeVariant::DstackAmdSevSnp); assert_eq!(boot_info.mr_aggregated.len(), 32); assert_eq!(boot_info.device_id, vec![0xab; 64]); assert_eq!(boot_info.app_id, vec![0x11; 20]); @@ -1045,7 +1045,7 @@ mod tests { let boot_info = build_boot_info_for_attestation(&attestation, false, "") .expect("snp local KMS attestation should use embedded vm_config"); - assert_eq!(boot_info.attestation_mode, TeeVariant::DstackAmdSevSnp); + assert_eq!(boot_info.tee_variant, TeeVariant::DstackAmdSevSnp); assert_eq!(boot_info.mr_aggregated.len(), 32); assert_eq!(boot_info.app_id, vec![0x11; 20]); } @@ -1060,7 +1060,7 @@ mod tests { let boot_info = build_boot_info_for_attestation(&attestation, false, &vm_config) .expect("self-contained SNP vm_config should not require KMS-local sev_snp config"); - assert_eq!(boot_info.attestation_mode, TeeVariant::DstackAmdSevSnp); + assert_eq!(boot_info.tee_variant, TeeVariant::DstackAmdSevSnp); assert_eq!(boot_info.device_id, vec![0xab; 64]); } diff --git a/dstack/kms/src/main_service/amd_attest.rs b/dstack/kms/src/main_service/amd_attest.rs index b629113bd..59387c895 100644 --- a/dstack/kms/src/main_service/amd_attest.rs +++ b/dstack/kms/src/main_service/amd_attest.rs @@ -109,7 +109,7 @@ fn build_amd_snp_boot_info_with_tcb_status( let key_provider_info = mr_config_key_provider_info(&mr_config)?; Ok(BootInfo { - attestation_mode: TeeVariant::DstackAmdSevSnp, + tee_variant: TeeVariant::DstackAmdSevSnp, mr_aggregated, os_image_hash: os_image_hash.to_vec(), mr_system, @@ -366,7 +366,7 @@ mod tests { let boot_info = build_amd_snp_boot_info(&verified, &chip_id, &input) .expect("matching measurement should build snp boot info"); - assert_eq!(boot_info.attestation_mode, TeeVariant::DstackAmdSevSnp); + assert_eq!(boot_info.tee_variant, TeeVariant::DstackAmdSevSnp); assert_eq!(boot_info.mr_aggregated.len(), 32); assert_eq!(boot_info.device_id, chip_id.to_vec()); assert_eq!(boot_info.app_id, vec![0x11; 20]); diff --git a/dstack/kms/src/main_service/upgrade_authority.rs b/dstack/kms/src/main_service/upgrade_authority.rs index 6c3bcd4c3..bb63df6b5 100644 --- a/dstack/kms/src/main_service/upgrade_authority.rs +++ b/dstack/kms/src/main_service/upgrade_authority.rs @@ -23,12 +23,12 @@ pub(crate) fn build_boot_info( use_boottime_mr: bool, vm_config_str: &str, ) -> Result { - let mode = att.quote.mode(); + let variant = att.quote.variant(); let (tcb_status, advisory_ids) = dstack_verifier::policy_tcb_fields(att); let app_info = att.decode_app_info_ex(use_boottime_mr, vm_config_str)?; ensure_app_id_len(&app_info.app_id)?; Ok(BootInfo { - attestation_mode: mode, + tee_variant: variant, mr_aggregated: app_info.mr_aggregated.to_vec(), os_image_hash: app_info.os_image_hash, mr_system: app_info.mr_system.to_vec(), diff --git a/dstack/kms/src/onboard_service.rs b/dstack/kms/src/onboard_service.rs index 4fa65b761..8734d151d 100644 --- a/dstack/kms/src/onboard_service.rs +++ b/dstack/kms/src/onboard_service.rs @@ -127,7 +127,7 @@ impl OnboardRpc for OnboardHandler { // Decode and verify the attestation to get real device ID let attestation = VersionedAttestation::from_bytes(&response.attestation) .context("Failed to decode attestation")?; - let attestation_mode = match &attestation.clone().into_v1().platform { + let tee_variant = match &attestation.clone().into_v1().platform { PlatformEvidence::Tdx { .. } => "dstack-tdx", PlatformEvidence::SevSnp { .. } => "dstack-amd-sev-snp", PlatformEvidence::GcpTdx { .. } => "dstack-gcp-tdx", @@ -161,7 +161,7 @@ impl OnboardRpc for OnboardHandler { build_attestation_info_response( &verified, - attestation_mode, + tee_variant, &info.vm_config, self.state.config.site_name.clone(), eth_rpc_url, @@ -176,7 +176,7 @@ impl OnboardRpc for OnboardHandler { fn build_attestation_info_response( verified: &VerifiedAttestation, - attestation_mode: String, + tee_variant: String, vm_config: &str, site_name: String, eth_rpc_url: String, @@ -189,7 +189,7 @@ fn build_attestation_info_response( device_id: sha2::Sha256::digest(&raw_device_id).to_vec(), mr_aggregated: boot_info.mr_aggregated, os_image_hash: boot_info.os_image_hash, - attestation_mode, + tee_variant, site_name, eth_rpc_url, kms_contract_address, @@ -336,7 +336,7 @@ mod tests { assert_eq!(response.ppid, vec![0xab; 64]); assert_eq!(response.mr_aggregated.len(), 32); assert_eq!(response.os_image_hash, os_image_hash.to_vec()); - assert_eq!(response.attestation_mode, "dstack-amd-sev-snp"); + assert_eq!(response.tee_variant, "dstack-amd-sev-snp"); assert_eq!(response.site_name, "test-site"); assert_eq!(response.eth_rpc_url, "https://rpc.example"); assert_eq!(response.kms_contract_address, "0x1234"); diff --git a/dstack/kms/src/www/onboard.html b/dstack/kms/src/www/onboard.html index 9f28784ca..a2bc75552 100644 --- a/dstack/kms/src/www/onboard.html +++ b/dstack/kms/src/www/onboard.html @@ -174,8 +174,8 @@

{{ siteName || 'dstack KMS Setup' }}

Attestation Info (for on-chain registration)

- Attestation Mode: - {{ attestationInfo.attestation_mode }} + TEE Variant: + {{ attestationInfo.tee_variant }}
PPID: diff --git a/dstack/tests/docs/kms-self-authorization.md b/dstack/tests/docs/kms-self-authorization.md index fbde050e9..d9e365fd9 100644 --- a/dstack/tests/docs/kms-self-authorization.md +++ b/dstack/tests/docs/kms-self-authorization.md @@ -293,7 +293,7 @@ Expected fields: - `device_id` - `mr_aggregated` - `os_image_hash` -- `attestation_mode` +- `tee_variant` Extract values: diff --git a/dstack/verifier/README.md b/dstack/verifier/README.md index dff564d66..58272d7af 100644 --- a/dstack/verifier/README.md +++ b/dstack/verifier/README.md @@ -40,7 +40,7 @@ against the returned evidence. "acpi_tables_verified": true, // true only when TDX ACPI table contents are verified "os_image_is_dev": false, // true=dev image, false=prod, null=unknown/N/A "os_image_version": "0.5.10", // dstack OS version, null if unknown - "attestation_mode": "dstack-tdx", // dstack-tdx | dstack-gcp-tdx | dstack-nitro-enclave | dstack-amd-sev-snp | dstack-aws-nitro-tpm + "tee_variant": "dstack-tdx", // dstack-tdx | dstack-gcp-tdx | dstack-nitro-enclave | dstack-amd-sev-snp | dstack-aws-nitro-tpm "report_data": "hex-encoded-64-byte-report-data", "tcb_status": "UpToDate", "advisory_ids": [], @@ -61,7 +61,7 @@ against the returned evidence. "key_provider_info": "hex-string" }, "boot_info": { - "attestationMode": "dstack-aws-nitro-tpm", + "teeVariant": "dstack-aws-nitro-tpm", "mrAggregated": "hex-string", "osImageHash": "hex-string", "mrSystem": "hex-string", @@ -161,7 +161,7 @@ The verification checks that: Clients, gateways, or release validators should combine this certificate-level check with the policy fields emitted by `/verify`: accepted OS image, -`attestationMode`, `mrAggregated`, app compose hash, KMS identity, a +`teeVariant`, `mrAggregated`, app compose hash, KMS identity, a `report_data` challenge, and any deployment-specific endpoint allowlist. ### Running with Docker Compose @@ -263,9 +263,9 @@ Beyond pass/fail, the result carries a few descriptive fields so a relying party - **`os_image_is_dev`** — `true` for a development OS image, `false` for production. Dev images are built for local testing and are not hardened for production use, so a relying party generally wants to reject them. - **`os_image_version`** — the dstack OS version (e.g. `0.5.10`), useful for enforcing a minimum version. -- **`attestation_mode`** — the TEE variant that produced the verified quote, serialized as `TeeVariant`: `dstack-tdx`, `dstack-gcp-tdx`, `dstack-nitro-enclave`, `dstack-amd-sev-snp`, or `dstack-aws-nitro-tpm`. +- **`tee_variant`** — the TEE variant that produced the verified quote, serialized as `TeeVariant`: `dstack-tdx`, `dstack-gcp-tdx`, `dstack-nitro-enclave`, `dstack-amd-sev-snp`, or `dstack-aws-nitro-tpm`. - **`acpi_tables_verified`** — whether TDX ACPI table contents were verified. This is useful for relying parties that require `requirements.tdx_measure_acpi_tables = true`. - **`key_provider`** — the decoded `app_info.key_provider_info` (`{name, id}`); `name` is e.g. `kms` or `local`. A `local` key provider means the CVM is not KMS-backed, which is itself a dev/insecure posture signal. The raw bytes remain in `app_info.key_provider_info`. -- **`boot_info`** — the policy object a relying party should feed to its auth/governance layer. For AWS EC2 NitroTPM this includes `attestationMode = dstack-aws-nitro-tpm`, PCR4/7/12-derived `osImageHash`, PCR14-bound `mrAggregated`, app identity, instance/device identity, and a `tcbStatus` normalized to `UpToDate`. +- **`boot_info`** — the policy object a relying party should feed to its auth/governance layer. For AWS EC2 NitroTPM this includes `teeVariant = dstack-aws-nitro-tpm`, PCR4/7/12-derived `osImageHash`, PCR14-bound `mrAggregated`, app identity, instance/device identity, and a `tcbStatus` normalized to `UpToDate`. `os_image_is_dev` and `os_image_version` are read from the image's `metadata.json`, which is part of `sha256sum.txt` and therefore bound to the `os_image_hash` that step 3 verifies against the quote — so they are as trustworthy as the os-image-hash check itself. They are `null` when the platform does not expose them (e.g. GCP TDX / Nitro Enclave) or when the image predates the field (images without `is_dev` are always production). diff --git a/dstack/verifier/src/main.rs b/dstack/verifier/src/main.rs index 90d5f603a..c8758ac99 100644 --- a/dstack/verifier/src/main.rs +++ b/dstack/verifier/src/main.rs @@ -187,7 +187,7 @@ async fn run_cert_oneshot(file_path: &str, config: &Config) -> anyhow::Result<() let output = serde_json::json!({ "is_valid": true, "details": { - "attestation_mode": verified.attestation.quote.mode(), + "tee_variant": verified.attestation.quote.variant(), "report_data": hex::encode(verified.attestation.report_data), "public_key_der": hex::encode(&verified.public_key_der), "app_id_extension": verified.app_id.as_ref().map(hex::encode), diff --git a/dstack/verifier/src/types.rs b/dstack/verifier/src/types.rs index 84cfbdecb..1d4851526 100644 --- a/dstack/verifier/src/types.rs +++ b/dstack/verifier/src/types.rs @@ -32,7 +32,7 @@ pub struct VerificationResponse { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct PolicyBootInfo { - pub attestation_mode: TeeVariant, + pub tee_variant: TeeVariant, #[serde(with = "serde_bytes")] pub mr_aggregated: Vec, #[serde(with = "serde_bytes")] @@ -55,13 +55,13 @@ pub struct PolicyBootInfo { impl PolicyBootInfo { pub fn from_app_info( - attestation_mode: TeeVariant, + tee_variant: TeeVariant, app_info: &AppInfo, tcb_status: String, advisory_ids: Vec, ) -> Self { Self { - attestation_mode, + tee_variant, mr_aggregated: app_info.mr_aggregated.to_vec(), os_image_hash: app_info.os_image_hash.clone(), mr_system: app_info.mr_system.to_vec(), @@ -99,8 +99,8 @@ pub struct VerificationDetails { pub os_image_is_dev: Option, /// dstack OS version, from the same metadata.json. pub os_image_version: Option, - /// Attestation mode that produced the verified quote. - pub attestation_mode: Option, + /// TEE variant that produced the verified quote. + pub tee_variant: Option, pub report_data: Option, pub tcb_status: Option, pub advisory_ids: Vec, @@ -213,7 +213,7 @@ mod tests { ); let encoded = serde_json::to_value(&boot_info).unwrap(); - assert_eq!(encoded["attestationMode"], "dstack-aws-nitro-tpm"); + assert_eq!(encoded["teeVariant"], "dstack-aws-nitro-tpm"); assert_eq!(encoded["tcbStatus"], ""); assert_eq!(encoded["advisoryIds"], serde_json::json!([])); assert!(encoded.get("mrAggregated").unwrap().is_string()); diff --git a/dstack/verifier/src/verification.rs b/dstack/verifier/src/verification.rs index 7a665839b..3b1e8fad7 100644 --- a/dstack/verifier/src/verification.rs +++ b/dstack/verifier/src/verification.rs @@ -61,7 +61,12 @@ fn policy_boot_info_from_verified_app_info( app_info: &AppInfo, ) -> PolicyBootInfo { let (tcb_status, advisory_ids) = policy_tcb_fields(attestation); - PolicyBootInfo::from_app_info(attestation.quote.mode(), app_info, tcb_status, advisory_ids) + PolicyBootInfo::from_app_info( + attestation.quote.variant(), + app_info, + tcb_status, + advisory_ids, + ) } /// best-effort: None for empty/malformed blobs. @@ -586,7 +591,7 @@ impl CvmVerifier { let verified_attestation = match verified { Ok(att) => { details.quote_verified = true; - details.attestation_mode = Some(att.quote.mode()); + details.tee_variant = Some(att.quote.variant()); // keep the top-level tcb_status consistent with the // boot_info.tcbStatus fed to the auth policy (notably AWS // NitroTPM, which is normalized to "UpToDate" there). @@ -1426,7 +1431,7 @@ mod tests { assert!(response.details.os_image_hash_verified); assert!(!response.details.acpi_tables_verified); assert_eq!( - response.details.attestation_mode, + response.details.tee_variant, Some(ra_tls::attestation::TeeVariant::DstackAmdSevSnp) ); assert!( @@ -1454,7 +1459,7 @@ mod tests { let response = verifier.verify(request).await.expect("verifier runs"); assert!(response.is_valid, "{:?}", response.reason); assert_eq!( - response.details.attestation_mode, + response.details.tee_variant, Some(ra_tls::attestation::TeeVariant::DstackAmdSevSnp) ); } @@ -1480,7 +1485,7 @@ mod tests { assert!(response.details.os_image_hash_verified); assert!(!response.details.acpi_tables_verified); assert_eq!( - response.details.attestation_mode, + response.details.tee_variant, Some(ra_tls::attestation::TeeVariant::DstackTdx) ); assert!(