Here's a simple Kubernetes role:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: temp-role
namespace: stackoverflow
rules:
- apiGroups: [""]
resources:
- pods
verbs:
- get
This role allows me to say kubectl get pod foobar
and I can get the pod.
However, I cannot get the pod logs now:
Error from server (Forbidden): pods "foobar" is forbidden: User "system:serviceaccount:kube-system:myuser" cannot get resource "pods/log" in API group "" in the namespace "stackoverflow"
So the error tells me there's a separate sub-resource pods/log
that I need to mention explicitly in my resources.
Interestingly kubectl auth can-i
lies to me:
$ kubectl -n stackoverflow auth can-i get pods/log
yes
Okay let's fix this and menetion the subresource directly:
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: temp-role
namespace: stackoverflow
rules:
- apiGroups: [""]
resources:
- pods
- pods/log
verbs:
- get
Now I can retrieve logs properly!
Thing is, I'm trying to create a ClusterRole
with read/write access to some specific resources (subset of edit
ClusterRole, specifically), and I had hoped I can accomplish it by using kubectl api-resources
and allowing everything from there, except the few things I don't want to allow.
But subresources like pods/log
don't appear on the list, so this approach doesn't work - I'd block access to some things I intend to expose, but I don't even know what exactly. I only learned about pods/log
after I tried it and noticed it doesn't work.
So I'm looking for a way to either:
rules.resources
(I tried pods/*
but it didn't seem to do anything)rules.resources
individually.Thoughts?
Answer is inspired by [Bash] [Kubernetes] Script to List All Available Resource/Sub-resource Name for RBAC Configuration article.
2 scripts, both worked for me:
_list=($(kubectl get --raw / |grep "^ \"/api"|sed 's/[",]//g'));
for _api in ${_list[@]}; do
_aruyo=$(kubectl get --raw ${_api} | jq .resources);
if [ "x${_aruyo}" != "xnull" ]; then
echo;
echo "===${_api}===";
kubectl get --raw ${_api} | jq -r ".resources[].name";
fi;
done
or
_list=($(kubectl get --raw / |grep "^ \"/api"|sed 's/[",]//g')); for _api in ${_list[@]}; do _aruyo=$(kubectl get --raw ${_api} | jq .resources); if [ "x${_aruyo}" != "xnull" ]; then echo; echo "===${_api}==="; kubectl get --raw ${_api} | jq -r ".resources[].name"; fi; done
Result:
===/api/v1===
bindings
componentstatuses
configmaps
endpoints
events
limitranges
namespaces
namespaces/finalize
namespaces/status
nodes
nodes/proxy
nodes/status
persistentvolumeclaims
persistentvolumeclaims/status
persistentvolumes
persistentvolumes/status
pods
pods/attach
pods/binding
pods/eviction
pods/exec
pods/log
pods/portforward
pods/proxy
pods/status
podtemplates
replicationcontrollers
replicationcontrollers/scale
replicationcontrollers/status
resourcequotas
resourcequotas/status
secrets
serviceaccounts
serviceaccounts/token
services
services/proxy
services/status
===/apis/admissionregistration.k8s.io/v1beta1===
mutatingwebhookconfigurations
validatingwebhookconfigurations
===/apis/apiextensions.k8s.io/v1beta1===
customresourcedefinitions
customresourcedefinitions/status
===/apis/apiregistration.k8s.io/v1===
apiservices
apiservices/status
===/apis/apiregistration.k8s.io/v1beta1===
apiservices
apiservices/status
===/apis/apps/v1===
controllerrevisions
daemonsets
daemonsets/status
deployments
deployments/scale
deployments/status
replicasets
replicasets/scale
replicasets/status
statefulsets
statefulsets/scale
statefulsets/status
===/apis/apps/v1beta1===
controllerrevisions
deployments
deployments/rollback
deployments/scale
deployments/status
statefulsets
statefulsets/scale
statefulsets/status
===/apis/apps/v1beta2===
controllerrevisions
daemonsets
daemonsets/status
deployments
deployments/scale
deployments/status
replicasets
replicasets/scale
replicasets/status
statefulsets
statefulsets/scale
statefulsets/status
===/apis/authentication.k8s.io/v1===
tokenreviews
===/apis/authentication.k8s.io/v1beta1===
tokenreviews
===/apis/authorization.k8s.io/v1===
localsubjectaccessreviews
selfsubjectaccessreviews
selfsubjectrulesreviews
subjectaccessreviews
===/apis/authorization.k8s.io/v1beta1===
localsubjectaccessreviews
selfsubjectaccessreviews
selfsubjectrulesreviews
subjectaccessreviews
===/apis/autoscaling/v1===
horizontalpodautoscalers
horizontalpodautoscalers/status
===/apis/autoscaling/v2beta1===
horizontalpodautoscalers
horizontalpodautoscalers/status
===/apis/batch/v1===
jobs
jobs/status
===/apis/batch/v1beta1===
cronjobs
cronjobs/status
===/apis/certificates.k8s.io/v1beta1===
certificatesigningrequests
certificatesigningrequests/approval
certificatesigningrequests/status
===/apis/cloud.google.com/v1beta1===
backendconfigs
===/apis/coordination.k8s.io/v1beta1===
leases
===/apis/extensions/v1beta1===
daemonsets
daemonsets/status
deployments
deployments/rollback
deployments/scale
deployments/status
ingresses
ingresses/status
networkpolicies
podsecuritypolicies
replicasets
replicasets/scale
replicasets/status
replicationcontrollers
replicationcontrollers/scale
===/apis/metrics.k8s.io/v1beta1===
nodes
pods
===/apis/networking.gke.io/v1beta1===
managedcertificates
===/apis/networking.k8s.io/v1===
networkpolicies
===/apis/policy/v1beta1===
poddisruptionbudgets
poddisruptionbudgets/status
podsecuritypolicies
===/apis/rbac.authorization.k8s.io/v1===
clusterrolebindings
clusterroles
rolebindings
roles
===/apis/rbac.authorization.k8s.io/v1beta1===
clusterrolebindings
clusterroles
rolebindings
roles
===/apis/scalingpolicy.kope.io/v1alpha1===
scalingpolicies
===/apis/scheduling.k8s.io/v1beta1===
priorityclasses
===/apis/storage.k8s.io/v1===
storageclasses
volumeattachments
volumeattachments/status
===/apis/storage.k8s.io/v1beta1===
storageclasses
volumeattachments
What I also wanna to do - is to pay your attention that kubernetes doesn't allow you get this list ny default and this is expect and by design.
Refer to Permission to "pods/*" should work
comment:
services/* does not grant permissions to service status updates.
If you want to give unrestricted access to all resources, you can grant that with *
Unrestricted access to all current and future subresources is misleading to reason about. Different subresources are used for different purposes. Authorizing all subresources of a resource assumes that no new subresource will ever be added that grants access to far more powerful capabilities. Granting access to pods/* would allow what is currently a restricted user access to future subresources, even if those subresources far exceeded the capabilities of the current subresources.
The format */scale can be used to grant access to the subresource named scale on all resources, and is useful for things like autoscaling which needs access to a specific subresource.