Skip to content

bug(sandbox): reconnect, credential renewal and liveness accept a backend Confirm without checking the launch binding #4703

Description

@shiju-nv

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 a Confirmed, via expect_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 Confirmed the 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.proto states 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

  1. Register an external isolation backend under [[openshell.supervisor.isolation_backends]] and select it with [openshell.drivers.<name>].isolation_backend. Make the backend derive the session_id in Confirmed from its own process start, not from the launch.
  2. Run openshell sandbox create ... and wait for Ready.
  3. Restart the backend process on the same endpoint.
  4. Run openshell sandbox exec .... That forces a reconnect; alternatively, wait for a credential renewal.
  5. 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: main at 77929d9c1
  • 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

Logs

Activity

  1. added theissue type on Oct 19, 2026
  2. TaylorMutch commented on Oct 21, 2026

    @TaylorMutch
    Collaborator

    📋 triage-agent

    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.

  3. added a commit that references this issue on Oct 21, 2026
    826a94f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:acceptedA maintainer decided OpenShell should pursue this issue

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions