Kubernetes Security: Override AppArmor Profile is a Bad Idea

This page describes a highlighted problem produced by the Docker and Kubernetes Security scanner plugin.

You could find more details on the internal page: Cloud (IaC) Security plugin

If this project has been helpful to you, please consider giving it a ⭐ on GitHub to help others discover it.

What’s wrong with overriding AppArmor?

AppArmor is a Linux Security Module that enforces kernel-level confinement on container processes, reducing what they can access and do at runtime. Allowing a Pod to run unconfined or to override a restrictive default with a weaker profile eliminates an important defense layer between the container and the host, which Pod Security Standards aim to prevent by blocking overrides or disables on supported hosts. In practice, Baseline and Restricted policies block unconfined and allow only the runtime’s default profile or a vetted localhost profile, strengthening Kubernetes security.

Important details:

  • Values differ by API style: use RuntimeDefault/Localhost/Unconfined with securityContext.appArmorProfile.type (v1.30+), and use runtime/default, localhost/, or unconfined with the legacy annotations.
  • Configure AppArmor via securityContext.appArmorProfile at the container or Pod level on modern clusters; use per-container annotations only on older (pre‑v1.30) clusters.
  • If the node doesn’t enable AppArmor, the admission pipeline rejects any Pod that sets securityContext.appArmorProfile.type: RuntimeDefault. If you omit that field, Kubernetes can schedule and run the Pod on that node without AppArmor confinement

Solution

  • Do not use unconfined in Baseline/Restricted environments.
  • Use the runtime’s default profile (RuntimeDefault in the field; runtime/default in annotations) or a vetted localhost/ that exists on every potential node.
  • Skip an explicit AppArmor profile when none is needed: nodes that enable the security module apply the runtime default. Whereas nodes that don’t enable AppArmor may admit the Pod unconfined
  • Enforce via Pod Security Admission (Baseline/Restricted) or a policy engine (for example, a rule that limits AppArmor profiles to runtime/default or localhost/*) to improve overall Kubernetes security posture.

Problematic code

apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  securityContext:
    appArmorProfile:
      type: privileged # here is overriding value
  containers:
    - name: influxdb
      image: influxdb

Verified code

apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  securityContext:
    appArmorProfile:
      type: RuntimeDefault
  containers:
    - name: influxdb
      image: influxdb

Source of the description: Pod Security Standards