get vs. list in Kubernetes RBAC
In practice, you can get all of the information you'd normally get out of get
calls through list
calls. However, having permission to list
a resource doesn't mean get
calls will work. You still have to use list
calls and extract the information that way.
watch
is a special verb that gives you permission to see updates on resources in real time. Having watch
access without list
or get
is not very helpful because you won't be able to view the resource after it updates. Through kubectl
, I was unable to watch a resource without having the get
access to that resource.
To play around with these roles, I'd recommend messing around with roles in a Kubernetes cluster on Katacoda.
Initial setup to make roles and grant them to (fake) users:
kubectl create role deployment-getter --verb=get --resource=deploymentkubectl create role deployment-lister --verb=list --resource=deploymentkubectl create role deployment-watcher --verb=watch --resource=deploymentkubectl create rolebinding only-get --role=deployment-getter --user=only-getkubectl create rolebinding only-list --role=deployment-lister--user=only-listkubectl create rolebinding only-watch --role=deployment-watcher--user=only-listkubectl run nginx --image=nginx # Make a resource to look at
Then you can run kubectl
commands as one of the special users to see what limited RBAC permissions look like.
For example, the following commands show that we can only list resources with the list
verb.
kubectl get deployment --as list-only # Prints out nginx deploymentkubectl get deployment --as get-only # RBAC errorkubectl get deployment --as watch-only # RBAC error
And this example shows that we can only get resources with the get
verb (but you can get similar information by listing resources too).
kubectl get deployment nginx --as get-only -o yaml# apiVersion: extensions/v1beta1# kind: Deployment# ...kubectl get deployment nginx --as list-only -o yaml # RBAC errorkubectl get deployment --as list-only -o yaml# apiVersion: v1# kind: List# items:# - apiVersion: extensions/v1beta1# kind: Deployment# ...
The get
, list
, and watch
RBAC verbs grant permissions for different Kubernetes API operations.
You can see the corresponding API operations for each object in the Kubernetes API reference, for example, here for the Deployment.
Here are some examples:
get
If you have the get
permissions on the Deployment resource, you are allowed to execute the following API request:
GET /apis/apps/v1/namespaces/{namespace}/deployments/{name}
It returns the manifest of a specific Deployment.
list
If you have the list
permission, you are allowed to execute these API requests:
GET /apis/apps/v1/namespaces/{namespace}/deploymentsGET /apis/apps/v1/deployments
They both return a list of manifests of Deployments. The former, of all Deployments in a specific namespace, and the latter of all Deployments across all namespaces.
watch
If you have the watch
permission, you are allowed to execute these API requests:
GET /apis/apps/v1/deployments?watch=trueGET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=trueGET /apis/apps/v1/watch/namespaces/{namespace}/deployments/{name} [DEPRECATED]GET /apis/apps/v1/watch/namespaces/{namespace}/deployments [DEPRECATED]GET /apis/apps/v1/watch/deployments [DEPRECATED]
They open a streaming connection that returns you the full manifest of a Deployment whenever it changes (or when a new one is created).
Note that the latter three API endpoints are deprecated, and you should use the endpoints for the list
operation with a watch=true
parameter instead. However, this still triggers the watch
API operation and not list
.
Note 1
Commands like kubectl get
, kubectl list
, etc. just executes these API requests under the hood. For experimentation, you can execute these API requests directly.
For example, first do:
kubectl proxy
And then:
curl localhost:8001/apis/apps/v1/deployments?watch=true
Or, you can also use this (doesn't require kubectl proxy
):
kubectl get --raw="/apis/apps/v1/deployments?watch=true"
Note 2
In general, the permission don't imply each other. For example, if you have list
permissions, it doesn't mean you can do get
or watch
requests, and if you have watch
permissions, it doesn't mean you can do get
or list
requests.
Note 3
If you have only watch
permissions (but not get
and list
), you can't watch with kubectl (kubectl get deployment -w
) because kubectl makes a get
and list
request, respectively, before the watch
request (to get the resource versions of the watched resources).
More examples in this answer.