Repository navigation
feat(k8s): resolve the sandbox account name for driver-injected numeric UIDs on OpenShift #5034
Description
User Story
I run OpenShell sandboxes on an OpenShift cluster.
OpenShift's restricted-v2 SCC assigns each namespace an allocated UID range, so every sandbox I create runs as a numeric UID like 1000920000.
I need tools inside the sandbox to resolve that UID to the image's sandbox account so shells, prompts, and scripts that display or match on the account name work as they do on other runtimes.
Problem Statement
The Kubernetes driver resolves the namespace's openshift.io/sa.scc.uid-range annotation and runs sandbox pods, init containers, and the supervisor under that numeric UID (by design, from #1959). But nothing reconciles the account name:
- The image's
/etc/passwdstill mapssandboxto its build-time UID, sogetpwuid()fails andid,whoami,ls -l, and shell prompts show the bare number. - The supervisor sets
USERandHOMEfor the canonical process (session_user_and_homeincrates/openshell-sandbox/src/process.rs), which papers over some tools, butLOGNAMEis never set and anything consulting passwd directly still fails. - The VM driver already solves this by rewriting the guest's
/etc/passwd/group/shadow(ensure_sandbox_guest_userincrates/openshell-driver-vm/src/rootfs.rs), but image layers are immutable on Kubernetes, so the Kubernetes driver has no equivalent. - The first-party sandbox runtime image is
FROM scratchwith no passwd file, so the name never resolves there at all.
Impact / Why This Matters
The numeric UID is the SCC working as intended and permissions are unaffected — the breakage is purely in name resolution — but the visible effect is that every OpenShift sandbox presents an anonymous numeric identity.
Workloads and agents that read the account name (shell prompts, dotfile lookup via $HOME-adjacent logic, tooling that logs or matches usernames, and license/entitlement checks as described in #4216) behave differently on OpenShift than on every other OpenShell runtime.
The only current workaround is a per-image entrypoint script that synthesizes a passwd via nss_wrapper (the pattern OpenShift s2i images use), which is per-user burden, cannot cover the first-party scratch image, and does not survive OpenShell's image-entrypoint replacement unless wired in manually.
Proposed Design
When the resolved sandbox identity is numeric, the supervisor should reconcile the account name for the canonical workload process.
Synthesize a passwd/group pair that maps the running UID/GID to the intended account name (defaulting to sandbox, or the image-declared account when the driver knows it), expose it to the workload via the nss_wrapper environment (NSS_WRAPPER_PASSWD/NSS_WRAPPER_GROUP/LD_PRELOAD), and set LOGNAME alongside the existing USER.
The synthesized files belong in the writable runtime-state area, not the image. The environment must apply only to the workload child — the existing LD_PRELOAD sanitization that keeps it away from supervisor and sandbox-runtime processes must be preserved.
Open question for maintainers: always-on when the identity is numeric with no matching passwd entry, or opt-in via driver/gateway configuration.
Acceptance Criteria
- On an OpenShift cluster with an SCC-assigned UID,
idinside a BYO-container sandbox reportsuid=1000920000(sandbox)andwhoamireturnssandbox USER,LOGNAME, andHOMEare set consistently for the canonical process- Dynamically linked tools resolve the account name; statically linked tools continue to work unchanged (numeric display acceptable and documented)
LD_PRELOAD/NSS_WRAPPER_*never appear in the supervisor or sandbox-runtime process environments- The first-party
FROM scratchruntime image is unaffected (no regression, documented limitation) - Non-OpenShift Kubernetes and other runtimes are unchanged
Alternatives Considered
- Accept the numeric UID — display-only, but leaves OpenShift as the only runtime with an anonymous identity and pushes the workaround onto every user.
- Per-image
nss_wrapperentrypoint scripts — works today (OpenShift s2i pattern) but must be repeated in every image, conflicts with entrypoint replacement, and cannot cover the first-party image. enable_user_namespaces (hostUsers: false)— an isolation feature, not a naming fix; OpenShift's user-namespace support is limited and it does not reconcilepasswd.- The Optionally expose the host and user identity #4216 authenticated-username proposal — shares the passwd-reconciliation mechanism but sources the name from the authenticated principal for licensing; the two could share infrastructure while remaining separate options.
Agent Investigation
crates/openshell-driver-kubernetes/src/config.rs—resolve_sandbox_uidreadsopenshift.io/sa.scc.uid-range;resolved UID must fall withinMIN_SANDBOX_UID..MAX_SANDBOX_UID.crates/openshell-sandbox/src/process.rs:187—session_user_and_homesetsUSER/HOME; comment already notes "Numeric identities have no reliable passwd entry."crates/openshell-driver-vm/src/rootfs.rs:1021—ensure_sandbox_guest_usershows the in-repo precedent for name reconciliation (real passwd rewrite, possible because the VM driver owns the rootfs).crates/openshell-driver-vm/src/driver.rs(build_guest_environment) —LD_PRELOADis already filtered from control-plane environments while reaching the workload child, so the proposed env injection fits the existing security model.
Checklist
- I've reviewed existing issues and the published docs
- This is a design proposal, not a "please build this" request
Activity