Skip to main content

Seccomp Profile Is docker Default Your Pod Definitions

More Info:

Enable docker/default seccomp profile in your pod definitions

Risk Level

High

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. List and inspect pods missing an explicit seccompProfile

    • Run on: any machine with kubectl access
    • Command to list pods and show securityContext:
      kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.securityContext.seccompProfile.type}{"\n"}{end}' \
      | sort
    • Identify pods where the third column is empty (no pod-level seccompProfile), or not RuntimeDefault.
  2. Check container-level overrides within those pods

    • For each pod of interest (NAMESPACE and POD_NAME from step 1), inspect the full spec:
      kubectl get pod POD_NAME -n NAMESPACE -o yaml
    • Under .spec.containers[].securityContext.seccompProfile.type, note any containers that specify a different profile, or none at all.
  3. Decide which workloads must use RuntimeDefault vs. a custom profile

    • For each workload owner (Deployment/StatefulSet/DaemonSet/Job/CronJob), determine whether RuntimeDefault is acceptable or whether a justified, documented custom seccomp profile is required.
    • To find the owning controller:
      kubectl get pod POD_NAME -n NAMESPACE -o jsonpath='{.metadata.ownerReferences[*].kind}{" "}{.metadata.ownerReferences[*].name}{"\n"}'
    • Record exceptions where RuntimeDefault cannot be used, along with justification.
  4. Update workload manifests to set seccompProfile: RuntimeDefault

    • Retrieve the manifest for the owning controller (example for a Deployment):
      kubectl get deployment DEPLOYMENT_NAME -n NAMESPACE -o yaml > deployment-seccomp-fix.yaml
    • Edit deployment-seccomp-fix.yaml to add or update:
      spec:
      template:
      spec:
      securityContext:
      seccompProfile:
      type: RuntimeDefault
    • If any container-level securityContext.seccompProfile exists and is not required, remove or change it to RuntimeDefault as well.
  5. Apply the updated manifests and roll out changes

    • Apply changes:
      kubectl apply -f deployment-seccomp-fix.yaml
    • If needed, trigger rollouts or restarts according to your operational process (e.g., for Deployments, they will roll out automatically when the Pod template changes).
  6. Verify that pods now use RuntimeDefault

    • After rollouts complete, re-run:
      kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.securityContext.seccompProfile.type}{"\n"}{end}' \
      | sort
    • For any remaining pods without RuntimeDefault (or with container-level overrides), confirm they are explicitly approved exceptions; otherwise, repeat steps 3–5 to correct them.
Using kubectl
# 1. List all pods and their namespaces (for scoping your review)
# Run on: any machine with kubectl access
kubectl get pods --all-namespaces -o wide

Review which namespaces/workloads you actually intend to enforce a seccomp profile for (often your application namespaces, not system namespaces like kube-system).

# 2. Inspect a specific pod’s securityContext (pod-level)
# Replace NAMESPACE and POD_NAME with real values
kubectl get pod POD_NAME -n NAMESPACE -o yaml | \
sed -n '/^spec:/,/^status:/p' | sed -n '/^ securityContext:/,/^[^ ]/p'

If this prints nothing, the pod has no pod-level securityContext, which means it is not explicitly configured for seccompProfile at pod level.

# 3. Inspect containers’ securityContext (container-level)
kubectl get pod POD_NAME -n NAMESPACE -o yaml | \
sed -n '/^spec:/,/^status:/p'

In the spec: section, look for:

  • securityContext: at pod level:
    spec:
    securityContext:
    seccompProfile:
    type: RuntimeDefault
  • And/or securityContext: under each container:
    containers:
    - name: ...
    securityContext:
    seccompProfile:
    type: RuntimeDefault

Output that indicates a problem (needs review/change):

  • No seccompProfile at pod or container level at all:
    spec:
    securityContext: {}
    # or no securityContext block
  • A seccompProfile with type not set to RuntimeDefault (or explicitly set to Unconfined):
    seccompProfile:
    type: Unconfined # problem
    # or
    seccompProfile:
    type: Localhost
    localhostProfile: ... # does not match docker/default

These situations require human judgement to decide whether to add or adjust the seccompProfile to use type: RuntimeDefault (which aligns with the provided remediation).

# 4. Quickly find pods missing any seccompProfile (JSONPath-based review)
kubectl get pods --all-namespaces -o jsonpath='{range .items[?(@.spec.securityContext.seccompProfile.type!="RuntimeDefault")]}{@.metadata.namespace}{" "}{@.metadata.name}{"\n"}{end}'

This prints pods where the pod-level seccompProfile.type is either not set or not RuntimeDefault. Each printed line is a candidate for manual review. Note it does not check container-level overrides—those still require inspecting the full YAML as in step 3.

Automation
#!/usr/bin/env bash
#
# Report Pods that are NOT using a seccomp profile type RuntimeDefault
# or that have no seccomp profile set at all.
#
# Run on: any machine with kubectl access and current-context pointing
# to the target cluster.

set -euo pipefail

echo "Scanning all namespaces for Pods without seccompProfile.type=RuntimeDefault ..."
echo

# Header
printf "%-30s %-40s %-30s %-20s\n" "NAMESPACE" "POD" "CONTAINER" "SECCOMP_PROFILE"
printf "%-30s %-40s %-30s %-20s\n" "---------" "---" "---------" "--------------"

# This jq expression evaluates the effective seccomp profile for each container:
# 1. Check container-level securityContext.seccompProfile.type
# 2. Fallback to pod-level securityContext.seccompProfile.type
# 3. If neither is set, it's reported as "NONE"
kubectl get pods --all-namespaces -o json \
| jq -r '
.items[]
| . as $pod
| (
$pod.spec.securityContext.seccompProfile.type // ""
) as $podSeccomp
| $pod.spec.containers[]
| (
.name as $cname
| (
.securityContext.seccompProfile.type // ""
) as $cSeccomp
| (
if $cSeccomp != "" then $cSeccomp
elif $podSeccomp != "" then $podSeccomp
else "NONE"
end
) as $effective
| select($effective != "RuntimeDefault")
| [
$pod.metadata.namespace,
$pod.metadata.name,
$cname,
$effective
]
| @tsv
)
' \
| while IFS=$'\t' read -r ns pod container seccomp; do
printf "%-30s %-40s %-30s %-20s\n" "$ns" "$pod" "$container" "$seccomp"
done

echo
echo "Explanation:"
echo "- Rows listed above are POD CONTAINERS that do NOT effectively use seccompProfile.type=RuntimeDefault."
echo "- SECCOMP_PROFILE = NONE means no seccomp profile is defined at Pod or container level."
echo "- SECCOMP_PROFILE with any value other than RuntimeDefault (for example, Localhost or another type)"
echo " indicates a configuration that does not meet this specific benchmark control."
echo
echo "Next steps (manual review required):"
echo "- For each listed Pod, review its manifest and determine whether you should add:"
echo " securityContext:"
echo " seccompProfile:"
echo " type: RuntimeDefault"
echo " at the Pod level or per-container, according to your security policy."

What output indicates a problem

  • Any line printed by the script indicates a container that does not comply with the benchmark expectation of seccompProfile.type: RuntimeDefault:
    • SECCOMP_PROFILE is NONE: no seccomp profile configured at Pod or container level.
    • SECCOMP_PROFILE is any value other than RuntimeDefault (e.g., Localhost).

Additional Reading: