Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get vs. list in Kubernetes RBAC

What is the difference between the get and list RBAC verbs?

All I could find in the the documentation is this: "get (for individual resources), list (for collections, including full object content)", which I find severely lacking. Is list a superset of get, meaning if you have list permissions can you fetch all the information from get and more? While we're at it, what about watch? Does it only give permissions to read the change stream but not full object?

like image 412
g.o.a.t. Avatar asked Sep 29 '19 23:09

g.o.a.t.


2 Answers

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=deployment
kubectl create role deployment-lister --verb=list --resource=deployment
kubectl create role deployment-watcher --verb=watch --resource=deployment

kubectl create rolebinding only-get --role=deployment-getter --user=only-get
kubectl create rolebinding only-list --role=deployment-lister--user=only-list
kubectl create rolebinding only-watch --role=deployment-watcher--user=only-list

kubectl 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 deployment
kubectl get deployment --as get-only # RBAC error
kubectl 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 error
kubectl get deployment --as list-only -o yaml
# apiVersion: v1
# kind: List
# items:
# - apiVersion: extensions/v1beta1
#   kind: Deployment
#   ...
like image 83
supersam654 Avatar answered Nov 01 '22 10:11

supersam654


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}/deployments
GET /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=true
GET /apis/apps/v1/watch/namespaces/{namespace}/deployments?watch=true
GET /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.

like image 9
weibeld Avatar answered Nov 01 '22 09:11

weibeld