Skip to content

feat(kubernetes): inherit operator-assigned sandbox UID/GID from tenant namespaces #5494

Description

@drew

User Story

I need OpenShell to run agents in dedicated Kubernetes tenant namespaces, where each tenant namespace has a unique operator-assigned UID/GID. Sandboxes must inherit that tenant identity without requiring the sandbox creator to select it in policy YAML.

Problem Statement

OpenShell supports Kubernetes driver-wide sandbox_uid / sandbox_gid overrides and namespace identity discovery through OpenShift SCC annotations. Ordinary Kubernetes namespaces lack an OpenShell-native way for an operator to declare their tenant's workload UID/GID.

Per-sandbox policy selectors do not currently choose arbitrary Kubernetes workload identities. More importantly, caller-controlled selectors would place tenant identity selection with the sandbox creator rather than the tenant operator.

Impact / Why This Matters

A shared OpenShell gateway needs to create sandboxes in multiple tenant namespaces with different workload identities. A single driver-wide identity cannot represent those assignments. Operators need a namespace-scoped source of truth so workloads use the intended permissions for tenant files and mounted storage without duplicating identity configuration in every sandbox request.

Proposed Design

Allow operators to configure the sandbox workload UID/GID on each tenant namespace using OpenShell-specific annotations. All sandboxes created in that namespace inherit the configured pair.

  • Namespace identity is authoritative for sandboxes in that tenant. A conflicting sandbox policy selector is rejected with an actionable error; it cannot override the operator assignment.
  • Require both annotation values when either is present, and validate them as supported non-root numeric IDs. Reject incomplete or invalid configuration rather than silently falling back.
  • Offer an operator-controlled mode requiring namespace identity configuration. In that mode, missing configuration or an inability to read it prevents sandbox creation.
  • Preserve existing default behavior for deployments that have not opted into required namespace identities. Document precedence between namespace assignments, driver-wide settings, and existing OpenShift SCC discovery. Explicit namespace assignments must not be silently ignored in favor of a driver-wide default.
  • Resolve the identity at sandbox creation and retain it across exec, stop/start, and recovery. Namespace changes affect new sandboxes, not existing sandbox identities.
  • Report the resolved UID/GID through sandbox status and explain configuration failures clearly. Kubernetes admission restrictions continue to apply.

Suggested UX

Notional annotation names for review, not existing supported configuration:

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a
  annotations:
    openshell.ai/sandbox-uid: "1500"
    openshell.ai/sandbox-gid: "1600"

The operator provisions this namespace and controls permission to modify its annotations. Users create sandboxes in their assigned tenant namespace through the normal OpenShell workflow, without adding UID/GID selectors to sandbox policy. A sandbox in tenant-a runs as 1500:1600; a sandbox in another namespace uses that namespace's assignment.

The exact annotation names and configuration switch for required namespace identities should be finalized during design review.

Acceptance Criteria

  • A shared gateway can create sandboxes in two tenant namespaces with different operator-assigned UID/GID pairs, and each workload runs with its namespace's pair.
  • Namespace identity configuration applies consistently to workload execution and relevant mounted-storage group handling.
  • Sandbox creators cannot override an assigned tenant identity through policy selectors or sandbox templates; conflicts produce actionable errors.
  • Incomplete, malformed, root, or otherwise unsupported annotation values prevent creation without silent fallback.
  • Required-identity mode rejects missing or unreadable namespace configuration.
  • Exec and sandbox restart/recovery retain the identity selected at creation, even after namespace annotations change.
  • Existing deployments retain their documented behavior unless they configure namespace assignments or enable required-identity mode; precedence with driver defaults and OpenShift SCC annotations is documented and verified.
  • Sandbox status exposes the resolved pair, and published documentation covers operator setup, permissions, precedence, and identity lifecycle.

Alternatives Considered

  • Per-sandbox policy UID/GID: useful for caller-selected identities, but this deployment requires operator-owned tenant assignments and no repeated identity selection in sandbox requests.
  • Driver-wide UID/GID: already supported, but a single pair cannot represent multiple tenant namespaces served by the same driver configuration.
  • OpenShift SCC annotations: existing discovery is relevant and should remain compatible, but ordinary Kubernetes tenant namespaces need a portable OpenShell configuration surface.
  • Namespace labels: could select an administrator-defined execution profile in a future design. Direct numeric execution configuration fits annotations; these values are not needed as resource selectors.
  • Sandbox templates or image USER: the Kubernetes driver writes explicit workload security contexts, so these do not provide the requested namespace identity interface today.
  • Gateway interceptors, supervisor middleware, or credential providers: no existing namespace-identity configuration workflow was identified in these extension points. Operator-managed namespace metadata also keeps the assignment adjacent to tenant provisioning. An existing extension should be preferred if review establishes that it can provide the same enforcement and lifecycle guarantees.

Investigation

Current source behavior:

  • crates/openshell-driver-kubernetes/src/driver.rs: resolve_sandbox_identity_in_namespace resolves driver configuration and OpenShift namespace annotations. Sandbox creation passes the resolved pair into workload provisioning.
  • The driver explicitly writes Pod and workload-container runAsUser / runAsGroup and Pod fsGroup; sandbox templates do not independently select the identity.
  • docs/how-it-works/sandboxes/runtimes.mdx and docs/how-it-works/policies/schema.mdx document current driver-owned Kubernetes identity behavior.

Related context: #1959 (driver-injected sandbox UID), #2697 (Helm UID/GID settings), and #5034 (OpenShift numeric UID account resolution). This request adds portable operator-managed namespace identity configuration.

Activity

  1. added theissue type on Nov 11, 2026
  2. rafamolina1 commented on Nov 11, 2026

    @rafamolina1

    I pushed the implementation and opened PR #5499 for review.

    The change adds namespace-scoped UID/GID assignments for operator workspaces, validates them before provisioning, and preserves the resolved identity across sandbox restarts. It also adds an opt-in strict mode and coverage for tenant isolation, invalid assignments, and restart behavior.

    Local validation passed: 352 Kubernetes driver tests, 479 Helm tests, and 7 operator E2E tests. The focused identity E2E also passed with strict mode, Agent Sandbox v0.4.6, and shared supervisor with TLS. The full remote CI matrix and before/after performance benchmarks were not run.

  3. rafamolina1 commented on Nov 11, 2026

    @rafamolina1

    I got a vouch, Just waiting for an approval, Thank you!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions