Views:
Profile applicability: Level 1
The Kubernetes API stores secrets, which may be service account tokens for the Kubernetes API or credentials used by workloads in the cluster. Access to these secrets should be restricted to the smallest possible group of users to reduce the risk of privilege escalation.
Inappropriate access to secrets stored within the Kubernetes cluster can allow for an attacker to gain additional access to the Kubernetes cluster or external resources whose credentials are stored as secrets.

Impact

Care should be taken not to remove access to secrets to system components which require this for their operation

Audit

Review the users who have get, list or watch access to secrets objects in the Kubernetes API.
Below is a command to print which objects have get, list or watch granted for each matching role including roles that grant access via wildcards like resources: ["","secrets/"] or verbs: ["*"]
kubectl get clusterrole,role -A -o json | jq -r ' def wanted: ["get","list","watch"]; .items[] as $r | [ $r.rules[]? | select( ((.apiGroups? // [""]) | any(.=="" or .=="*")) and ((.resources? // []) | any(.=="secrets" or .=="secrets/*" or .=="*")) and ((.verbs? // []) | any(.=="*" or .=="get" or .=="list" or .=="watch")) ) | if ((.verbs? // []) | any(.=="*")) then wanted[] else (.verbs[]? | select(IN("get","list","watch"))) end ] as $verbs | select($verbs | length > 0) | "\($r.kind): \($r.metadata.name) (namespace: \($r.metadata.namespace // "cluster-wide")) | verbs: \($verbs | unique | join(","))" '
Sample output:
ClusterRole: admin (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: cluster-admin (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: edit (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:aggregate-to-edit (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:cloud-controller-manager (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:controller:generic-garbage-collector (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:controller:namespace-controller (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:controller:resourcequota-controller (namespace: cluster-wide) | verbs: list,watch
ClusterRole: system:gcp-controller-manager (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:gke-common-webhooks (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:glbc-status (namespace: cluster-wide) | verbs: get
ClusterRole: system:kube-controller-manager (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:kubestore-collector (namespace: cluster-wide) | verbs: get,list,watch
ClusterRole: system:node (namespace: cluster-wide) | verbs: get,list,watch
Role: operator (namespace: gmp-public) | verbs: get,list,watch
Role: operator (namespace: gmp-system) | verbs: get,list,watch
Role: system:controller:bootstrap-signer (namespace: kube-system) | verbs: get,list,watch
Role: system:controller:token-cleaner (namespace: kube-system) | verbs: get,list,watch

Remediation

Where possible, remove get, list or watch access to secret objects in the cluster.

Default value

CLUSTERROLEBINDING                                    SUBJECT
TYPE                      SA-NAMESPACE
cluster-admin                                                  system:masters
Group
system:controller:clusterrole-aggregation-controller           clusterroleaggregation-
controller ServiceAccount kube-system
system:controller:expand-controller                            expand-controller
ServiceAccount kube-system
system:controller:generic-garbage-collector                    generic-garbagecollector
ServiceAccount kube-system
system:controller:namespace-controller                         namespace-controller
ServiceAccount kube-system
system:controller:persistent-volume-binder                     persistent-volumebinder
ServiceAccount kube-system
system:kube-controller-manager                                 system:kube-controllermanager 
    User