Information disclosure from cluster-wide Secret read by ServiceAccounts or nodes in Kubernetes

Critical Risk infrastructure-security
kubernetesrbacsecrets-managementinformation-disclosurecluster-securityservice-accountsprivilege-escalation

What it is

Kubernetes RBAC configurations that grant cluster-wide Secret read permissions to ServiceAccounts or Node identities create severe information disclosure vulnerabilities. Attackers who compromise these identities can access all secrets across all namespaces, including database credentials, API keys, certificates, and other sensitive data, enabling lateral movement and broader system compromise.

# VULNERABLE: ServiceAccount with cluster-wide secret access
apiVersion: v1
kind: ServiceAccount
metadata:
  name: vulnerable-app-sa
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: vulnerable-secret-reader
rules:
# VULNERABLE: Cluster-wide secret read access
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: vulnerable-secret-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: vulnerable-secret-reader
subjects:
- kind: ServiceAccount
  name: vulnerable-app-sa
  namespace: default

# VULNERABLE: CI/CD with excessive permissions
apiVersion: v1
kind: ServiceAccount
metadata:
  name: vulnerable-cicd-sa
  namespace: cicd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: vulnerable-cicd-role
rules:
# VULNERABLE: Can read all cluster secrets
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "watch", "create", "update"]
# SECURE: ServiceAccount with namespace-scoped access
apiVersion: v1
kind: ServiceAccount
metadata:
  name: secure-app-sa
  namespace: production
automountServiceAccountToken: false
---
# SECURE: Namespace-scoped Role with specific secrets
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: secure-app-secrets
rules:
# SECURE: Access only to specific named secrets
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list"]
  resourceNames:
    - "app-database-credentials"
    - "app-api-keys"
    - "app-tls-certificates"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: secure-app-secrets-binding
  namespace: production
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: secure-app-secrets
subjects:
- kind: ServiceAccount
  name: secure-app-sa
  namespace: production

# SECURE: CI/CD with namespace-specific access
apiVersion: v1
kind: ServiceAccount
metadata:
  name: secure-cicd-sa
  namespace: cicd
automountServiceAccountToken: false
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: secure-cicd-prod-role
rules:
# SECURE: Limited to deployment secrets only
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create", "update"]
  resourceNames:
    - "app-deployment-secrets"

💡 Why This Fix Works

The vulnerable configurations use ClusterRoleBindings to grant cluster-wide secret read permissions, allowing compromised ServiceAccounts to access all secrets across all namespaces. The secure alternatives use namespace-scoped RoleBindings that restrict access to specific namespaces, and further limit access to specific named secrets using resourceNames in RBAC rules, implementing the principle of least privilege.

Why it happens

ClusterRoleBindings that grant get/list/watch verbs on secrets resources across all namespaces. This configuration allows ServiceAccounts or identities to read every secret in the cluster, including credentials for unrelated applications and infrastructure components.

Root causes

Cluster-Wide Secret Access Grants

ClusterRoleBindings that grant get/list/watch verbs on secrets resources across all namespaces. This configuration allows ServiceAccounts or identities to read every secret in the cluster, including credentials for unrelated applications and infrastructure components.

Overprivileged ServiceAccount Permissions

ServiceAccounts configured with broad secret access through RBAC ClusterRoles rather than namespace-scoped Roles. These overprivileged accounts violate least-privilege principles and enable lateral movement if pods are compromised.

Shared ServiceAccounts Across Workloads

Multiple applications and workloads sharing a single ServiceAccount with accumulated permissions from various requirements. This anti-pattern creates unnecessarily broad access as each application gains permissions needed by all others.

Missing Resource Name Restrictions

RBAC rules grant access to the secrets resource type without using resourceNames to restrict access to specific named secrets. Without resourceNames, grants apply to all secrets within scope (namespace or cluster-wide).

Insufficient RBAC Auditing

Organizations lack tooling and processes to regularly audit RBAC permissions for overprivileged access to sensitive resources like secrets. Excessive permissions accumulate over time without detection or remediation.

Fixes

1

Use Namespace-Scoped RoleBindings

Replace ClusterRoleBindings with namespace-scoped RoleBindings that grant secret access only within the workload's namespace. This prevents cross-namespace secret access and limits the blast radius of compromised ServiceAccounts to a single namespace.

2

Restrict to Specific Named Secrets

Add resourceNames array to RBAC rules listing exactly which secrets each ServiceAccount can access (e.g., ['app-db-credentials', 'app-api-keys']). This provides fine-grained access control preventing discovery of unrelated secrets.

3

Create Dedicated ServiceAccounts

Deploy separate ServiceAccounts for each workload or application with permissions tailored to their specific requirements. Eliminate shared ServiceAccounts that accumulate excessive permissions across multiple use cases.

4

Remove Node Secret Access

Audit and remove any cluster-wide secret read permissions granted to Node identities (system:nodes group). Nodes typically don't require secret access - pods should use their own ServiceAccounts for secret retrieval.

5

Deploy Policy Enforcement

Implement admission controllers like Kyverno, OPA Gatekeeper, or Pod Security Admission with policies that prevent creation of ClusterRoleBindings granting cluster-wide secret access. Automate detection and blocking of overprivileged RBAC configurations.

Detect This Vulnerability in Your Code

Sourcery automatically identifies information disclosure from cluster-wide secret read by serviceaccounts or nodes in kubernetes and many other security issues in your codebase.