Skip to main content
RunBook Academy

KubernetesLXV · Secrets SecuritySecrets security

Secrets RBAC — controlling who can read Secrets

Advanced⏱ ~13 minkubectl

What you'll learn

  • Write a minimum-surface RBAC Role for Secret access
  • Use `resourceNames` to scope access to specific Secrets
  • Apply the production patterns (default-deny, per-Secret RBAC)
  • Audit a cluster for over-broad Secret RBAC

Prerequisites

Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16

Not yet marked complete on this device.

Secrets RBAC is the API-server-level control for Secret access. A workload with secrets: get can read every Secret in the namespace (or in every namespace, with a ClusterRoleBinding); a workload without the verb cannot read any. The discipline is to scope access to the minimum surface: specific Secrets, specific verbs, specific subjects. This lesson covers the patterns, the audit, and the failure modes.

The secrets resource

secrets is a resource in the core API group (""). The verbs are get, list, watch, create, update, patch, delete. Read access (get, list, watch) is the dangerous one; the workload can read the Secret’s value.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: read-specific-secret
  namespace: prod
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["db-credentials"]  # only this Secret
  verbs: ["get"]                     # only read

This Role allows a SA to read one specific Secret. No list, no watch, no other Secret.

Default-deny

A defensible cluster has default-deny on Secrets: no Role or ClusterRole grants broad access; only specific Roles grant access to specific Secrets.

# Find broad Secrets RBAC
kubectl get roles,clusterroles -A -o json | \
  jq '.items[] | select(.rules[]?.resources[]? == "secrets") |
  {name: .metadata.name, rules: .rules[] | select(.resources[]? == "secrets")}'

A Role that grants secrets: [get, list, watch] without resourceNames is a finding. A ClusterRoleBinding to a ClusterRole with broad Secrets access is a Critical finding.

Per-workload RBAC

Each workload has its own SA and its own Secret access:

# SA for the API workload
apiVersion: v1
kind: ServiceAccount
metadata:
  name: api-sa
  namespace: prod

---
# Role for the API workload (read one Secret)
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: api-secrets
  namespace: prod
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["db-credentials"]
  verbs: ["get"]

---
# RoleBinding for the API workload
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: api-secrets
  namespace: prod
subjects:
- kind: ServiceAccount
  name: api-sa
  namespace: prod
roleRef:
  kind: Role
  name: api-secrets
  apiGroup: rbac.authorization.k8s.io

The api-sa SA can read the db-credentials Secret. No other Secret.

Verifying with kubectl auth can-i

# Can the SA read the specific Secret?
kubectl auth can-i get secrets/db-credentials -n prod \
  --as=system:serviceaccount:prod:api-sa
# yes

# Can the SA list Secrets?
kubectl auth can-i list secrets -n prod \
  --as=system:serviceaccount:prod:api-sa
# no

# Can the SA read any Secret?
kubectl auth can-i get secrets -n prod \
  --as=system:serviceaccount:prod:api-sa
# no (because resourceNames restricts to db-credentials)

The audit is the verification. The cluster’s RBAC is defensible if every SA’s effective Secret access is the minimum the SA needs.

Production patterns

  1. Per-workload SAs with per-Secret RBAC. Each workload has its own SA; each SA has access to only the Secrets it needs.
  2. resourceNames on every Secrets Role. The Role allows access to specific Secrets, not all.
  3. No secrets: list for workloads. The verb is denied for workloads that need only get.
  4. Audit quarterly. A script walks every SA and verifies its effective Secret access.

Production failure modes

  1. A SA has secrets: list and secrets: get. The SA can enumerate and read every Secret in the namespace. The fix is to scope to specific Secrets.
  2. A ClusterRoleBinding grants secrets: get to a SA cluster-wide. The SA can read every Secret in every namespace. The fix is to remove the ClusterRoleBinding and bind to the specific namespace.
  3. A developer has secrets: get in production. A leaked developer kubeconfig has production Secret access. The fix is OIDC + IdP groups for production RBAC.
  4. A controller has broad Secrets access. A controller with secrets: get, list, watch is over-broad. resourceNames cannot restrict list or watch, so the fix is a namespaced Role bound once in each namespace the controller manages.

Cross-course references

  • The Observability course covers the audit log entries for Secret access.
  • The Linux course covers the file permissions on mounted Secret data.

Quiz

Knowledge check · 4 questions

  1. Q1. What is the role of `resourceNames` in a Secrets RBAC Role?

  2. Q2. A SA with `secrets: list` can enumerate every Secret in the namespace; if it also has `secrets: get`, it can read every Secret.

  3. Q3. Your team's monitoring stack has a ClusterRoleBinding that grants `secrets: get, list, watch` cluster-wide. The binding is to the Prometheus SA. An attacker compromises the Prometheus SA and reads every Secret in every namespace. Walk the response.

    The ClusterRoleBinding is `monitoring-secrets` -> `prometheus-sa` -> ClusterRole `monitoring-all-secrets`. The ClusterRole grants `secrets: [get, list, watch]`. The Prometheus SA is bound cluster-wide. The attacker compromised the Prometheus SA via a known CVE in a sidecar.

  4. Q4. What does 'default-deny' for Secrets RBAC mean, and how is it enforced?

Passing score: 75%. Answers are checked in this browser.

Production discipline

Secrets RBAC is the API-server-level control for Secret access. A defensible RBAC programme uses resourceNames to scope access to specific Secrets, denies list for workloads, audits every SA’s effective Secret access quarterly, and removes broad secrets: get, list, watch bindings. The audit is the verification: every SA’s effective access is the minimum the SA needs. A cluster whose Secrets RBAC is minimum-surface has a Secret programme that is auditable.