← Policy catalog
</> ValidatingAdmissionPolicy · Apache-2.0

Grants Write Access to Admission Webhooks

clusterrole-admission-api-control

severityHigh resourceClusterRoles productKubernetes bundles1

Write access to webhook configurations lets the holder delete or rewrite admission control itself, disabling every policy that guards the cluster and mutating arbitrary objects as they are admitted.

Rejects unless

!has(object.rules) || object.rules.all(r,
  !(has(r.apiGroups) && has(r.resources) && has(r.verbs) &&
    r.apiGroups.exists(ag, ag == "admissionregistration.k8s.io") &&
    r.resources.exists(res, variables.admissionResources.exists(ar, ar == res)) &&
    r.verbs.exists(v, variables.admissionVerbs.exists(av, av == v))
  )
)

ClusterRoles must not grant write access to ValidatingWebhookConfiguration/MutatingWebhookConfiguration.

Variables

admissionResources

["validatingwebhookconfigurations","mutatingwebhookconfigurations"]

admissionVerbs

["create","update","patch","delete"]

Remediation

Drop create, update, patch and delete on validatingwebhookconfigurations and mutatingwebhookconfigurations in the admissionregistration.k8s.io group, leaving at most get, list and watch. Fields: rules[*].apiGroups, rules[*].resources, rules[*].verbs.

Applies to

  • clusterroles · rbac.authorization.k8s.io/v1 · CREATE, UPDATE

Manifest

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: clusterrole-admission-api-control
  annotations:
    kubeapt.io/uuid: "e267b65e-ae33-47c3-9a1d-7d5efd27b359"
    security.kubeapt.io/displayName: "Grants Write Access to Admission Webhooks"
    security.kubeapt.io/description: "Write access to webhook configurations lets the holder delete or rewrite admission control itself, disabling every policy that guards the cluster and mutating arbitrary objects as they are admitted."
    security.kubeapt.io/resource: "ClusterRoles"
    security.kubeapt.io/severity: "High"
    security.kubeapt.io/remediation: "Drop create, update, patch and delete on validatingwebhookconfigurations and mutatingwebhookconfigurations in the admissionregistration.k8s.io group, leaving at most get, list and watch. Fields: rules[*].apiGroups, rules[*].resources, rules[*].verbs."
    security.kubeapt.io/product: "Kubernetes"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:
      - rbac.authorization.k8s.io
      apiVersions:
      - v1
      operations:
      - CREATE
      - UPDATE
      resources:
      - clusterroles
  variables:
  - name: admissionResources
    expression: |
      ["validatingwebhookconfigurations","mutatingwebhookconfigurations"]
  - name: admissionVerbs
    expression: |
      ["create","update","patch","delete"]
  validations:
  - expression: |
      !has(object.rules) || object.rules.all(r,
        !(has(r.apiGroups) && has(r.resources) && has(r.verbs) &&
          r.apiGroups.exists(ag, ag == "admissionregistration.k8s.io") &&
          r.resources.exists(res, variables.admissionResources.exists(ar, ar == res)) &&
          r.verbs.exists(v, variables.admissionVerbs.exists(av, av == v))
        )
      )
    message: |
      ClusterRoles must not grant write access to ValidatingWebhookConfiguration/MutatingWebhookConfiguration.

Save it as clusterrole-admission-api-control.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 ./clusterrole-admission-api-control.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 clusterrole-admission-api-control -r ./manifests

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

$ kubeapt validate --policy-name clusterrole-admission-api-control -A