Skip to content

feat(sandbox): add Kubernetes user namespace isolation #983

Open
mrunalp wants to merge 8 commits intoNVIDIA:mainfrom
mrunalp:feat/kubernetes-user-namespaces
Open

feat(sandbox): add Kubernetes user namespace isolation #983
mrunalp wants to merge 8 commits intoNVIDIA:mainfrom
mrunalp:feat/kubernetes-user-namespaces

Conversation

@mrunalp
Copy link
Copy Markdown
Contributor

@mrunalp mrunalp commented Apr 27, 2026

Summary

Add opt-in Kubernetes user namespace isolation for sandbox pods. When enabled, container UID 0 maps to an unprivileged host UID and capabilities become namespaced, providing defense-in-depth against container escape vulnerabilities.

  • Two-layer configuration: cluster-wide default via OPENSHELL_ENABLE_USER_NAMESPACES / Helm server.enableUserNamespaces (default off), with per-sandbox override via SandboxTemplate.user_namespaces in the API
  • Extended capability set (SETUID, SETGID, DAC_READ_SEARCH) when user namespaces are active, matching the Podman driver's approach
  • GPU + user namespaces warning (compatibility unverified)
  • Supervisor hostPath type changed from DirectoryOrCreate to Directory
  • Architecture docs, security best practices, and OCP testing guide
  • Unit tests for pod spec generation and server-side inversion

Related Issue

Fixes #982

Changes

Proto & config (3 files):

  • proto/openshell.proto — add optional bool user_namespaces to SandboxTemplate
  • crates/openshell-core/src/config.rs — add enable_user_namespaces to Config
  • crates/openshell-driver-kubernetes/src/config.rs — add field to KubernetesComputeConfig

Server & driver wiring (4 files):

  • crates/openshell-server/src/cli.rs — add --enable-user-namespaces CLI arg
  • crates/openshell-server/src/lib.rs — pass config to K8s driver
  • crates/openshell-server/src/compute/mod.rs — translate user_namespaceshost_users in build_platform_config
  • crates/openshell-driver-kubernetes/src/main.rs — add CLI arg for standalone driver

K8s driver (1 file):

  • crates/openshell-driver-kubernetes/src/driver.rs — add platform_config_bool helper, set spec.hostUsers: false, extend capabilities conditionally, change hostPath type to Directory, GPU warning, unit tests

Helm (2 files):

  • deploy/helm/openshell/values.yaml — add enableUserNamespaces: false
  • deploy/helm/openshell/templates/statefulset.yaml — wire env var

Docs (4 files):

  • docs/security/best-practices.mdx — add User Namespace Isolation section
  • architecture/kubernetes-user-namespaces.md — design doc with DinD limitation and Helm deployment guide
  • architecture/kubernetes-user-namespaces-ocp-testing.md — step-by-step OCP reproduction guide

Tests (1 file):

  • e2e/rust/tests/user_namespaces.rs — e2e pod spec verification

Testing

  • cargo test -p openshell-driver-kubernetes — 26 tests pass (8 new for user namespaces)
  • cargo test -p openshell-server --lib — server-side inversion test passes
  • mise run e2e — 31/32 pass (1 pre-existing flaky failure unrelated to this change)
  • E2e user_namespaces test passes against mise run cluster (verifies pod spec)
  • End-to-end validated on OCP 4.22 (K8s 1.35.3, CRI-O 1.35, RHEL CoreOS, kernel 5.14): full SSH tunnel with non-identity UID mapping (0 → 3285581824)
  • End-to-end validated on native K8s v1.37 (CRI-O 1.36, Fedora, kernel 6.19): UID mapping confirmed (0 → 2437873664)
  • Confirmed DinD limitation: pod spec correct but MOUNT_ATTR_IDMAP fails on nested overlayfs (documented)

Checklist

  • Follows conventional commits
  • Unit tests added
  • E2E test added
  • Architecture docs updated
  • User-facing docs updated (docs/security/best-practices.mdx)
  • Helm chart updated
  • Feature defaults to off (no breaking changes)
  • Validated on a real cluster (OCP 4.22)

Open Items

  • Fully automated testing on target k8s clusters.
  • Further testing with gpus

mrunalp added 8 commits April 25, 2026 21:29
Add opt-in support for Kubernetes user namespace isolation on sandbox
pods. When enabled, container UID 0 maps to an unprivileged host UID
and capabilities become namespaced, providing defense-in-depth for the
supervisor process.

Configuration is two-layered: a cluster-wide default via
OPENSHELL_ENABLE_USER_NAMESPACES (default false) and a per-sandbox
override via the new `user_namespaces` field on SandboxTemplate.

When user namespaces are active, the pod security context is extended
with SETUID, SETGID, and DAC_READ_SEARCH capabilities to match the
bounding-set requirements inside a user namespace.
…ation

Address review feedback:
- Emit a warning when GPU and user namespaces are both active on a
  sandbox, matching the risk mitigation documented in the architecture.
- Add a User Namespace Isolation section to the security best practices
  doc covering prerequisites, Helm config, and GPU caveats.
Enable OPENSHELL_ENABLE_USER_NAMESPACES on the gateway, create a
sandbox, and verify the pod spec has hostUsers: false and the extended
capability set (SETUID, SETGID, DAC_READ_SEARCH) required for user
namespace operation.
Explain why user namespaces fail in Docker-in-Docker dev clusters:
nested overlayfs does not support MOUNT_ATTR_IDMAP. Document where
user namespaces work (bare-metal, VM-based, managed K8s) and where
they don't (kind, k3s-in-Docker, old kernels, NFS).
Step-by-step reproduction guide for deploying OpenShell with user
namespace isolation on OpenShift. Covers TLS setup, image push to
the internal registry, supervisor binary distribution via DaemonSet
with SELinux labeling, Helm deploy, CLI configuration, and
end-to-end verification.
Document that user namespaces can be deployed via Helm on any K8s
1.33+ cluster and link to the OCP testing guide. Update verification
section to reflect successful end-to-end validation on OCP 4.22.
Use an explicit sandbox name and deterministic cleanup so the user namespace e2e test cannot inspect the wrong sandbox on a busy cluster. Align the documented Kubernetes requirements with the tested rollout story and save the pre-PR review notes for sharing.
Drop hardcoded binary paths and KUBECONFIG variable assignments.
Readers are expected to have kubectl and helm on their PATH.
@mrunalp mrunalp requested a review from a team as a code owner April 27, 2026 02:21
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented Apr 27, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Kubernetes User Namespace Isolation for Sandbox Pods

1 participant