Summary
Apply pod-level and container-level securityContext to all agent pods as part of L1 (Hardened Container) isolation. This restricts process privileges, filesystem access, and syscall surface using standard Kubernetes APIs — no infrastructure changes required.
Target Spec
spec:
securityContext:
runAsNonRoot: true
runAsUser: 65534 # nobody user
fsGroup: 65534
containers:
- name: agent
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
seccompProfile:
type: RuntimeDefault
What Each Field Prevents
| Field |
Effect |
runAsNonRoot: true |
Pod fails to start if image uses root — prevents privilege escalation from root inside container |
runAsUser: 65534 |
Forces UID 65534 (nobody) — consistent non-root identity across all agents |
readOnlyRootFilesystem |
Container filesystem is read-only — prevents writing malicious binaries, modifying system files, persisting backdoors |
allowPrivilegeEscalation: false |
Blocks setuid/execve gaining elevated privileges — prevents SUID binary exploits |
capabilities.drop: ["ALL"] |
Removes all Linux capabilities — blocks NET_RAW, SYS_ADMIN, SYS_PTRACE, NET_BIND_SERVICE |
seccompProfile: RuntimeDefault |
Blocks ~50 dangerous syscalls (reboot, mount, ptrace, kexec_load, add_key, etc.) |
Writable Volume Mounts
Since readOnlyRootFilesystem is enabled, agents need explicit emptyDir mounts for writable paths:
spec:
containers:
- name: agent
volumeMounts:
- name: tmp
mountPath: /tmp
- name: agent-workspace
mountPath: /data
- name: pip-cache
mountPath: /home/nobody/.cache
volumes:
- name: tmp
emptyDir:
sizeLimit: "1Gi"
- name: agent-workspace
emptyDir:
sizeLimit: "5Gi"
- name: pip-cache
emptyDir:
sizeLimit: "2Gi"
Writable Paths by Agent Framework
| Framework |
Required Writable Paths |
Reason |
| Python (general) |
/tmp, /home/nobody/.cache/pip |
Temp files, pip package cache |
| Python + OpenLLMetry |
/tmp, /home/nobody/.cache, possibly /home/nobody/.local |
sitecustomize.py bootstrap writes to cache |
| Node.js |
/tmp, /home/nobody/.npm, /data/node_modules |
npm cache, module installation |
| Java |
/tmp |
Temp files; JAR-based agents rarely need writable fs |
| Go (compiled) |
/tmp |
Minimal needs; binary agents are the easiest case |
Note: The sizeLimit on emptyDir volumes is enforced by kubelet eviction — if the agent exceeds the limit, the pod is evicted. This prevents a compromised agent from filling the node's disk.
Prerequisites
- Agent images must run as non-root. Build pipeline should enforce:
RUN adduser --disabled-password --gecos '' --uid 65534 agent
USER agent
WORKDIR /data
Implementation Notes
- OpenChoreo controller must preserve (not override) securityContext fields from podTemplate
Acceptance Criteria
Summary
Apply pod-level and container-level
securityContextto all agent pods as part of L1 (Hardened Container) isolation. This restricts process privileges, filesystem access, and syscall surface using standard Kubernetes APIs — no infrastructure changes required.Target Spec
What Each Field Prevents
runAsNonRoot: truerunAsUser: 65534readOnlyRootFilesystemallowPrivilegeEscalation: falsesetuid/execvegaining elevated privileges — prevents SUID binary exploitscapabilities.drop: ["ALL"]NET_RAW,SYS_ADMIN,SYS_PTRACE,NET_BIND_SERVICEseccompProfile: RuntimeDefaultreboot,mount,ptrace,kexec_load,add_key, etc.)Writable Volume Mounts
Since
readOnlyRootFilesystemis enabled, agents need explicitemptyDirmounts for writable paths:Writable Paths by Agent Framework
/tmp,/home/nobody/.cache/pip/tmp,/home/nobody/.cache, possibly/home/nobody/.localsitecustomize.pybootstrap writes to cache/tmp,/home/nobody/.npm,/data/node_modules/tmp/tmpPrerequisites
Implementation Notes
Acceptance Criteria
/var/log) with read-only rootfs/tmp,/data, and framework-specific cache pathssizeLimitenforced — pod evicted if exceeded