Overview
A service account is an identity that an instance or an application can use to run API requests on your behalf. This identity is used to identify applications running on your virtual machine instances to other Google Cloud Platform services. By default, Kubernetes Engine nodes are given the Compute Engine default service account. This account has broad access by default, making it useful to a wide variety of applications, but it has more permissions than are required to run your Kubernetes Engine cluster.
Rationale
You should create and use a minimally privileged service account to run your Kubernetes Engine cluster instead of using the Compute Engine default service account. If you are not creating a separate service account for your nodes, you should limit the scopes of the node service account to reduce the possibility of a privilege escalation in an attack. Kubernetes Engine requires, at a minimum, the service account to have the monitoring.viewer, monitoring.metricWriter, and logging.logWriter roles. This ensures that your default service account does not have permissions beyond those necessary to run your cluster. While the default scopes are limited, they may include scopes beyond the minimally required scopes needed to run your cluster.
Remediation guidance
Using Console
- Go to Kubernetes GCP Console by visiting https://console.cloud.google.com/kubernetes/list?
- Click on
CREATE CLUSTER - Choose required name/value for cluster fields
- Click on
More - Choose
Service accountwhich has the least privilege under Project access section, Instead of defaultCompute Engine default service account
NOTE: The default scopes for the nodes in Kubernetes Engine are devstorage.read_only, logging.write, monitoring, service.management.readonly, servicecontrol, and trace.append. If you are accessing private images in Google Container Registry, the minimally required scopes are only logging.write, monitoring, and devstorage.read_only.
You can configure a service account with minimal privileges and assign the same.
- Click on Create
Using Command Line
To create a new node pool with service account with least privilege:, run the following command:
gcloud container node-pools create \[NODE_POOL\] --service-account="\[SA_NAME\]@\[PROJECT_ID\].iam.gserviceaccount.com" --cluster=\[CLUSTER_NAME\] --zone=\[COMPUTE_ZONE\] \`\`
Default Value
By default, Compute Engine default service account is chosen when you create a new cluster.
References
- https://cloud.google.com/compute/docs/access/service-accounts#compute_engine_default_service_account
Multiple Remediation Paths
Google Cloud
SERVICE-WIDE (RECOMMENDED when many resources are affected): Enforce Organization Policies at org/folder level so new resources inherit secure defaults.
gcloud org-policies set-policy policy.yaml
ASSET-LEVEL: Use the product-specific remediation steps above for only the impacted project/resources.
PREVENTIVE: Use org policy constraints/custom constraints and enforce checks in deployment pipelines.
References for Service-Wide Patterns
- GCP Organization Policy overview: https://cloud.google.com/resource-manager/docs/organization-policy/overview
- GCP Organization policy constraints catalog: https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints
- gcloud org-policies: https://cloud.google.com/sdk/gcloud/reference/org-policies
Operational Rollout Workflow
Use this sequence to reduce risk and avoid repeated drift.
1. Contain at Service-Wide Scope First (Recommended)
- Google Cloud: apply organization policy constraints at org/folder scope.
gcloud org-policies set-policy policy.yaml
2. Remediate Existing Affected Assets
- Execute the control-specific Console/CLI steps documented above for each flagged resource.
- Prioritize internet-exposed and production assets first.
3. Validate and Prevent Recurrence
- Re-scan after each remediation batch.
- Track exceptions with owner and expiry date.
- Add preventive checks in IaC/CI pipelines.
Query logic
These are the stored checks tied to this control.
Default Service account is not used for Project access in Kubernetes Clusters
Connectors
Covered asset types
Expected check: eq []
{gkeClusters(where:{nodePools_SOME:{nodeConfig:{serviceAccount:"default"}}}){...AssetFragment}}
Google Cloud