Skip to content

bug(driver-docker): token file not cleaned up when container is already gone with no pending record #3041

Closed
letv1nnn/OpenShell
#12

Description

@politerealism

User Story

As an operator running OpenShell with the Docker compute driver, I want a sandbox's per-sandbox token file removed whenever its resources are reclaimed — including when the container was already removed out-of-band — so that credential material doesn't accumulate indefinitely on disk.

Problem Statement

In crates/openshell-driver-docker/src/lib.rs's delete_sandbox_inner, when find_managed_container_summary finds no container and there's no in-memory pending record for the sandbox, the function returns Ok(false) immediately without calling the token-file cleanup. Every other branch in this function (found container, or a pending record with no live container) does call the cleanup. This is the one gap.

Impact / Why This Matters

#2352 fixed the server-side gap where out-of-band sandbox removal never triggered a DeleteSandbox call at all. Now that it does, Docker's own DeleteSandbox implementation needs to be idempotent-complete for that fix to actually close Docker's leak — right now it isn't, for this specific branch. The result: a sandbox's token file can still leak indefinitely when its container disappears out-of-band and the in-memory pending-record has already expired or was never populated (e.g. after a gateway restart).

Acceptance Criteria

  • delete_sandbox_inner calls the token-file cleanup in the "container gone, no pending record" branch, matching the other branches.
  • Regression test covering this specific branch.

Reproduction Steps

  1. Create a sandbox on the Docker driver.
  2. Remove its container out-of-band (docker rm -f), and ensure enough time/restart passes that the in-memory pending record is gone.
  3. Trigger cleanup (via bug(driver-podman): per-sandbox secrets and volumes are orphaned when a container disappears without DeleteSandbox #2352's fix: a watch deletion event or the prune sweep).
  4. Observe the token file still present on disk.

Environment

Any Docker-driver deployment; not version-specific, this branch predates #2352.

Activity

  1. letv1nnn commented on Sep 8, 2026

    @letv1nnn
    Contributor

    📋 triage-agent

    Triage Assessment

    Classification: validated-bug

    Summary

    Confirmed by direct code read. High confidence.

    Investigation

    delete_sandbox_inner in crates/openshell-driver-docker/src/lib.rs (~line 1042-1105): when find_managed_container_summary returns None (no live container) and remove_pending_sandbox also returns None (no in-memory pending record), execution falls through to return Ok(false); at line 1081 with no call to any token-cleanup function. Every other exit path in this function (live container found, or pending record present with container gone) calls cleanup_sandbox_token_file / cleanup_sandbox_token_file_for_delete before returning. cleanup_sandbox_token_file_by_id(sandbox_id, config) (line 2695) already supports id-only cleanup with no dependency on a PendingSandboxRecord, so the fix is a straightforward added call before the Ok(false) return — no new plumbing required. Related to #2352 (closed), which fixed the server-side gap so out-of-band container removal now reaches DeleteSandbox at all; this issue is the one remaining Docker-side branch that isn't idempotent-complete for that fix to fully close the leak.

    Impact Signals

    • Affected users/scope: Docker-driver deployments only; triggered when a container is removed out-of-band (e.g. docker rm -f) after the in-memory pending record has expired or the gateway has restarted.
    • Regression: No — this branch predates bug(driver-podman): per-sandbox secrets and volumes are orphaned when a container disappears without DeleteSandbox #2352 and was never covered.
    • Workaround: None found; token file persists on disk until manual cleanup.
    • Evidence quality: High — exact code path and missing call confirmed by reading the function directly; no reproduction run needed given the code is unambiguous.

    Human Decision Required

    Decide whether OpenShell should address this issue. If yes, apply
    state:accepted, associate it with a roadmap item, or do both, and decide
    whether the work remains human-owned. Either action records acceptance;
    roadmap placement additionally records sequencing.
    To queue investigation or planning for an unattended agent, also apply
    agent:plan-requested. You can instead directly ask an agent to use
    create-spike or build-from-issue on this issue; the agent will warn about
    missing expected workflow labels and continue without changing them. If no,
    close it as not planned and record the rationale.

    Note: I do not have permission to update labels on this repo (state:triage-needed → state:validated, add area:compute). A maintainer needs to apply these manually.

  2. letv1nnn commented on Sep 8, 2026

    @letv1nnn
    Contributor

    Hey @politerealism, I'd like to take this one.

  3. politerealism commented on Sep 8, 2026

    @politerealism
    ContributorAuthor

    Sounds good tome!

  4. removed
    state:triage-neededOpened without agent diagnostics and needs triage
    on Oct 1, 2026
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions