Skip to content

k8s: create workspace group-writable in fs-init so non-root job images can write it#395

Open
DJRH wants to merge 1 commit into
actions:mainfrom
DJRH:fix/novolume-workspace-writable
Open

k8s: create workspace group-writable in fs-init so non-root job images can write it#395
DJRH wants to merge 1 commit into
actions:mainfrom
DJRH:fix/novolume-workspace-writable

Conversation

@DJRH

@DJRH DJRH commented Jul 6, 2026

Copy link
Copy Markdown

Problem

In kubernetes-novolume container mode, a job whose container image runs as a non-root user with a uid other than 1001 cannot write its own workspace — actions/checkout (and anything that writes the workspace) fails with:

/__w/<repo>/<repo>/.git: Permission denied

Images that run as root or as uid 1001 are unaffected, so this only shows up with hardened app images that use a dedicated non-root user (e.g. uid 8001).

Root cause

In novolume mode the workspace lives on an emptyDir that the fs-init container populates. fs-init runs as uid/gid 1001 and creates the work directories with a plain mkdir (default umask 022 → mode 0755):

const initCommands = [
  'mkdir -p /mnt/externals',
  'mkdir -p /mnt/work',
  'mkdir -p /mnt/github',
  'mv /home/runner/externals/* /mnt/externals/'
]
if (workingDirPath) {
  initCommands.push(`mkdir -p /mnt/work/${workingDirPath}`)
}

The pod securityContext sets fsGroup: 1001, so every job container process is a member of group 1001 — but a 0755 directory only grants the group r-x. A job process running as a non-1001 uid therefore has no write permission on the workspace it's supposed to use.

(The classic kubernetes mode isn't affected: there the workspace is a mounted shared volume that Kubernetes makes group-writable via fsGroup, rather than a directory created by fs-init.)

Fix

Set umask 002 in fs-init so those directories are created 0775 (group-writable). Combined with the existing fsGroup: 1001, any job container user can then write the workspace, regardless of its uid.

const initCommands = [
  'umask 002',
  'mkdir -p /mnt/externals',
  ...
]

Testing

  • npm run build-all builds cleanly.
  • Verified on self-hosted kubernetes-novolume runners: with the fix, job containers whose image runs as a non-root uid (≠1001) get a drwxrwsr-x workspace and actions/checkout succeeds where it previously failed with .git: Permission denied.

@DJRH DJRH requested a review from nikola-jokic as a code owner July 6, 2026 16:15
fs-init runs as uid 1001 and mkdir's the work/externals/github dirs at the
default 0755. The pod securityContext uses fsGroup: 1001, so every job
container process is in group 1001 — but 0755 grants the group only r-x, so a
job image running as a non-root uid other than 1001 can't write the workspace
and checkout fails with '.git: Permission denied'.

Set umask 002 in fs-init so those dirs are created 0775 (group-writable),
letting any job user write the workspace via the fsGroup.
@DJRH DJRH force-pushed the fix/novolume-workspace-writable branch from 1f7c4d6 to 3af9543 Compare July 6, 2026 16:27
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