Rust workspace for TEE attestation libraries, tools, and services.
| Package | Path | Description |
|---|---|---|
attestation |
crates/attestation |
Core TEE attestation evidence generation and verification library |
attestation-cli |
crates/attestation-cli |
CLI for generating and verifying attestation evidence |
attestation-api |
crates/attestation-api |
REST API service wrapping the attestation library |
attestation-wasm |
crates/attestation-wasm |
WASM verification harness |
cargo fmt --all -- --check
cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspaceBuild the CLI with guest-side attestation support:
cargo build -p attestation-cli --release --features attestBuild the REST service:
cargo build -p attestation-api --release
docker build .The service image is published as ghcr.io/confidential-dot-ai/attestation-api.
attestation-wasm compiles the SNP verification path to WebAssembly so evidence
can be verified entirely client-side. To produce a blob usable in a browser, build
with the web target (this requires wasm-pack):
cd crates/attestation-wasm
wasm-pack build --target web --releaseThis writes an ES module and the .wasm binary to pkg/:
pkg/attestation_wasm.js— JS bindings and theinitloaderpkg/attestation_wasm_bg.wasm— the WASM blob
Serve pkg/ over HTTP (browsers won't load WASM from file://) and use it from a
module script:
<script type="module">
import init, { verify_snp } from './pkg/attestation_wasm.js';
await init(); // fetches and instantiates the .wasm blob
// evidence: SNP evidence JSON with an inline cert_chain.vcek (base64 DER)
// generation: "milan" | "genoa" | "turin"
// expectedReportData (optional): Uint8Array of the nonce to bind against
const resultJson = verify_snp(
JSON.stringify(evidence),
'genoa',
new TextEncoder().encode('my-nonce'),
);
console.log(JSON.parse(resultJson));
</script>The module also exports verify_az_snp for full Azure SEV-SNP (vTPM)
verification. Unlike verify_snp, which checks only the bare SNP hardware report,
it verifies the HCL-wrapped report and the vTPM quote — the TPM signature against
the attestation key (AK) in the HCL runtime data, the AK→TEE binding, and the
freshness anchor in the quote's extraData (not the SNP report_data). The
processor generation is auto-detected from the report CPUID, so no generation
argument is needed:
import init, { verify_az_snp } from './pkg/attestation_wasm.js';
await init();
// evidence: AzSnpEvidence JSON { version, tpm_quote, hcl_report, vcek }
// expectedReportData (optional): Uint8Array the quote's extraData must equal
const resultJson = verify_az_snp(JSON.stringify(evidence), expectedReportData);It returns the same result shape as verify_snp with platform: "az-snp". The
WASM path skips the async CRL revocation check (collateral_verified: false); the
native async az_snp::verify::verify_evidence adds it via a CertProvider.
For a Node.js end-to-end example (generate live evidence, fetch the VCEK from AMD
KDS, verify in WASM), build with --target nodejs and run
crates/attestation-wasm/example.mjs.
- Core library:
crates/attestation/README.md - REST service:
crates/attestation-api/README.md