<p>I'm trying to incorporate the <code>kubectl auth can-i</code> <a href="https://github.com/kubernetes/kubernetes/blob/master/pkg/kubectl/cmd/auth/cani.go#L236" rel="nofollow noreferrer">logic</a> into my code base, but while the code is working, the results are not what I expect.</p>
<p>I have 2 users (<strong>minikube</strong>/<strong>jenny</strong>). <strong>minikube</strong> has full cluster wide access, but <strong>jenny</strong> is limited to a namespaced role/rolebinding:</p>
<pre class="lang-sh prettyprint-override"><code>kubectl create role &quot;jenny-pod-creator&quot; --verb=create --resource=pod -n &quot;jenny&quot;
kubectl create rolebinding &quot;jenny-creator-binding&quot; --role=&quot;jenny-pod-creator&quot; --user=&quot;jenny&quot; --namespace=&quot;jenny&quot;
</code></pre>
<p>Using the cli, I get the results I expect:</p>
<pre class="lang-sh prettyprint-override"><code>$ kubectl auth can-i create pod --context jenny -n jenny
yes
$ kubectl auth can-i create pod --context jenny -n default
no - RBAC: role.rbac.authorization.k8s.io &quot;jenny-pod-creator&quot; not found
</code></pre>
<p>but in my code, <strong>jenny</strong> is not coming up with permission to create. <code>response.Status.Allowed</code> is always <code>false</code> for <strong>jenny</strong> <em>(always true for <strong>minikube</strong>)</em></p>
<pre class="lang-golang prettyprint-override"><code>package main

import (
    &quot;context&quot;
    &quot;fmt&quot;
    &quot;log&quot;
    &quot;os&quot;
    &quot;path/filepath&quot;

    authorizationv1 &quot;k8s.io/api/authorization/v1&quot;
    metav1 &quot;k8s.io/apimachinery/pkg/apis/meta/v1&quot;
    &quot;k8s.io/client-go/kubernetes&quot;
    &quot;k8s.io/client-go/tools/clientcmd&quot;
)

func main() {
    kubeconfig := filepath.Join(
        os.Getenv(&quot;HOME&quot;), &quot;.kube&quot;, &quot;config&quot;,
    )
    config, err := clientcmd.BuildConfigFromFlags(&quot;&quot;, kubeconfig)
    if err != nil {
        log.Fatal(err)
    }
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        log.Fatal(err)
    }
    a := clientset.AuthorizationV1().SelfSubjectAccessReviews()
    sar := &amp;authorizationv1.SelfSubjectAccessReview{
        Spec: authorizationv1.SelfSubjectAccessReviewSpec{
            ResourceAttributes: &amp;authorizationv1.ResourceAttributes{
                Namespace: &quot;jenny&quot;,
                Verb:      &quot;create&quot;,
                Resource:  &quot;Pod&quot;,
            },
        },
    }
    response, err := a.Create(context.TODO(), sar, metav1.CreateOptions{})
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf(&quot;create resource POD is %v \n&quot;, response.Status.Allowed)
}
</code></pre>

GrandVizier
<p>In Kubernetes there's a notion of Kinds and Resources. It's very well explained in <a href="https://stackoverflow.com/questions/52309496/difference-between-kubernetes-objects-and-resources">Difference between Kubernetes Objects and Resources</a> and in <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#types-kinds" rel="nofollow noreferrer">API Conventions</a>, if your curious to learn more.</p>
<p>In short:</p>
<ol>
<li><em>Kind</em> is the type which tells a client what kind of entity it represents, and this is always upper case, <code>Pod</code> for example.</li>
<li><em>Resource</em> is the representation of such entity sent via HTTP, and this is always lower case and plural.</li>
</ol>
<p>In your case, you're working with <em>Resource</em> so you need to change <code>Pod</code> (<em>Kind</em>) to <code>pods</code> (<em>resource</em>), which should give you <code>true</code> for <code>jenny</code>. As for minikube, you're getting always <code>true</code> because that user is system:admin, which has full access to the cluster.</p>
