TL;DR
Having get permissions to a Kubernetes object does not imply you have list permissions and vice versa.
This was not immediately obvious to me.
I figured that if you can list all objects of a certain kind (like secrets) you can also get an individual object by name, but that’s not the case.
Here’s how it works using Kubernetes Secrets as an example object:
If you only have
getpermissions, you will have to know the exact name of the secret you are trying to read beforehand. You can run a command likekubectl get secret <secret-name>successfully, but runningkubectl get secretswill not work.If you only have
listpermissions for secrets, you can runkubectl get secretsand see a list of secrets. But runningkubectl get secret <secret-name>will not work.There’s a tricky part: if you run
kubectl get secrets -o yamlyou will see a list of secrets and all of their contents. Havinglistpermissions doesn’t mean you only get to list the names of the secrets, you can append-o yamlto the command and see all the contents as well. Just because you don’t havegetpermissions doesn’t mean you can’t see the contents of the objects.
Example with Minikube
I’ll be demonstrating the conclusion from above using
Minikube. I’ll be creating the following in K8s: a Secret, two Roles, two Service Accounts, and two RoleBindings to assign get and list RBAC permissions to each service account for testing.
Here is a very long manifest that creates the following objects:
- A namespace called
example - A
basic authentication secret called
credentialsin theexamplenamespace - Two service accounts. One called
service-account-1and another calledservice-account-2 - Two Roles:
- A role named
get-secretsthat allows users associated with this role to get a secret. - A role named
list-secretsthat allows users to list secrets.
- A role named
- Two RoleBindings:
- A RoleBinding named
get-secrets-bindingthat will associate the service accountservice-account-1with theget-secretsrole. - A RoleBinding named
list-secrets-bindingthat will associate the service accountservice-account-2with thelist-secretsrole.
- A RoleBinding named
---
apiVersion: v1
kind: Namespace
metadata:
name: example
labels:
name: example
---
apiVersion: v1
kind: Secret
metadata:
namespace: example
name: credentials
type: kubernetes.io/basic-auth
stringData:
username: admin
password: securepassword
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-1
namespace: example
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: service-account-2
namespace: example
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: example
name: get-secrets
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: example
name: list-secrets
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: get-secrets-binding
namespace: example
subjects:
- kind: ServiceAccount
name: service-account-1
namespace: example
roleRef:
kind: Role
name: get-secrets
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: list-secrets-binding
namespace: example
subjects:
- kind: ServiceAccount
name: service-account-2
namespace: example
roleRef:
kind: Role
name: list-secrets
apiGroup: rbac.authorization.k8s.ioThis manifest can be saved to a YAML file and applied like so:
$ kubectl apply -f manifest.yaml
namespace/example created
secret/credentials created
serviceaccount/service-account-1 created
serviceaccount/service-account-2 created
role.rbac.authorization.k8s.io/get-secrets created
role.rbac.authorization.k8s.io/list-secrets created
rolebinding.rbac.authorization.k8s.io/get-secrets-binding created
rolebinding.rbac.authorization.k8s.io/list-secrets-binding created
Testing It All Out
Now we can test the get and list RBAC verbs with our service accounts.
To summarize:
- The service account
service-account-1hasgetpermissions for secrets in theexamplenamespace. This service account should not be able to list secrets but should be able to get an individual secret in theexamplenamespace. - The service account
service-account-2haslistpermissions for secrets in theexamplenamespace. This service account should not be able to get an individual secret but should be able to list all secrets in theexamplenamespace.
We can use the following command formula to test the permissions set to both service accounts:
kubectl auth can-i <verb> <resource> --as=system:serviceaccount:<namespace>:<serviceaccountname> -n <namespace>Testing get Permissions
First let’s try getting a secret under both service accounts. We expect service-account-1 to be able to get a secret, but not service-account-2:
$ kubectl auth can-i get secrets -n example --as=system:serviceaccount:example:service-account-1
yes
$ kubectl auth can-i get secrets -n example --as=system:serviceaccount:example:service-account-2
no
Works as expected!
Now let’s try getting the credentials secret specifically that we created earlier, just to double check. We should get the same results as above.
$ kubectl auth can-i get secrets/credentials -n example --as=system:serviceaccount:example:service-account-1
yes
$ kubectl auth can-i get secrets/credentials -n example --as=system:serviceaccount:example:service-account-2
no
Works as expected.
Testing list Permissions
Next let’s try listing secrets under both service accounts. This time we expect service-account-2 to be able to list secrets, but not service-account-1:
$ kubectl auth can-i list secrets -n example --as=system:serviceaccount:example:service-account-1
no
$ kubectl auth can-i list secrets -n example --as=system:serviceaccount:example:service-account-2
yes
Works as expected once again.
Revealing Secret Data With Only list Permissions
Next, let’s try listing secrets with -o yaml to show that just because you don’t have get permissions it doesn’t mean you can’t see contents of secrets.
service-account-2 has list permissions but not get. If we try to get a specific Secret, Kubernetes doesn’t allow it. This is expected:
$ kubectl get secret credentials -n example --as=system:serviceaccount:example:service-account-2
Error from server (Forbidden): secrets "credentials" is forbidden: User "system:serviceaccount:example:service-account-2" cannot get resource "secrets" in API group "" in the namespace "example"
Listing secrets does work, as expected.
$ kubectl get secrets -n example --as=system:serviceaccount:example:service-account-2
NAME TYPE DATA AGE
credentials kubernetes.io/basic-auth 2 9m38s
And if we add -o yaml to the command, we get the full YAML output for the Secret, revealing a username and password, despite not having get permissions:
$ kubectl get secrets -n example -o yaml --as=system:serviceaccount:example:service-account-2
apiVersion: v1
items:
- apiVersion: v1
data:
password: c2VjdXJlcGFzc3dvcmQ=
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2026-07-20T08:12:24Z"
name: credentials
namespace: example
resourceVersion: "418"
uid: bcd4013c-9ed5-4cdc-9436-9ff8dc7d9982
type: kubernetes.io/basic-auth
kind: List
metadata:
resourceVersion: ""
The data of each Secret is revealed under the data key in base64 encoding, which can easily be decoded:
$ echo "YWRtaW4=" | base64 --decode
admin
$ echo "c2VjdXJlcGFzc3dvcmQ=" | base64 --decode
securepassword