Repository navigation
feat: support provider attach and detach for running sandboxes #1171
Description
Activity
- addedarea:cliCLI-related workCLI-related workarea:policyPolicy engine and policy lifecycle workPolicy engine and policy lifecycle workarea:gatewayGateway server and control-plane workGateway server and control-plane work
on May 5, 2026 - added a parent issue
on May 5, 2026 🏗️ build-plan
Implementation Plan
Issue type:
feat
Complexity: Medium
Confidence: High — the sandbox already stores provider attachments inSandboxSpec.providers, and effective policy/provider env resolution already reads that list JIT.Summary
Add provider attach/detach/list lifecycle support for existing sandboxes. The implementation will mutate the persisted sandbox
spec.providerslist, rely on the existing JIT effective-policy and provider-env fetch paths to observe the current attachments, and keep the credential boundary explicit: already-running process environments are not mutated, while future process/session launches resolve from the current sandbox attachments.Scope
proto/openshell.proto: add sandbox provider list/attach/detach RPCs plus request/response messages.crates/openshell-server/src/grpc/mod.rs: wire new RPCs into the OpenShell service.crates/openshell-server/src/grpc/sandbox.rs: implement validation, idempotent provider attachment mutation, provider existence checks, duplicate avoidance, and list behavior using the existing sandbox object/schema.crates/openshell-server/src/auth/authz.rs: add authz mappings for the new RPCs, using sandbox read/write scopes consistent with nearby sandbox lifecycle operations.crates/openshell-cli/src/main.rs: addopenshell sandbox provider list|attach|detachCLI shape.crates/openshell-cli/src/run.rs: call the new RPCs and render concise user-facing output.- CLI integration test stubs under
crates/openshell-cli/tests/: update fake OpenShell services for the new generated trait methods and add focused CLI coverage where practical. - Gateway unit tests in
crates/openshell-server/src/grpc/sandbox.rsand/or policy tests incrates/openshell-server/src/grpc/policy.rs: cover attachment mutation, policy composition effects, and provider env resolution from the current provider list.
Implementation Steps
- Extend protobuf API with
ListSandboxProviders,AttachSandboxProvider, andDetachSandboxProvider, then update generated bindings through the normal build path. - Implement gateway handlers that fetch sandboxes by name, validate provider existence for attach, mutate only
spec.providers, preserve sandbox metadata/status/policy, and persist through the existing object store. - Wire authz/service dispatch and add gateway tests for validation, idempotency, duplicate avoidance, and detach/list behavior.
- Add CLI subcommands under
openshell sandbox providerand implement list/attach/detach output. - Add tests proving JIT policy/env behavior uses the current persisted attachments: attach adds provider profile policy when v2 is enabled, detach removes it, v2 disabled does not add provider-profile policy, and provider env resolution reflects the updated provider list for future launches.
- Update generated test service implementations and CLI integration tests for the new API surface.
Test Plan
- Unit tests: Gateway handler tests for attach, detach, list, missing sandbox, missing provider, idempotent attach, duplicate avoidance, and preservation of existing sandbox fields.
- Policy/config tests: Effective policy tests showing attach/detach changes provider profile layers through current sandbox attachments when
providers_v2_enabled=true, and no provider-profile layer when false. - Credential boundary tests: Provider env tests showing resolution reads the current sandbox attachment list after attach/detach; no attempt is made to mutate already-running process env.
- CLI tests: Argument parsing and/or integration tests for
openshell sandbox provider list|attach|detachcalling the expected RPCs and surfacing clear output/errors. - E2E tests: N/A unless implementation needs to modify existing
e2e/coverage; the behavior can be covered with gateway and CLI integration tests against fake services/object stores.
Risks & Open Questions
- The generated gRPC trait change will require updating every fake OpenShell service in tests; this is mechanical but easy to miss.
- Exact detach semantics should follow nearby API style. The proposed default is idempotent detach with a clear success response, since attach is explicitly idempotent and repeated lifecycle commands should be script-friendly.
- If existing exec/session launch code only obtains provider env once at sandbox startup, this issue should add the smallest fetch/refresh point for future launches, but it should not add a harness restart primitive.
Documentation Impact
- None for this issue. The issue explicitly excludes published docs and architecture docs; docs can be swept separately.
Revision 1 — initial plan
- addedstate:review-readyReady for human reviewReady for human reviewstate:agent-readyApproved for agent implementationApproved for agent implementationstate:in-progressWork is currently in progressWork is currently in progress
on May 7, 2026 Implemented in PR #1242: #1242
Build notes:
- Added sandbox provider list/attach/detach gRPC APIs and CLI commands.
- Attach/detach update persisted sandbox provider attachments, so JIT effective policy and provider environment resolution follow the current attachment set.
- Attach is idempotent and validates the provider exists; detach is idempotent and can remove stale attachments even if the provider record no longer exists.
- Docs/architecture updates intentionally left out of this scope.
Verification:
- RUSTC_WRAPPER= cargo check -p openshell-server -p openshell-cli
- RUSTC_WRAPPER= cargo test -p openshell-server attach_sandbox_provider --lib
- RUSTC_WRAPPER= cargo test -p openshell-server detach_sandbox_provider --lib
- RUSTC_WRAPPER= cargo test -p openshell-server list_sandbox_providers_returns_attached_provider_records --lib
- RUSTC_WRAPPER= cargo test -p openshell-server sandbox_config_and_provider_env_follow_attached_provider_lifecycle --lib
- RUSTC_WRAPPER= cargo test -p openshell-cli sandbox_provider_subcommands_parse --bin openshell
- RUSTC_WRAPPER= cargo clippy -p openshell-server --lib --tests -- -D warnings
- RUSTC_WRAPPER= mise run pre-commit
- addedstate:pr-openedPR has been opened for this issuePR has been opened for this issueand removedstate:in-progressWork is currently in progressWork is currently in progress
on May 7, 2026 Updated PR #1242 with the provider credential refresh blocker fix.
What changed:
- Added provider_env_revision to sandbox config and provider environment responses.
- Added sandbox-side generation-scoped credential snapshots. Future SSH/exec/SFTP launches read the latest snapshot; already-running processes keep their launch-time env.
- Updated proxy credential resolution to retain recent generations so old placeholders remain resolvable for already-running processes.
- Blocked provider deletion while attached to any sandbox to prevent stale references.
- Added focused tests for revision changes, attach/detach env lifecycle, generation-scoped placeholders, delete blocking, and authz scopes.
Verification:
- RUSTC_WRAPPER= mise run pre-commit
- added a commit that references this issue
on May 8, 2026
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
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.
Credential injection needs an explicit boundary in this issue. Attaching a provider to a running sandbox should affect new process/session launches that resolve provider env from the sandbox's current attachments, but it should not attempt to mutate the environment of already-running processes. Existing long-running harnesses such as Codex, Claude, or OpenClaw may need to be relaunched by the user to observe newly attached provider credentials.
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:
Equivalent API shape could be explicit RPCs such as:
or an update operation with attach/detach semantics, as long as it avoids accidental full replacement of the provider list.
Expected behavior:
providers_v2_enabledis true, attaching a provider whoseProvider.typemaps to a built-in or custom profile adds that profile-generated policy layer on the next running policy/config refresh.providers_v2_enabledis false, attach/detach should update the provider list without adding provider-profile policy layers.Running sandbox 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. The same current-attachment invariant should be used for future process/session launches that perform provider env resolution.
Alternatives Considered
Provider.type.Definition of Done
providers_v2_enabled=false, attach/detach does not add provider-profile policy layers.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.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.Non-Goals
providers_v2_enabledis 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.
Credential injection currently has process-environment constraints independent of provider profiles. This issue should preserve the current injection mechanism, make future process/session launches consult the current sandbox attachments, and explicitly avoid promising runtime env mutation for processes that are already running.