Avoid Use Of System Masters Group
More Info:
The special group system:masters should not be used to grant permissions to any user or service account, except where strictly necessary (e.g. bootstrapping access prior to RBAC being fully available)
Risk Level
High
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
List all subjects currently bound to
system:masters- On any machine with kubectl access:
kubectl get clusterrolebindings -o yaml | grep -A5 '\bcluster-admin\b'kubectl get clusterrolebindings -o yaml | grep -A5 'system:masters'kubectl get clusterrolebindings -o wide
- Identify any
ClusterRoleBindingwhere:.roleRef.nameiscluster-admin, and/or- Any subject has
kind: Userorkind: Groupwithname: system:masters.
- On any machine with kubectl access:
-
Inventory which concrete identities rely on
system:masters- For each binding referencing
system:masters(either asroleRef==cluster-adminor subject group name), capture full details:kubectl get clusterrolebinding <BINDING_NAME> -o yaml - Note which are:
- Human users (e.g., corporate SSO groups, individual user names).
- Service accounts (kind: ServiceAccount).
- External identities mapped to
system:mastersvia authentication (e.g., OIDC, client cert CN/O, cloud IAM).
- For each binding referencing
-
Review necessity of cluster‑wide superuser access for each subject
- For each user/group/service account discovered:
- Determine its actual operational purpose (admin, CI/CD, monitoring, break‑glass, etc.).
- Confirm with owners whether:
- Ongoing
cluster-admin/system:masterslevel access is required, or - Access can be reduced to specific namespaces/verbs/resources, or
- Access is only needed for rare break‑glass scenarios.
- Ongoing
- For each user/group/service account discovered:
-
Design replacement RBAC where full superuser is not strictly required
- For subjects that do not need full
system:masters/cluster-admin:- Identify the minimal
ClusterRole/Role(existing or to be created) that matches required permissions. - Prepare corresponding
RoleBinding/ClusterRoleBindingmanifests that:- Bind the subject to that minimal role.
- Do not reference the
system:mastersgroup and avoid unnecessarycluster-adminusage.
- Save the manifests locally (e.g.
restricted-access-<subject>.yaml) for change review/approval.
- Identify the minimal
- For subjects that do not need full
-
Apply reduced‑privilege bindings, then remove
system:mastersmembership- On any machine with kubectl access, for each subject you have redesigned access for:
- Apply the replacement binding(s):
kubectl apply -f restricted-access-<subject>.yaml
- Remove the previous binding that relied on
system:masters/cluster-admin(only after confirming new access works in a test):kubectl delete clusterrolebinding <OLD_BINDING_NAME>
- For identities mapped to
system:mastersat the auth layer (e.g., client certs with O=system:masters, OIDC groups, cloud IAM bindings), coordinate with the identity/IAM team to:- Stop mapping those identities into
system:masters. - Map them into the new, least‑privilege roles instead.
- Stop mapping those identities into
- Apply the replacement binding(s):
- On any machine with kubectl access, for each subject you have redesigned access for:
-
Verify no users are effectively granted via
system:masters- On any machine with kubectl access, confirm there are no bindings referencing
system:mastersor unintendedcluster-admingrants:kubectl get clusterrolebindings -o yaml | grep -A5 'system:masters' || echo "No system:masters references found"kubectl get clusterrolebindings -o yaml | grep -A5 '\bcluster-admin\b' - Manually confirm that:
- Any remaining
cluster-adminbinding is strictly necessary (e.g., a controlled break‑glass account). - No regular user, group, or service account is granted access via
system:masters.
- Any remaining
- On any machine with kubectl access, confirm there are no bindings referencing
Using kubectl
# 1) List all ClusterRoleBindings referencing system:masters
# Run on: any machine with kubectl access
kubectl get clusterrolebindings -o json | \
jq -r '
.items[]
| select(
(.roleRef.kind=="ClusterRole" and .roleRef.name=="cluster-admin")
or (.subjects[]?.kind=="Group" and .subjects[]?.name=="system:masters")
)
| .metadata.name
'
Problem indication:
- Any ClusterRoleBinding that:
- Has
roleRef.name: cluster-adminand a subject withname: system:masters, or - Has any subject with
kind: Groupandname: system:masters, means membership insystem:mastersgives full admin access.
- Has
# 2) Inspect each suspicious ClusterRoleBinding in detail
# Replace <crb-name> with each name from the previous command
kubectl get clusterrolebinding <crb-name> -o yaml
In the output, look for:
subjectsentries like:kind: Groupwithname: system:masters- Any identity provider group (e.g. from OIDC) that you know is mapped to
system:masters
roleRefwithname: cluster-adminor any highly privileged role.
If system:masters is present in subjects, or if you know an external group is mapped to system:masters, that binding is high risk and needs human review.
# 3) List all RoleBindings that reference system:masters (less common, but possible)
kubectl get rolebindings --all-namespaces -o json | \
jq -r '
.items[]
| select(.subjects[]? | .kind=="Group" and .name=="system:masters")
| "\(.metadata.namespace)/\(.metadata.name)"
'
Problem indication:
- Any RoleBinding where a subject has
kind: Groupandname: system:mastersis using this special group to grant namespace-scoped access and should be reviewed. Even if the Role is notcluster-admin, those subjects also inherit any cluster-wide privileges ofsystem:masters.
# 4) Enumerate which Kubernetes users/groups are currently authenticated
# (from kubeconfig contexts; this does NOT show all possible IdP users)
kubectl config view --raw -o json | jq -r '
.users[]?.user
| {
username: (.username // "N/A"),
client-certificate: (.["client-certificate-data"] // "cert-ref"),
exec: .exec
}
'
Problem indication:
- Any user identity that you know (from your IdP, certificates, or API server auth config) is mapped into the
system:mastersgroup is a candidate for review. kubectl cannot see that mapping; you must correlate with your authentication setup.
# 5) Verify post-review state (re-run focused query)
kubectl get clusterrolebindings -o json | \
jq -r '
.items[]
| select(.subjects[]? | .kind=="Group" and .name=="system:masters")
| .metadata.name
'
If this command prints no names, then no ClusterRoleBindings directly grant access to the system:masters group. If it still returns any names, those bindings still need human review and a decision on whether to keep or change them.
Automation
#!/usr/bin/env bash
#
# Report any bindings that grant cluster-admin or system:masters-equivalent
# privileges so they can be reviewed manually.
#
# Run on: any machine with kubectl access and current-context set to target cluster
set -euo pipefail
echo "=== Context ==="
kubectl config current-context
echo
echo "=== 1) ClusterRoleBindings referencing 'system:masters' group directly ==="
kubectl get clusterrolebindings -o jsonpath='{range .items[?(@.subjects)]}{.metadata.name}{"\n"}{range .subjects[*]} KIND={.kind} NAME={.name} API-GROUP={.apiGroup}{"\n"}{end}{"\n"}{end}' \
| awk 'NR==1{print} /system:masters/ || NR==1'
echo
echo "=== 2) RoleBindings referencing 'system:masters' group directly (all namespaces) ==="
kubectl get rolebindings --all-namespaces -o jsonpath='{range .items[?(@.subjects)]}{.metadata.namespace}{"/"}{.metadata.name}{"\n"}{range .subjects[*]} KIND={.kind} NAME={.name} API-GROUP={.apiGroup}{"\n"}{end}{"\n"}{end}' \
| awk 'NR==1{print} /system:masters/ || NR==1'
echo
echo "=== 3) ClusterRoleBindings granting 'cluster-admin' ==="
kubectl get clusterrolebindings -o jsonpath='{range .items[?(@.roleRef.name=="cluster-admin")]}{.metadata.name}{"\n"}{.roleRef.kind}{" "}{.roleRef.name}{"\n"}{range .subjects[*]} KIND={.kind} NAME={.name} NAMESPACE={.namespace} API-GROUP={.apiGroup}{"\n"}{end}{"\n"}{end}'
echo
echo "=== 4) RoleBindings granting 'cluster-admin' (all namespaces) ==="
kubectl get rolebindings --all-namespaces -o jsonpath='{range .items[?(@.roleRef.name=="cluster-admin")]}{.metadata.namespace}{"/"}{.metadata.name}{"\n"}{.roleRef.kind}{" "}{.roleRef.name}{"\n"}{range .subjects[*]} KIND={.kind} NAME={.name} NAMESPACE={.namespace} API-GROUP={.apiGroup}{"\n"}{end}{"\n"}{end}'
echo
echo "=== 5) Users in kubeconfig(s) that may map to high-privilege subjects ==="
echo "Current kubectl kubeconfig:"
kubectl config view --minify --raw
echo
echo "Note:"
echo "- PROBLEMATIC output is any subject of kind 'User' or 'ServiceAccount' whose NAME is 'system:masters' in sections 1 or 2."
echo "- Also review any 'User' or 'ServiceAccount' subjects bound to 'cluster-admin' (sections 3 and 4); these are not"
echo " automatically violations of this control, but often indicate over-privileged identities."
echo "- There is no safe automatic removal: for each flagged subject you must decide manually whether it is still needed,"
echo " and, if not, adjust or delete the corresponding RoleBinding/ClusterRoleBinding."
Interpreting the output
- A definite problem for this specific control is any line in sections 1 or 2 where:
KIND=GroupandNAME=system:masters
- These bindings should be reviewed and, if not strictly required, updated to remove the
system:mastersgroup subject.