The grading rule
A third-party sandbox provider is pinned toadvisory_filter. security_boundary is earned
only through a conformance matrix Checkfu runs itself.
egress_certification is the capability-honesty grade for one exact
(provider, provider_revision) pair. It is a total order:
A SandboxProfile’s
allowlist policy may name
required_egress_certification: "advisory_filter" | "security_boundary". Selection compares
the requirement against the selected provider’s advertised grade and fails typed before any
provider work starts. It never infers, upgrades, or averages, and unsupported is not a
spelling a policy may require — a policy may not ask that nothing apply its own restriction.
An
allowlist policy that names nothing still requires advisory_filter. The
requirement is opt-in, never retroactive, so an omitted field falls to the floor an
allowlist profile has always been admitted under — not to unsupported. The practical
consequence for a day-one provider: advertising egress_certification: "unsupported" means
no allowlist profile can ever select you, whether or not any profile mentions the
requirement. none and unrestricted policies are unaffected, because they declare no
destination restriction for a grade to be honest about.allowlist member of the policy union, so “require a boundary while asking for unrestricted
egress” is unrepresentable rather than merely rejected. And the requirement is optional and
omitted by default, so no retained profile changes meaning — or template digest — when the
field was added.
The grade is not purchasable by configuration, and it is not inferable from anything else. In
particular it is deliberately independent of enforcement.network_policy: a provider declaring
provider_attested there has said “I own my configured filter,” which is a different and much
weaker claim than D130’s fact set. That independence is test-pinned precisely so
security_boundary can never be back-derived from an attestation.
The five facts, and the three that cannot be self-attested
Asecurity_boundary receipt must prove all five together. A receipt missing one certifies
nothing:
Two of the five —
exact_destination_match and redirect_recheck — are positive and
enumerable. Hand the implementation a host and a port and watch it accept or refuse; hand it
a redirect and watch it recheck the target. Anyone can construct those inputs, and the
observations are about what the code does, not about what it lacks.
The other three are not that shape, and this is why the rule is a structural one rather than a
judgment about partners.
“Un-self-attestable” does not mean unprovable. Checkfu’s own Docker matrix proves two of
these three — it owns the resolver and it owns the topology, so it can construct the
adversarial cases. The claim is narrower and sharper: they cannot be proved by the party
making the claim about itself, because each is a statement about a case that party would
have to choose to construct, about something it does not hold, or about paths it did not
think of. That is why the grade is earned through a matrix Checkfu runs rather than through
a document you send.
connect_time_public_address
The claim is negative, per-connection, and about a moment that has not happened yet: every
resolved address, on every connection, at connect time, was public. Testing it requires
controlling the answer — you must make an admitted hostname resolve to a private address and
observe the refusal. Only a party that owns the resolver can construct that case, and a
self-attester constructs only the cases they thought of. DNS rebinding is precisely an attack on
the gap between check and connect; a statement cannot close a gap.
The sharper problem is that the obvious test passes against an implementation that does not
implement the fact. Checkfu’s own matrix owns the private-address answer end to end through
Docker’s embedded DNS, and its target deliberately accepts TCP on 443 — because the guard
answers 403 for an upstream connection error exactly as it does for a policy denial. Point
that case at a host with nothing listening and it goes green against a guard whose connect-time
classification had been deleted. With a live listener it reds. A self-attester has no reason to
build the harder version, and no way to prove they did.
authority_separation
This is a claim about what the provider does not have — that the workload egress edge holds
no plane credential, and that workload and plane traffic ride separate sealed authorities. A
party cannot attest to its own non-possession. The evidence for “I do not hold this” is the
absence of something inside a boundary only that party can see.
Docker is at least architecturally positioned to prove it rather than assert it: two
containers on two routes, and a guard whose environment is compiled by the Runner, so its
contents are Checkfu-authored fact rather than a provider report. Note that positioning is not
proof, and Checkfu does not claim it as one — authority_separation is one of the two facts
the owned Docker matrix still does not establish, because it needs a real Run through the
transport. The difference between “structurally provable” and “proved” is exactly the
difference this grade is measuring.
The rule is not aimed at strangers, and E2B is the proof. E2B validates the two authorities
separately and then flattens them into the provider’s single allowOut list, because the
provider API exposes no authority dimension at all. That fact alone holds a shipped first-party
integration at advisory_filter. A partner is being held to a bar Checkfu already failed to
clear on one of its own providers.
default_deny
The claim quantifies over the complement of the implementation: when any other fact is absent,
nothing gets out. A suite the implementer wrote enumerates the paths the implementer thought
of — which is exactly the set default-deny exists to backstop.
Checkfu’s matrix includes a case that only exists because the tester assumed the workload would
be hostile to the mechanism: no route at all when the workload simply ignores the proxy
environment variables. That case is not discoverable from a cooperative reading of your own
design.
What a signature proves
Receipts travel as a detached Ed25519 signature over domain-separated canonical bytes (checkfu.sandbox-egress-conformance.v1) from an attester named in the reviewed
SANDBOX_EGRESS_CONFORMANCE_ATTESTERS set. That mechanism proves authorship and integrity:
this exact statement came from this exact key and was not altered.
It does not, and cannot, prove the statement. Adding a partner key to the attester set would not
make a partner’s claims true — it would make Checkfu’s reviewed set include a signer whose
claims Checkfu has not verified, which is the same thing as deleting the grade.
The current posture
SANDBOX_EGRESS_CONFORMANCE_ATTESTERS is empty.
No provider has
security_boundary today — including Checkfu’s own. A
security_boundary-requiring profile is currently refused by every provider. That is the
decision working, not a gap: the grade is not purchasable by configuration, so the
requirement stays unsatisfiable until an owned matrix runs and the release authority publishes
an attester key in a reviewed change.
The Worker-hosted runner’s cloud-vendor adapters (Daytona, E2B, Vercel) sit at
advisory_filter
too, and their grade does not carry over from the identically named Node adapters: a receipt
for checkfu:daytona-provider@2 says nothing about a *-worker-provider@* revision. Same
provider name, different exact revision, separate evidence.
So the third-party rule is not a stranger tax layered on top of a privilege Checkfu enjoys. It
is the same rule, and Checkfu is currently on the same side of it.
The enforcement ceiling gap
Egress grading is the solved half of the honesty problem. The unsolved half is larger, and a partner should know it is open because it gates when this seam can be published.SandboxEnforcement — the nine-axis authority statement — is not a field of
RunnerProviderCapability. The server-owned enrollment ceiling that intersects a Runner’s
drivers, launch_kinds, tiers, platforms, network_modes, retention_modes,
mount_kinds, runtime_assurances, snapshot_clone, snapshot_custody, and
package_materialization therefore never touches the enforcement statement.
Nor is enforcement the only axis that escapes it. RunnerProviderCapability also omits
egress_certification (compared Runner-locally at selection), image_mode,
fixed_base_images, package_managers, snapshots, and list_dir — every one of them
declared Runner-locally with nothing in the enrollment able to contradict it.
list_dir is the one that reaches a customer-visible outcome on its own. It gates memory
writeback under D38, so a provider admitted for memory mounts can decline writeback
Runner-locally and the Run records a visible skip — correct behavior, but the enrollment that
admitted the mount never had a say in it.
In-tree that is harmless: the only authors are Checkfu’s own adapters, and runner_enforced is
true because the Runner set the flags itself. It stops being harmless the moment a stranger
authors one.
The concrete consequence is on the openProcess evidence cross-check. Today it compares a
provider’s per-process evidence.enforcement against capabilities.enforcement — where the
right-hand side is a constant compiled into the trusted Runner. That is provider statement
versus Runner-owned fact. Over a wire, both sides are authored by the same partner, and the
comparison degenerates into a self-consistency check. It still catches a partner whose
per-process evidence disagrees with its own advertisement, which is a real class of bug. It
catches nothing about physical isolation.
Three existing mechanisms close it, and all three are reuse rather than invention: cap the
authority vocabulary by placement so a non-Runner may not say runner_enforced; add
enforcement to RunnerProviderCapability and intersect it with the operator-issued enrollment
ceiling every other axis already uses; and bind the envelope to an attributable signed
materialization statement. None of that makes the claim true. It makes it ceilinged and
attributable, which is the most a wire can offer — physical truth still comes from a
Checkfu-run matrix, exactly as egress_certification already requires.
What openProcess costs across a wire
openProcess is the one member of the contract that is a live object rather than a value. It
does cross a network boundary — the design is complete and a spike drove a real ACP agent
across it, including a connection severed mid-turn — but it crosses at a stated cost. Three
guarantees the in-process handle makes do not survive, and all three are named here rather than
engineered around.
Real stdin backpressure becomes a credit window
In-process, the writable stream handed to the driver is the child’s actual OS pipe: a slow guest slows the writer, and the flow control is physical. Across a wire it cannot be. TCP or HTTP/2 flow control on the Runner↔provider hop does not reach the provider↔guest stdin pipe — the provider must accept and buffer. So backpressure becomes an explicit credit window: the provider grantsinput_credit bytes at open and refreshes it on
every accepted write, the Runner may not have more than that outstanding, and overrun is refused
as input_buffer_full and retried after the next grant. When the guest’s stdin pipe blocks, the
provider simply stops granting.
This is a new failure mode that does not exist today, and the exposure is not small. An
earlier revision of this page said it was, citing a 1 MiB frame ceiling and a one-shot driver
that writes a single prompt and closes. Both citations were wrong and are withdrawn:
ACP_MAX_FRAME_BYTESbounds the other direction. It is read in exactly one place, insideboundAcpOutput, which is applied tooutputand only tooutput—inputis passed raw. There is no frame bound on the stdin direction anywhere in the repository.- The one-shot reassurance describes a harness nobody can currently launch.
oneshot-v1’s sole catalog entry isavailability: "blocked"; every other packaged entry isacp-v1, so the ACP case is the real one.
resume_blob, whose entire
schema constraint is a minimum length — no maximum, and harness-authored. It is bounded only
transitively and by accident: the blob arrives as a session/update on the output side, so
boundAcpOutput errors the stream above 1 MiB and no larger blob is ever received. Nothing on
the stdin path re-checks it, and base64 turns ≈1 MiB into ≈1.37 MiB inside one session/new
frame. Its neighbours have no accidental ceiling at all: mcpServers is unbounded by server
count, and builtinTools, continuity, and runtimeConfig are unbounded outright.
input_buffer_full is therefore a condition your implementation must have a real answer for,
not a corner case.
stdout is lossless only within a declared replay window
In-process, the readable stream is the child’s pipe. Between child and driver nothing is dropped, and no window is involved. Across a wire, resume after a dropped connection requires a bounded replay journal. A Runner disconnected longer thanoutput_window_bytes cannot be served a correct suffix, and asking for
a cursor below the journal’s low-water mark is refused as output_truncated.
The design fails closed: output_truncated terminates the process rather than delivering a
hole, because a gapped NDJSON stream cannot be resynchronised and a silent hole would corrupt
the transcript. That is the right behavior and it is still a loss. Stated without softening:
Downstream “backpressure” is this journal bound, not flow control. It is a fail-closed ceiling,
not throttling.
evidence stops being an isolation cross-check
Restated here because it is the loss most likely to be forgotten. evidenceMatches is sixteen
clauses. Nine bind evidence to state the Runner already holds — instance, provider and
materialization revisions, root image, platform, profile digest, network mode, resource limits —
and those survive a wire intact and unweakened, because the reference side is
Runner-owned. A remote provider that starts a process on another image or under another network
mode is caught exactly as it is today. Six more are internal consistency of the evidence object
and were never cross-party.
One clause is genuinely cross-party, and it does not survive: the comparison of
evidence.enforcement against capabilities.enforcement. See
the enforcement ceiling gap.
On the wire seam, evidenceMatches is an identity and self-consistency check. It is not, and
cannot be, an isolation check.
What is not lost
Worth stating, because it bounds the anxiety:- Cross-channel interleaving. stdout and stderr have no ordering guarantee relative to each other today either — the in-process shape is two independent pipes. A wire loses nothing that exists.
- Chunk boundaries. Nothing observes them. ACP reframes on newlines; the one-shot driver concatenates to EOF. Re-chunk freely.
- Multiplexing. At most one live process per instance. The Docker adapter reserves it today and the wire design inherits the rule, so there is no multiplexing to build — though the reservation is yours to keep, not the runtime’s.
- The stream identity check. A transport shim constructs the three Web Streams itself, so the check passes by construction. It is a requirement to satisfy, not a thing to transport.
- stderr fidelity. It is never a semantic channel — piped to the Runner’s own stderr under a debug flag, or discarded. It needs a bound and best-effort delivery, not exactly-once.
- Exactly-once stdout across a mid-process drop. Enforced by the reader’s sequence filter, so a provider that lazily replays its whole journal on reconnect is still correct. Proved by the spike, including a drop injected after frames had actually been applied.
What is not yet proven
TheopenProcess wire was spiked end to end and every case passed, five consecutive runs. The
spike’s green output is narrower than it reads, and these are the gaps:
Summary: what to treat as settled
Settled and safe to build against: the grading rule and its total order; the five facts and which three you cannot self-attest; the admission comparison and where it fails. Two of the three wire losses fail closed and announce themselves —input_buffer_full is
typed and retryable, output_truncated terminates the process rather than serving a gap. The
third does not. The evidence cross-check does not fail when it degrades; it keeps passing and
simply means less, because both sides of the comparison end up authored by the same partner.
Nothing in the system currently records that difference, which is exactly why the enforcement
ceiling is called blocking rather than pending.
Not settled: the enforcement ceiling (blocking), the egress-grade ceiling on
RunnerProviderCapability (blocking), the out_end/err_end and window frames, the sizing
of output_window_bytes, and everything in
the readiness table.
Next steps
- Sandbox providers — the concept page and the publication readiness table.
- Sandbox provider contract — the operations, the optional members, and the minimum provider.
- Security — where a SandboxProfile’s network policy sits relative to a Connection’s egress rules, and why the latter is the stronger boundary.