Skip to content

fix(ci): keep buildx cache group-writable across runner users - #3304

Merged
Xore merged 2 commits into
mainfrom
fix/buildx-cache-group-write
Sep 25, 2026
Merged

Xore merged 2 commits into
mainfrom
fix/buildx-cache-group-write

Conversation

@Xore

@Xore Xore commented Sep 25, 2026

Copy link
Copy Markdown
Owner

Three PRs (#3297, #3298, #3301, #3302) fail on backend-service with:

ERROR: failed to build: open /var/buildx-cache/backend-service/oci-layout: permission denied

Root cause

/var/buildx-cache/<image> is shared by seven runner users and any of them can take any matrix row. The workflow sets umask 002 before mkdir, but that governs only the workflow's own shell. BuildKit writes index.json, oci-layout and the blobs from inside its buildkitd container, under that container's own umask, so the files land group-read-only.

/var/buildx-cache does carry a default ACL (group:github-ci-runner:rwx), but an inherited ACL entry is still ANDed with the creating process's umask. The result is mask::r--:

group:github-ci-runner:rwx	#effective:r--
mask::r--

So only the runner that happened to write last can build the next image sharing that cache dir. Measured directly on the homeserver:

github-ci-runner:  write OK
github-ci-runner-2: Permission denied
github-ci-runner-3: Permission denied
github-ci-runner-4: Permission denied

Fix

Re-grant group write at the end of scripts/prune-buildx-cache.sh, which the Containers workflow already runs on every job unconditionally (if: always()). The invariant is repaired on the same run that would otherwise poison the next one, rather than needing a separate repair step.

Verification

  • Reproduced the split write access across all four active runner users.
  • Ran the patched script against the live /var/buildx-cache/backend-service; all four runner users then wrote successfully.
  • Full container CI is the proof for the rest.

Non-href card variant was mouse-only and its toggle rendered 0x0 with
no focus target (WCAG 2.4.7/2.5.8). Replace with a real inner button:
visible caret reflecting expanded state, aria-expanded/aria-label,
closest() guard on the card click keeps nested interactives on native
Enter/Space.

Closes #3183
The cache dir is shared by seven runner users, any of which can take any
matrix row. The workflow's `umask 002` governs only its own shell;
BuildKit writes index.json, oci-layout and blobs from inside its buildkitd
container, so those files inherit that container's umask and land
group-read-only. The default ACL on /var/buildx-cache is ANDed with it,
collapsing the mask to r-- and leaving every runner except the last
writer with:

  ERROR: failed to build: open /var/buildx-cache/<image>/oci-layout: permission denied

Re-grant group write at the end of the prune step, which already runs
unconditionally on every job (`if: always()`), so the invariant is
repaired on the same run that would otherwise poison the next one.
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@Xore
Xore merged commit 853fb54 into main Sep 25, 2026
109 of 110 checks passed
@Xore
Xore deleted the fix/buildx-cache-group-write branch September 25, 2026 14:45
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