Repository navigation
feat(kubernetes): map workspaces to sandbox namespaces #2486
Description
Problem Statement
OpenShell now has logical workspaces, but the Kubernetes compute driver still
creates every Agent Sandbox resource in one configured namespace. Workspace
isolation is therefore logical only: platform operators cannot map each
OpenShell workspace to its own pre-provisioned Kubernetes namespace while
retaining one shared gateway.
This is a focused prerequisite for the broader platform-managed sandbox request
in #1678 and the operator-managed model in RFC 0011.
Proposed Design
Add an explicit workspace-to-namespace mapping to the Kubernetes driver:
- Configure a map of OpenShell workspace names to existing Kubernetes
namespaces. - Resolve the target namespace from
DriverSandbox.workspacebefore creating
the Agent SandboxSandboxresource. - Reject sandbox creation for an unmapped workspace when mapping mode is
enabled; never silently fall back to another tenant's namespace. - Keep the existing single
namespacebehavior when no mapping is configured
for backward compatibility. - Make get, delete, list, watch, event lookup, and SCC discovery
namespace-aware across the configured namespace set. - Preserve the logical workspace label and resource-name mapping so the gateway
can reconstruct the workspace from Kubernetes objects. - Do not create or delete namespaces; namespace lifecycle remains
platform-owned. - Surface the map through gateway TOML and Helm values, and document the
required namespaced RBAC.
Prefer bounded namespaced API clients over unrestricted cluster-wide
create/delete permissions. A separately installed workspace chart can bind the
shared gateway ServiceAccount in each mapped namespace. Tests should cover
mapped creation, unmapped fail-closed behavior, duplicate namespace mappings,
cross-namespace list/watch, delete/get resolution, and legacy single-namespace
mode.
Alternatives Considered
- Workspace name always equals namespace: simple but cannot integrate with
platform naming conventions or existing namespaces. - Caller-supplied namespace on every sandbox request: more flexible, but
expands the trusted API surface and requires a separate authorization policy
to prevent namespace confusion. - Cluster-wide list/watch/create/delete: operationally simple but grants
broader permissions than a configured namespace allowlist. - One gateway per namespace: works with the current driver but duplicates
control-plane state and operations.
Agent Investigation
KubernetesComputeDrivercurrently constructs namespaced APIs from one
config.namespace.- Create, get, list, delete, watch, event lookup, and OpenShift SCC discovery
all assume that namespace. - Logical workspaces merged in feat(workspace): add workspace resource model with scoping, membershi… #2243 use workspace-qualified resource names but
do not select a Kubernetes namespace. - RFC 0011 proposes managed and operator workspace namespace modes; the RFC
remains draft. - Support platform-managed Kubernetes sandboxes with namespace, Secret, and SandboxClaim controls #1678 requests a platform-selected namespace as part of a broader set of
platform integration features, but it is not scoped to this independently
deliverable mapping.
Checklist
- I've reviewed existing issues and the architecture docs
- This is a design proposal, not a "please build this" request
Activity
dhirajsb commentedon Jul 27, 2026
dhirajsb commentedon Jul 27, 2026
I am happy to contribute the implementation for this feature rather than leaving it as a request for another contributor.
I have a working experimental implementation on my fork: https://github.com/dhirajsb/OpenShell/tree/codex/k8s-workspace-namespace-mapping
The spike adds an explicit, fail-closed workspace-to-Kubernetes-namespace map and applies it across sandbox create/get/list/delete/watch behavior, OpenShift SCC lookup, and Kubernetes ServiceAccount bootstrap authentication. It preserves the existing single-namespace behavior when no map is configured and includes Rust and Helm tests that pass locally.
If maintainers confirm how this should align with RFC 0011 and the namespaced RBAC work in #2485, I can rebase the branch onto current
main, incorporate the requested direction, and submit the PR with this issue linked.lbelyaev commentedon Jul 27, 2026
The fail-closed-on-unmapped default is the right call, and worth treating as non-negotiable:
namespace_for_workspaceerroring when a configured map has no entry for the workspace — rather than falling back to the legacy namespace — is exactly right, because a silent fallback would put one tenant's sandbox in another tenant's namespace, which is the failure this is meant to prevent. We run a workspace-scoped model and treat any silent widening of a tenant boundary as a defect, not a convenience.On the RFC 0011 coordination question you raised: this mapping and the workspace-authorization work in #2445 are two enforcement layers for the same tenant boundary, and they key the same way. Your
workspace_namespacesmap is keyed by workspace name; #2445 resolves workspace membership by name too (get_message_by_name(&workspace, &subject)). If a workspace is deleted and a new one is created with the same name, both layers can rebind to it off that reused name — independently. If they rebind out of step (one config updated, one stale), a caller authorized for the new workspace could resolve into the old workspace's namespace, or the reverse. Keying both to the workspace's identity rather than its name closes that and keeps the two layers from disagreeing — which is the coordination point worth settling with #2445 before either lands.Second, on attribution: once sandboxes for different workspaces live in different namespaces, the namespace becomes part of the audit story. I see the created object carries
LABEL_SANDBOX_WORKSPACEand lands in the resolved namespace, so the pairing is present at creation — but the workspace→namespace resolution itself isn't recorded as a durable fact, only reconstructable from the label plus wherever the object currently lives. If the map config changes later, re-deriving which namespace a historical sandbox belonged to leans on the current map. Recording the resolved namespace alongside the workspace label at creation would make attribution self-contained rather than dependent on config that may have moved.dhirajsb commentedon Aug 4, 2026
@NVIDIA/openshell-codeowners, could you please help with triage on this proposal?
Does an explicit, fail-closed workspace-to-namespace mapping sound useful for the shared-gateway deployment model? If so, would you be comfortable moving this through validation/acceptance and approving me to contribute the implementation as a PR?
I have an experimental, tested branch linked above and can revise it to address the identity and durable-attribution feedback in this thread. I would also appreciate guidance on whether this should be folded into #1678, RFC-0011, #2445, or another implementation already in progress.