Skip to content

feat: support provider attach and detach for running sandboxes #1171

@johntmyers

Description

@johntmyers

Problem Statement

Issue #1081 adds a custom provider profile registry, but sandbox provider attachments are still effectively fixed at sandbox creation time. The next provider v2 chunk from #896 should let operators and agents attach or detach providers from a running sandbox and have the effective policy update reflect the sandbox's current provider set.

This is the runtime lifecycle step needed after profile import/export: create or import a profile, create a provider of that profile type, attach that provider to a sandbox, verify the profile-generated policy layer appears, detach it, and verify the effective policy returns to the previous state.

Related: #896, #1081, #1170

Proposed Design

Add a gateway and CLI surface for mutating a sandbox's attached provider list after creation. The attachment should be provider-record based, not a raw profile id, because the current model stores providers separately from profiles and derives profile policy from Provider.type.

Suggested CLI shape:

openshell sandbox provider list <sandbox>
openshell sandbox provider attach <sandbox> <provider-name>
openshell sandbox provider detach <sandbox> <provider-name>

Equivalent API shape could be explicit RPCs such as:

ListSandboxProviders
AttachSandboxProvider
DetachSandboxProvider

or an update operation with attach/detach semantics, as long as it avoids accidental full replacement of the provider list.

Expected behavior:

  • Attach validates that the sandbox exists.
  • Attach validates that the provider exists.
  • Attach is idempotent when the provider is already attached.
  • Detach validates that the sandbox exists.
  • Detach is idempotent or returns a clear not-attached result; choose the convention that best matches nearby APIs.
  • Attach/detach updates the persisted sandbox provider list using the existing sandbox object/schema.
  • Effective policy composition remains JIT and reads the current provider list from storage.
  • When providers_v2_enabled is true, attaching a provider whose Provider.type maps to a built-in or custom profile adds that profile-generated policy layer on the next running policy/config refresh.
  • Detaching that provider removes the profile-generated policy layer on the next running policy/config refresh.
  • When providers_v2_enabled is false, attach/detach should update the provider list without adding provider-profile policy layers.
  • Existing credential injection behavior remains unchanged in this issue unless a safe runtime refresh path already exists. Do not introduce profile-defined credential injection here.

Running sandbox policy behavior is the key acceptance path. If the supervisor already refreshes policy/config periodically or on demand, use that mechanism. If not, add the smallest gateway-to-supervisor notification or refresh trigger needed so a running sandbox observes provider attachment changes without restart.

Alternatives Considered

  • Attach raw profile ids to sandboxes. This does not match the current schema or provider credential model; sandboxes attach provider names, and profile policy is derived through Provider.type.
  • Fold this into profile import/export. That would make feat: support custom provider profile import and export #1081 too broad and mix registry management with running sandbox lifecycle behavior.
  • Wait for profile-defined credential injection. Policy attach/detach can be validated independently now, while credential injection refresh can remain a later provider v2 chunk.

Definition of Done

  • Gateway exposes an attach provider operation for existing sandboxes.
  • Gateway exposes a detach provider operation for existing sandboxes.
  • Gateway exposes a way to list providers attached to a sandbox, or reuses an existing sandbox get/list response clearly enough for CLI UX.
  • Attach validates sandbox existence and provider existence.
  • Attach/detach preserve existing sandbox fields and mutate only the attached provider list.
  • Attach/detach do not create duplicate provider entries.
  • Attach/detach semantics are documented in API/handler tests, including idempotency or clear errors.
  • CLI supports attaching a provider to a sandbox.
  • CLI supports detaching a provider from a sandbox.
  • CLI supports listing attached providers for a sandbox or clearly shows attachments through an existing command.
  • With providers_v2_enabled=false, attach/detach does not add provider-profile policy layers.
  • With providers_v2_enabled=true, attaching a provider backed by a built-in profile adds that provider profile policy layer on the next effective policy/config fetch.
  • With providers_v2_enabled=true, attaching a provider backed by a custom profile adds that custom provider profile policy layer on the next effective policy/config fetch.
  • Detaching a provider removes that provider profile policy layer on the next effective policy/config fetch.
  • Test coverage includes the full lifecycle: create/import profile, create provider, create sandbox, capture baseline effective policy, attach provider, verify policy includes provider layer, detach provider, verify policy returns to baseline.
  • Running sandbox behavior is covered by an integration test or the closest available supervisor/config-refresh test.
  • Existing provider credential injection behavior is unchanged by this issue.
  • Internal architecture notes are updated if the attach/detach flow changes provider lifecycle semantics.

Non-Goals

  • Do not implement profile-defined credential injection in this issue.
  • Do not implement OAuth refresh or token-store refresh in this issue.
  • Do not add a new sandbox profile attachment field unless the existing provider-name attachment model proves insufficient.
  • Do not persist composed effective policy revisions; effective policy should remain derived from current inputs.
  • Do not change default provider behavior when providers_v2_enabled is false.

Agent Investigation

PR #1170 establishes the custom profile registry and confirms custom profiles participate in JIT policy composition when referenced by the current sandbox provider list. The missing lifecycle surface is mutating that provider list after sandbox creation and proving a running sandbox observes policy changes when providers are attached or detached.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions