<p>I have my Kubernetes cluster running in GKE I want to run an application outside the cluster and talk to the Kubernetes API.</p>

<p>By using password retrieved from running:</p>

<pre><code>gcloud container clusters get-credentials cluster-2 --log-http
</code></pre>

<p>I am able to access the API with Basic authentication.
But I want to create multiple Kubernetes service accounts and configure them with required authorization and use appropriately.</p>

<p>So, I created service accounts and obtained the tokens using:</p>

<pre><code>kubectl create serviceaccount sauser1
kubectl get serviceaccounts sauser1 -o yaml
kubectl get secret sauser1-token-&lt;random-string-as-retrieved-from-previous-command&gt; -o yaml
</code></pre>

<p>If I try to access the Kubernetes API with the obtained token using Bearer authentication then I get a 401 HTTP error. I thought that some permissions may have to be set for the service account, so based on the documentation <a href="https://kubernetes.io/docs/admin/authorization/rbac/" rel="nofollow noreferrer">here</a>, I created below YAML file:</p>

<pre><code>apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: pod-reader
subjects:
- kind: ServiceAccount
  name: sauser1
  namespace: default
roleRef:
  kind: ClusterRole
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
</code></pre>

<p>and tried to apply it using the below command:</p>

<pre><code>kubectl apply -f default-sa-rolebinding.yaml
</code></pre>

<p>I got the following error:</p>

<pre><code>clusterrolebinding "pod-reader" created
Error from server (Forbidden): error when creating "default-sa-rolebinding.yaml"
: clusterroles.rbac.authorization.k8s.io "pod-reader" is forbidden: attempt to g
rant extra privileges: [PolicyRule{Resources:["pods"], APIGroups:[""], Verbs:["g
et"]} PolicyRule{Resources:["pods"], APIGroups:[""], Verbs:["watch"]} PolicyRule
{Resources:["pods"], APIGroups:[""], Verbs:["list"]}] user=&amp;{xyz@gmail.
com  [system:authenticated] map[authenticator:[GKE]]} ownerrules=[PolicyRule{Res
ources:["selfsubjectaccessreviews"], APIGroups:["authorization.k8s.io"], Verbs:[
"create"]} PolicyRule{NonResourceURLs:["/api" "/api/*" "/apis" "/apis/*" "/healt
hz" "/swagger-2.0.0.pb-v1" "/swagger.json" "/swaggerapi" "/swaggerapi/*" "/versi
on"], Verbs:["get"]}] ruleResolutionErrors=[]
</code></pre>

<p>I dont know how to proceed from here. Is my approach correct or am I missing something here?</p>

<p><strong>UPDATE</strong>: As per the post referred by @JanosLenart in the comments, modified the kubectl command and the above error is not observed. But accessing the API, still gives 401 error. The curl command that I am using is: </p>

<pre><code>curl -k -1 -H "Authorization: Bearer &lt;token&gt;" https://&lt;ip-address&gt;/api/v1/namespaces/default/pods -v
</code></pre>

<p>@Janos pointed out the potential problem, however I think you will need an actual Cloud IAM Service Account as well, because you said: </p>

<blockquote>
  <p>I want to run an application outside the cluster [...]</p>
</blockquote>

<p>If you're authenticating to GKE from outside, I believe you can only use the Google IAM identities. (I might be wrong, if so, please let me know.)</p>

<p>In this case, what you need to do:</p>

<ol>
<li>Create an IAM service account and download a json key file of it.</li>
<li>set <code>GOOGLE_APPLICATION_CREDENTIALS</code> to that file.</li>
<li><p>either:</p>

<ul>
<li><p>use RBAC like in your question to give permissions to the email address of the IAM Service Account</p></li>
<li><p>use IAM Roles to give the IAM Service Account on the GKE API (e.g. <code>Container Developer</code> role is usually sufficient)</p></li>
</ul></li>
<li><p>Use <code>kubectl</code> command against the cluster (make sure you have a <code>.kube/config</code> file  with the cluster's IP/CA cert beforehand) with the environment variable above, it should work.</p></li>
</ol>
