Unexpected results from clientset.AuthorizationV1().SelfSubjectAccessReviews().Create()

Viewed 363

I'm trying to incorporate the kubectl auth can-i logic into my code base, but while the code is working, the results are not what I expect.

I have 2 users (minikube/jenny). minikube has full cluster wide access, but jenny is limited to a namespaced role/rolebinding:

kubectl create role "jenny-pod-creator" --verb=create --resource=pod -n "jenny"
kubectl create rolebinding "jenny-creator-binding" --role="jenny-pod-creator" --user="jenny" --namespace="jenny"

Using the cli, I get the results I expect:

$ 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 "jenny-pod-creator" not found

but in my code, jenny is not coming up with permission to create. response.Status.Allowed is always false for jenny (always true for minikube)

package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "path/filepath"

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

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

In Kubernetes there's a notion of Kinds and Resources. It's very well explained in Difference between Kubernetes Objects and Resources and in API Conventions, if your curious to learn more.

In short:

  1. Kind is the type which tells a client what kind of entity it represents, and this is always upper case, Pod for example.
  2. Resource is the representation of such entity sent via HTTP, and this is always lower case and plural.

In your case, you're working with Resource so you need to change Pod (Kind) to pods (resource), which should give you true for jenny. As for minikube, you're getting always true because that user is system:admin, which has full access to the cluster.

Related