Skip to content

Container Security

Make containers pass Kupe’s baseline security requirements at deploy time.

Every container must include these security context settings:

spec:
securityContext:
runAsNonRoot: true
containers:
- name: my-app
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
SettingRequiredPurpose
runAsNonRoot: trueYesPrevents running as UID 0 (root)
allowPrivilegeEscalation: falseYesBlocks setuid binaries from gaining privileges
capabilities.drop: ["ALL"]YesRemoves all Linux capabilities
readOnlyRootFilesystem: trueRecommendedPrevents writing to the container filesystem
seccompProfile.type: RuntimeDefaultRecommendedRestricts available syscalls

Required settings are enforced — violations are blocked. Recommended settings are currently logged in audit mode.

Most official images already support non-root. If you’re building your own:

FROM alpine:3.21
# Create non-root user
RUN addgroup -g 65532 -S app && \
adduser -u 65532 -S app -G app
# Set ownership
COPY --chown=app:app ./bin/myapp /app/myapp
# Switch to non-root
USER 65532
ENTRYPOINT ["/app/myapp"]

With readOnlyRootFilesystem: true, use emptyDir volumes for directories that need writes (temp files, caches, uploads):

containers:
- name: app
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir:
sizeLimit: 100Mi

If your application needs a specific capability (e.g., binding to ports below 1024), you can add it back after dropping all:

securityContext:
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]

NET_BIND_SERVICE is the only capability you can add back yourself. If your workload genuinely needs a different capability, request a platform-issued policy exception through the process in Cluster Policies — there is no self-service annotation for it.

”exec format error” after switching to non-root

Section titled “”exec format error” after switching to non-root”

Your image may use a shell script entrypoint without a shebang line. Add #!/bin/sh as the first line, or use the binary directly as the entrypoint.

Move writes to an emptyDir volume. Common paths that need this:

  • /tmp — temp files
  • /var/cache — application caches
  • /var/log — log files (prefer stdout instead)
  • /app/data — application data (use a PVC for persistence)