A Kubernetes secret is an object that lets users store and manage sensitive information, such as passwords and connection strings in the cluster. Secrets can be consumed by reference in the pod configuration. Attackers who have permissions to retrieve the secrets from the API server (by using the pod service account, for example) can access sensitive information that might include credentials to various services.
Create a ClusterRole secret-reader
that can read secrets:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Create a service account and a ClusterRoleBinding for the secret-reader
ClusterRole
apiVersion: v1
kind: ServiceAccount
metadata:
name: secret-reader
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: secret-reader-binding
subjects:
- kind: ServiceAccount
name: secret-reader
namespace: default
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
Create secret for the secret-reader
service account (needed for Kubernetes >=1.24 as no secrets for service accounts will be auto-generated by default):
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: secret-reader
annotations:
kubernetes.io/service-account.name: "secret-reader"
We can now read all secrets in our Kubernetes cluster:
$ kubectl auth can-i --list --as system:serviceaccount:default:secret-reader
Resources Non-Resource URLs Resource Names Verbs
selfsubjectaccessreviews.authorization.k8s.io [] [] [create]
selfsubjectrulesreviews.authorization.k8s.io [] [] [create]
secrets [] [] [get watch list]
...
If we create a pod which uses the secret-reader
service account as follows, the token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token
can be used by an attacker to perform the actions described above:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
serviceAccount: secret-reader
containers:
- image: nginx
name: my-pod