Skip to content

feat(sandbox): add server-managed expiration leases #2591

Description

@waveywaves

Problem Statement

A client that creates a persistent sandbox is currently responsible for eventually deleting it. Process traps handle graceful exits, but a hard process termination, deleted workload pod, node loss, or disconnected orchestrator can leave the logical sandbox and its compute resources running indefinitely.

External reapers can encode expiry in labels and call the gateway later, but every orchestrator must then implement authorization, pagination, race handling, and lifecycle semantics independently. OpenShell should remain the owner of sandbox deletion and provide a first-class bounded lifetime for callers that need it.

Proposed Design

Add an optional server-managed expiration lease to sandbox creation.

  • CreateSandbox accepts either an absolute expiration time or bounded TTL. The default remains no expiration for backward compatibility.
  • The gateway persists the absolute expiry with sandbox metadata and returns it from get/list/watch APIs.
  • An authorized renewal operation extends the lease using optimistic concurrency so a stale client cannot shorten or overwrite a newer lease accidentally.
  • A gateway lifecycle reconciler selects expired sandboxes and invokes the existing DeleteSandbox lifecycle path. It must not delete driver resources directly.
  • Expiration is idempotent, bounded per reconciliation pass, observable through structured lifecycle events, and retried when driver cleanup fails.
  • Authorization to renew or remove an expiry follows existing workspace authorization.
  • A final re-read or resource-version precondition prevents stale expiry observations from deleting a renewed sandbox.
  • Driver-specific orphan cleanup remains responsible for resources that exist after the logical sandbox record is already lost.

The initial API can remain sandbox-scoped. Session-level TTL from #1884 and operator-owned lifecycle from #1719 can build on the same expiration primitive later.

Alternatives Considered

  • External label-based reaper. It works without API changes but duplicates lifecycle logic, requires broad administrative access for cross-workspace cleanup, and cannot guarantee consistent semantics across clients.
  • Kubernetes TTL or owner references. These are useful for Kubernetes-only deployments but bypass OpenShell's gateway lifecycle and do not cover Docker, Podman, or VM drivers.
  • Delete the Task-owned compute resources directly. This can leave gateway state, provider records, and workspace resources inconsistent.
  • Model only session expiry through feat(sandbox): add first-class session and conversation lifecycle support #1884. A sandbox still needs a bounded lifetime when one orchestration invocation maps directly to one sandbox.

Agent Investigation

Checklist

  • I've reviewed existing issues and the architecture docs
  • This is a design proposal, not a "please build this" request

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions