Back to Checks
Prowlerprowler-provider-kubernetes
Role or ClusterRole does not grant get, list, or watch access to Kubernetes Secrets
rbac_minimize_secret_access
Service: rbacSeverity: high
OfficialBuilt-inVerified
Categories:identity-accesssecretscluster-security
Resource Type:ClusterRole
RBAC Roles and ClusterRoles granting read permissions to Kubernetes Secrets are identified. The evaluation looks for rules that allow get, list, or watch on secrets, either namespace-scoped or cluster-wide.
Risk
Excessive Secret read access compromises confidentiality of tokens, keys, and credentials. Attackers can harvest service account tokens to impersonate workloads, pivot across namespaces, and modify resources, threatening integrity and availability via lateral movement.
Run this check with Prowler
Run in Prowler CloudRun
prowler kubernetes --checks rbac_minimize_secret_accessRecommendation
Apply least privilege: avoid granting get, list, or watch on secrets except to narrowly scoped subjects. Constrain by namespace and resourceNames where feasible, use dedicated service accounts, avoid wildcards, and enforce separation of duties with policy and reviews.
Remediation
Terraform
# Remove secret read permissions by ensuring no rule includes the "secrets" resource
resource "kubernetes_cluster_role" "<example_resource_name>" {
metadata {
name = "<example_resource_name>"
}
rule {
api_groups = [""]
resources = ["pods"] # Critical: do NOT include "secrets" to avoid get/list/watch on Secrets
verbs = ["get"]
}
}Other
1Identify the offending Role or ClusterRole name
2Edit it: run either `kubectl edit clusterrole <example_resource_name>` or `kubectl edit role <example_resource_name> <namespace>`
3In `rules`, remove any entry where `resources` contains `secrets` with verbs `get`, `list`, or `watch` (or delete those verbs/resources from the rule)
4Save and exit; the change applies immediately
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 = ["get", "list", "watch"]
resources = ["secret"]
class rbac_minimize_secret_access(Check):
def execute(self) -> Check_Report_Kubernetes:
findings = []
# Check ClusterRoleBindings for seceret access
for cr in rbac_client.cluster_roles.values():
report = Check_Report_Kubernetes(
metadata=self.metadata(), resource=cr.metadata
)
report.status = "PASS"
report.status_extended = (
f"ClusterRole {cr.metadata.name} does not have secret access."
)
if is_rule_allowing_permissions(cr.rules, resources, verbs):
report.status = "FAIL"
report.status_extended = (
f"ClusterRole {cr.metadata.name} has secret access."
)
findings.append(report)
# Check RoleBindings for secret access
for role in rbac_client.roles.values():
report = Check_Report_Kubernetes(
metadata=self.metadata(), resource=role.metadata
)
report.status = "PASS"
report.status_extended = (
f"Role {role.metadata.name} does not have secret access."
)
if is_rule_allowing_permissions(cr.rules, resources, verbs):
report.status = "FAIL"
report.status_extended = f"Role {role.metadata.name} has secret access."
findings.append(report)
return findings