<p>We created the GKE cluster with the <strong>public</strong> endpoint. The <strong>service account</strong> of the GKE <strong>cluster</strong> and <strong>Node pool</strong> has the following roles.</p>
<pre><code>&quot;roles/compute.admin&quot;,
&quot;roles/compute.viewer&quot;,
&quot;roles/compute.securityAdmin&quot;,
&quot;roles/iam.serviceAccountUser&quot;,
&quot;roles/iam.serviceAccountAdmin&quot;,
&quot;roles/resourcemanager.projectIamAdmin&quot;,
&quot;roles/container.admin&quot;,
&quot;roles/artifactregistry.admin&quot;,
&quot;roles/storage.admin&quot;
</code></pre>
<p>The node pool of the GKE cluster has the following <strong>OAuth scopes</strong></p>
<pre><code>&quot;https://www.googleapis.com/auth/cloud-platform&quot;,
&quot;https://www.googleapis.com/auth/devstorage.read_write&quot;,
</code></pre>
<p>The <strong>private</strong> GCS bucket has the same service account as the principal, with the <strong>storage admin</strong> role.</p>
<p>When we try to read/write in this bucket from a GKE POD, we get the below error.</p>
<pre><code># Read
AccessDeniedException: 403 Caller does not have storage.objects.list access to the Google Cloud Storage bucket

# Write
AccessDeniedException: 403 Caller does not have storage.objects.create access to the Google Cloud Storage object
</code></pre>
<p>We also checked this <a href="https://stackoverflow.com/questions/46497002/gcs-write-access-from-inside-a-gke-pod">thread</a> but the solution was credential oriented and couldn't help us. <strong>We would like to read/write without maintaining the SA auth key or any sort of credentials</strong>.</p>
<p>Please guide what is missing here.</p>
<hr />
<p><strong>UPDATE</strong>: as per the suggestion by @boredabdel we checked and found that <code>workload identity</code> was already enabled on the GKE cluster as well as NodePool. We are using this <a href="https://registry.terraform.io/modules/terraform-google-modules/kubernetes-engine/google/latest/submodules/beta-private-cluster" rel="nofollow noreferrer">module</a> to create our cluster where it is already enabled by default. Still, we are facing connectivity issues.</p>
<p><strong>Cluster</strong>
Security:</p>
<p><a href="https://i.stack.imgur.com/oEeIW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oEeIW.png" alt="enter image description here" /></a></p>
<p><strong>NodePool</strong>
Security:</p>
<p><a href="https://i.stack.imgur.com/MH0Fw.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/MH0Fw.png" alt="enter image description here" /></a></p>

Nitin G
<p>This is for all who are looking for an answer to implement this solution via terraform. Please refer below:</p>
<h5>Create a Kubernetes service account with annotation</h5>
<pre><code>resource &quot;kubernetes_manifest&quot; &quot;service_account&quot; {
  manifest = {
    &quot;apiVersion&quot; = &quot;v1&quot;
    &quot;kind&quot;       = &quot;ServiceAccount&quot;
    &quot;metadata&quot; = {
      &quot;name&quot;      = &quot;KSA_NAME&quot;
      &quot;namespace&quot; = &quot;NAME&quot;
      &quot;annotations&quot; = {
        &quot;iam.gke.io/gcp-service-account&quot; = &quot;GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com&quot;
      }
    }
    &quot;automountServiceAccountToken&quot; = true
  }
}
</code></pre>
<h5>Create an IAM policy binding to allow the Kubernetes service account to act as the IAM service account.</h5>
<pre><code>resource &quot;google_service_account_iam_binding&quot; &quot;service-account-iam&quot; {
  service_account_id = &quot;projects/PROJECT_ID/serviceAccounts/GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com&quot;
  role               = &quot;roles/iam.workloadIdentityUser&quot;
  members            = [
    &quot;serviceAccount:${var.project_id}.svc.id.goog[NAMESPACE/KSA-NAME]&quot;,
  ]
}
</code></pre>
<h5>Add service account to the deployment/statefulset manifest like this</h5>
<pre><code>spec:
  serviceAccount: KSA-NAME
  containers:
</code></pre>
<p><strong>NOTE</strong>:</p>
<ol>
<li>GSA_PROJECT and PROJECT_ID are the same if you are using the same project for all objects.</li>
<li>K8s service account is created via <code>resource &quot;kubernetes_manifest&quot;</code> method because there is an open <a href="https://github.com/hashicorp/terraform-provider-kubernetes/issues/1724" rel="nofollow noreferrer">issue</a> for it to create via <code>resource &quot;kubernetes_service_account&quot;</code> method where it is throwing an error stating. <em><code>Waiting for default secret of &quot;NAMESPACE/KSA_NAME&quot; to appear</code></em></li>
</ol>
