You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Platforms deploying agents as bare Sandbox CRs, using the agent-sandbox controller directly without an OpenShell Gateway, have no path to enable OpenShell security on those agents without deleting and recreating the CR.
The Sandbox CR is often the source of truth for a running agent's configuration (image, env vars, ports, PVCs, annotations). Deleting it loses that state, PVCs are garbage-collected via owner references, and post-deploy config changes are lost.
Proposed Design
Technical Context
OpenShell enriches Sandbox CRs at creation time, injecting the supervisor, capabilities, credentials, and policy enforcement into spec.podTemplate. A bare Sandbox CR created outside the Gateway runs the agent image directly without any of this.
The Gateway watcher already sees bare CRs (no label filter), but has no mechanism to retroactively apply enrichment to them. CreateSandbox returns AlreadyExists if the name is taken. The only current path is delete and recreate, which loses the CR and its owned resources.
Proposed Design
Add an AdoptSandbox RPC to the compute driver and public API.
Behavior:
GET existing Sandbox CR (fail with NotFound if absent)
Mutating admission webhook: enriches CRs on label change. More Kubernetes-native but more complex. Could be future evolution (Kubernetes Operator #1719).
Agent Investigation
AdoptSandbox RPC — Feasibility Summary
Complexity: Medium-High Confidence: High — all code paths read end-to-end Estimated files to change: 8-12 Issue type: feat
Why it's feasible
The enrichment logic is well-encapsulated in three functions that already accept &mut serde_json::Value pod templates:
apply_workspace_persistence() (driver.rs:1245-1334) — PVC init container, volume mount
sandbox_template_to_k8s_with_gpu_requirements() (driver.rs:1507-1788) — env vars, TLS mounts, SA token projection
The watcher already sees bare CRs (uses ListParams::default(), no label filter). The store-first-then-driver pattern from CreateSandbox is directly reusable.
Why it's not trivial
No patch operations exist in the K8s driver today — only create, get, list, delete. Need to add kube::api::PatchParams / Api::patch() or server-side apply.
Enrichment builds from scratch, not merges — sandbox_to_k8s_spec() constructs the full containers array rather than merging into an existing one. Refactoring needed.
StopSandbox is unimplemented — the K8s driver returns Status::unimplemented. Adopt needs suspend/resume for pod restart. This is a prerequisite.
29 enrichment items must be injected (supervisor sidecar, 6 env vars, mTLS volume, SA token projection, capabilities, workspace PVC, init containers, labels, etc.).
Conflict resolution is a design decision — bare CRs may already have containers named "agent", existing runAsUser, or PVCs at /sandbox. No existing pattern for this.
Critical design decisions needing human input
Conflict resolution: Overwrite (simple, may break workload) vs merge-with-precedence (complex, safer) vs fail-on-conflict (safest, most restrictive)
Agent container identification: Bare CRs won't name their container "agent" — require it, target containers[0], or accept name in request?
Pod restart: Does the agent-sandbox controller recreate pods on podTemplate change, or must we delete the pod manually? Needs controller behavior verification.
Idempotency: Re-adopt for supervisor upgrades, or reject already-adopted CRs?
Problem Statement
Platforms deploying agents as bare Sandbox CRs, using the agent-sandbox controller directly without an OpenShell Gateway, have no path to enable OpenShell security on those agents without deleting and recreating the CR.
The Sandbox CR is often the source of truth for a running agent's configuration (image, env vars, ports, PVCs, annotations). Deleting it loses that state, PVCs are garbage-collected via owner references, and post-deploy config changes are lost.
Proposed Design
Technical Context
OpenShell enriches Sandbox CRs at creation time, injecting the supervisor, capabilities, credentials, and policy enforcement into
spec.podTemplate. A bare Sandbox CR created outside the Gateway runs the agent image directly without any of this.The Gateway watcher already sees bare CRs (no label filter), but has no mechanism to retroactively apply enrichment to them.
CreateSandboxreturnsAlreadyExistsif the name is taken. The only current path is delete and recreate, which loses the CR and its owned resources.Proposed Design
Add an
AdoptSandboxRPC to the compute driver and public API.Behavior:
spec.podTemplate— preserve user's image, env vars, ports, volumessandbox_to_k8s_spec()— same code path as Create, merging with existing spec rather than overwritingspec.podTemplate+openshell.ai/managed-byandopenshell.ai/sandbox-idlabelsoperatingMode→Suspended(controller deletes old pod)operatingMode→Running(controller creates new pod from enriched spec)The CR is never deleted. Same UID, same PVCs, same user annotations. The pod restarts with the supervisor.
Merge semantics: Preserve user's image, env, ports, volumes. Append OpenShell env vars and volumes. Override container command to supervisor entrypoint (documented breaking change). Inject supervisor init container.
Proto: New
rpc AdoptSandbox(AdoptSandboxRequest) returns (SandboxResponse)in bothopenshell.protoandcompute_driver.proto.RBAC: Add
patchverb to the K8s Role forsandboxes.agents.x-k8s.io.Alternatives Considered
sandbox_to_k8s_spec()output. Fragile, breaks on upstream changes.Agent Investigation
AdoptSandbox RPC — Feasibility Summary
Complexity: Medium-High
Confidence: High — all code paths read end-to-end
Estimated files to change: 8-12
Issue type: feat
Why it's feasible
The enrichment logic is well-encapsulated in three functions that already accept
&mut serde_json::Valuepod templates:apply_supervisor_sideload()(driver.rs:1124-1228) — supervisor binary, runAsUser:0, capabilitiesapply_workspace_persistence()(driver.rs:1245-1334) — PVC init container, volume mountsandbox_template_to_k8s_with_gpu_requirements()(driver.rs:1507-1788) — env vars, TLS mounts, SA token projectionThe watcher already sees bare CRs (uses
ListParams::default(), no label filter). The store-first-then-driver pattern from CreateSandbox is directly reusable.Why it's not trivial
kube::api::PatchParams/Api::patch()or server-side apply.sandbox_to_k8s_spec()constructs the full containers array rather than merging into an existing one. Refactoring needed.StopSandboxis unimplemented — the K8s driver returnsStatus::unimplemented. Adopt needs suspend/resume for pod restart. This is a prerequisite.runAsUser, or PVCs at/sandbox. No existing pattern for this.Critical design decisions needing human input
patchverb added — Helm chart update required.Recommended phasing
StopSandbox(prerequisite)Checklist