Skip to main content

Avoid Use Of The System:Masters Group

More Info:

Membership of system:masters grants unrestricted access that bypasses RBAC and cannot be revoked by removing bindings. It should not be used.

Risk Level

Critical

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. List all ClusterRoleBindings that reference system:masters

    • Run on: any machine with kubectl access
    • Command:
      kubectl get clusterrolebindings -o yaml | grep -C5 'system:masters'
    • Note the names of any ClusterRoleBinding objects where subjects[*].kind is Group and subjects[*].name is system:masters.
  2. Review each identified ClusterRoleBinding in detail

    • Run on: any machine with kubectl access
    • For each binding name found in step 1 (replace BINDING_NAME):
      kubectl get clusterrolebinding BINDING_NAME -o yaml
    • Record the metadata.name, subjects, and roleRef fields, and identify which external identities (e.g., OIDC groups, SSO mappings, user certs) end up in system:masters.
  3. Identify business need and safer alternatives for each subject

    • Outside Kubernetes, review your identity provider / certificate issuance to see why each subject is mapped to system:masters (e.g., “cluster-admins” IdP group mapped to system:masters).
    • Decide per subject whether they truly need unrestricted cluster-wide admin, or if a scoped ClusterRole / Role (e.g., cluster-admin via RBAC or a custom admin role) is sufficient.
  4. Plan and apply RBAC changes to replace system:masters use

    • If subjects should keep admin rights, bind them to an explicit ClusterRole (commonly cluster-admin) instead of using system:masters. Example (edit as needed):
      • Run on: any machine with kubectl access
        kubectl create clusterrolebinding admin-replacement-binding \
        --clusterrole=cluster-admin \
        --group=YOUR-ADMIN-GROUP
    • Coordinate with your IdP / certificate configuration so that identities are no longer placed into the system:masters group going forward.
  5. Remove or edit bindings that reference system:masters

    • After confirming replacement access is in place and tested for affected users:
      • To remove an entire binding (if it only exists to grant system:masters):
        kubectl delete clusterrolebinding BINDING_NAME
      • Or to surgically remove system:masters from subjects, edit the binding:
        kubectl edit clusterrolebinding BINDING_NAME
        In the editor, delete any subjects entries where kind: Group and name: system:masters, then save.
  6. Verify that system:masters is no longer used

    • Run on: any machine with kubectl access
    • Commands:
      kubectl get clusterrolebindings -o yaml | grep -C5 'system:masters' || echo "No ClusterRoleBindings reference system:masters"
    • Optionally, have a former system:masters member log in and confirm that their access is now mediated via RBAC bindings you created, not via system:masters.
Using kubectl
# 1. List all ClusterRoleBindings that reference the system:masters group
# Run on: any machine with kubectl access
kubectl get clusterrolebindings -o jsonpath='{range .items[?(@.subjects)]}{.metadata.name}{"\n"}{range .subjects[*]}{.kind}{" "}{.name}{"\n"}{end}{"---\n"}{end}' \
| awk 'BEGIN{RS="---\n"} /Group system:masters/'

What to look for:
Any ClusterRoleBinding name printed by this command has at least one subjects entry where:

  • kind is Group, and
  • name is system:masters

These bindings indicate the system:masters group is being used and need human review.


# 2. Show full details of all ClusterRoleBindings for manual review
# Run on: any machine with kubectl access
kubectl get clusterrolebindings -o yaml

What to look for (problematic examples): Under each ClusterRoleBinding, look at the subjects: list. Entries like these are high-risk:

subjects:
- kind: Group
name: system:masters
apiGroup: rbac.authorization.k8s.io

or

subjects:
- kind: Group
name: system:masters

Any non-system or external user or group that is made a member of system:masters (in your IdP/OS) effectively gets full, non-revocable cluster admin access. Every such usage must be consciously justified or removed.


# 3. Identify subjects that are effectively getting cluster-admin via system:masters
# (helps prioritize review)
# Run on: any machine with kubectl access
kubectl get clusterrolebindings -o json \
| jq -r '
.items[]
| select(.subjects != null)
| select(.subjects[]?.kind == "Group" and .subjects[]?.name == "system:masters")
| .metadata.name as $crb
| .subjects[]
| select(.kind == "Group" and .name == "system:masters")
| "ClusterRoleBinding: \($crb) -> Group: \(.name)"
'

What this tells you:
Each line shows a ClusterRoleBinding that directly binds the system:masters group. Any such binding is a candidate for redesign. Decide, per binding, whether membership in system:masters is truly required or whether a narrower Role/ClusterRole should be used instead.


# 4. Verify that system:masters is no longer referenced
# (run after you have made and applied your own RBAC changes)
# Run on: any machine with kubectl access
kubectl get clusterrolebindings -o json \
| jq -e '
.items[]
| select(.subjects != null)
| select(.subjects[]?.kind == "Group" and .subjects[]?.name == "system:masters")
' >/dev/null && echo "system:masters still in use" || echo "No ClusterRoleBindings reference system:masters"

Success condition:
The final message should be No ClusterRoleBindings reference system:masters. If you see system:masters still in use, there are still bindings that must be reviewed and a decision made on whether to keep or change them.

Automation
#!/usr/bin/env bash
# Report all uses of the system:masters group across the cluster.
# Run on: any machine with kubectl access and current kube-context set.

set -euo pipefail

echo "=== Checking ClusterRoleBindings that reference group system:masters ==="
kubectl get clusterrolebindings -o yaml \
| awk '
$1 == "kind:" {kind=$2}
$1 == "metadata:" {ns=""; name=""}
$1 == "name:" && prev=="metadata:" {name=$2}
$1 == "subjects:" {in_subj=1; next}
in_subj && $1 == "-" {type=""; group=""; next}
in_subj && $1 == "kind:" {type=$2}
in_subj && $1 == "apiGroup:" {ag=$2}
in_subj && $1 == "name:" {subname=$2}
in_subj && $1 == "namespace:" {subns=$2}
/^ roleRef:/ {in_subj=0}
{
if (type=="Group" && subname=="system:masters") {
printf "ClusterRoleBinding: %s\n", name
}
}
{prev=$1}
' | sort -u

echo
echo "=== Checking RoleBindings (all namespaces) that reference group system:masters ==="
kubectl get rolebindings --all-namespaces -o yaml \
| awk '
$1 == "kind:" {kind=$2}
$1 == "metadata:" {ns=""; name=""}
$1 == "namespace:" && prev=="metadata:" {ns=$2}
$1 == "name:" && prev=="metadata:" {name=$2}
$1 == "subjects:" {in_subj=1; next}
in_subj && $1 == "-" {type=""; group=""; next}
in_subj && $1 == "kind:" {type=$2}
in_subj && $1 == "apiGroup:" {ag=$2}
in_subj && $1 == "name:" {subname=$2}
in_subj && $1 == "namespace:" {subns=$2}
/^ roleRef:/ {in_subj=0}
{
if (type=="Group" && subname=="system:masters") {
printf "Namespace: %s\tRoleBinding: %s\n", ns, name
}
}
{prev=$1}
' | sort -u

echo
echo "=== Checking Subjects that resolve to system:masters via groups in kubeconfig (best-effort) ==="
echo "Note: This part is heuristic; authoritative group membership is managed outside Kubernetes."
echo "KUBECONFIG inspected: ${KUBECONFIG:-$HOME/.kube/config}"
kubectl config view --minify -o jsonpath='{.contexts[0].context.user}{"\n"}' 2>/dev/null || true

How to interpret the output

  • Any line under:

    • === Checking ClusterRoleBindings that reference group system:masters ===

      • e.g. ClusterRoleBinding: cluster-admin-binding
    • === Checking RoleBindings (all namespaces) that reference group system:masters ===

      • e.g. Namespace: kube-system RoleBinding: ops-admins

    indicates a problem: those bindings are granting permissions to the system:masters group and should be reviewed and, where possible, replaced with least-privilege RBAC targeting specific users/groups or custom roles.

  • If both sections print nothing (no ClusterRoleBinding or RoleBinding listed), the cluster has no RBAC bindings directly referencing system:masters, which is the desired state for this control.