kubernetes / kubernetes/kubectl

kubectl get <category> should filter out 403 errors from non authorized types

Open
#1,853 8 comments 0 reactions 1 assignee Claimed by @danyalahmed1995 View on GitHub
kind/bug sig/api-machinery sig/cli triage/accepted
Dominant language
Go
Stars
3.3k
Forks
1k
PR merge metrics
No merged PRs in 30d

Description

### What happened?

The categories field within CRDs allows users to discover crds, see https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#categories
> Categories is a list of grouped resources the custom resource belongs to (eg. all). You can use kubectl get to list the resources belonging to the category.

Underneath kubectl is leveraging the k8s api discovery endpoint documented at https://kubernetes.io/docs/concepts/overview/kubernetes-api/#unaggregated-discovery e.g. /apis/mycorp.com/v1 to discover all resources including their categories and then query all resources matching the required category (e.g. "claim")

However, the discovery api is not filtering the types against lack of authorization, aka the discovery api is returning types that the requester may not have any authorization.

As a result, `kubectl get ` displays errors from non-authorized resources.

Let's take the example of the crossplane library which uses the following categories to support discovering the following type of resources dynamically loaded into a cluster
* `claim`: crossplane claims (platform user)
* `composite` : crossplane XRs (platform engineer)
* `composition`: crossplane compositions (platform engineer)
* `managed`: crossplane managed resources (platform engineer)
* `xrd`: crossplane composite resource definitions

Each category is used by many CRDs targetting different roles in a k8s multi tenant cluster.

`kubectl get claim` will return authorized CRs along with errors for unauthorized CRs such as the following

`Error from server (Forbidden): mariadatabasebackups.mycorp.org forbidden: User "xxx" cannot list resource "mariadatabasebackups" in API group "mycorp.org" in the namespace "my-namespace"`

The current kubectl user has to explicitly filter out errors from stderr and fix the unreliable exit status

### What did you expect to happen?

`kubectl get ` should offer a flag to only return resources from authorized resources types, filtering out 403 errors from non authorized resources

### How can we reproduce it (as minimally and precisely as possible)?

* deploy crd1 and crd2 referencing category "mycategory"
* grant service account permission to list/get crd1 but not crd2
* type `kubectl get mycategory`

### Anything else we need to know?

There are related documented decisions to not support acl-filtered list operations on resources:
* https://github.com/kubernetes/kubernetes/issues/112686#issuecomment-1260952844
* https://github.com/kubernetes/community/issues/1486#issuecomment-350741039
> What you are describing is acl-filtered list, which is desired, but not able to be implemented without breaking watch semantics. If the content of a list call depends on two dimensions (actual resources present AND current state of ACL), a single resourceVersion will not represent the results correctly.
>
> Additionally, if the API server does not have a way to know when ACLs have changed, it does not know when to react by sending add events for newly granted resources or remove events for newly denied resources)

But I did not see related discussion/decisions to acl-filterered operations on types (what does `kubectl get ` or `kubectl api-resources`). Also `kubectl get ` does not support --watch

```
kubectl get claim --watch
error: you may only specify a single resource type
```

https://github.com/kubernetes/kubernetes/blob/2a9b8baab74f268b65ce5abd3cf897606ff43b3b/staging/src/k8s.io/cli-runtime/pkg/resource/builder.go#L132-L134

https://github.com/kubernetes/kubernetes/blob/2a9b8baab74f268b65ce5abd3cf897606ff43b3b/staging/src/k8s.io/kubectl/pkg/cmd/get/get.go#L606-L620

### Kubernetes version

```console
$ kubectl version

Client Version: v1.34.3
Kustomize Version: v5.7.1
Server Version: v1.34.0
```

### Cloud provider

### OS version

```console
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture
# paste output here
```

### Install tools

### Container runtime (CRI) and version (if applicable)

### Related plugins (CNI, CSI, ...) and versions (if applicable)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.