← Policy catalog
</> ValidatingAdmissionPolicy · Apache-2.0

Sets a Non-Standard AppArmor Annotation

pod-apparmor-annotation-values

severityModerate resourcePods productKubernetes bundles2

A legacy AppArmor annotation set to unconfined leaves the named container with no mandatory access control profile, so its file, capability and mount operations run unrestricted against the host kernel.

Rejects unless

!has(object.metadata.annotations) || !object.metadata.annotations.exists(k,
  k.startsWith("container.apparmor.security.beta.kubernetes.io/") &&
  !(object.metadata.annotations[k] == "runtime/default" ||
    object.metadata.annotations[k].startsWith("localhost/"))
)

Annotations under container.apparmor.security.beta.kubernetes.io/* must be "runtime/default" or start with "localhost/". Other values are not allowed.

Remediation

Set the annotation value to runtime/default, or to localhost/ followed by a profile loaded on the node. Field: metadata.annotations[container.apparmor.security.beta.kubernetes.io/<container-name>].

Applies to

  • pods · v1 · CREATE, UPDATE

Manifest

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: pod-apparmor-annotation-values
  annotations:
    kubeapt.io/uuid: "79f6f10f-1013-45a8-bd05-cd509c20383a"
    security.kubeapt.io/displayName: "Sets a Non-Standard AppArmor Annotation"
    security.kubeapt.io/description: "A legacy AppArmor annotation set to unconfined leaves the named container with no mandatory access control profile, so its file, capability and mount operations run unrestricted against the host kernel."
    security.kubeapt.io/resource: "Pods"
    security.kubeapt.io/severity: "Moderate"
    security.kubeapt.io/remediation: "Set the annotation value to runtime/default, or to localhost/ followed by a profile loaded on the node. Field: metadata.annotations[container.apparmor.security.beta.kubernetes.io/<container-name>]."
    security.kubeapt.io/product: "Kubernetes"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:
      - ''
      apiVersions:
      - v1
      operations:
      - CREATE
      - UPDATE
      resources:
      - pods
  validations:
  - expression: |
      !has(object.metadata.annotations) || !object.metadata.annotations.exists(k,
        k.startsWith("container.apparmor.security.beta.kubernetes.io/") &&
        !(object.metadata.annotations[k] == "runtime/default" ||
          object.metadata.annotations[k].startsWith("localhost/"))
      )
    message: |
      Annotations under container.apparmor.security.beta.kubernetes.io/* must be "runtime/default" or start with "localhost/". Other values are not allowed.

Save it as pod-apparmor-annotation-values.yaml — the commands below assume that name.

Validate with kubeapt

Check a workload against this one policy, before anything is installed on a cluster.

$ kubeapt validate -p ./pod-apparmor-annotation-values.yaml -r ./workload.yaml

Or without the file, from the published policy set — -r takes a directory too:

$ kubeapt policies download && kubeapt validate --policy-name pod-apparmor-annotation-values -r ./manifests

Or against every namespace in the cluster your kubeconfig points at:

$ kubeapt validate --policy-name pod-apparmor-annotation-values -A