A HTTP server that provides dstack quote verification services using the same verification process as the dstack KMS.
Verifies a dstack attestation or quote with the provided data and VM configuration. The body can be grabbed via getQuote or attest.
Request Body:
Provide either attestation or (quote + event_log + vm_config).
{
"quote": "hex-encoded-quote",
"event_log": "hex-encoded-event-log",
"vm_config": "json-vm-config-string",
}or
{
"attestation": "hex-encoded-attestation"
}For challenge-response verification, the relying party embeds its own challenge
in the certificate's report_data (or the NitroTPM nonce) and checks it
against the returned evidence.
Response:
{
"is_valid": true,
"details": {
"quote_verified": true,
"event_log_verified": true, // See "Verification Process" for semantics
"os_image_hash_verified": true,
"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
"report_data": "hex-encoded-64-byte-report-data",
"tcb_status": "UpToDate",
"advisory_ids": [],
"key_provider": { "name": "kms", "id": "hex-string" }, // decoded; null if absent
"app_info": {
"app_id": "hex-string",
"compose_hash": "hex-string",
"instance_id": "hex-string",
"device_id": "hex-string",
"mrtd": "hex-string",
"rtmr0": "hex-string",
"rtmr1": "hex-string",
"rtmr2": "hex-string",
"rtmr3": "hex-string",
"mr_system": "hex-string",
"mr_aggregated": "hex-string",
"os_image_hash": "hex-string",
"key_provider_info": "hex-string"
},
"boot_info": {
"attestationMode": "dstack-aws-nitro-tpm",
"mrAggregated": "hex-string",
"osImageHash": "hex-string",
"mrSystem": "hex-string",
"appId": "hex-string",
"composeHash": "hex-string",
"instanceId": "hex-string",
"deviceId": "hex-string",
"keyProviderInfo": "hex-string",
"tcbStatus": "UpToDate",
"advisoryIds": []
}
},
"reason": null
}Health check endpoint that returns service status.
Response:
{
"status": "ok",
"service": "dstack-verifier"
}You usually don't need to edit the config file. Just using the default is fine, unless you need to deploy your cunstomized os images.
host: Server bind address (default: "0.0.0.0")port: Server port (default: 8080)image_cache_dir: Directory for cached OS images (default: "/tmp/dstack-verifier/cache")image_download_url: URL template for downloading OS images (default: dstack official releases URL)image_download_timeout_secs: Download timeout in seconds (default: 300)pccs_url: PCCS URL for quote verification (default: uses Intel's public PCCS)
host = "0.0.0.0"
port = 8080
image_cache_dir = "/tmp/dstack-verifier/cache"
image_download_url = "https://download.dstack.org/os-images/mr_{OS_IMAGE_HASH}.tar.gz"
image_download_timeout_secs = 300
# pccs_url = "https://pccs.phala.network"# Run with default config
cargo run --bin dstack-verifier
# Run with custom config file
cargo run --bin dstack-verifier -- --config /path/to/config.toml
# Set via environment variables
DSTACK_VERIFIER_PORT=8080 cargo run --bin dstack-verifierTo bind a network endpoint to attestation, verify the endpoint's RA-TLS certificate instead of trusting DNS, load balancer identity, or a normal Web PKI certificate alone:
cargo run --bin dstack-verifier -- --verify-cert endpoint-cert.pemThe input may be PEM or DER. On success, the verifier prints JSON and writes the
same result next to the input as endpoint-cert.pem.ratls-verification.json.
The verification checks that:
- the certificate contains a dstack RA-TLS attestation extension;
- the embedded attestation verifies against the platform root, including AWS NitroTPM documents for EC2;
- the attestation
report_dataisQuoteContentType::RaTlsCert(SubjectPublicKeyInfo), so the verified attestation is bound to this exact TLS public key; and - the reported
app_info.os_image_hashis bound to the attested boot measurement, surfaced asapp_info.os_image_hash_verified. This binding is self-contained (no image download) for AWS NitroTPM, SEV-SNP, Nitro Enclave, GCP TDX, and TDX lite. It is reported asfalsefor the TDX legacy full-image path, which needs an image download that this cert mode does not perform — use/verifyfor that path. Only trustos_image_hashwhenos_image_hash_verifiedistrue.
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
report_data challenge, and any deployment-specific endpoint allowlist.
services:
dstack-verifier:
image: dstacktee/dstack-verifier:latest
ports:
- "8080:8080"
restart: unless-stoppedSave the docker compose file as docker-compose.yml and run docker compose up -d.
Grab an attestation or quote from your app. It's depends on your app how to grab it.
# Grab an attestation from the demo app
curl https://712eab2f507b963e11144ae67218177e93ac2a24-3000.test0.dstack.org:12004/Attest?report_data=0x1234 -o attest.jsonSend the attestation to the verifier.
$ curl -s -d @attest.json localhost:8080/verify | jq# Grab a quote from the demo app
curl https://712eab2f507b963e11144ae67218177e93ac2a24-3000.test0.dstack.org:12004/GetQuote?report_data=0x1234 -o quote.json
Send the quote to the verifier.
$ curl -s -d @quote.json localhost:8080/verify | jq
{
"is_valid": true,
"details": {
"quote_verified": true,
"event_log_verified": true,
"os_image_hash_verified": true,
"acpi_tables_verified": true,
"report_data": "12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"tcb_status": "UpToDate",
"advisory_ids": [],
"app_info": {
"app_id": "e631a04a5d068c0e5ffd8ca60d6574ac99a18bda",
"compose_hash": "e631a04a5d068c0e5ffd8ca60d6574ac99a18bdaf0417d129d0c4ac52244d40f",
"instance_id": "712eab2f507b963e11144ae67218177e93ac2a24",
"device_id": "ee218f44a5f0a9c3233f9cc09f0cd41518f376478127feb989d5cf1292c56a01",
"mrtd": "f06dfda6dce1cf904d4e2bab1dc370634cf95cefa2ceb2de2eee127c9382698090d7a4a13e14c536ec6c9c3c8fa87077",
"rtmr0": "68102e7b524af310f7b7d426ce75481e36c40f5d513a9009c046e9d37e31551f0134d954b496a3357fd61d03f07ffe96",
"rtmr1": "a7b523278d4f914ee8df0ec80cd1c3d498cbf1152b0c5eaf65bad9425072874a3fcf891e8b01713d3d9937e3e0d26c15",
"rtmr2": "dbf4924c07f5066f3dc6859844184344306aa3263817153dcaee85af97d23e0c0b96efe0731d8865a8747e51b9e351ac",
"rtmr3": "5e7d8d84317343d28d73031d0be3c75f25facb1b20c9835a44582b8b0115de1acfe2d19350437dbd63846bcc5d7bf328",
"mr_system": "145010fa227e6c2537ad957c64e4a8486fcbfd8265ddfb359168b59afcff1d05",
"mr_aggregated": "52f6d7ccbee1bfa870709e8ff489e016e2e5c25a157b7e22ef1ea68fce763694",
"os_image_hash": "b6420818b356b198bdd70f076079aa0299a20279b87ab33ada7b2770ef432a5a",
"key_provider_info": "7b226e616d65223a226b6d73222c226964223a223330353933303133303630373261383634386365336430323031303630383261383634386365336430333031303730333432303030343139623234353764643962386161363434366439383066313336666666373831326563643663373737343065656230653238623130643536633063303030323861356236653539646365613330376435383362643166373037363965396331313664663262636662313735386139356438363133653764653163383438326330227d"
}
},
"reason": null
}The verifier performs the following verification steps:
- Quote Verification: Validates the platform quote using the platform verifier: DCAP for TDX, AMD SNP report verification for SEV-SNP, NSM for Nitro Enclaves, and AWS NitroTPM attestation-document verification for EC2 NitroTPM.
- Event Log Verification: Replays event logs to ensure RTMR/PCR values match and extracts app information. For RTMR3 and AWS NitroTPM PCR14 launch measurements, both the digest and payload integrity are verified. For TDX RTMR 0-2 boot-time measurements, only the digests are verified; the payload content is not validated as dstack does not define semantics for these payloads.
- OS Image Hash Verification:
- Treats
vm_configand any attached measurement material as untrusted inputs until they are bound to the hardware quote - For the full-image TDX path, downloads or loads the image identified by
os_image_hash, checks the image checksum manifest, uses dstack-mr to compute expected MRTD/RTMR0-2, and compares them against the verified measurements from the quote - For TDX lite, AMD SEV-SNP, and GCP TDX, verifies that
os_image_hash = sha256(sha256sum.txt), wheresha256sum.txtis the image build's checksum manifest (<sha256> <relative-file-name>lines for image files), that the manifest entry formeasurement.tdx.cbor,measurement.snp.cbor, ormeasurement.gcp.cbormatches the supplied measurement material, and that the measurement material replays to the quote's hardware-signed measurements or GCP TPM UKI event - For AWS NitroTPM, requires
vm_config.aws_measurementand verifies thatos_image_hash = sha256(sha256sum.txt)matches the measurement material and that itsboot_pcr_digest = sha256(PCR4 || PCR7 || PCR12)matches the attested boot PCRs
- Treats
- Policy Input Construction: Emits
details.boot_info, the canonical auth-policy payload shape used by dstack KMS/bootAuth/appand/bootAuth/kms. This object is only present on successful verification. - Endpoint Certificate Verification: In
--verify-certmode, verifies the dstack RA-TLS certificate extension and checks that the attestationreport_datais bound to the certificate SubjectPublicKeyInfo. This is the production path for preventing an admin-controlled DNS/LB/proxy endpoint from impersonating an attested workload with a different TLS key. It also bindsapp_info.os_image_hashto the attested boot measurement and reports the result asapp_info.os_image_hash_verified(self-contained for all platforms except the TDX legacy full-image path, which reportsfalse).
details.acpi_tables_verified is true only for the full-image TDX path, where the verifier recomputes ACPI table contents and checks the resulting RTMRs against the quote. It is false for TDX lite, which uses the quote's named ACPI DATA digests without validating table contents, and for non-TDX platforms where ACPI table verification is not applicable.
All verification steps must pass for the verification to be considered valid.
Beyond pass/fail, the result carries a few descriptive fields so a relying party can apply its own policy:
os_image_is_dev—truefor a development OS image,falsefor 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 attestation mode that produced the verified quote, serialized asAttestationMode:dstack-tdx,dstack-gcp-tdx,dstack-nitro-enclave,dstack-amd-sev-snp, ordstack-aws-nitro-tpm.acpi_tables_verified— whether TDX ACPI table contents were verified. This is useful for relying parties that requirerequirements.tdx_measure_acpi_tables = true.key_provider— the decodedapp_info.key_provider_info({name, id});nameis e.g.kmsorlocal. Alocalkey provider means the CVM is not KMS-backed, which is itself a dev/insecure posture signal. The raw bytes remain inapp_info.key_provider_info.boot_info— the policy object a relying party should feed to its auth/governance layer. For AWS EC2 NitroTPM this includesattestationMode = dstack-aws-nitro-tpm, PCR4/7/12-derivedosImageHash, PCR14-boundmrAggregated, app identity, instance/device identity, and atcbStatusnormalized toUpToDate.
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).