Repository navigation
bug(sandbox): reconnect, credential renewal and liveness accept a backend Confirm without checking the launch binding #4703
Description
User Story
I maintain an out-of-tree OpenShell compute driver. It runs each workload behind its own isolation backend, which implements IsolationBackend and SandboxProtocol and launches the stock supervisor. I need the supervisor to keep holding the backend to the launch it confirmed, and I need to know how long my backend must keep answering Attach and Confirm replays. Without that, a backend restart can go unnoticed, or a routine credential renewal can terminate a healthy sandbox.
Problem Statement
The delegated client checks a backend's Confirmed against the trusted launch only on the first confirm, in BoundBoundary::confirm (crates/openshell-sandbox-backend/src/runtime.rs). That check covers generation, session, resource claims and provisioning digest. Three later paths in the same file replay Attach and Confirm without repeating it:
- Credential renewal (
ensure_current_credential_connection) checks only that the reply is aConfirmed, viaexpect_response(response, "confirmed")?. - The liveness probe (
connection_is_live) matches only the variant,Ok(Ok(Response::Confirmed { .. })). - Reconnect (
attach_new_channel) discards both the Attach and the Confirm reply, so any non-error response is accepted.
Impact / Why This Matters
- Unconfirmed boundary: a backend that restarts on the same endpoint and loses its launch state can answer the next reconnect, renewal or probe with a different session, claims or provisioning digest. The supervisor keeps the channel and goes on running exec, provider updates and network mediation against a boundary it never confirmed.
- Healthy sandboxes terminated: a backend that follows the written contract can still get its sandboxes terminated. One with a bounded replay ledger, or a strict Attach→Confirm state machine, rejects a late replay, and the sandbox is then terminated after a routine credential renewal.
Acceptance Criteria
- Every
Confirmedthe delegated client accepts (first confirm, reconnect, renewal and liveness) is checked against the trusted launch binding. A mismatch fails closed with an error that names the mismatched field. - On reconnect, a reply of the wrong variant to the replayed Attach or Confirm is rejected.
-
proto/sandbox_protocol.protostates that Attach and Confirm must keep succeeding with the original result for the whole generation, and that the supervisor reuses Confirm for credential renewal and liveness. - Tests cover a backend that returns a different session, claims or digest on reconnect and on renewal.
Reproduction Steps
- Register an external isolation backend under
[[openshell.supervisor.isolation_backends]]and select it with[openshell.drivers.<name>].isolation_backend. Make the backend derive thesession_idinConfirmedfrom its own process start, not from the launch. - Run
openshell sandbox create ...and wait for Ready. - Restart the backend process on the same endpoint.
- Run
openshell sandbox exec .... That forces a reconnect; alternatively, wait for a credential renewal. - Observed: the exec succeeds and the supervisor logs no mismatch. Expected: the supervisor rejects the new confirmation.
Suggested UX (if applicable)
None. No user-facing change; the supervisor logs and the sandbox status show the mismatch.
Environment
- OpenShell:
mainat77929d9c1 - OS: platform-independent (reviewed on a macOS host)
- OpenShell deployment mode and runtime: gateway with an external isolation backend registered by endpoint, stock
openshell-supervisor
Activity
TaylorMutch commentedon Oct 21, 2026
Confirmed by code inspection: the initial backend confirmation is checked against the trusted launch, while credential renewal, liveness, and reconnect previously accepted replay replies without applying the same binding validation. This can preserve a channel after the backend has lost or replaced its launch state.
The issue is actionable and has been accepted for pursuit. PR #4706 covers the affected lifecycle paths; remaining review feedback is tracked on that PR.
fix(sandbox): check every backend confirmation against the launch