How Kubernetes Secures Pods with Seccomp, AppArmor, and SELinux

This article explains how Kubernetes leverages the Linux kernel security mechanisms Seccomp, AppArmor, and SELinux together with Pod Security Standards and the built‑in admission controller to enforce fine‑grained security policies for container workloads in cloud‑native environments.

System Architect Go
System Architect Go
System Architect Go
How Kubernetes Secures Pods with Seccomp, AppArmor, and SELinux

Linux kernel security mechanisms used by Kubernetes

Kubernetes leverages three Linux kernel security features to harden container workloads:

Seccomp – filters system calls that a process may invoke.

AppArmor – confines a program to a profile that defines allowed file, network and capability accesses.

SELinux – enforces label‑based policies (user:role:type:level) for resource access.

Seccomp

Seccomp is configured through the securityContext.seccompProfile field of a Pod or Container. Three profile types are supported: Unconfined – no syscall filtering. RuntimeDefault – uses the default profile supplied by the container runtime (e.g., containerd or CRI‑O). Localhost – loads a JSON profile file from the node’s filesystem (e.g., /var/lib/kubelet/seccomp/profiles/my-profile.json).

Example Pod spec that selects the runtime default profile:

apiVersion: v1
kind: Pod
metadata:
  name: seccomp-demo
spec:
  containers:
  - name: app
    image: nginx:latest
    securityContext:
      seccompProfile:
        type: RuntimeDefault

AppArmor

Starting with Kubernetes v1.30, AppArmor profiles are set via securityContext.appArmorProfile. The same three profile types apply: Unconfined – no AppArmor confinement. RuntimeDefault – uses the runtime’s default AppArmor profile. Localhost – loads a profile file located on the node (e.g., /etc/apparmor.d/my-profile).

Example configuration:

apiVersion: v1
kind: Pod
metadata:
  name: apparmor-demo
spec:
  containers:
  - name: app
    image: nginx:latest
    securityContext:
      appArmorProfile:
        type: Localhost
        localhostProfile: my-profile

SELinux

SELinux options are expressed with securityContext.seLinuxOptions. The four fields correspond to the SELinux label format user:role:type:level:

securityContext:
  seLinuxOptions:
    user: unconfined_u
    role: system_r
    type: container_t
    level: "s0:c123,c456"

Pod Security Standards (PSS)

Kubernetes defines three predefined security levels that can be enforced via the built‑in Pod Security Admission controller: Privileged – almost no restrictions; suitable for trusted workloads. Baseline – moderate restrictions. Disallows host networking, host PID/IPC, privileged containers, and requires a Seccomp/AppArmor/SELinux profile. Only a limited set of Linux capabilities is allowed. Restricted – strong restrictions. Includes all Baseline rules, restricts volume types to a safe whitelist, forces containers to run as non‑root users, and further limits capabilities.

Pod Security Admission controller

The controller enforces a selected PSS level using namespace labels. The label key follows the pattern pod-security.kubernetes.io/<MODE> where <MODE> is enforce, audit or warn. A corresponding version label ( …-version) specifies the Kubernetes minor version or latest for which the policy applies.

Example namespace configuration that enforces the baseline level for Kubernetes v1.31:

apiVersion: v1
kind: Namespace
metadata:
  name: my-baseline-namespace
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/enforce-version: v1.31
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/audit-version: v1.31
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: v1.31

Supported modes: enforce – Pods that violate the selected level are rejected. audit – Violating Pods are allowed but a violation is recorded in the audit log. warn – Violating Pods are allowed and a warning is returned to the client.

Exemptions can be defined in the admission controller configuration to skip checks for specific users, runtime classes, or namespaces. Example AdmissionConfiguration snippet:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
  configuration:
    apiVersion: pod-security.admission.config.k8s.io/v1
    kind: PodSecurityConfiguration
    defaults:
      enforce: "privileged"
      enforce-version: "latest"
      audit: "privileged"
      audit-version: "latest"
      warn: "privileged"
      warn-version: "latest"
    exemptions:
      usernames: []
      runtimeClasses: []
      namespaces: []

Apply the configuration to the API server with the --admission-control-config-file flag.

References

https://kubernetes.io/docs/concepts/security/linux-kernel-security-constraints/

https://kubernetes.io/docs/reference/node/seccomp/

https://kubernetes.io/docs/tutorials/security/apparmor/

https://kubernetes.io/docs/concepts/security/pod-security-standards/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

cloud nativeKubernetesInformation SecurityAppArmorSELinuxseccompPod Security
System Architect Go
Written by

System Architect Go

Programming, architecture, application development, message queues, middleware, databases, containerization, big data, image processing, machine learning, AI, personal growth.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.