From 7f51242e74bf1f647172d0950c8a05a2fd3e8003 Mon Sep 17 00:00:00 2001 From: Antoni Segura Puimedon Date: Thu, 21 May 2026 20:23:08 +0200 Subject: [PATCH] ci(runner): enable fuse-overlayfs via user namespaces and custom SCC The fuse-overlayfs binary was added to the runner image in the previous PR but /dev/fuse was not exposed and the SCC blocked the mount syscall. Enable unprivileged FUSE mounts in ARC runner pods by: - Adding the CRI-O annotation to expose /dev/fuse - Running pods in user namespaces (hostUsers: false) so uid 0 maps to an unprivileged host identity - Requesting CAP_SYS_ADMIN explicitly on the container (needed for mount(2) inside the user namespace) - Introducing restricted-v3-fuse SCC: identical to restricted-v3 except it allows SYS_ADMIN in allowedCapabilities, drops only MKNOD and NET_RAW (instead of ALL), and permits uid 0 inside the user namespace via userNamespaceLevel: RequirePodLevel The runner SA must be granted the SCC before deploying: oc adm policy add-scc-to-user restricted-v3-fuse \ -z arc-runner-set-gha-rs-no-permission -n arc-runners Co-Authored-By: Claude Opus 4.6 --- .../restricted-v3-fuse-scc.yaml | 59 +++++++++++++++++++ hack/github-actions-runner/values.yaml | 10 ++++ 2 files changed, 69 insertions(+) create mode 100644 hack/github-actions-runner/restricted-v3-fuse-scc.yaml diff --git a/hack/github-actions-runner/restricted-v3-fuse-scc.yaml b/hack/github-actions-runner/restricted-v3-fuse-scc.yaml new file mode 100644 index 000000000000..a95613eebc8f --- /dev/null +++ b/hack/github-actions-runner/restricted-v3-fuse-scc.yaml @@ -0,0 +1,59 @@ +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: restricted-v3-fuse + annotations: + kubernetes.io/description: >- + Based on restricted-v3 with minimal changes to enable unprivileged + FUSE mounts: allows uid 0 and CAP_SYS_ADMIN inside user + namespaces. userNamespaceLevel: RequirePodLevel ensures these + privileges only exist inside the user namespace and map to + unprivileged host identities. +# Identical to restricted-v3 +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: false +allowPrivilegedContainer: false +readOnlyRootFilesystem: false +priority: null +seLinuxContext: + type: MustRunAs +seccompProfiles: +- runtime/default +userNamespaceLevel: RequirePodLevel +volumes: +- configMap +- csi +- downwardAPI +- emptyDir +- ephemeral +- image +- persistentVolumeClaim +- projected +- secret +users: [] +groups: [] +# Changed from restricted-v3: allow SYS_ADMIN for FUSE mounts +allowedCapabilities: +- NET_BIND_SERVICE +- SYS_ADMIN +requiredDropCapabilities: +- ALL +# Changed from restricted-v3: allow uid 0 inside user namespace +runAsUser: + type: MustRunAsRange + uidRangeMin: 0 + uidRangeMax: 65534 +fsGroup: + type: MustRunAs + ranges: + - min: 0 + max: 65534 +supplementalGroups: + type: MustRunAs + ranges: + - min: 0 + max: 65534 diff --git a/hack/github-actions-runner/values.yaml b/hack/github-actions-runner/values.yaml index bdcd8bf6e29a..969444da22f3 100644 --- a/hack/github-actions-runner/values.yaml +++ b/hack/github-actions-runner/values.yaml @@ -5,11 +5,21 @@ minRunners: 1 maxRunners: 70 template: + metadata: + annotations: + io.kubernetes.cri-o.Devices: "/dev/fuse" spec: + hostUsers: false + securityContext: + runAsUser: 0 containers: - name: runner image: quay.io/redhat-user-workloads/crt-redhat-acm-tenant/hypershift-gh-actions-runner:latest command: ["/home/runner/run.sh"] + securityContext: + capabilities: + drop: ["ALL"] + add: ["SYS_ADMIN"] volumeMounts: - name: go-cache mountPath: /cache/go-build