Skip to content

Support OpenShift arbitrary UIDs (restricted-v2 SCC)#84

Open
snecklifter wants to merge 1 commit intovespa-engine:masterfrom
snecklifter:openshift-arbitrary-uid-support
Open

Support OpenShift arbitrary UIDs (restricted-v2 SCC)#84
snecklifter wants to merge 1 commit intovespa-engine:masterfrom
snecklifter:openshift-arbitrary-uid-support

Conversation

@snecklifter
Copy link
Copy Markdown

Summary

  • Make Vespa container images compatible with OpenShift 4.20's default restricted-v2 Security Context Constraint (SCC)
  • Containers can now run under arbitrary UIDs assigned by OpenShift, with file access via GID 0 (root group)
  • Entrypoint injects a /etc/passwd entry at runtime so standard utilities (id, whoami, Go's user.Current()) work

Background: OpenShift SCCs and the root group

OpenShift uses Security Context Constraints (SCCs) to control what pods can do at runtime. The default restricted-v2 SCC enforces:

  • Arbitrary UID assignment: Containers run as a random UID from a namespace-specific range (e.g. 1000660000+), not the UID specified via USER in the Dockerfile
  • GID 0 (root group): The arbitrary UID is always a member of the root group (GID 0). This is by design — the root group is used as the access mechanism for arbitrary UIDs, while the root user (UID 0) remains prohibited
  • No privilege escalation: setuid()/setgid() are blocked; CAP_SETUID and CAP_SETGID are dropped

As stated in the OpenShift documentation:

"The directories and files that are read from or written to by processes in the image should be owned by the root group and be read/writable by that group. Files to be executed should also have group execute permissions [...] because the container user is always a member of the root group, the container user can read and write these files."

Why root group ownership is safe

Using GID 0 as the group owner does not grant root privileges. It simply allows any UID assigned to the root group (which OpenShift always does) to read/write the directories. The actual user remains unprivileged — it cannot escalate to UID 0, bind privileged ports, or perform any root-level operations.

Changes

Dockerfiles (Dockerfile, Dockerfile.minimal)

  • Added -G root to useradd so the vespa user is a member of the root group
  • Made /etc/passwd group-writable (chmod g+w) to allow runtime UID injection
  • Set root group ownership (chgrp -R 0) and group-write permissions (chmod -R g+w) on all writable directories: /opt/vespa/logs, /opt/vespa/var, /opt/vespa/secure, /opt/vespa/var/zookeeper

Entrypoint (include/start-container.sh)

  • Added passwd entry injection for arbitrary UIDs: when whoami fails (UID not in /etc/passwd), a vespa entry is appended mapping the current UID to GID 0
  • Sets VESPA_USER=vespa so downstream scripts resolve correctly

Companion PR

The corresponding Vespa application code changes (user-switching, ownership validation, startup scripts) are in vespa-engine/vespa.

Test plan

  • Build image and run with docker run --user=$(shuf -i 1000000-1999999 -n1):0 to simulate OpenShift
  • Verify whoami returns vespa inside container after entrypoint passwd injection
  • Verify all directories under /opt/vespa/var and /opt/vespa/logs are writable
  • Verify vespa-start-configserver and vespa-start-services succeed under arbitrary UID
  • Confirm no regression when running as default vespa user (UID 1000)
  • Test Dockerfile.minimal build with same arbitrary UID scenario

🤖 Generated with Claude Code

Make container images compatible with OpenShift 4.20's default security
context which assigns arbitrary UIDs with GID 0 (root group):

- Add vespa user to root group (-G root) in both Dockerfiles
- Make /etc/passwd group-writable for runtime UID injection
- Set root group ownership with g+w on all writable directories
- Entrypoint: inject passwd entry for arbitrary UIDs so id/whoami work

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant