A confidential run's TEE report bound BLAKE3(unit) ‖ BLAKE3(receipt), with
no domain tag. The outcome sat only under the Supervisor's signature, the
only freshness input was a host-chosen nonce (every call site passed
[0; 8]), and the report was dropped once the host had checked it, so no
one else could. verify_eat compared no nonce, so any token the Supervisor
key signed verified, whichever run it was for.
sandbox-runtime (SPEC §7.6):
- run_report_data is one preimage: BLAKE3-XOF-64 in derive-key mode
("sandbox/1 run report_data v1") over length-prefixed unit_id,
receipt_id and JCS(outcome), then 0x01 ‖ challenge, or 0x00 when there
is none. The receipt binds the metered energy, so the report vouches for
the joules through it. It replaces tee_report_data.
- TierRequest.challenge carries the relying party's 32 bytes into
run_and_seal. seal_run_with_mechanism takes a challenge; seal_run and its
callers are unchanged.
- The sealed TeeEvidence carries report_hex (the report itself) and
challenge_hex.
- verify_run_evidence lets a party other than the host check:
- the report's signature and policy;
- that its report_data binds the attestation's unit, receipt and
outcome and the verifier's OWN challenge, never the recorded one;
- that the summary is the report's.
Evidence without its report is refused.
sandbox-attest:
- Outcome::core is shared by the attestation core and the preimage.
- TeeEvidence.report_hex and challenge_hex are omitted when absent, so
evidence sealed before them keeps its bytes.
- run_nonce is exposed.
- verify_eat takes expect_nonce and refuses a token whose nonce is not
that run's. The CLI, MCP and build paths now pass the run's nonce. The
MCP verify_eat tool takes an optional expected_nonce_hex and reports
nonce_checked.
SPEC §7.6 gives the binding, the challenge and the third-party check;
§7.8, spec/eat.md and spec/attestation.md are updated to match.
Also: an orphaned doc comment in sandbox-conformance's vectors.rs that
clippy refused (it predates this change).
Tests:
- Binding and challenge.
- An unchallenged report is never taken for a challenged one.
- The preimage separates its inputs, including a length-delimitation
collision.
- A requested challenge reaches the report through run_and_seal.
- An EAT is checked against the run the verifier holds.
Mutation testing: 12 mutants, all killed. They cover:
- the challenge, its presence tag, the outcome, the receipt and the
length prefixes;
- the verifier trusting the recorded challenge, the summary check, and the
report and challenge being carried;
- the seal and run_and_seal dropping the challenge;
- the EAT nonce check.
Verified on the build host:
- sandbox-rs: 421 tests (--locked); every conformance class passes.
- Clippy -D warnings clean on sandbox-runtime, -attest, -tee, -build,
-mcp, -cli and -conformance.
Not in this change: running it on SEV-SNP hardware (a billable cloud cell),
a challenge slot in jcp-wire, and TDX on the run path, which still
verifies SEV-SNP only.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
42 KiB
Sandbox v0.1 — Isolated, Capability-Gated, Metered, Attested Execution Across the Heterogeneous Compute Fabric
Status: Draft Standard. Reference implementation: sandbox-rs/ (Rust workspace, Apache-2.0). Specification text: CC-BY-4.0.
The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, MAY, and OPTIONAL are to be interpreted as described in RFC 2119.
1. Scope and doctrine
Sandbox specifies how a unit of work is isolated, granted a bounded set of capabilities, executed, metered for energy across the compute fabric it touches, and accounted for in a signed attestation. It is the isolated-execution substrate of the Transaction Science open standards.
The doctrine is one sentence: isolation per joule, across the whole fabric. Three normative consequences follow.
1.1 The isolation ladder (REQUIRED)
A conforming host MUST run a unit at the lowest tier of the eight-rung isolation ladder (§2.1) whose guarantees satisfy the unit's capability set, and MUST NOT escalate to a higher tier than the grants require. A host MAY decline to run a unit whose grants require a tier it does not implement; it MUST NOT run the unit at a tier weaker than required. The tier at which a unit ran MUST be recorded in its attestation (§7).
1.2 The capability grant (REQUIRED)
A unit's access to every resource — network, storage, key-value, host services, subprocess execution, browser, display, and each compute device class (§2.3) — MUST be governed by an explicit grant (§5). Access to a resource not named by a grant MUST be denied (deny-by-default). A host MUST NOT widen a unit's grants during a run; a mutation to the granted capability set MUST terminate the run and invalidate its attestation.
1.3 The attested receipt (REQUIRED)
Every completed run MUST emit (a) an energy receipt (§6) accounting joules per device class, two-part (measured + estimated, integer microjoules), each reading carrying a Provenance tag, sealed as a JCR-1 envelope; and (b) an attestation (§7) binding the unit, its image, the tier it ran at, the grants it ran under, the hardware it ran on, and the receipt — signed Ed25519 over JCS-canonicalized JSON. A host MUST NOT report a measured figure it did not obtain from a hardware energy interface (§6.3).
1.4 No capture (REQUIRED)
The protocol carries no token. A conforming host MUST perform its core function — isolate a unit, enforce its grants, meter its energy, seal its attestation — without contacting any single steward's servers as a condition of operation. Where a unit's grants permit network egress (§5.3), that egress is the unit's own; it MUST NOT be a precondition of the host's operation.
2. The model
2.1 The three entities
Every Sandbox run involves three entities, kept separated, generalizing the ARL Sandbox model:
- Unit — the code under execution. Sealed inside the sandbox boundary. It can read and influence only what its grants permit, and nothing outside the boundary.
- Host — the runtime that establishes the boundary, mediates every capability the unit exercises, meters energy, and runs the unit. The host is itself subject to telemetry but is trusted to enforce the boundary at the tier in force.
- Supervisor — the process outside the boundary that orchestrates the run, reads physical telemetry, and signs the attestation. The signing key is held where the unit and the host's in-boundary code cannot reach it (§7.4).
2.2 The isolation ladder (S0–S7)
A host runs a unit at exactly one tier. Each tier strictly contains the guarantees of the tier below it.
| Tier | Wire tag | Name | Boundary mechanism (reference) | Typical use |
|---|---|---|---|---|
| S0 | S0 |
Bare | process only; no added boundary | trusted code, local development |
| S1 | S1 |
Capability | unforgeable capability tokens; no ambient authority | capability-confined modules |
| S2 | S2 |
Sandbox | managed runtime + fuel/instruction metering + memory caps (e.g. WASM) | untrusted single-tenant units (default for agent tools) |
| S3 | S3 |
Partition | temporal + spatial partitioning over a shared kernel | multi-tenant on one host |
| S4 | S4 |
Unikernel | VMM + single-address-space unikernel guest | minimal-surface confined service |
| S5 | S5 |
MicroVM | VMM + full guest kernel; dedicated vCPU/memory | untrusted multi-tenant, Firecracker-class |
| S6 | S6 |
Confidential | S5 + hardware memory encryption + remote attestation (TEE) | confidential workloads on untrusted hosts |
| S7 | S7 |
Sovereign | S6 + geographic pinning + immutable audit trail | jurisdiction-bound, fully provenanced |
A host MUST treat the tags S0–S7 as the canonical wire identifiers. The reference mechanisms are non-normative: a host MAY satisfy a tier's guarantees by any means that provides them. The guarantees, not the named technology, define the tier (§ spec/tiers.md).
A unit's required tier is the lowest tier whose guarantees satisfy every grant it holds (§5 fixes the per-capability minimum tiers). The host computes this tier and runs there (§1.1).
2.3 Device classes (REQUIRED)
The compute fabric is enumerated as a fixed set of device classes:
DeviceClass = Cpu | Simd | Gpu | Npu | Tpu | Lpu | Photonic | Quantum
A device class is a first-class subject of the capability model (§5.1), the receipt (§6.2), and the attestation (§7.2). A host MUST NOT grant, meter, or attest accelerator work as undifferentiated CPU work. The Cpu class denotes scalar host compute; Simd denotes vector lanes on the host CPU; the remaining classes denote distinct accelerators. A host MAY support any subset of classes; it MUST reject a grant naming a class it cannot isolate and meter (§5.1).
2.4 Shared resources and side channels (REQUIRED)
Logical isolation separates memory and code; it does not partition the physical resources a tier shares, and a shared resource is a channel. At S0–S2 the host kernel and device I/O paths are shared, so co-tenants can observe one another through contention with no privileged access (see SECURITY.md for the storage-I/O worked example). Tier minimization (§2.2) is therefore side-channel-aware: a unit's required tier accounts not only for what its grants name but for what they expose. A workload sensitive to — or, as an untrusted neighbor, capable of — cross-tenant leakage through a shared resource MUST either carry the capability that bounds the channel (e.g. a storage I/O ceiling, §5.2) or run at the tier that partitions it (S3), or assigns the device exclusively (S5). A host MUST NOT silently colocate such a workload at a tier whose shared resources leave the channel open.
3. Identity and content addressing
Every load-bearing object (unit descriptor, image, grant set, receipt, attestation) is identified by the content address of its canonical serialization (§4): id = "b3:" + base64url-unpadded( BLAKE3-256( canonical_bytes ) ). Identity is independently computable by any party; no central authority assigns it.
- A unit id is the content address of the unit descriptor (the image id, the entrypoint, and the declared grant request) excluding any signature.
- An image id is the content address of the executable artifact the unit runs.
- A grants id is the content address of the granted capability set (§5).
A signature over an object binds its content address, not the reverse (§7.3).
4. Canonical serialization
The canonical form of receipt and attestation cores is deterministic CBOR (RFC 8949 §4.2 core deterministic encoding) for the JCR-1 receipt, and JCS (RFC 8785) for the JSON attestation. A conforming implementation MUST produce byte-identical canonical encodings for equal objects across platforms. Floats MUST NOT appear in any canonical form or decision path. All energy figures are integer microjoules; all budgets, counts, and limits are unsigned integers. In the JCS form every integer MUST lie within ±(2⁵³ − 1): RFC 8785 holds numbers as IEEE-754 doubles (I-JSON, RFC 7493 §2.2), so a larger one has no encoding that every platform writes alike, and an implementation MUST refuse a core that holds one.
5. The capability grant
A grant set is the complete, explicit description of what a unit may touch. The normative type is in spec/capabilities.md; this section fixes the load-bearing structure and the per-capability minimum tiers.
Grants {
compute : ComputeGrant,
storage : StorageGrant,
network : NetworkGrant,
kv : KvGrant,
host : HostGrant, // logging, clock, randomness, inference
process : ProcessGrant, // subprocess / shell (§5.5)
browser : BrowserGrant, // browser automation (§5.6)
display : DisplayGrant, // framebuffer / desktop (§5.7)
}
5.1 Compute grant (REQUIRED; the heterogeneity clause)
ComputeGrant {
devices : Set<DeviceClass>, // which classes the unit may use
energy_budget_uj : u64, // total joule budget for the run, microjoules
cpu_time_ms : u64, // wall/CPU time bound
memory_bytes : u64, // resident memory cap
}
A unit MUST NOT dispatch work to a device class not present in devices. A host MUST deny a dispatch to an ungranted class. A host MUST reject the whole grant (refuse to run) if devices names a class the host cannot both isolate (confine per the tier in force) and meter (attribute energy to per §6.2). Granting any class other than Cpu/Simd requires a tier of at least S2; granting a class via direct device assignment (passthrough/SR-IOV) requires at least S5; granting a confidential-compute device requires S6.
When the run exceeds energy_budget_uj, cpu_time_ms, or memory_bytes, the host MUST terminate the unit and record the breached bound in the attestation.
5.2 Storage grant
StorageGrant { read : [Glob], write : [Glob], delete : [Glob],
max_iops : u64?, max_read_bps : u64? }
A path operation MUST match an allow-glob for its access mode or be denied. The empty grant denies all storage. A grant MAY carry sustained-I/O ceilings (max_iops, max_read_bps); a sustained rate is permitted iff it stays within every ceiling that is set. A ceiling is the deny-by-default lever against storage-contention side channels (§2.4, SECURITY.md); it is bound into the grant's content id and attested. Omitted ceilings (null) do not bound that dimension and serialize to nothing, leaving pre-ceiling grants byte-identical.
5.3 Network grant
NetworkGrant { outbound : [Endpoint],
inbound : bool,
credentials : [EgressCredential] }
EgressCredential { endpoint : Endpoint, secret_ref : Handle, inject : Injection }
outbound is an allowlist of host:port endpoints; an egress to an endpoint not on the list MUST be denied. The empty grant denies all network. Network access is never a precondition of the host's own operation (§1.4).
credentials names the secrets the boundary injects on the unit's behalf, so that a unit can reach an authorized service without ever holding the secret. Three rules, and the third is what makes the other two attestable:
secret_refis a handle, not a key — an opaque name the boundary resolves in its own keystore. The grant, and every receipt and attestation over it, therefore carries no secret material. A grant that carries a secret by value does not conform.- A credential's
endpointMUST also appear inoutbound. Injection can never reach further than egress itself; a credential for an endpoint egress does not allow MUST be refused, not silently ignored. - The credential set MUST be part of the grant's content address (§1.2), committed as the ordered list of per-credential commitments —
BLAKE3over(endpoint, secret_ref, inject)— never as the credentials themselves. Swapping a handle on an endpoint that is already allowlisted changes nothing else about the grant, so without this the mutation is undetectable and every attestation sealed under the old set goes on verifying while describing a surface no longer in force. An empty set is omitted from the address, so a grant that injects nothing addresses as it did before this field existed.
5.4 Key-value and host grants
KvGrant { read : bool, write : bool, prefixes : [Bytes] }
HostGrant { logging : bool, clock : bool, random : bool, inference : bool }
inference gates the unit's access to an on-host model endpoint; when granted, inference energy is metered to the device class that served it (§6.2), never hidden.
5.5 Process grant
ProcessGrant { exec : bool, programs : [String],
allow_hashes : [ContentId], deny_hashes : [ContentId],
max_processes : u32 }
Governs the unit's ability to spawn subprocesses — the substrate for shell access and code-interpreter capabilities. A unit MUST NOT spawn a program unless exec is true and the program is permitted; deny-by-default, so an empty grant permits nothing. Granting exec requires a tier of at least S2 (§2.2): subprocess execution crosses a brokered host boundary and is untrusted-execution class.
Name-based control (programs) is advisory: rename, relocation, or a wrapper script defeats it. Against an untrusted unit the binding that holds is content-addressed. The host MUST decide on the BLAKE3 content address of the executable's bytes: a binary whose address is on deny_hashes MUST be refused regardless of its name, path, or wrapping, and the denylist MUST override every allow rule; when allow_hashes is non-empty it is authoritative, so a binary absent from it MUST be refused even if its name is allowed. With no hash allowlist the name allowlist applies. Both hash lists are omitted when empty, so a name-only grant is byte-identical to a pre-hash grant and its content address is unchanged. Conformance class C8.
5.6 Browser grant
BrowserGrant { enabled : bool, origins : [Origin], headless : bool }
Governs browser automation — the substrate for browser and GUI-agent capabilities. A navigation MUST be denied unless enabled is true and the target origin (scheme://host[:port]) is on the origins allowlist. Granting enabled requires a tier of at least S2.
5.7 Display grant
DisplayGrant { enabled : bool, vnc : bool, max_width : u32, max_height : u32 }
Governs access to a framebuffer / desktop and an optional remote (VNC) export — the substrate for desktop capabilities. Display access MUST be denied unless enabled is true; a VNC export MUST additionally require vnc. The framebuffer is bounded by max_width × max_height. Granting enabled requires a tier of at least S2.
The filesystem capability is
storage(§5.2) and a code-interpreter is a composition ofprocess(§5.5) andstorage; this standard models the underlying resources, not the composed product.
6. The energy receipt (JCR-1)
A receipt accounts for one run's energy. The normative schema is in spec/receipts.md.
6.1 Structure
A Receipt MUST carry:
unit_id— the unit it accounts for (§3).tier— the tier the unit ran at (§2.2).devices— a non-empty list of per-device-class energy records (§6.2).total— the summed two-part energy{ measured_uj: Option<u64>, estimated_uj: u64 }over all device records.sequence,nonce— a monotonic sequence number and a per-receipt nonce.
6.2 Per-device energy (REQUIRED; the heterogeneity clause)
devices MUST contain exactly one DeviceEnergy record per device class the unit actually used:
DeviceEnergy {
class : DeviceClass,
measured_uj : Option<u64>, // present ONLY from a hardware energy interface for THIS class
estimated_uj : u64, // always present
provenance : Provenance, // HwShunt | ModelBased | Estimator
}
A host that ran accelerated work MUST emit a separate record for each accelerator class used; it MUST NOT fold accelerator energy into the Cpu record or omit it. The total MUST equal the field-wise sum of the device records (a measured total is present only if every used class has a measured figure).
6.3 Provenance discipline
provenance is one of:
HwShunt— read from a hardware energy interface for that class (RAPL/powercap for CPU; NVML for NVIDIA; ROCm SMI for AMD; Level Zero for Intel; an SMC/shunt otherwise). MUST correspond to a presentmeasured_uj.ModelBased— computed from a per-operation model for that class calibrated on the host (or against a reading), or a hardware reading apportioned by a model.measured_ujMAY be absent.Estimator— a figure nothing calibrated: a coarse constant estimator, or a model at a nominal or assumed coefficient (wall-clock × TDP, a reference per-vCPU-second cost, a datasheet J/op). MUST NOT carry ameasured_uj.
A host MUST NOT report measured_uj it did not obtain from a hardware interface for that specific device class. At tiers S5 and above, where a hardware energy interface for a used class is available on the host, the host MUST use it (HwShunt) rather than estimate.
6.4 Signed form
The receipt's on-the-wire form is a JCR-1 envelope — the signed-receipt format shared across the Transaction Science family: a canonical det-CBOR signed core (RFC 8949 §4.2.1, length-first key order, no floats/bools/nulls) inside a COSE_Sign1 envelope (RFC 9052, EdDSA/Ed25519, alg = -8). A Sandbox receipt uses the sandbox/1 profile tag and verifies under the family's existing JCR-1 tooling.
7. The attestation
An attestation is the Supervisor's signed statement of what a run was. The normative schema is in spec/attestation.md.
7.1 Structure
An Attestation MUST carry:
unit_id,image_id,grants_id— content addresses (§3) of the unit, the image that ran, and the granted capability set.tier— the tier the unit ran at (§2.2).devices— the device identities used (§7.2).receipt_id— the content address of the energy receipt (§6) for this run.journal_root— the BLAKE3 root of the deterministic-replay journal (§8) where one was produced; absent otherwise.outcome—Completed | Failed | Terminated{ breach }, recording any resource breach (§5.1) or detected tamper (§7.5).tee— TEE evidence (§7.6) when the tier is S6 or above; absent otherwise.locality— the region and jurisdiction the run was bound to (§7.7); REQUIRED when the tier is S7, absent otherwise.audit_prev— the audit-chain head before this run was appended (§7.7); REQUIRED when the tier is S7, absent otherwise.host_id,started_at_us,finished_at_us— the host identity and the run window.
7.2 Device identity (REQUIRED; the heterogeneity clause)
devices MUST name, for each device class the unit used, its { class, model, driver } — for example { Gpu, "NVIDIA H100", "560.x" }. A run that used an accelerator but does not record its identity is not conformant.
7.3 Signing
The attestation signs Ed25519 over JCS-canonicalized JSON (RFC 8032 + RFC 8785), with SHA-256 used for the content addresses it references. This is the attestation primitive of the ARL Sandbox; a Sandbox attestation and an ARL-S session attestation verify under the same tooling. The signature binds the canonical bytes; any change to any field invalidates it.
7.4 Key custody
The Supervisor's signing key MUST be held where neither the unit nor the host's in-boundary code can read it — a TPM, HSM, or secure enclave for production tiers. The unit MUST have no access to the telemetry stream or the signing path.
7.5 Anti-evasion
The host MUST normalize hostnames, paths, process tree, time, timezone, and locale visible to the unit to deployment-realistic values, and MUST record probing (hardware enumeration, root filesystem walks, evasion of the energy interface) in the attestation. A detected VM-escape, privilege escalation, or out-of-allocation write MUST set outcome = Terminated and invalidate the run. The grant set, image, and any harness configuration are content-addressed before the run begins; a mutation to any of them during the run invalidates the attestation (§1.2).
Tier-claim trust boundary. A host MUST NOT seal an attestation at a tier the run did not execute at. The strength of that obligation differs by tier, and a verifier MUST treat it accordingly: for S0–S5 the tier is host-asserted — there is no in-band cryptographic proof that the named boundary was established, so the claim is only as trustworthy as the host. From S6 up the attestation carries verified tee evidence (§7.6) bound to the run identity, which is independently checkable. A relying party that requires proof of isolation rather than host assertion MUST require S6+. The reference enforces the executor↔tier binding in its run-and-seal path (the executor's tier is checked against the grants' required tier before sealing); the bare sealing primitive trusts its caller for the execution tier.
7.6 TEE evidence (S6+)
At S6 and above, tee MUST carry a summary of the hardware attestation report (kind ∈ { SevSnp, Tdx, ArmCca }, the launch measurement, and the platform TCB) so a verifier can establish the boundary was hardware-enforced. A host MUST obtain the report from the platform's attestation interface, bind it to the run through the report's 64-byte report_data field, and MUST verify the report — its signature against the platform's VCEK and its measurement/TCB/debug-state/report-data against policy — before sealing the attestation. A host MUST NOT present a tee summary it did not verify.
The binding. report_data is one preimage over everything a report vouches for:
report_data = BLAKE3-XOF-64(derive_key = "sandbox/1 run report_data v1",
len‖unit_id ‖ len‖receipt_id ‖ len‖JCS(outcome) ‖ challenge_tag)
challenge_tag = 0x01 ‖ challenge[32] when the relying party issued one
= 0x00 otherwise
unit_idandreceipt_idare the content addresses as text, andJCS(outcome)is the outcome as the attestation core carries it (§7.1). Each is preceded by its length as a little-endianu64.- The receipt binds the metered energy (§6.1), so the report vouches for the joules through it.
- The
challengeis 32 fresh bytes from the party that asked for the run. With it, that party can tell a report made for its request from one made for another. Without it, a report shows which run it is for, but not that it is fresh. A challenge's presence is part of the preimage, so no challenge is not a challenge of zeros.
Carried for a third party. The tee object also carries report_hex, the report itself, and challenge_hex where there was a challenge. Both are omitted when absent, so evidence sealed before they existed keeps its bytes. A verifier other than the host then checks:
- the report's signature and policy;
- that its
report_datais the preimage above, for the attestation's unit, receipt and outcome and the challenge the verifier itself issued, never the one the attestation records; - that the summary is the report's.
Evidence without its report MUST NOT be taken as verified by anyone but the host that sealed it.
The reference splits this honestly (§9): verification — parsing the SEV-SNP report, the policy checks, and the ECDSA-P384/SHA-384 signature — is implemented and vectored (sandbox-tee). Generation of a genuine vendor-signed report requires the CPU's security processor: the reference configfs-tsm provider requests one on Linux confidential hardware and reports Unavailable elsewhere, and a software-grounded provider (explicitly tagged, never claiming a hardware root) covers wiring and tests.
7.7 Sovereign binding (S7)
At S7, the attestation MUST additionally carry:
locality— the{ region, jurisdiction }the run was pinned to. A host MUST NOT seal an S7 run whose execution it cannot bind to the stated locality.locality_evidence(RECOMMENDED) — observations bounding where the run could not have been. See below.audit_prev— the head of the host's append-only, hash-chained audit log before this run. After signing, the host MUST append the attestation's content address to the log, advancing the head:head' = BLAKE3(head ‖ attestation_id). The chain is tamper-evident — reordering or removing any entry breaks it — so the sequence of sovereign runs is itself attestable.
Locality evidence. Left as two free-text strings, locality is the weakest normative claim in the ladder: an assertion by the party under audit, checked for presence and nothing else, at the one tier whose entire purpose is jurisdictional. The obligation above is real but had no mechanism behind it, and a data-residency auditor attacks exactly this.
locality_evidence supplies a partial one. Round-trip time to an anchor of known position bounds distance — a signal cannot outrun light, so rtt/2 × c is the farthest the host can be from that anchor. The asymmetry is what makes it useful: latency is trivial to add and impossible to remove, so a host can always appear farther away than it is and never closer than physics permits.
That gives a test that falsifies but does not verify:
- It can refute a claim. If the claimed position is farther from an anchor than light could travel in the observed time, the claim is impossible, and that conclusion does not rest on trusting anyone.
- It can never confirm one. Surviving every bound means "not excluded" and nothing more: the feasible region is an intersection of discs that routinely spans several jurisdictions, and being somewhere inside it is not evidence of being at any particular point in it.
Accordingly:
- An implementation MUST NOT report a surviving claim as proven, verified, or attested. The reference names the passing verdict
NotRefutedfor this reason. - Only observations signed by an independent anchor count. A round-trip time the host measured about itself is the same unchecked assertion as the region string it was meant to improve on, and MUST be reported as unsubstantiated rather than blended into a verdict.
- Observations MUST be bound to the run by a challenge, or an observation taken in a real datacentre can be replayed onto a later run somewhere else.
- A host MUST NOT seal an attestation whose own evidence refutes its own locality claim.
locality_evidenceMUST be absent below S7, where no locality is claimed.- The bound SHOULD be computed with the vacuum speed of light rather than a fibre constant. This costs sensitivity and buys certainty in the only direction that matters: a refutation under vacuum-c cannot be argued away by an unusual path.
Locality evidence is timing-derived, and this specification already holds that a timing-derived measurement may not claim a hardware-rooted provenance (§6.3). It is therefore its own evidence class: it never reaches the standing of the verified tee evidence at S6, and carries no Provenance of any kind.
7.8 EAT interoperability (RECOMMENDED)
The native attestation (§7.3) is the standard's own signed form. A host SHOULD additionally emit the attestation as an EAT (Entity Attestation Token, RFC 9711) — a CWT (RFC 8392) signed as a COSE_Sign1/EdDSA token — so a generic RATS (RFC 9334) verifier can appraise it without understanding this format. The EAT is a view of the attestation, signed by the same Supervisor key; it is not a second source of truth.
The claims-set carries the IANA-registered EAT/CWT claims iat (6), nonce (10) — bound to the run as BLAKE3(unit_id ‖ receipt_id), ueid (256), eat_profile (265) = https://transaction.science/sandbox/eat/v1, and measurements (273) — plus a profile-scoped private claim referencing the canonical attestation by content address and naming the tier and receipt. A verifier checks the COSE_Sign1 signature and alg = EdDSA, the eat_profile, and (for this profile) resolves the referenced attestation. A verifier that holds the run's receipt MUST also check that nonce is that run's binding: without it, any token the Supervisor key signed verifies, whichever run it is for. See spec/eat.md; the reference implements both directions (sandbox-attest::{seal_eat, verify_eat}) and every sealed run carries the EAT alongside the native attestation.
7.9 Enforcement mechanism (S1–S5; RECOMMENDED)
Below S6 the tier is host-asserted (§7.5): the standard offers no in-band evidence that the named boundary was ever established, so tier = "S2" is the host's word with a signature around it. An attestation at S1–S5 SHOULD therefore carry mechanism, a commitment to how confinement was established:
runtime— the enforcement runtime that established the boundary, name and version (e.g."seatbelt/14.5","bubblewrap/0.11","wasmtime/28"). A bare name is insufficient: the same profile under a different runtime version is a different enforcement.profile_id— a BLAKE3 commitment over the length-prefixed encoding of the runtime identity, the policy profile actually applied, and the egress allowlist actually installed. Fields are length-prefixed rather than concatenated because bare concatenation is not injective: two distinct configurations whose fields split differently at the same boundary would share a commitment.
An attestation carrying mechanism uses the profile tag sandbox.attestation/2. One without it remains sandbox.attestation/1 and canonicalizes to byte-identical JSON, so attestations sealed before this section existed verify unchanged.
What a mechanism does and does not establish. It is not proof of isolation, and a verifier MUST NOT treat it as such. A host willing to misstate its tier is equally able to misstate its profile; a commitment made by the party under scrutiny cannot bootstrap its own trustworthiness. What changes is the shape of the claim. An unadorned tier label is unfalsifiable — there is nothing to check it against. A profile_id is checkable against a known-good profile the relying party already trusts, and a false one is a specific, attributable falsehood about a named artifact rather than a vague assertion. This narrows the gap at S1–S5; it does not close it. A relying party that requires proof of isolation rather than assertion still MUST require S6+ (§7.5).
Normative rules:
- A host MUST NOT seal a
mechanismat S0. S0 is "process only; trusted code" — there is no boundary, so a mechanism there is incoherent rather than merely redundant. - A host MUST NOT publish a
profile_idit did not derive from the configuration it actually applied. - A
mechanismMUST name a runtime version; a runtime name alone is non-conformant. - A verifier MUST NOT accept
mechanismin place of theteeevidence required at S6+ (§7.6).
Requiring a mechanism is a relying-party decision, not a producer obligation: making it mandatory for all producers would retroactively invalidate every attestation sealed before this section, and the standard does not make honest historical records non-conformant. A consumer that needs the guarantee demands it at appraisal time — the same posture §7.5 already takes for isolation proof. The reference exposes this as require_mechanism_evidence(), under which S0 passes trivially (it claims no confinement) and S6+ passes on its tee evidence (strictly stronger).
8. Determinism and replay
A host MAY record a deterministic-replay journal: an ordered log of the unit's nondeterministic inputs (host-call results, timer fires, randomness draws) with a hash at each entry, plus periodic state-hash checkpoints. When a journal is produced, its BLAKE3 root MUST appear as journal_root in the attestation (§7.1), and the run MUST be replayable from the journal to the identical sequence of state hashes. Replay is for audit — reconstructing what occurred — not for re-execution. A journal that does not replay to its recorded root invalidates the attestation.
9. Readiness classification
Each part is classified by how much of it is proven in the reference implementation:
| Part | Class | Note |
|---|---|---|
| Content addressing, canonical forms (§3, §4) | Solid | BLAKE3 + det-CBOR + JCS, vectored |
| Capability grant + deny-by-default enforcement (§5) | Solid | reference enforcer, vectored |
| Per-device energy receipt + JCR-1 sealing (§6) | Solid | JCR-1 envelope, family-compatible |
| Attestation + Ed25519/JCS signing (§7.1–§7.4) | Solid | ARL-S-compatible primitive |
| Isolation ladder S0–S3 (§2.2) | Engineering | guarantees specified; sandbox-exec-wasm runs and meters real WASM guests at S2 (wasmtime, fuel + memory caps) |
| Isolation ladder S4–S5 (§2.2) | Engineering | sandbox-exec-microvm is a real Firecracker driver (boots a guest on Linux+KVM) with pluggable per-device power metering; lifecycle wait/teardown is the host integration point |
| Deterministic replay journal (§8) | Engineering | journal + root specified; reference records and verifies |
| Anti-evasion (§7.5) | Engineering | normalization + probing record specified |
| TEE report verification — SEV-SNP (§7.6) | Solid | sandbox-tee parses the SEV-SNP report, checks version/measurement/TCB/debug/report-data, and verifies the real ECDSA-P384/SHA-384 signature; vectored |
| TEE report verification — Intel TDX (§7.6) | Solid | sandbox-tee::tdx parses a DCAP v4 quote + TD10 report body and verifies the ECDSA-P256 quote signature, the QE-report endorsement of the attestation key, and the PCK signature over the QE report, then policy (MR_TD/debug/report-data); self-tested |
| Accelerator attestation — NVIDIA GPU EAT (§7.6) | Solid | sandbox-tee::gpu verifies an NRAS GPU EAT (JWT/ES384) — the real ECDSA-P384/SHA-384 signature, alg pinning (never none), and the eat_nonce binding — and surfaces the device claims; self-tested |
| TEE/quote/JWKS chaining to vendor roots (§7.6) | Engineering | the reference verifies signatures against the supplied key; fetching and pinning the endorsing key to the vendor root (AMD KDS VCEK, Intel PCS PCK, NVIDIA NRAS JWKS) is the production wiring, documented and not faked |
| TEE report generation (§2.2 S6, §7.6) | Engineering | the configfs-tsm provider requests a report on Linux confidential hardware and returns Unavailable elsewhere; a software-grounded provider (tagged, never claiming hardware) covers wiring |
| EAT / RATS interoperability (§7.8) | Solid | sandbox-attest::eat emits and verifies the attestation as a CWT/COSE_Sign1 EAT (RFC 9711); round-trip tested, carried on every sealed run |
| Sovereign tier — locality + audit chain (§2.2 S7) | Engineering | locality binding and the hash-chained, tamper-evident audit log are implemented and signed into the attestation; vectored |
| MCP agent server (§11) | Solid | sandbox-mcp runs units at S2 over JSON-RPC and returns the attested, metered receipt + EAT as the tool result; tested |
A host MUST NOT advertise a part at a readiness it does not deliver.
10. Conformance
A host is conformant if it satisfies every REQUIRED clause of §1–§7 for the tiers it advertises and round-trips the conformance vectors in conformance/. The test obligations are enumerated in spec/conformance.md: canonicality (C1), capability enforcement / deny-by-default (C2), per-device receipt integrity and provenance coupling (C3), attestation signing and verification (C4), tier-minimization (C5), durable run records (C6, §13), environment-manifest ingestion and addressing (C7, §14), content-addressed process control (C8, §5.5), warm-pool idle-energy accounting (C9, §15), and fleet merkle aggregation (C10, §16). A conforming host MUST pass the full pack with no skips for its advertised tiers.
11. Agent integration (MCP)
A host MAY expose the sandbox to agents over the Model Context Protocol. The distinguishing requirement is the tool result: a tool that runs a unit MUST return the run's attested, energy-metered receipt — the JCR-1 receipt, the attestation, and (RECOMMENDED) the EAT (§7.8) — not merely the program output. Agent-supplied code is untrusted and therefore minimizes to at least S2 (§2.3). The tool input is the capability grant: a resource not named is not granted (deny-by-default, §5), and whatever is named is metered and attested. See spec/mcp.md; the reference sandbox-mcp implements it.
12. The attested build loop
A coding agent acts in many steps. A host that exposes a "build" capability MUST return a build receipt: a signed, content-addressed account of the whole build, with — per step — the content address of the unit that ran, the tier, the outcome, the joules it cost (§6), the attestation (§7), and the EAT (§7.8), each verified before it is recorded. The build's identity is BLAKE3(intent ‖ each step's image id), so an identical build is identical by address (reproducibility). Receipts MUST chain into an append-only, tamper-evident build ledger (prev = the previous build's id). This is the verifiable, metered, reproducible account of how an artifact was built and what it costs to run — the record regulated use and energy-disclosure regimes require. See spec/build.md; the reference sandbox-build implements it and sandbox-mcp exposes it as the build tool.
13. Durable run records
Long-horizon work outlives the sandbox that started it. A host that suspends and resumes units MUST keep a run record: an append-only hash chain over the run's segments — executed intervals (by attestation address, §7), suspensions (by snapshot content addresses: filesystem root, optional memory image, environment manifest) and resumptions (same snapshot, plus the idle energy the retained state drew while parked). The genesis head binds unit_id and grants_id, so records cannot be spliced across units or grant sets. Resumption MUST be refused unless the offered snapshot is content-identical to the one recorded at suspension and the chain verifies from genesis. The run's total cost is its receipts' energy plus its idle energy — a parked run is not free, and a conformant host does not pretend it is. Conformance class C6 exercises the chain, the refusals and the tamper-evidence. See spec/durable-runs.md; the reference sandbox-attest::runrecord implements it.
14. The environment manifest
A durable run is only the same run if it resumes into the same toolchain — checkable by hash, not asserted by trust. The environment manifest is one canonical, content-addressed object standing for the declared environment: base image and tool features (each pinned by digest where honest claims require it: a manifest is pinned only when both are), environment variables and mounts. Declarations are ingested from the open devcontainer.json format — its declarative subset only: fields that execute commands or widen the sandbox (build, the lifecycle *Command hooks, privileged, …) are refused, and unknown fields are refused rather than silently dropped. Networking fields are excluded from identity: the network surface belongs to the grant (§5). The manifest is JCS-canonicalized, BLAKE3-addressed, Ed25519-signed (§7.3 convention); SnapshotRef.manifest (§13) records it at suspension and resumption MUST be refused on a drifted address. Conformance class C7. See spec/environment-manifest.md; the reference sandbox-attest::manifest implements it.
15. Warm pools
Pre-warmed environments make an agent's first action fast — the toolchain is already booted. Every platform that does this hides the same cost: a warm slot draws power while it waits, used or not. This standard does not hide it. A slot is warmed for one environment (its manifest address, §14) and accrues idle microjoules; a host that serves a run from a warm slot MUST attribute that accrued energy to the run, so a fast start carries a visible joule price. A slot evicted unclaimed MUST record its idle energy as pool overhead (attributed to the operator), never zero. A claim MUST match the slot's environment address — a run cannot be served a slot warmed for a different toolchain. Every microjoule the pool draws is accounted as claimed, overhead, or pending; a pool that reports only the energy of served runs does not conform. Conformance class C9. The reference sandbox-attest::warmpool implements it.
16. Fleet records
A single intent often fans out across many units — patch every repo, render every frame. Each item runs in its own bounded sandbox and produces its own receipt and attestation (§6, §7). A fleet record commits to the whole fan-out with one root: a merkle tree over the per-item (item, attestation) leaves, domain-separated so a node hash can never be taken for a leaf. The root is a single aggregate receipt — sign it once and the whole fan-out is sealed — and any one item's membership is provable against it with a logarithmic proof, without holding all N envelopes. A foreign item, or any change to a leaf, MUST fail to verify against the original root. Conformance class C10. The reference sandbox-attest::fleet implements it.