Harden container images and runtime configuration. Use when building, reviewing, or auditing Containerfiles, Dockerfiles, container compose files, or Kubernetes pod security settings.
How this skill is triggered — by the user, by Claude, or both
Slash command
/prodsec-skills-ge-core:container-hardeningThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Secure container images and runtime configuration to reduce attack surface, prevent privilege escalation, and ensure compliance with Kubernetes security best practices.
Secure container images and runtime configuration to reduce attack surface, prevent privilege escalation, and ensure compliance with Kubernetes security best practices.
ubi8/ubi-minimal or ubi9/ubi-minimal) to reduce attack surfaceRequired for: all profiles (mandatory)
| Source | Strategy |
|---|---|
| Red Hat Catalog | Omit floating tags to get the latest image; exception: Konflux project uses digest-based pinning with automated updates |
| Non-Red Hat registries | Pin the version or digest to ensure you use the intended image and not a tampered one |
Remove non-essential packages and clean up package manager caches:
RUN microdnf upgrade -y && \
microdnf install -y <required-packages> && \
microdnf remove -y <unnecessary-packages> && \
microdnf clean all
Use microdnf on ubi-minimal images; dnf on full UBI images.
Containers must not run as root. Set runAsNonRoot: true and provide a numeric non-root USER in the Containerfile.
Required for: all profiles (mandatory)
USER 1000
securityContext:
runAsNonRoot: true
runAsUser: 1000
Either the pod-level or container-level securityContext can set these fields. Do not use UID 0 (root) or UID 1337 (reserved for Istio sidecar proxies).
Required for: Extended (mandatory), all others (optional) — UID 1337 restriction
Set allowPrivilegeEscalation: false to prevent privilege escalation during container execution:
Required for: all profiles (mandatory)
securityContext:
allowPrivilegeEscalation: false
Or in a compose file:
security_opt:
- no-new-privileges: true
Use read-only root filesystems wherever possible:
Required for: all profiles (optional, recommended best practice)
securityContext:
readOnlyRootFilesystem: true
Mount writable tmpfs volumes only where the application requires write access (e.g., /tmp, /var/run).
Mount volumes as read-only unless the container must write to them:
volumeMounts:
- name: config
mountPath: /etc/app
readOnly: true
Disable automatic mounting of the Kubernetes API service account token unless the pod needs API access:
Required for: Telco (mandatory), Far-Edge (mandatory), Extended (mandatory), Non-Telco (optional)
spec:
automountServiceAccountToken: false
Pods that require API access (e.g., operators, controllers) should use a dedicated service account with minimal RBAC permissions and explicitly set automountServiceAccountToken: true.
Each container should run a single process. This simplifies monitoring, log collection, debugging, and security assessment. Use sidecar containers for auxiliary tasks (log shipping, proxy, etc.) rather than running multiple daemons in one container.
Required for: all profiles (optional, recommended best practice)
Containers must not run SSH daemons. SSH in containers creates additional attack surfaces and violates immutable infrastructure principles. Use kubectl exec or oc debug for troubleshooting instead.
Required for: Telco (mandatory), Far-Edge (mandatory), Extended (mandatory), Non-Telco (optional)
The certsuite defines 4 approved security context categories based on required Linux capabilities. Target Category 1 (most restrictive) unless the workload requires advanced networking or DPDK.
Required for: Extended (mandatory), all others (optional)
| Category | Description | Added Capabilities |
|---|---|---|
| Category 1 | Limited access (default) | None |
| Category 1 (no UID 0) | Basic rights with mesh networks | None (runAsNonRoot: true) |
| Category 2 | Advanced networking (VLAN tag, DSCP, priority) | NET_ADMIN, NET_RAW |
| Category 3 | SR-IOV and DPDK | NET_ADMIN, NET_RAW, IPC_LOCK |
All categories require:
ALL (or at minimum MKNOD, SETUID, SETGID, KILL)hostIPC: false, hostNetwork: false, hostPID: false, no hostPortprivileged: falserunAsUser and fsGroup set, SELinux context presentspec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
seLinuxOptions:
type: container_t
containers:
- name: app
image: registry.example.com/app:v1.2.3
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
Container base images must not be modified after startup. All required binaries and dependencies must be built into the image at build time.
Required for: all profiles (mandatory)
Protected directories that must remain unchanged at runtime:
/bin, /sbin, /lib, /lib64, /usr/bin, /usr/sbin, /usr/lib, /usr/lib64, /var/lib/rpm, /var/lib/dpkg
OpenShift Note: SELinux must be in Enforcing mode on all cluster nodes (mandatory across all profiles). Base images must be Red Hat UBI (mandatory across all profiles).
Use Hadolint to lint Containerfiles for best-practice violations and inline bash issues:
hadolint Containerfile
Hadolint catches common issues (running as root, missing version pins, unnecessary sudo) but should not be trusted without additional verification.
runAsNonRoot: true is set at pod or container levelUSER is set in the ContainerfileallowPrivilegeEscalation: false is setreadOnlyRootFilesystem: true is setautomountServiceAccountToken: false unless API access is requiredALL, or at minimum MKNOD, SETUID, SETGID, KILL)| Guidance | Certsuite Test ID | Profiles |
|---|---|---|
| Privilege escalation disabled | access-control-security-context-privilege-escalation | All profiles: mandatory |
| Run as non-root | access-control-security-context-non-root-user-id-check | All profiles: mandatory |
| Read-only root filesystem | access-control-security-context-read-only-file-system | All profiles: optional |
| Security context category | access-control-security-context | Extended: mandatory, all others: optional |
| UID not 1337 | access-control-no-1337-uid | Extended: mandatory, all others: optional |
| One process per container | access-control-one-process-per-container | All profiles: optional |
| Service account token | access-control-pod-automount-service-account-token | Telco/Far-Edge/Extended: mandatory, Non-Telco: optional |
| No SSH daemons | access-control-ssh-daemons | Telco/Far-Edge/Extended: mandatory, Non-Telco: optional |
| Base image not modified | platform-alteration-base-image | All profiles: mandatory |
| SELinux enforcing | platform-alteration-is-selinux-enforcing | All profiles: mandatory |
| Red Hat base image | platform-alteration-isredhat-release | All profiles: mandatory |
npx claudepluginhub redhatproductsecurity/prodsec-skills --plugin prodsec-skills-ge-core<!-- AUTO-GENERATED by export-plugins.py — DO NOT EDIT -->
Hardens Docker/container images and Kubernetes deployments with secure base images, non-root users, CVE scanning, SBOM/signing, seccomp/AppArmor, and pod security controls.
Review container security including image scanning, runtime policies, and supply chain integrity.