sandbox: injected egress credentials — the secret never enters the unit (+ sandbox-jcp regression fix) #33
Loading…
Reference in a new issue
No description provided.
Delete branch "sandbox/credential-injection"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The Notion sweep found their Workers run on Vercel Firecracker microVMs with network-level credential injection — credentials never enter the execution environment — plus dynamic egress policy. Strong isolation, but no energy meter and no attestation. TX's Sandbox standard already had the egress allowlist and the meter (S5 + RAPL → signed joule receipt); what it lacked was credential injection. This ingests exactly that, and adds the two properties the incumbent pattern ships without.
The pattern, as a capability
A
NetworkGrantmay now carrycredentials: Vec<EgressCredential>. Each names:endpoint,secret_refhandle the enforcement boundary resolves in its own keystore outside the sandbox,Injectionmode (Bearer/Header/Query/BasicAuth) — the shape, never the secret.The unit makes authenticated calls without ever holding the key. A compromised or hallucinating agent inside the sandbox cannot read, log, or exfiltrate a credential it was never given. The grant — and any receipt over it — carries only the reference.
Two invariants
Enforcer::credential_for(endpoint)returns a credential only when the endpoint is both on the egress allowlist and has a declared credential — injection can never exceed egress even if the grant is malformed.injection_within_egress()flags such a grant at mint; the enforcer is defensive regardless.EgressCredential::commitment()content-addresses the(endpoint, secret_ref, mode)decision, so an attestation records which credential was injected for which call without exposing the secret — the audit primitive Notion/Vercel lack.Backward compatible
credentialsskips serialization when empty → a grant with none is byte-identical to one minted before the field existed. Published sandbox conformance vectors unchanged and still verify (asserted by test).⚠️ Also in this PR: a latent regression fix (separate commit
c8dd25f6)sandbox-jcppath-depends onjcp-schemaacross a workspace boundary, and itsGrantliteral was missingbudget_funds+caveats— the fields added by the dual-ceilings and caveats work. Those swept every Grant site inside the jcp workspace, but sandbox-jcp is in the separate sandbox workspace, so a clean build of the sandbox tree has been broken since (masked by a warm cache; a fresh checkout surfaces it). Fixed. Lesson: a required-field addition to a shared schema must be verified against every workspace that path-depends on it.5 new tests, sandbox-capability clippy-clean, full sandbox workspace green (one pre-existing unrelated warning in
sandbox-conformance/vectors.rs, untouched).