In this lesson, you will learn how to enforce the Principle of Least Privilege by restricting which ServiceAccounts can access sensitive Kubernetes Secrets.
The Problem with Default Permissions
By default, Kubernetes Secrets are stored in etcd in base64-encoded format. If your Pods are running with a default ServiceAccount that has overly broad permissions (or if you have not explicitly restricted RBAC), any container compromised within your cluster could potentially list or read these sensitive credentials. Securing these objects requires moving beyond simple namespace-wide access to granular, resource-specific permissions.
Implementing Granular Secret Access
To restrict access, you must ensure that your application’s ServiceAccount has a Role that grants access only to the specific secrets it requires, rather than granting access to all secrets in the namespace.
First, define a Role that references a specific resource name:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["db-credentials"] # Only allow access to this specific secret
verbs: ["get", "watch"]
Next, bind this Role to the specific ServiceAccount used by your Pod:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-db-secret
subjects:
- kind: ServiceAccount
name: my-app-service-account
roleRef:
kind: Role
name: secret-reader
apiGroup: rbac.authorization.k8s.io
Why This Matters
By utilizing the resourceNames field in your RBAC policy, you create a "fence" around your sensitive data. Even if a pod is compromised, the attacker cannot list or access other secrets (like API keys for cloud providers or third-party integrations) because the ServiceAccount lacks the authority to touch anything outside of the explicitly named object. This approach transforms your security posture from "open by default" to "explicitly permitted," drastically reducing your attack surface and limiting the potential impact of a container breakout or malicious code execution.
Key Takeaway: Always use granular RBAC Roles with resourceNames to bind access to specific, required secrets rather than granting broad read access to all secrets in a namespace.