open-standards/sandbox/sandbox-rs/crates/sandbox-cli/src/main.rs
Transaction Science 9caa8dcf13
All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 16s
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 1m45s
standards workspaces build + test / jcp-rs (jcp-conformance, jcp/jcp-rs, -p jcp-energy --features nvml, jcp-rs, linux) (pull_request) Successful in 1m46s
standards workspaces build + test / joule-ui-rs (joule-ui/joule-ui-rs, joule-ui-rs, linux) (pull_request) Successful in 1m15s
standards workspaces build + test / proof-rs (proof-conformance, proof/proof-rs, proof-rs, linux, true) (pull_request) Successful in 1m41s
standards workspaces build + test / sandbox-rs (sandbox-conformance, sandbox/sandbox-rs, sandbox-rs, linux) (pull_request) Successful in 2m43s
standards workspaces build + test / joulecontract-rs (joulecontract/joulecontract-rs, joulecontract-rs, linux-arm64, true) (pull_request) Successful in 2m39s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 4m38s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 13m15s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 4m41s
sandbox: TDX on the run path, through a pinned PCK
The run path sealed and verified SEV-SNP only: TeeConfig held a VCEK and
both seal and verify_run_evidence called verify_snp, so a TDX guest could
not run a confidential unit. Wiring TDX in exposed a soundness gap first.
verify_tdx took the PCK key from the quote's own certification data and
checked the QE report against it, so any quote that was consistent with
itself, endorsed by a key its maker generated, verified.

sandbox-tee:
- verify_tdx takes the PCK key the verifier pinned (from Intel's PCS, its
  chain checked, as a VCEK comes from AMD's KDS); the quote must carry that
  key, and the QE report is checked against it.
- TeeAnchor { SevSnp(vcek), Tdx(pck) } and verify_report dispatch on it.
- LocalTdxProvider: a software-grounded TDX provider (real ECDSA-P256, dev
  keys, Grounding::Software), the TDX counterpart of LocalSnpProvider; the
  test-only quote builder becomes the crate-visible local_quote.
- ConfigfsTsmProvider is no longer hard-coded to SEV-SNP: for_kind(kind),
  and a report is refused when the kernel's `provider` attribute names
  another platform (tsm_provider_kind: sev_guest, tdx_guest).

sandbox-runtime:
- TeeConfig.anchor replaces TeeConfig.vcek. Sealing refuses a provider and
  anchor of different kinds, then verifies through verify_report.
- verify_run_evidence takes the verifier's anchor and refuses evidence of
  another kind.
sandbox-cli is updated to the anchor.

SPEC §7.6: the anchor rule (a report is trusted through a key the verifier
pins, never one it carries) and the TDX PCK rule. The §9 readiness row is
updated.

Tests:
- A quote endorsed by its own PCK is refused.
- A local TDX quote verifies against its PCK.
- TSM provider names map to kinds.
- A report of another platform kind is refused.
- A confidential run on TDX is sealed and verified, and refused for another
  challenge, outcome, PCK or kind.
- A provider and anchor of different kinds cannot seal.
Mutation testing: 10 mutants; 9 killed, 1 equivalent (checking the QE
report with the quote's PCK once it is pinned equal).

Verified on the build host: sandbox-rs 427 tests (--locked), sandbox-tee
with amd-kds, and every conformance class; clippy -D warnings clean on
sandbox-tee, -runtime, -cli. Repo checks pass, including lockfiles.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 12:44:36 -04:00

465 lines
18 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! `sandbox` — the reference checker/runner for the Sandbox standard.
//!
//! Subcommands:
//! sandbox conformance run the C1–C5 conformance pack (SPEC §10)
//! sandbox demo seal an illustrative heterogeneous (CPU+GPU) run and
//! print its ids
//! sandbox run-wasm execute a real WASM unit at tier S2, metered
//! sandbox confidential seal illustrative S6 (TEE) and S7 (sovereign) runs
//! sandbox version print the spec/profile versions
//!
//! **`demo` and `confidential` run no unit.** They build a run report here
//! and seal it, to show the receipt and attestation each tier produces. With
//! no work done there is nothing to read, so every energy record they seal
//! is an illustrative figure graded `Estimator`, with no measured figure
//! ([`illustrative`]) — never a hardware reading (SPEC §6.3: `HwShunt` is a
//! figure read from a hardware energy interface for that device class). With
//! no device detected, every device identity they seal is a placeholder named
//! by capability and labelled illustrative ([`illustrative_identity`]). A
//! real unit's energy, metered as it ran, is `run-wasm`'s.
use ed25519_dalek::SigningKey;
use sandbox_attest::{DeviceIdentity, Locality, Outcome};
use sandbox_capability::{ComputeGrant, Grants};
use sandbox_exec_wasm::WasmExecutor;
use sandbox_meter::{DeviceEnergy, Provenance};
use sandbox_runtime::{required_tier, Host, RunReport, TeeConfig, TierRequest, Unit};
use sandbox_schema::{ContentId, DeviceClass, Tier};
use sandbox_tee::policy::TeePolicy;
use sandbox_tee::provider::LocalSnpProvider;
fn main() {
let args: Vec<String> = std::env::args().collect();
let cmd = args.get(1).map(String::as_str).unwrap_or("help");
match cmd {
"conformance" => conformance(),
"demo" => demo(),
"run-wasm" => run_wasm(),
"confidential" => confidential(),
"version" => version(),
_ => help(),
}
}
fn conformance() {
let mut ok = true;
for (title, report) in [
("in-code:", sandbox_conformance::run()),
("file-backed:", sandbox_conformance::run_file_backed()),
] {
println!("{title}");
for r in &report.results {
let mark = if r.passed { "PASS" } else { "FAIL" };
println!(" [{mark}] {} — {}", r.class, r.detail);
}
ok &= report.ok();
}
if !ok {
std::process::exit(1);
}
}
fn version() {
println!("sandbox spec: v0.1 (draft)");
println!("receipt profile: {}", sandbox_meter::PROFILE);
println!("attestation profile: {}", sandbox_attest::PROFILE);
}
fn help() {
println!(
"sandbox — reference checker/runner for the Sandbox standard\n\n\
USAGE:\n sandbox <conformance|demo|run-wasm|version>\n\n\
conformance run the C1–C5 conformance pack (SPEC §10)\n \
demo seal an illustrative CPU+GPU run (no unit runs; its energy\n \
records are estimates) and print its receipt/attestation ids\n \
run-wasm execute a real WASM unit at tier S2, meter fuel→joules, seal + verify\n \
confidential seal illustrative S6 (TEE-attested) and S7 (sovereign) runs, verify\n \
the TEE report\n \
version print spec and profile versions"
);
}
/// Seal a confidential (S6) and a sovereign (S7) run: obtain a TEE report from
/// the software-grounded provider, verify it against policy + VCEK, embed the
/// evidence in the attestation, bind a locality, and link the run into the
/// audit chain (SPEC §2.2 S6/S7, §7.6).
fn confidential() {
let measurement = [0x11u8; 48];
let provider = LocalSnpProvider::new(measurement, 0x0708_0000_0000_0003);
let vcek = provider.vcek();
let policy = TeePolicy::sev_snp_baseline().with_measurement(measurement);
let host = Host::new(
"host-cc",
"steward.cc",
SigningKey::from_bytes(&[41u8; 32]),
SigningKey::from_bytes(&[42u8; 32]),
)
.with_tee(TeeConfig {
provider: Box::new(provider),
policy,
anchor: sandbox_tee::policy::TeeAnchor::SevSnp(vcek),
})
.with_locality(Locality {
region: "us-east-1".into(),
jurisdiction: "US".into(),
});
let (_rk, supervisor_vk) = host.verifying_keys();
let report = confidential_report;
let grants = Grants::default();
println!("Sandbox confidential — S6 (TEE) and S7 (sovereign) runs\n");
println!(" NOTE: the TEE report here is SOFTWARE-grounded (LocalSnpProvider);");
println!(" a hardware root requires SEV-SNP/TDX via configfs-tsm on real CC hardware.");
println!(" No unit runs: each run's energy record is an illustrative estimate.\n");
// S6 — confidential.
let s6 = host
.seal_run(
ContentId::of_bytes(b"unit-s6"),
ContentId::of_bytes(b"image-s6"),
&grants,
Tier::S6,
report(),
1,
[0; 8],
1_000,
2_000,
)
.expect("seal S6");
s6.attestation
.verify(&s6.attestation_sig, &supervisor_vk)
.expect("S6 attestation verifies");
let ev = s6.attestation.tee.as_ref().unwrap();
println!(" [S6] tier: {}", s6.attestation.tier.wire_tag());
println!(" TEE kind: {:?}", ev.kind);
println!(" measurement: {}…", &ev.measurement_hex[..16]);
println!(" TCB: {}", ev.tcb);
print_energy(&s6.receipt.devices);
println!(" attestation: {}", s6.attestation.content_id().unwrap());
println!(" TEE report verified against policy + VCEK ✓\n");
// S7 — sovereign.
let head_before = host.audit_head();
let s7 = host
.seal_run(
ContentId::of_bytes(b"unit-s7"),
ContentId::of_bytes(b"image-s7"),
&grants,
Tier::S7,
report(),
2,
[0; 8],
3_000,
4_000,
)
.expect("seal S7");
s7.attestation
.verify(&s7.attestation_sig, &supervisor_vk)
.expect("S7 attestation verifies");
let loc = s7.attestation.locality.as_ref().unwrap();
println!(" [S7] tier: {}", s7.attestation.tier.wire_tag());
println!(" locality: {} / {}", loc.region, loc.jurisdiction);
println!(" audit_prev: {}", s7.attestation.audit_prev.as_ref().unwrap());
print_energy(&s7.receipt.devices);
println!(" audit head: {} → {}", head_before, host.audit_head());
println!(" sovereign run bound + appended to the audit chain ✓");
}
/// Execute a real WASM unit end-to-end: the wasmtime S2 executor runs it under
/// a CPU grant, the host meters fuel→joules, then seals and verifies the
/// receipt + attestation. This exercises the full tier-minimize → execute →
/// attest path (SPEC §1.1, §1.3) against an actual guest.
fn run_wasm() {
// A unit that does bounded work, then exercises brokered host calls — a kv
// write, a journaled kv read, and a journaled clock read — and exits 0.
const UNIT_WAT: &str = r#"
(module
(import "sandbox" "kv_put" (func $put (param i32 i32 i32 i32) (result i32)))
(import "sandbox" "kv_get" (func $get (param i32 i32 i32 i32) (result i32)))
(import "sandbox" "clock_now" (func $clock (result i64)))
(import "sandbox" "storage_write" (func $sw (param i32 i32 i32 i32) (result i32)))
(import "sandbox" "storage_read" (func $sr (param i32 i32 i32 i32) (result i32)))
(memory (export "memory") 1)
(data (i32.const 0) "key")
(data (i32.const 16) "value")
(data (i32.const 32) "/work/f")
(func (export "run") (result i32)
(local $i i32) (local $acc i32)
(loop $l
(local.set $acc (i32.add (local.get $acc) (local.get $i)))
(local.set $i (i32.add (local.get $i) (i32.const 1)))
(br_if $l (i32.lt_u (local.get $i) (i32.const 50000))))
(drop (local.get $acc))
(drop (call $put (i32.const 0) (i32.const 3) (i32.const 16) (i32.const 5)))
(drop (call $get (i32.const 0) (i32.const 3) (i32.const 64) (i32.const 16)))
(drop (call $clock))
;; brokered storage: write a file then read it back (within the I/O ceiling)
(drop (call $sw (i32.const 32) (i32.const 7) (i32.const 16) (i32.const 5)))
(drop (call $sr (i32.const 32) (i32.const 7) (i32.const 64) (i32.const 16)))
(i32.const 0)))
"#;
let host = Host::new(
"host-wasm",
"steward.demo",
SigningKey::from_bytes(&[31u8; 32]),
SigningKey::from_bytes(&[32u8; 32]),
);
let (receipt_vk, supervisor_vk) = host.verifying_keys();
let executor = WasmExecutor::with_defaults().expect("wasm engine");
// Untrusted CPU-only code ⇒ tier minimizes to S2, matching the executor.
// Grant kv read/write and the clock; everything else stays denied.
let mut grants = Grants {
compute: ComputeGrant::cpu_only(5_000_000, 200, 16 * 1024 * 1024),
..Grants::default()
};
grants.kv.read = true;
grants.kv.write = true;
grants.host.clock = true;
grants.storage.read = vec!["/work/**".into()];
grants.storage.write = vec!["/work/*".into()];
// An I/O ceiling: this run does a handful of ops, so 1000/sec is ample —
// but a contention storm would hit the wall. Demonstrates the rate lever.
grants.storage.max_iops = Some(1000);
grants.storage.max_read_bps = Some(64 * 1024 * 1024);
let unit = Unit::new(UNIT_WAT.as_bytes(), &grants);
let mut req = TierRequest::minimal(&grants);
req.trusted = false;
let sealed = host
.run_and_seal(&executor, &unit, &req, 1, [0; 8], 1_000, 2_000)
.expect("run and seal");
sealed
.receipt
.verify_sealed(&sealed.receipt_envelope, &receipt_vk, Some("steward.demo"))
.expect("receipt verifies");
sealed
.attestation
.verify(&sealed.attestation_sig, &supervisor_vk)
.expect("attestation verifies");
println!("Sandbox run-wasm — real WASM unit executed at tier S2\n");
println!(" image id: {}", unit.image_id());
println!(" tier: {}", sealed.attestation.tier.wire_tag());
println!(" outcome: {:?}", sealed.attestation.outcome);
for d in &sealed.receipt.devices {
println!(
" energy: {:<4} est={} uj [{}]",
d.class.wire_tag(),
d.estimated_uj,
d.provenance.label()
);
}
if let Some(s) = &sealed.storage {
println!(
" storage: {} ops, {} B read, est={} uj [{}] (rate within I/O ceiling)",
s.iops,
s.bytes,
s.estimated_uj,
s.provenance.label()
);
}
println!(" receipt id: {}", sealed.receipt.content_id());
match &sealed.attestation.journal_root {
Some(jr) => println!(" journal root: {jr} (brokered host calls recorded for replay)"),
None => println!(" journal root: (none recorded)"),
}
println!(
" attestation: {}",
sealed.attestation.content_id().expect("attestation id")
);
// RATS interop: the same attestation as a signed EAT (CWT), verified here.
let eat = sandbox_attest::verify_eat(&sealed.eat, &supervisor_vk, Some("steward.demo"), Some(&sandbox_attest::run_nonce(&sealed.attestation.unit_id, &sealed.receipt.content_id())))
.expect("EAT verifies");
println!(
" eat (RATS): {} bytes, profile {}, tier {} (CWT/COSE_Sign1 verified ✓)",
sealed.eat.len(),
eat.profile,
eat.tier
);
println!(" executed real WASM + brokered host calls, metered, journaled, verified ✓");
}
/// Seal a heterogeneous run end-to-end: a unit granted CPU + GPU, metered per
/// device, attested with named silicon, sealed and verified.
fn demo() {
let host = Host::new(
"host-demo",
"steward.demo",
SigningKey::from_bytes(&[11u8; 32]),
SigningKey::from_bytes(&[22u8; 32]),
);
let (receipt_vk, supervisor_vk) = host.verifying_keys();
let mut grants = Grants {
compute: ComputeGrant {
devices: vec![DeviceClass::Cpu, DeviceClass::Gpu],
energy_budget_uj: 1_000_000,
cpu_time_ms: 5000,
memory_bytes: 1 << 30,
},
..Grants::default()
};
grants.host.inference = true;
let report = demo_report();
let unit_id = ContentId::of_bytes(b"demo-unit");
let image_id = ContentId::of_bytes(b"demo-image");
let tier = required_tier(&TierRequest::minimal(&grants));
let sealed = host
.seal_run(
unit_id, image_id, &grants, tier, report, 1, [0; 8], 1_000, 2_000,
)
.expect("seal run");
sealed
.receipt
.verify_sealed(&sealed.receipt_envelope, &receipt_vk, Some("steward.demo"))
.expect("receipt verifies");
sealed
.attestation
.verify(&sealed.attestation_sig, &supervisor_vk)
.expect("attestation verifies");
println!("Sandbox demo — sealed heterogeneous (CPU+GPU) run, illustrative: no unit runs\n");
println!(" tier: {}", tier.wire_tag());
println!(" receipt id: {}", sealed.receipt.content_id());
println!(
" energy (est): {} uj total ({} per-device records)",
sealed.receipt.total.estimated_uj,
sealed.receipt.devices.len()
);
match sealed.receipt.total.measured_uj {
Some(m) => println!(" energy (meas): {m} uj total (all classes HwShunt)"),
None if sealed.receipt.devices.iter().all(|d| d.measured_uj.is_none()) => {
println!(" energy (meas): none (illustrative figures, sealed as estimates)")
}
None => println!(" energy (meas): partial (not every class measured)"),
}
for d in &sealed.receipt.devices {
println!(
" - {:<8} est={} uj{} [{}]",
d.class.wire_tag(),
d.estimated_uj,
d.measured_uj
.map(|m| format!(" meas={m} uj"))
.unwrap_or_default(),
d.provenance.label()
);
}
println!(
" attestation id: {}",
sealed.attestation.content_id().expect("attestation id")
);
println!(" receipt+attestation verified ✓");
}
/// An illustrative energy record for `class`: `estimated_uj` graded
/// `Estimator`, with no measured figure. `demo` and `confidential` run no
/// unit, so nothing was read; a record of theirs that carried a measured
/// figure, or a `HwShunt` grade, would claim a hardware reading of work that
/// never happened (SPEC §6.3).
fn illustrative(class: DeviceClass, estimated_uj: u64) -> DeviceEnergy {
DeviceEnergy {
class,
measured_uj: None,
estimated_uj,
provenance: Provenance::Estimator,
}
}
/// An illustrative device identity for `class`: a placeholder named by the
/// capability it stands for (`what`), labelled illustrative, with an
/// illustrative driver. `demo` and `confidential` detect no device, so an
/// identity of theirs that named a product or a driver release would claim a
/// device nothing saw.
fn illustrative_identity(class: DeviceClass, what: &str) -> DeviceIdentity {
DeviceIdentity {
class,
model: format!("illustrative {what} (none detected)"),
driver: "illustrative".into(),
}
}
/// The run report `demo` seals: a CPU and a GPU record, both illustrative.
fn demo_report() -> RunReport {
RunReport {
device_energy: vec![
illustrative(DeviceClass::Cpu, 2_100),
illustrative(DeviceClass::Gpu, 51_000),
],
device_identity: vec![
illustrative_identity(DeviceClass::Cpu, "host CPU"),
illustrative_identity(DeviceClass::Gpu, "accelerator GPU"),
],
outcome: Outcome::Completed,
journal: None,
storage: None,
}
}
/// The run report `confidential` seals for each of its S6 and S7 runs: one
/// illustrative CPU record.
fn confidential_report() -> RunReport {
RunReport {
device_energy: vec![illustrative(DeviceClass::Cpu, 2_100)],
device_identity: vec![illustrative_identity(DeviceClass::Cpu, "confidential-compute CPU")],
outcome: Outcome::Completed,
journal: None,
storage: None,
}
}
/// Print a sealed receipt's energy records, each with its grade.
fn print_energy(devices: &[DeviceEnergy]) {
for d in devices {
println!(
" energy: {} est={} uj{} [{}]",
d.class.wire_tag(),
d.estimated_uj,
d.measured_uj.map(|m| format!(" meas={m} uj")).unwrap_or_default(),
d.provenance.label()
);
}
}
#[cfg(test)]
mod tests {
use super::*;
/// No unit runs in `demo` or `confidential`, so every record they seal
/// must be an estimate: `Estimator`, no measured figure.
#[test]
fn the_illustrative_runs_seal_no_reading() {
for (name, report) in [("demo", demo_report()), ("confidential", confidential_report())] {
assert!(!report.device_energy.is_empty(), "{name}: no records");
for d in &report.device_energy {
eprintln!("{name}: {:?} est={} meas={:?} [{}]", d.class, d.estimated_uj, d.measured_uj, d.provenance.label());
assert_eq!(d.provenance, Provenance::Estimator, "{name}: a record of no work graded {:?}", d.provenance);
assert_eq!(d.measured_uj, None, "{name}: a measured figure nothing read: {d:?}");
assert!(d.check_provenance().is_ok(), "{name}: {d:?}");
}
}
}
/// Nothing is detected in `demo` or `confidential`, so the device
/// identities their attestations seal must say so: each one a
/// capability-named placeholder labelled illustrative, never a named
/// product or driver release that no probe saw.
#[test]
fn the_illustrative_runs_seal_no_detected_identity() {
for (name, report) in [("demo", demo_report()), ("confidential", confidential_report())] {
assert!(!report.device_identity.is_empty(), "{name}: no identities");
for d in &report.device_identity {
assert!(d.model.starts_with("illustrative "), "{name}: an identity nothing detected: {d:?}");
assert_eq!(d.driver, "illustrative", "{name}: a driver nothing detected: {d:?}");
}
}
}
}