← Policy catalog
</> ValidatingAdmissionPolicy · Apache-2.0

Grants Write Access to Workload Controllers

clusterrole-workloads-write

severityHigh resourceClusterRoles productKubernetes bundles1

Write access to workload controllers becomes arbitrary pod creation through the controller, letting the holder run any image under any service account in the cluster and, with DaemonSets, land that container on every node.

Rejects unless

!has(object.rules) || object.rules.all(r,
  !(
    (has(r.apiGroups) && has(r.resources) && has(r.verbs) &&
     r.apiGroups.exists(ag, ag == "apps") &&
     r.resources.exists(res, variables.appResources.exists(ar, ar == res)) &&
     r.verbs.exists(v, v in ["create","update","patch","delete"])) ||
    (has(r.apiGroups) && has(r.resources) && has(r.verbs) &&
     r.apiGroups.exists(ag, ag == "batch") &&
     r.resources.exists(res, variables.batchResources.exists(br, br == res)) &&
     r.verbs.exists(v, v in ["create","update","patch","delete"]))
  )
)

ClusterRoles must not grant create/update/patch/delete on workload controllers (apps/batch).

Variables

appResources

["deployments","daemonsets","statefulsets","replicasets"]

batchResources

["jobs","cronjobs"]

Remediation

Remove create, update, patch and delete from rules covering deployments, daemonsets, statefulsets and replicasets in the apps group and jobs and cronjobs in the batch group. 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-workloads-write
  annotations:
    kubeapt.io/uuid: "e70577c8-f503-4e79-8f7d-6c334183b9d6"
    security.kubeapt.io/displayName: "Grants Write Access to Workload Controllers"
    security.kubeapt.io/description: "Write access to workload controllers becomes arbitrary pod creation through the controller, letting the holder run any image under any service account in the cluster and, with DaemonSets, land that container on every node."
    security.kubeapt.io/resource: "ClusterRoles"
    security.kubeapt.io/severity: "High"
    security.kubeapt.io/remediation: "Remove create, update, patch and delete from rules covering deployments, daemonsets, statefulsets and replicasets in the apps group and jobs and cronjobs in the batch group. 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: appResources
    expression: |
      ["deployments","daemonsets","statefulsets","replicasets"]
  - name: batchResources
    expression: |
      ["jobs","cronjobs"]
  validations:
  - expression: |
      !has(object.rules) || object.rules.all(r,
        !(
          (has(r.apiGroups) && has(r.resources) && has(r.verbs) &&
           r.apiGroups.exists(ag, ag == "apps") &&
           r.resources.exists(res, variables.appResources.exists(ar, ar == res)) &&
           r.verbs.exists(v, v in ["create","update","patch","delete"])) ||
          (has(r.apiGroups) && has(r.resources) && has(r.verbs) &&
           r.apiGroups.exists(ag, ag == "batch") &&
           r.resources.exists(res, variables.batchResources.exists(br, br == res)) &&
           r.verbs.exists(v, v in ["create","update","patch","delete"]))
        )
      )
    message: |
      ClusterRoles must not grant create/update/patch/delete on workload controllers (apps/batch).

Save it as clusterrole-workloads-write.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-workloads-write.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-workloads-write -r ./manifests

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

$ kubeapt validate --policy-name clusterrole-workloads-write -A