implementing-rbac-hardening-for-kubernetes skill (Anthropic-Cybersecurity-Skills)

From Public Agent Wiki

What it does. Hardens Kubernetes RBAC by designing least-privilege Roles and ClusterRoles, auditing RoleBindings, eliminating cluster-admin sprawl, separating service accounts, and integrating an external OIDC identity provider. Use when tightening cluster access control, removing excessive ClusterRoleBindings, or hardening service-account permissions against escalation and lateral movement. Keywords: RBAC, Role, ClusterRole, RoleBinding, least privilege, service account, OIDC, cluster-admin. Do not use for discovering existing escalation paths - use auditing-kubernetes-rbac-privilege-escalation. Part of mukul975/Anthropic-Cybersecurity-Skills (817 security skills) (mukul975/Anthropic-Cybersecurity-Skills).

Upstream mukul975/Anthropic-Cybersecurity-Skills
Skill file skills/implementing-rbac-hardening-for-kubernetes/SKILL.md
License Apache-2.0 (skill folder LICENSE)
Author mukul975
Fetched 2026-09-10

Install

  • npx skills add mukul975/Anthropic-Cybersecurity-Skills --skill implementing-rbac-hardening-for-kubernetes, or copy the skill folder into ~/.claude/skills/implementing-rbac-hardening-for-kubernetes/.
  • Raw file: curl -sL https://raw.githubusercontent.com/mukul975/Anthropic-Cybersecurity-Skills/HEAD/skills/implementing-rbac-hardening-for-kubernetes/SKILL.md

SKILL.md (verbatim)

name: implementing-rbac-hardening-for-kubernetes
description: >-
  Hardens Kubernetes RBAC by designing least-privilege Roles and ClusterRoles, auditing
  RoleBindings, eliminating cluster-admin sprawl, separating service accounts, and integrating
  an external OIDC identity provider. Use when tightening cluster access control, removing
  excessive ClusterRoleBindings, or hardening service-account permissions against escalation
  and lateral movement. Keywords: RBAC, Role, ClusterRole, RoleBinding, least privilege,
  service account, OIDC, cluster-admin. Do not use for discovering existing escalation paths -
  use auditing-kubernetes-rbac-privilege-escalation.
domain: cybersecurity
subdomain: container-security
tags:
- kubernetes
- rbac
- access-control
- least-privilege
- security-hardening
- iam
- oidc
- service-accounts
version: '1.0'
author: mahipal
license: Apache-2.0
nist_csf:
- PR.PS-01
- PR.IR-01
- ID.AM-08
- DE.CM-01
mitre_attack:
- T1610
- T1611
- T1609
- T1525

Implementing RBAC Hardening for Kubernetes

Overview

Kubernetes RBAC regulates access to cluster resources based on roles assigned to users, groups, and service accounts. Default configurations often grant excessive permissions, and without active hardening, RBAC becomes a primary attack vector for privilege escalation, lateral movement, and data exfiltration. Hardening requires implementing least-privilege principles, eliminating unnecessary ClusterRole bindings, separating service accounts, integrating external identity providers, and continuous auditing.

When to Use

  • When deploying or configuring implementing rbac hardening for kubernetes capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation

Prerequisites

  • Kubernetes cluster v1.24+ with RBAC enabled (default since v1.6)
  • kubectl access with cluster-admin for initial audit
  • External identity provider (OIDC) for user authentication
  • Audit logging enabled on the API server

Core Hardening Principles

1. Eliminate cluster-admin Sprawl

Audit and remove unnecessary cluster-admin bindings:

# List all cluster-admin bindings
kubectl get clusterrolebindings -o json | jq -r '
  .items[] |
  select(.roleRef.name == "cluster-admin") |
  "\(.metadata.name) -> \(.subjects[]? | "\(.kind)/\(.name) (\(.namespace // "cluster"))")"
'

2. Namespace-Scoped Roles Over ClusterRoles

Use Role and RoleBinding instead of ClusterRole and ClusterRoleBinding:

# Good: Namespace-scoped role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: application
  name: app-developer
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: application
  name: app-developer-binding
subjects:
  - kind: Group
    name: dev-team
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: app-developer
  apiGroup: rbac.authorization.k8s.io

3. Dedicated Service Accounts Per Workload

apiVersion: v1
kind: ServiceAccount
metadata:
  name: payment-processor
  namespace: payments
automountServiceAccountToken: false  # Disable auto-mount
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-processor
  namespace: payments
spec:
  template:
    spec:
      serviceAccountName: payment-processor
      automountServiceAccountToken: true  # Only mount when explicitly needed
      containers:
        - name: processor
          image: payments/processor:v2.1@sha256:abc...

4. Restrict Dangerous Permissions

Block permissions that enable privilege escalation:

# Dangerous verbs/resources to restrict:
# - secrets: get, list, watch (exposes all secrets in namespace)
# - pods/exec: create (enables command execution in pods)
# - pods: create with privileged securityContext
# - serviceaccounts/token: create (generates new tokens)
# - clusterroles/clusterrolebindings: create, update (self-escalation)
# - nodes/proxy: create (bypasses API server authorization)

# Safe read-only role example
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: security-viewer
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "namespaces", "nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "daemonsets", "statefulsets"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["networking.k8s.io"]
    resources: ["networkpolicies"]
    verbs: ["get", "list", "watch"]

5. OIDC Integration for User Authentication

# API server flags for OIDC integration
apiVersion: v1
kind: Pod
metadata:
  name: kube-apiserver
spec:
  containers:
    - name: kube-apiserver
      command:
        - kube-apiserver
        - --oidc-issuer-url=https://idp.company.com
        - --oidc-client-id=kubernetes
        - --oidc-username-claim=email
        - --oidc-groups-claim=groups
        - --oidc-ca-file=/etc/kubernetes/pki/oidc-ca.crt

RBAC Audit Process

Step 1: Enumerate All Bindings

# All ClusterRoleBindings with subjects
kubectl get clusterrolebindings -o json | jq -r '
  .items[] | select(.subjects != null) |
  .subjects[] as $s |
  "\(.metadata.name) | \(.roleRef.name) | \($s.kind)/\($s.name)"
' | sort | column -t -s '|'

# All RoleBindings across namespaces
kubectl get rolebindings --all-namespaces -o json | jq -r '
  .items[] | select(.subjects != null) |
  .subjects[] as $s |
  "\(.metadata.namespace) | \(.metadata.name) | \(.roleRef.name) | \($s.kind)/\($s.name)"
' | sort | column -t -s '|'

Step 2: Identify Overprivileged Service Accounts

# Find service accounts with cluster-admin or admin roles
kubectl get clusterrolebindings -o json | jq -r '
  .items[] |
  select(.roleRef.name == "cluster-admin" or .roleRef.name == "admin") |
  select(.subjects[]?.kind == "ServiceAccount") |
  "\(.subjects[] | select(.kind == "ServiceAccount") | "\(.namespace)/\(.name)")"
'

Step 3: Check Default Service Account Usage

# Find pods using the default service account
kubectl get pods --all-namespaces -o json | jq -r '
  .items[] |
  select(.spec.serviceAccountName == "default" or .spec.serviceAccountName == null) |
  "\(.metadata.namespace)/\(.metadata.name)"
'

Step 4: Verify Token Auto-Mount

# Find pods with auto-mounted service account tokens
kubectl get pods --all-namespaces -o json | jq -r '
  .items[] |
  select(.spec.automountServiceAccountToken != false) |
  "\(.metadata.namespace)/\(.metadata.name) sa=\(.spec.serviceAccountName // "default")"
'

Tooling

rbac-lookup

# Install rbac-lookup
kubectl krew install rbac-lookup

# View RBAC for a specific user
kubectl rbac-lookup developer@company.com

# View all RBAC bindings wide format
kubectl rbac-lookup --kind user -o wide

rakkess (Review Access)

# Install rakkess
kubectl krew install access-matrix

# Show access matrix for current user
kubectl access-matrix

# Show access for a specific service account
kubectl access-matrix --sa payments:payment-processor

References

Other files in this skill

assets/template.md (verbatim)

RBAC Hardening Assessment Template

Cluster Information

Field Value
Cluster Name
Kubernetes Version
Assessment Date

RBAC Audit Results

Metric Count
ClusterRoleBindings
cluster-admin bindings
Wildcard permissions
Default SA bindings

Hardening Checklist

  • Removed unnecessary cluster-admin bindings
  • All workloads use dedicated service accounts
  • automountServiceAccountToken disabled on default SAs
  • OIDC integration configured
  • RBAC monitoring and alerting active
  • Quarterly review process established

Sign-Off

Role Name Date
Security Engineer
Platform Lead

references/api-reference.md (verbatim)

API Reference: Kubernetes RBAC Hardening Audit

Libraries Used

Library Purpose
kubernetes Official Kubernetes Python client for RBAC API
json Parse and format RBAC audit results
yaml Read Kubernetes RBAC manifest files

Installation

pip install kubernetes pyyaml

Authentication

from kubernetes import client, config

# Local kubeconfig
config.load_kube_config()

# In-cluster
# config.load_incluster_config()

rbac_api = client.RbacAuthorizationV1Api()
core_api = client.CoreV1Api()

RBAC API Methods

Method Description
list_cluster_role() List all ClusterRoles
list_cluster_role_binding() List all ClusterRoleBindings
list_namespaced_role(namespace) List Roles in a namespace
list_namespaced_role_binding(namespace) List RoleBindings in a namespace
read_cluster_role(name) Get specific ClusterRole details
read_cluster_role_binding(name) Get specific ClusterRoleBinding

Core Audit Operations

Detect Wildcard Permissions

def find_wildcard_permissions():
    """Find ClusterRoles with wildcard (*) verbs, resources, or apiGroups."""
    findings = []
    roles = rbac_api.list_cluster_role()
    for role in roles.items:
        if not role.rules:
            continue
        for rule in role.rules:
            wildcards = []
            if rule.verbs and "*" in rule.verbs:
                wildcards.append("verbs")
            if rule.resources and "*" in rule.resources:
                wildcards.append("resources")
            if rule.api_groups and "*" in rule.api_groups:
                wildcards.append("apiGroups")
            if wildcards:
                findings.append({
                    "role": role.metadata.name,
                    "wildcards": wildcards,
                    "severity": "critical" if len(wildcards) >= 2 else "high",
                })
    return findings

Find Subjects Bound to cluster-admin

def find_cluster_admin_bindings():
    """Identify all subjects with cluster-admin privileges."""
    bindings = rbac_api.list_cluster_role_binding()
    admin_subjects = []
    for binding in bindings.items:
        if binding.role_ref.name == "cluster-admin":
            for subject in binding.subjects or []:
                admin_subjects.append({
                    "binding": binding.metadata.name,
                    "subject_kind": subject.kind,
                    "subject_name": subject.name,
                    "namespace": subject.namespace or "cluster-wide",
                    "severity": "high",
                })
    return admin_subjects

Detect Privilege Escalation Risks

ESCALATION_VERBS = {"bind", "escalate", "impersonate"}
DANGEROUS_RESOURCES = {"secrets", "pods/exec", "serviceaccounts/token"}

def find_escalation_risks():
    findings = []
    roles = rbac_api.list_cluster_role()
    for role in roles.items:
        for rule in (role.rules or []):
            dangerous_verbs = set(rule.verbs or []) & ESCALATION_VERBS
            dangerous_resources = set(rule.resources or []) & DANGEROUS_RESOURCES
            if dangerous_verbs:
                findings.append({
                    "role": role.metadata.name,
                    "issue": f"Escalation verbs: {dangerous_verbs}",
                    "severity": "critical",
                })
            if dangerous_resources and "get" in (rule.verbs or []):
                findings.append({
                    "role": role.metadata.name,
                    "issue": f"Access to sensitive resources: {dangerous_resources}",
                    "severity": "high",
                })
    return findings

Audit Service Account Token Auto-Mount

def find_automount_service_tokens():
    """Find pods with automountServiceAccountToken enabled."""
    findings = []
    namespaces = core_api.list_namespace()
    for ns in namespaces.items:
        pods = core_api.list_namespaced_pod(ns.metadata.name)
        for pod in pods.items:
            automount = pod.spec.automount_service_account_token
            if automount is None or automount is True:
                sa = pod.spec.service_account_name or "default"
                if sa != "default":
                    findings.append({
                        "namespace": ns.metadata.name,
                        "pod": pod.metadata.name,
                        "service_account": sa,
                        "issue": "automountServiceAccountToken not disabled",
                    })
    return findings

Find Unused Roles

def find_unused_roles():
    """Detect Roles with no corresponding RoleBindings."""
    namespaces = core_api.list_namespace()
    unused = []
    for ns in namespaces.items:
        roles = rbac_api.list_namespaced_role(ns.metadata.name)
        bindings = rbac_api.list_namespaced_role_binding(ns.metadata.name)
        bound_roles = {b.role_ref.name for b in bindings.items}
        for role in roles.items:
            if role.metadata.name not in bound_roles:
                unused.append({
                    "namespace": ns.metadata.name,
                    "role": role.metadata.name,
                    "issue": "Role has no bindings — candidate for removal",
                })
    return unused

kubectl Equivalents

# List all ClusterRoleBindings for cluster-admin
kubectl get clusterrolebindings -o json | \
  jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects[]'

# Find roles with wildcard permissions
kubectl get clusterroles -o json | \
  jq '.items[] | select(.rules[]?.verbs[]? == "*") | .metadata.name'

# Audit RBAC with rakkess (kubectl plugin)
kubectl krew install access-matrix
kubectl access-matrix --namespace production

Output Format

{
  "cluster": "production",
  "audit_date": "2025-01-15",
  "cluster_admin_subjects": 5,
  "wildcard_roles": 3,
  "escalation_risks": 2,
  "unused_roles": 8,
  "findings": [
    {
      "role": "custom-admin",
      "issue": "Wildcard verbs and resources",
      "severity": "critical",
      "remediation": "Replace * with explicit verb and resource lists"
    }
  ]
}

references/standards.md (verbatim)

Standards - RBAC Hardening for Kubernetes

CIS Kubernetes Benchmark v1.9

  • 5.1.1: Ensure cluster-admin role is only used where required
  • 5.1.2: Minimize access to secrets
  • 5.1.3: Minimize wildcard use in Roles and ClusterRoles
  • 5.1.4: Minimize access to create pods
  • 5.1.5: Ensure default service accounts are not actively used
  • 5.1.6: Ensure Service Account Tokens are only mounted where necessary

NIST SP 800-190

  • Section 3.4: Orchestrator security -- access control hardening
  • Section 4.4: Countermeasures for orchestrator vulnerabilities

MITRE ATT&CK

  • T1078.004: Valid Accounts: Cloud Accounts -- compromised service accounts
  • T1098: Account Manipulation -- RBAC escalation
  • T1069: Permission Groups Discovery -- enumerating RBAC bindings

references/workflows.md (verbatim)

Workflows - RBAC Hardening

Hardening Workflow

  1. Audit all existing ClusterRoleBindings and RoleBindings
  2. Identify overprivileged accounts (cluster-admin sprawl)
  3. Create namespace-scoped Roles with minimum required permissions
  4. Migrate workloads to dedicated service accounts
  5. Disable automountServiceAccountToken on default service accounts
  6. Integrate OIDC for user authentication
  7. Deploy RBAC monitoring and alerting
  8. Schedule quarterly RBAC reviews

Continuous Compliance

  • Weekly: automated RBAC audit with rbac-lookup
  • Monthly: review new RoleBindings created in past 30 days
  • Quarterly: full access review with stakeholder sign-off
  • Annually: penetration test RBAC boundaries

Back to mukul975/Anthropic-Cybersecurity-Skills (817 security skills) or Agent skills.