<p>Here's a simple Kubernetes role:</p>

<pre><code>apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: temp-role
  namespace: stackoverflow
rules:
- apiGroups: [""]
  resources:
  - pods
  verbs:
  - get
</code></pre>

<p>This role allows me to say <code>kubectl get pod foobar</code> and I can get the pod.</p>

<p>However, I cannot get the pod logs now:</p>

<pre><code>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"
</code></pre>

<p>So the error tells me there's a separate sub-resource <code>pods/log</code> that I need to mention explicitly in my resources. </p>

<p>Interestingly <code>kubectl auth can-i</code> lies to me:</p>

<pre><code>$ kubectl -n stackoverflow auth can-i get pods/log                                                                           
yes
</code></pre>

<p>Okay let's fix this and menetion the subresource directly:</p>

<pre><code>apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
  name: temp-role
  namespace: stackoverflow
rules:
- apiGroups: [""]
  resources:
  - pods
  - pods/log
  verbs:
  - get
</code></pre>

<p>Now I can retrieve logs properly!</p>

<hr>

<h2>So what's the problem</h2>

<p>Thing is, I'm trying to create a <code>ClusterRole</code> with read/write access to some specific resources (subset of <code>edit</code> ClusterRole, specifically), and I had hoped I can accomplish it by using <code>kubectl api-resources</code> and allowing everything from there, except the few things I don't want to allow.</p>

<p>But subresources like <code>pods/log</code> 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 <code>pods/log</code> after I tried it and noticed it doesn't work.</p>

<p>So I'm looking for a way to either:</p>

<ul>
<li>mention a resource with all sub-resources in <code>rules.resources</code> (I tried <code>pods/*</code> but it didn't seem to do anything)</li>
<li>if the above is not possible: get a list of all resources <em>and sub-resources</em>, so that I can whitelist them all in <code>rules.resources</code> individually.</li>
</ul>

<p>Thoughts?</p>

Kos
<p>Answer is inspired by <a href="https://medium.com/@tannhauser.sphinx/bash-kubernetes-script-to-list-all-available-resources-subresources-c65a5c2c1173" rel="noreferrer">[Bash] [Kubernetes] Script to List All Available Resource/Sub-resource Name for RBAC Configuration</a> article.</p>

<p>2 scripts, both worked for me:</p>

<pre><code>_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
</code></pre>

<p>or</p>

<pre><code>_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
</code></pre>

<p>Result:</p>

<pre><code>===/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
</code></pre>

<p>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.</p>

<p>Refer to <a href="https://github.com/kubernetes/kubernetes/issues/78936#issuecomment-501455971" rel="noreferrer">Permission to "pods/*" should work</a>  </p>

<p>comment:</p>

<blockquote>
  <p>services/* does not grant permissions to service status updates.</p>
  
  <p>If you want to give unrestricted access to all resources, you can
  grant that with *</p>
  
  <p>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.</p>
  
  <p>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.</p>
</blockquote>
