← Policy catalog
</> ValidatingAdmissionPolicy · Apache-2.0

Grants Write Access to Workload Controllers

role-workloads-write

severityHigh resourceRoles 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 namespace and, with DaemonSets, land that container on every node.

Rejects unless

!has(object.rules) || object.rules.all(r,
  !(
    (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"])) ||
    (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"]))
  )
)

Roles 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

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

Manifest

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: role-workloads-write
  annotations:
    kubeapt.io/uuid: "badd6afe-218a-4a3c-a102-737afb5a5fa9"
    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 namespace and, with DaemonSets, land that container on every node."
    security.kubeapt.io/resource: "Roles"
    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:
      - roles
  variables:
  - name: appResources
    expression: |
      ["deployments","daemonsets","statefulsets","replicasets"]
  - name: batchResources
    expression: |
      ["jobs","cronjobs"]
  validations:
  - expression: |
      !has(object.rules) || object.rules.all(r,
        !(
          (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"])) ||
          (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: |
      Roles must not grant create/update/patch/delete on workload controllers (apps/batch).

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

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

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