More Info:
The Kubernetes API stores secrets, which may be service account tokens for the Kubernetes API or credentials used by workloads in the cluster. Access to these secrets should be restricted to the smallest possible group of users to reduce the risk of privilege escalation.Risk Level
HighAddress
SecurityCompliance Standards
- APRA CPS 234 (Australia)
- AWS Startup Security Baseline
- BSI C5 (Germany)
- Brazil LGPD
- CCPA / CPRA (California)
- CIS Critical Security Controls v8
- CIS EKS
- CMMC 2.0
- CSA Cloud Controls Matrix v4
- DPDPA
- Digital Operational Resilience Act (EU)
- Essential 8
- ISO/IEC 27017
- ISO/IEC 27018
- ISO/IEC 27701
- KSA PDPL
- MAS Technology Risk Management (Singapore)
- MITRE ATT&CK (Cloud)
- NIS2 Directive
- NIST SP 800-171
- NYDFS 23 NYCRR 500
- SWIFT Customer Security Controls Framework
- Sarbanes-Oxley IT General Controls
- UK NCSC Cyber Assessment Framework
Triage and Remediation
- Remediation
Remediation
Manual Steps
Manual Steps
-
List all Roles that grant get/list/watch on secrets
- Run on: any machine with kubectl access
-
Inspect each identified Role to understand who uses it and why
- For each
<NAMESPACE> <ROLE_NAME>from step 1, run:
- Review whether subjects (users/groups/serviceaccounts) truly require get/list/watch on secrets.
- For each
-
Edit Roles to remove unnecessary get/list/watch on secrets
- For each Role where secret access is not strictly required, edit it:
- In the opened YAML, locate any rule with
resources: ["secrets"](or containingsecrets) and removeget,list, andwatchfrom theverbslist, keeping only the minimal verbs truly needed (often none). Save and exit.
-
Split mixed-purpose Roles if only some subjects need secret access
- If a Role includes both secret permissions and other needed permissions for many subjects, create a dedicated minimal-secret Role and narrow its binding:
- Edit
/tmp/<ROLE_NAME>.yamllocally to:- Remove all rules except the minimal
secretsrule for specific subjects that truly need it. - Change
metadata.nameto a new name, e.g.<ROLE_NAME>-secrets-minimal.
- Remove all rules except the minimal
- Apply the new Role:
- Create or update RoleBindings so that only the specific user/group/serviceaccount that truly needs secret access is bound to
<ROLE_NAME>-secrets-minimal, and other subjects are bound to a Role withoutsecretsaccess.
-
Repeat for all namespaces and avoid granting cluster-wide secret access via Roles
- Ensure you do not introduce new
ClusterRolepermissions on secrets while adjusting Roles. - For workloads that previously relied on broad secret access, verify and, if necessary, adjust their service accounts and secret mounting to use only the specific secrets they need.
- Ensure you do not introduce new
-
Verification
- Run on: any machine with kubectl access
Using kubectl
Using kubectl
On any machine with kubectl access:Example after (if only
- Identify roles with get/list/watch on secrets
- For each listed role, inspect current rules
Replace NAMESPACE and ROLE_NAME with values from the previous output:
- Edit the Role manifest locally (ROLE_NAME-role.yaml) and remove
get,list, andwatchfrom any rule that includesresources: ["secrets"], or remove thesecretsresource from rules that do not need it. Save the file.
create is required):- Apply the updated Role
- Repeat steps 2–4 for every Role that was identified in step 1.
- Verify that no Roles still grant get/list/watch on secrets
Automation
Automation

