CIS Podman Benchmark
Security configuration recommendations for Podman container engine
v1.0.0 01-2025Overview
▶This benchmark provides prescriptive guidance for establishing a secure configuration posture for Podman container environments. It covers host configuration, rootless operation, container registry policies, runtime security controls, image verification, pod security, logging, and systemd Quadlet integration using podman CLI commands and containers.conf configuration.
| Section | Area | Focus |
|---|---|---|
| 1 | Host Configuration | Podman installation, storage driver, and rootless setup |
| 2 | Runtime Configuration | Trusted registries, seccomp profiles, and capability restrictions |
| 3 | Image Security | Image signature verification and vulnerability scanning |
| 4 | Container Runtime | Privileged mode prevention, namespace isolation, and read-only rootfs |
| 5 | Pod Security | Resource limits and network isolation for pods |
| 6 | Logging & Monitoring | Logging drivers and container healthcheck configuration |
| 7 | Systemd Integration | Quadlet unit files for production container management |
Profile Definitions
▶| Profile | Description | Intended Use |
|---|---|---|
| L1 | Level 1 — Standard | Essential security for all Podman deployments; minimal performance impact. |
| L2 | Level 2 — Hardened | Advanced hardening for PCI-DSS, HIPAA, or high-security environments. |
1 — Host Configuration
▶1.1 Podman Installation
▶This recommendation verifies that Podman is up to date on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check Podman version and storage driver:
podman info --format '{{.Host.OCIRuntime.Name}} {{.Store.GraphDriverName}}'
podman version# Update Podman to latest: sudo dnf update -y podman # or sudo apt-get update && sudo apt-get install -y podman
This recommendation verifies that container storage is properly configured on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check container storage configuration:
cat /etc/containers/storage.conf | grep -v '^#' | grep -v '^$'
podman info --format '{{.Store.GraphRoot}}'# Configure overlay storage in /etc/containers/storage.conf: [storage] driver = "overlay" runroot = "/run/containers/storage" graphroot = "/var/lib/containers/storage" [storage.options.overlay] mountopt = "nodev,metacopy=on"
This recommendation verifies that rootless Podman is configured for unprivileged users on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check if rootless Podman is configured: podman unshare cat /proc/self/uid_map grep -E '^(sub[ug]id)' /etc/subuid /etc/subgid
# Configure rootless Podman: usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER podman system migrate
2 — Runtime Configuration
▶2.1 Security Settings
▶This recommendation verifies that only trusted registries are configured on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check registries configuration:
cat /etc/containers/registries.conf | grep -A5 '\[registries.search\]'
podman info --format '{{.Registries}}'# Configure trusted registries in /etc/containers/registries.conf: unqualified-search-registries = ["registry.access.redhat.com", "docker.io"] [[registry]] prefix = "docker.io" location = "docker.io" blocked = false [[registry]] location = "*" blocked = true
This recommendation verifies that default seccomp profile is enabled on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check seccomp profile:
podman info --format '{{.Host.Security.SECCOMPEnabled}}'
ls -la /usr/share/containers/seccomp.json# Ensure default seccomp profile is used: # Podman uses the default profile at /usr/share/containers/seccomp.json # Run containers with explicit profile: podman run --security-opt seccomp=/usr/share/containers/seccomp.json <image>
This recommendation verifies that unnecessary capabilities are dropped on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check default capabilities: cat /etc/containers/containers.conf | grep -A10 '\[containers\]' | grep -i cap podman run --rm alpine cat /proc/1/status | grep Cap
# Drop all unnecessary capabilities in /etc/containers/containers.conf:
[containers]
default_capabilities = [
"CHOWN",
"DAC_OVERRIDE",
"FOWNER",
"FSETID",
"KILL",
"NET_BIND_SERVICE",
"SETFCAP",
"SETGID",
"SETPCAP",
"SETUID",
]3 — Image Security
▶3.1 Image Management
▶This recommendation verifies that image signature verification is enabled on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List images and check for unsigned:
podman images --format '{{.Repository}}:{{.Tag}} {{.ID}}'
podman image inspect <image> | jq '.[0].Config.Labels'# Enable image signature verification in /etc/containers/policy.json:
{
"default": [{"type": "reject"}],
"transports": {
"docker": {
"registry.access.redhat.com": [{"type": "signedBy", "keyType": "GPGKeys", "keyPath": "/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release"}],
"docker.io/library": [{"type": "insecureAcceptAnything"}]
}
}
}This recommendation verifies that images are scanned for vulnerabilities on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Scan images for vulnerabilities: podman image scan <image> # or using trivy: trivy image <image>
# Remove unused and vulnerable images: podman image prune -a podman rmi $(podman images -q --filter 'dangling=true') # Rebuild with updated base images: podman build --pull --no-cache -t myapp:latest .
4 — Container Runtime
▶4.1 Container Hardening
▶This recommendation verifies that containers are not running in privileged mode on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check running containers for privileged mode:
podman ps --format '{{.Names}} {{.ID}}' | while read name id; do
priv=$(podman inspect $id --format '{{.HostConfig.Privileged}}')
echo "$name: privileged=$priv"
done# Never run containers in privileged mode: podman run --rm -d --name myapp \ --security-opt no-new-privileges:true \ --cap-drop ALL \ --cap-add NET_BIND_SERVICE \ myapp:latest
This recommendation verifies that host PID namespace is not shared on the Podman container engine. Disabling or removing unnecessary components reduces the attack surface and limits potential vectors for exploitation.
Running unnecessary components on the Podman container engine increases the attack surface and the risk of exploitation. Disabling or removing them follows the principle of least functionality and reduces exposure to known vulnerabilities.
# Check PID namespaces:
podman ps --format '{{.Names}} {{.ID}}' | while read name id; do
pid_mode=$(podman inspect $id --format '{{.HostConfig.PidMode}}')
echo "$name: pid=$pid_mode"
done# Do not share host PID namespace: # Ensure no containers use --pid=host: podman run --rm -d --name myapp myapp:latest # Not: podman run --pid=host ...
This recommendation verifies that read-only root filesystem is used on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check read-only rootfs:
podman ps --format '{{.Names}} {{.ID}}' | while read name id; do
ro=$(podman inspect $id --format '{{.HostConfig.ReadonlyRootfs}}')
echo "$name: readonly=$ro"
done# Run containers with read-only root filesystem: podman run --rm -d --name myapp \ --read-only \ --tmpfs /tmp:rw,noexec,nosuid \ myapp:latest
5 — Pod Security
▶5.1 Pod Configuration
▶This recommendation verifies that pods have resource limits configured on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# List pods and their containers:
podman pod list
podman pod inspect <pod_name> | jq '.Containers[] | {Name, Id}'# Create pods with resource limits: podman pod create --name myapp-pod \ --memory 512m \ --cpus 1.0 \ --share net \ --infra-name myapp-infra
This recommendation verifies that pods use isolated networks on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check pod network isolation: podman pod inspect <pod_name> | jq '.InfraConfig.Networks' podman network ls
# Create isolated networks for pods: podman network create --driver bridge myapp-net podman pod create --name myapp-pod --network myapp-net # Inspect network: podman network inspect myapp-net
6 — Logging & Monitoring
▶6.1 Container Logging
▶This recommendation verifies that container logging driver is configured on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check container logging driver:
podman info --format '{{.Host.LogDriver}}'
podman inspect <container> --format '{{.HostConfig.LogConfig}}'# Configure logging in /etc/containers/containers.conf: [containers] log_driver = "journald" log_size_max = 10485760 # Or use k8s-file: [containers] log_driver = "k8s-file" log_size_max = 10485760
This recommendation verifies that container healthchecks are defined on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check container health status:
podman ps --format '{{.Names}} {{.Status}}'
podman healthcheck run <container># Add healthchecks to containers: podman run -d --name myapp \ --health-cmd 'curl -f http://localhost:8080/health || exit 1' \ --health-interval 30s \ --health-retries 3 \ --health-timeout 5s \ myapp:latest
7 — Systemd Integration
▶7.1 Quadlet Units
▶This recommendation verifies that production containers use Quadlet systemd units on the Podman container engine. Implementing this control strengthens the overall security configuration and reduces exposure to potential threats.
Failure to implement this control may leave the Podman container engine vulnerable to attack or non-compliant with organizational security policies. This control helps establish a consistent, hardened configuration baseline.
# Check for systemd-managed containers (Quadlets): ls /etc/containers/systemd/ 2>/dev/null ls ~/.config/containers/systemd/ 2>/dev/null systemctl list-units 'podman-*'
# Create a Quadlet unit file /etc/containers/systemd/myapp.container: [Container] Image=myapp:latest PublishPort=8080:8080 Environment=NODE_ENV=production Volume=myapp-data.volume:/data:Z ReadOnly=true NoNewPrivileges=true [Service] Restart=always [Install] WantedBy=default.target systemctl daemon-reload systemctl start myapp