gcp-gke-credentials-cluster-admin-exec
container.clusters.getCredentials + cluster-admin ClusterRoleBinding (or system:masters group) => pods/exec create on all pods => CanExecuteCommand fan-out.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?cluster) ==
KubernetesCluster
?principal's GCP identity maps (via GKE IAM authenticator) to a k8s subject that holds cluster-admin (via ClusterRoleBinding OR system:masters group membership)
The ClusterRoleBinding or system:masters binding is present in the cluster's RBAC config
emit
| source type | Identity |
|---|---|
| target type | KubernetesWorkload |
| source | ?principal |
| target | <all pods in cluster> |
| permissions | container.clusters.getCredentials k8s:pods/exec:create k8s:pods/portforward:create |
| conditions | iam_permission trust_relationship network_reachability |
| state logic | ACTIVE if the ClusterRoleBinding to cluster-admin (or system:masters group assignment) binds the principal's GCP identity/email AND container.clusters.getCredentials is ACTIVE AND the k8s API server endpoint is reachable from the principal's network position. CONDITIONAL(network_reachability) when the cluster's masterAuthorizedNetworksConfig restricts access and the principal is not within an allowed CIDR / VPC peering. BLOCKED when the endpoint is fully private and the principal has no in-VPC foothold. Note: container.clusters.getCredentials itself uses the public GCP API and is always reachable, but the resulting kubeconfig must ALSO reach the k8s API server endpoint to perform exec. CONDITIONAL(trust_relationship) if the RBAC binding exists but the GKE IAM authenticator subject mapping is not confirmed (e.g. the GCP email vs. k8s User subject is ambiguous). |
Narrative
{principal.name} can obtain a cluster-admin kubeconfig for {cluster.name} (container.clusters.getCredentials + ClusterRoleBinding to cluster-admin); this grants pods/exec create on every pod, CanExecuteCommand across all workloads, and - via container-chains cluster-rbac-exec and each pod's ExecutesAs - CanExecuteAs every workload identity in the cluster.
Raw rule rules/derived/gcp/gke.yaml
id: gcp-gke-credentials-cluster-admin-exec
emits: CanExecuteCommand
description: container.clusters.getCredentials + cluster-admin ClusterRoleBinding (or system:masters group)
=> pods/exec create on all pods => CanExecuteCommand fan-out.
match:
- - principal: null
- CanRead
- cluster: null
where:
- node_type(?cluster) == KubernetesCluster
- ?principal's GCP identity maps (via GKE IAM authenticator) to a k8s subject that holds cluster-admin
(via ClusterRoleBinding OR system:masters group membership)
- The ClusterRoleBinding or system:masters binding is present in the cluster's RBAC config
emit:
source_type: Identity
target_type: KubernetesWorkload
source: ?principal
target: <all pods in cluster>
permissions:
- container.clusters.getCredentials
- k8s:pods/exec:create
- k8s:pods/portforward:create
conditions:
- iam_permission
- trust_relationship
- network_reachability
state_logic: 'ACTIVE if the ClusterRoleBinding to cluster-admin (or system:masters group assignment)
binds the principal''s GCP identity/email AND container.clusters.getCredentials is ACTIVE AND the
k8s API server endpoint is reachable from the principal''s network position. CONDITIONAL(network_reachability)
when the cluster''s masterAuthorizedNetworksConfig restricts access and the principal is not within
an allowed CIDR / VPC peering. BLOCKED when the endpoint is fully private and the principal has no
in-VPC foothold. Note: container.clusters.getCredentials itself uses the public GCP API and is always
reachable, but the resulting kubeconfig must ALSO reach the k8s API server endpoint to perform exec.
CONDITIONAL(trust_relationship) if the RBAC binding exists but the GKE IAM authenticator subject mapping
is not confirmed (e.g. the GCP email vs. k8s User subject is ambiguous).'
confidence: 0.93
derived_from:
- <gcp-gke-get-credentials CanRead edge>
- <ClusterRoleBinding to cluster-admin or system:masters group membership>
false_positive_note: "Only emit when BOTH sides are confirmed: (1) container.clusters.getCredentials\
\ is ACTIVE and (2) a ClusterRoleBinding (or system:masters group) binds the principal's GCP email/group\
\ to cluster-admin. Confirm the exact subject in the ClusterRoleBinding matches the GCP identity (user:\
\ vs. group: vs. serviceAccount: in the subjects list). For private clusters add network_reachability\
\ as a gate (the API endpoint is not internet-reachable without Authorized Networks or a VPN). Do\
\ NOT emit for container.clusters.get alone \u2014 that permission does not authenticate to the cluster\
\ API server."
narrative: "{principal.name} can obtain a cluster-admin kubeconfig for {cluster.name} (container.clusters.getCredentials\
\ + ClusterRoleBinding to cluster-admin); this grants pods/exec create on every pod, CanExecuteCommand\
\ across all workloads, and \u2014 via container-chains cluster-rbac-exec and each pod's ExecutesAs\
\ \u2014 CanExecuteAs every workload identity in the cluster."