Back to Checks
kubernetes

User or group does not have permission to create PersistentVolumes

rbac_minimize_pv_creation_access
Service: rbacSeverity: high
OfficialBuilt-inVerified
Categories:identity-accesscluster-security
Resource Type:ClusterRoleBinding

Kubernetes RBAC mapping of users or groups with the create verb on persistentvolumes through ClusterRoleBindings.

Shows which principals can provision PersistentVolumes cluster-wide.

Risk

With create on persistentvolumes, a principal can define hostPath PVs and mount them via claims, exposing node files and bypassing pod safeguards.

Results include secret disclosure and filesystem tampering (confidentiality/integrity), and potential node compromise affecting availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler kubernetes --checks rbac_minimize_pv_creation_access

Recommendation

Enforce least privilege: permit create on persistentvolumes only for trusted storage controllers and select administrators.

Adopt dynamic provisioning, maintain separation of duties, and use defense in depth (Pod Security and admission policies) to prevent unsafe volumes like hostPath.

Remediation

CLI

kubectl delete clusterrolebinding <example_resource_name>

Terraform

resource "kubernetes_cluster_role" "<example_resource_name>" {
  metadata { name = "<example_resource_name>" }

  rule {
    api_groups = [""]
    resources  = ["persistentvolumes"]
    verbs      = ["get", "list", "watch"]
    # Critical: exclude "create" on persistentvolumes to prevent PV creation
    # This removes the permission that caused the FAIL finding.
  }
}

Other

1Open the Kubernetes Dashboard (or your cluster RBAC UI)
2Navigate to ClusterRoles and select the role referenced by the failing ClusterRoleBinding
3Edit the role and locate the rule for resources: persistentvolumes
4Remove the verb "create" from that rule's verbs list
5Save the change to apply updated permissions

Check Code

from prowler.lib.check.models import Check, Check_Report_Kubernetes
from prowler.providers.kubernetes.services.rbac.lib.role_permissions import (
    is_rule_allowing_permissions,
)
from prowler.providers.kubernetes.services.rbac.rbac_client import rbac_client

verbs = ["create"]
resources = ["persistentvolumes"]


class rbac_minimize_pv_creation_access(Check):
    def execute(self) -> Check_Report_Kubernetes:
        findings = []
        # Collect unique subjects and the ClusterRole names bound to them
        subjects_bound_roles = {}
        for crb in rbac_client.cluster_role_bindings.values():
            for subject in crb.subjects:
                # CIS benchmarks scope these checks to human identities only
                if subject.kind in ["User", "Group"]:
                    key = (subject.kind, subject.name, subject.namespace)
                    if key not in subjects_bound_roles:
                        subjects_bound_roles[key] = (subject, set())
                    subjects_bound_roles[key][1].add(crb.roleRef.name)

        cluster_roles_by_name = {
            cr.metadata.name: cr for cr in rbac_client.cluster_roles.values()
        }
        for _, (subject, role_names) in subjects_bound_roles.items():
            report = Check_Report_Kubernetes(metadata=self.metadata(), resource=subject)
            report.resource_name = f"{subject.kind}:{subject.name}"
            report.resource_id = f"{subject.kind}/{subject.name}"
            report.status = "PASS"
            report.status_extended = f"User or group '{subject.name}' does not have access to create PersistentVolumes."
            for role_name in role_names:
                cr = cluster_roles_by_name.get(role_name)
                if cr and is_rule_allowing_permissions(cr.rules, resources, verbs):
                    report.status = "FAIL"
                    report.status_extended = f"User or group '{subject.name}' has access to create PersistentVolumes."
                    break
            findings.append(report)

        return findings