<h1>My Objective</h1>
<p>I want to use GCP impersonation to fetch my GKE cluster credentials. And then I want to run <code>kubectl</code> commands.</p>
<h1>Initial Context</h1>
<ol>
<li>I have a GCP project called <code>rakib-example-project</code></li>
<li>I have 2 ServiceAccounts in the project called:
<ul>
<li><strong>owner@rakib-example-project.iam.gserviceaccount.com</strong>
<ul>
<li>it has the project-wide <code>roles/owner</code> role - so it can do anything and everything inside the GCP project</li>
</ul>
</li>
<li><strong>executor@rakib-example-project.iam.gserviceaccount.com</strong>
<ul>
<li>it only has the project-wide <code>roles/iam.serviceAccountTokenCreator</code> role - so it can <strong>impersonate</strong> the <strong>owner</strong> ServiceAccount in the GCP project</li>
</ul>
</li>
</ul>
</li>
<li>I have 1 GKE cluster in the project called <code>my-gke-cluster</code></li>
</ol>
<h1>The Problem</h1>
<p>✅ I have authenticated as the <strong>executor</strong> ServiceAccount:</p>
<pre class="lang-sh prettyprint-override"><code>$ gcloud auth activate-service-account --key-file=my_executor_sa_key.json

Activated service account credentials for: [executor@rakib-example-project.iam.gserviceaccount.com]
</code></pre>
<p>✅ I have fetched GKE cluster credentials by impersonating the <strong>owner</strong>:</p>
<pre class="lang-sh prettyprint-override"><code>$ gcloud container clusters get-credentials my-gke-cluster \
  --zone asia-southeast1-a \
  --project rakib-example-project \
  --impersonate-service-account=owner@rakib-example-project.iam.gserviceaccount.com

WARNING: This command is using service account impersonation. All API calls will be executed as [owner@rakib-example-project.iam.gserviceaccount.com].
WARNING: This command is using service account impersonation. All API calls will be executed as [owner@rakib-example-project.iam.gserviceaccount.com].
Fetching cluster endpoint and auth data.
kubeconfig entry generated for my-gke-cluster.
</code></pre>
<p>❌ I am failing to list cluster nodes due to missing <code>container.nodes.list</code> permission:</p>
<pre class="lang-sh prettyprint-override"><code>$ kubectl get nodes

Error from server (Forbidden): nodes is forbidden: User &quot;executor@rakib-example-project.iam.gserviceaccount.com&quot; cannot list resource &quot;nodes&quot; in API group &quot;&quot; at the cluster scope: requires one of [&quot;container.nodes.list&quot;] permission(s).
</code></pre>
<p>But I have already impersonated the <strong>Owner</strong> ServiceAccount. Why would it still have missing permissions? 😧😧😧</p>
<h1>My Limitations</h1>
<p>It works well if i grant my <strong>executor</strong> ServiceAccount the <code>roles/container.admin</code> role. However, I am not allowed to grant such roles to my <strong>executor</strong> ServiceAccount due to compliance requirements. I can only impersonate the <strong>owner</strong> ServiceAccount and THEN do whatever I want through it - not directly.</p>

<p>If you have a look to your kubeconfig file at this location <code>~/.kube/config</code>, you can see the list of authorization and the secrets, such as</p>
<pre><code>- name: gke_gdglyon-cloudrun_us-central1-c_knative
  user:
    auth-provider:
      config:
        access-token: ya29.&lt;secret&gt;-9XQmaTQodj4kS39w
        cmd-args: config config-helper --format=json
        cmd-path: /usr/lib/google-cloud-sdk/bin/gcloud
        expiry: &quot;2020-08-25T17:48:39Z&quot;
        expiry-key: '{.credential.token_expiry}'
        token-key: '{.credential.access_token}'
      name: gcp
</code></pre>
<p>You see external references (<code>expiry-key</code> and <code>token-key</code>) and a <code>cmd-path</code>. The command path is interesting because when a new token need to be generated, it will be called.</p>
<p>However, you see any mention of the impersonation. You have to add it in the command path, to be used by default. For this, add it in your config like this:</p>
<pre><code>gcloud config set auth/impersonate_service_account owner@rakib-example-project.iam.gserviceaccount.com
</code></pre>
<p>Now, every use of the gcloud CLI will use the impersonate service account, and it's what you want to generate a valid access_token to reach your GKE cluster</p>
