diff --git a/apps/api/src/services/k8s-workload-service.ts b/apps/api/src/services/k8s-workload-service.ts index 49225610..6cb49c1e 100644 --- a/apps/api/src/services/k8s-workload-service.ts +++ b/apps/api/src/services/k8s-workload-service.ts @@ -528,14 +528,14 @@ export class K8sWorkloadManager { } // Pod-level security context for StatefulSets — ensures PVC mounts are - // writable by the agent user (UID/GID 1000). fsGroup sets the group owner - // of all files in mounted volumes. UID 1000 matches the `agent` user + // writable by the agent user (UID/GID 1001). fsGroup sets the group owner + // of all files in mounted volumes. UID 1001 matches the `agent` user // created in images/base.Dockerfile and owns /workspace in the image. if (restartPolicy === "Always") { const podSecCtx = new V1PodSecurityContext(); - podSecCtx.fsGroup = 1000; - podSecCtx.runAsUser = 1000; - podSecCtx.runAsGroup = 1000; + podSecCtx.fsGroup = 1001; + podSecCtx.runAsUser = 1001; + podSecCtx.runAsGroup = 1001; podSpec.securityContext = podSecCtx; } @@ -550,7 +550,7 @@ export class K8sWorkloadManager { const initContainers: V1Container[] = []; // For StatefulSets, prepend an initContainer that chowns the home PVC - // mount to UID 1000 (the `agent` user in images/base.Dockerfile). This + // mount to UID 1001 (the `agent` user in images/base.Dockerfile). This // is necessary because some storage classes (docker-desktop's hostpath, // GKE default) don't honor the pod's fsGroup setting, leaving the mount // root-owned and unwritable by the main container. Running chown as @@ -561,7 +561,7 @@ export class K8sWorkloadManager { permInit.name = "home-perm-fix"; permInit.image = spec.image; permInit.imagePullPolicy = spec.imagePullPolicy ?? "IfNotPresent"; - permInit.command = ["sh", "-c", "chown -R 1000:1000 /home/agent && chmod 755 /home/agent"]; + permInit.command = ["sh", "-c", "chown -R 1001:1001 /home/agent && chmod 755 /home/agent"]; const initSec = new V1SecurityContext(); initSec.runAsUser = 0; initSec.runAsGroup = 0; diff --git a/images/base.Dockerfile b/images/base.Dockerfile index f2f5c767..098fb5de 100644 --- a/images/base.Dockerfile +++ b/images/base.Dockerfile @@ -69,11 +69,9 @@ COPY scripts/optio-gh-wrapper /usr/local/bin/optio-gh-wrapper COPY scripts/optio-glab-wrapper /usr/local/bin/optio-glab-wrapper RUN chmod +x /usr/local/bin/optio-git-credential /usr/local/bin/optio-gh-wrapper /usr/local/bin/optio-glab-wrapper -# Non-root user (UID 1000 to match k8s securityContext) -# Ubuntu 24.04 ships with 'ubuntu' user at UID 1000 — remove it first -RUN userdel -r ubuntu 2>/dev/null || true \ - && groupadd -g 1000 agent \ - && useradd -m -s /bin/bash -u 1000 -g 1000 agent \ +# Non-root user (UID 1001 to match k8s securityContext) +RUN groupadd -g 1001 agent \ + && useradd -m -s /bin/bash -u 1001 -g 1001 agent \ && chown -R agent:agent /workspace USER agent WORKDIR /workspace