Kubernetes RBAC verbs: get without list and vice versa? Watch without list?

9/23/2019

While there's a lot of documentation and examples on Kubernetes RBAC and also the available verbs for different resources, I couldn't find any rules on whether certain verbs are always used in combination or whether there are use cases to using them individually. In particular, I'm wondering about the verbs get, list, and watch. What uses are for combining them, and especially not combining them?

  • are there uses for allowing get on resources, but not list?
  • au contraire, are there uses for list without allowing get? Maybe along the lines of information sparseness?
  • get and list, but no watch? To restrict only trusted subjects and service accounts to put more strain on the API server and etcd?
  • watch without list or get? Wouldn't that cripple most clients because they're listwatchers?
-- TheDiveO
kubernetes
rbac

1 Answer

9/24/2019

Interesting question, here are some ideas and examples of usages in practice.

There are many more examples in practice. For example, you can inspect the default ClusterRoles by browsing through kubectl describe clusterroles. And to see which API requests kubectl makes under the hood, you can increase the log verbosity, for example, kubectl get pods -w -v 10.

get but not list

You want someone to be able to read resources they know by name but not discover what other resources exist. For example, allows to do kubectl get mypod, but not kubectl get pods.

Examples:

  • The system:node ClusterRole has get but not list permissions on Endpoints, PVs, and PVCs.
  • The system:coredns ClusterRole has get but not list permissions on Nodes.
  • The system:controller:expand-controller ClusterRole has get but not list permissions on Endpoints, Secrets, and Services.

list but not get

Allows to do, for example, kubectl get pods but not kubectl get pod mypod. It doesn't make much sense, because all the information you can get with get is also included in list. Nevertheless, there are some usages of this in practice.

Examples:

  • The system:kube-dns ClusterRole has list and watch permissions for Endpoints and Services, but not get.
  • The system:controller:daemon-set-controller ClusterRoel has list and watch permissions for Nodes, but not get.
  • The system:coredns ClusterRole has list and watch permissions for Endpoints, Namespaces, Pods, and Services, but not get.

get and list, but not watch

In practice, in most cases where there is list there is also watch. You could deprive someone of watch to reduce the number of watchers on etcd. Users can do kubectl get pods and kubectl get pods mypod, but not use the -w option.

Makes also sense if the API does not support watch operations, like, for example, the optional metric APIs.

Examples:

  • The system:controller:persistent-volume-binder ClusterRole has get and list permissions for Nodes, but not watch

watch, but not get and list

Regarding the use case, it doesn't make much sense, because all the information you can get with get and list is also included in watch. I don't know of any concrete usage of this in practice.

However, technically, it's possible. For example, if you have watch permissions for Pods, but not get and list, you can do:

✅ kubectl get --raw="/api/v1/watch/namespaces/default/pods"
✅ kubectl get --raw="/api/v1/watch/namespaces/default/pods/mypod"

And it works. However, these watch endpoints are deprecated and you should use the list endpoint with a watch parameter instead. But this also works:

✅ kubectl get --raw="/api/v1/namespaces/default/pods?watch=true"

However, you can't watch a single Pod like this, because the get endpoint doesn't have a watch parameter. So, the following is invalid:

❌ kubectl get --raw="/api/v1/namespaces/default/pods/mypod?watch=true"

And you can't watch resources with kubectl at all. The following fails:

❌ kubectl get pods -w
❌ kubectl get pods mypod -w

Because kubectl makes a list and get request, respectively, before the watch request, most probably to get the resourceVersion of the resources which will then be included in the subsequent watch request.

Note: that means, if you have list and watch, then kubectl get pods -w works, but kubectl get pods mypod -w doesn't, and if you have get and watch, then kubectl get pods mypod -w works but kubectl get pods -w doesn't.

-- weibeld
Source: StackOverflow