title: kubernetes.client.rest.ApiException: (401) Reason: Unauthorized; What IAM to create/delete GKE pods
body: <p>I'm trying to read a list of active pods in my GKE cluster.  I also want to be able to programmatically create and/or delete pods using a python client.  What IAM access rights should I grant my service account to accomplish this?  Since I've been trying almost anything to get it working this service account currently has <code>Kubernetes Engine Admin</code>, <code>Kubernetes Engine Cluster Admin</code>, and <code>Kubernetes Engine Developer</code> access.</p>
  <p>Here's some sample code that attempts to read the pods in the 'default' namespace at my cluster's IP</p>
  <pre class="lang-py prettyprint-override"><code>import kubernetes
  from oauth2client.client import GoogleCredentials
  
  
  def get_access_config(cluster_ip):
      # access the k8s cluster, https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/
      credentials = GoogleCredentials.get_application_default()
      access_token = credentials.get_access_token()
  
      # Create a configuration object
      access_configuration = kubernetes.client.Configuration()
  
      # Specify the access configuration to access k8s cluster
      access_configuration.host = f&quot;https://{cluster_ip}:443&quot;
      access_configuration.verify_ssl = False
      access_configuration.api_key = {&quot;authorization&quot;: &quot;Bearer &quot; + access_token.access_token}
      return access_configuration
  
  
  def get_pod_list(access_configuration):
      v1 = kubernetes.client.CoreV1Api(kubernetes.client.ApiClient(access_configuration))
      print(&quot;Listing pods with their IPs:&quot;)
      ret = v1.list_namespaced_pod(namespace='default')
  
  
  cluster_ip = '0.0.0.0'  # replace with your cluster_ip
  access_configuration = get_access_config(cluster_ip)
  get_pod_list(access_configuration)
  </code></pre>
  <p>Whenever I run the <code>get_pod_list</code> function, I get the following Traceback:</p>
  <blockquote>
  <pre class="lang-sh prettyprint-override"><code>Traceback (most recent call last):   File &quot;&lt;input&gt;&quot;, line 3, in
  &lt;module&gt;   File
  &quot;/Users/&lt;user&gt;/miniconda3/envs/&lt;my_env&gt;/lib/python3.7/site-packages/kubernetes/client/api/core_v1_api.py&quot;,
  line 12803, in list_namespaced_pod
      (data) = self.list_namespaced_pod_with_http_info(namespace, **kwargs)  # noqa: E501   File &quot;/Users/&lt;user&gt;/miniconda3/envs/&lt;my_env&gt;/lib/python3.7/site-packages/kubernetes/client/api/core_v1_api.py&quot;,
  line 12905, in list_namespaced_pod_with_http_info
      collection_formats=collection_formats)   File &quot;/Users/&lt;user&gt;/miniconda3/envs/&lt;my_env&gt;/lib/python3.7/site-packages/kubernetes/client/api_client.py&quot;,
  line 345, in call_api
      _preload_content, _request_timeout)   File &quot;/Users/&lt;user&gt;/miniconda3/envs/&lt;my_env&gt;/lib/python3.7/site-packages/kubernetes/client/api_client.py&quot;,
  line 176, in __call_api
      _request_timeout=_request_timeout)   File &quot;/Users/&lt;user&gt;/miniconda3/envs/&lt;my_env&gt;/lib/python3.7/site-packages/kubernetes/client/api_client.py&quot;,
  line 366, in request
      headers=headers)   File &quot;/Users/&lt;user&gt;/miniconda3/envs/&lt;my_env&gt;/lib/python3.7/site-packages/kubernetes/client/rest.py&quot;,
  line 241, in GET
      query_params=query_params)   File &quot;/Users/&lt;user&gt;/miniconda3/envs/&lt;my_env&gt;/lib/python3.7/site-packages/kubernetes/client/rest.py&quot;,
  line 231, in request
      raise ApiException(http_resp=r) kubernetes.client.rest.ApiException: (401) Reason: Unauthorized HTTP
  response headers: HTTPHeaderDict({'Audit-Id':
  '22bd2789-30d0-4be8-a211-277a39396de7', 'Content-Type':
  'application/json', 'Date': 'Wed, 22 Jul 2020 22:12:17 GMT',
  'Content-Length': '129'}) HTTP response body:
  {&quot;kind&quot;:&quot;Status&quot;,&quot;apiVersion&quot;:&quot;v1&quot;,&quot;metadata&quot;:{},&quot;status&quot;:&quot;Failure&quot;,&quot;message&quot;:&quot;Unauthorized&quot;,&quot;reason&quot;:&quot;Unauthorized&quot;,&quot;code&quot;:401} ```
  </code></pre>
  </blockquote>
  <p>If my IAM access rights aren't the issue, what's causing this 401 &quot;Unauthorized&quot; error and how should I fix it?</p>
  <h2>EDIT/UPDATE</h2>
  <p>I was still getting the same error even after following the instructions in the current answer.  These instructions seem to be necessary, but not sufficient to solve the problem.</p>
  <p>I thought that my <code>GOOGLE_APPLICATION_CREDENTIALS</code> path variable might be pointing to the wrong JSON file, but I checked with the code below and it's pointing to the right file:</p>
  <pre><code>import os
  os.environ.get('GOOGLE_APPLICATION_CREDENTIALS')
  </code></pre>
  <p>After checking that, I tried a simpler version of the code from <a href="https://github.com/kubernetes-client/python" rel="nofollow noreferrer">https://github.com/kubernetes-client/python</a> :</p>
  <pre><code>from kubernetes import client, config
  
  # Configs can be set in Configuration class directly or using helper utility
  config.load_kube_config()
  
  v1 = client.CoreV1Api()
  print(&quot;Listing pods with their IPs:&quot;)
  ret = v1.list_namespaced_pod(namespace='default')
  </code></pre>
  <p>That version WORKED!?!  So, what's the problem/difference with the <code>GoogleCredentials</code> version of getting the <code>api_client</code> to be loaded into <code>kubernetes.client.CoreV1Api</code>?  Is the <code>GoogleCredentials.get_application_default()</code> line somehow looking for and finding the wrong credentials?  If so, how can I point it to the right credentials?</p>