Skip to content

Instantly share code, notes, and snippets.

@vicenteherrera
Last active February 28, 2024 11:37
Show Gist options
  • Save vicenteherrera/0bfe2762ecd5794eba65ed19d0d51188 to your computer and use it in GitHub Desktop.
Save vicenteherrera/0bfe2762ecd5794eba65ed19d0d51188 to your computer and use it in GitHub Desktop.
How to obtain all Kubernetes apigroups, resources and corresponding verbs available to set up RBAC

Kubernetes RBAC apiGroups, resources and verbs

List all RBAC verbs for resources

Start your Kubernetes cluster.

On one terminal window:

# Open connection from another terminal window
kubectl proxy

On a different terminal window:

# List all API urls
curl http://localhost:8001/ | yq '.paths[]'

# List all objects and verbs for an API path /api/v1
curl http://localhost:8001/api/v1 | yq '.resources[] | [{"resources":.name,"verbs":.verbs}]'

# Combined in a single line
for url in $(curl -s http://localhost:8001/ | yq '.paths[]' | xargs) ; do doc=$(curl -s http://localhost:8001$url) ; echo "# $url" ; [ "$doc" != "ok" ] && echo "$doc" | yq '[.resources[] | {"apiGroups":["'$url'"], "resources":[.name],"verbs":.verbs}] | .. style="double" | .[].* style="flow"' ; done

If you want a script that skips all endpoints that doesn't return relevant information:

#!/bin/bash

# Remember to run on another terminal before this script:
# kubectl proxy

set -euo pipefail

# Show Kubernetes server version
echo -n '# '
kubectl version --short 2>/dev/null | grep 'Server'

for url in $(curl -s http://localhost:8001/ | yq '.paths[]' | xargs) ; do 
    [ "$url" == "/metrics" ] && continue
    doc=$(curl -s http://localhost:8001$url)

    # If URL doesn't publish info, skip
    [ "$doc" == "ok" ] && continue

    # Remove from apiGroup prefix (/, /api/v1, /apis/) and suffix ( /v1, /v1beta1)
    apiGroup=$(echo $url | sed 's/\/api\/v1//' | sed 's/\/apis\///' | sed 's/^\///' | sed 's/\/v[0-9]*\(beta[0-9]\+\)\?$//'  )

    # Get permissions and format them nicely in YAML
    yaml=$(echo "$doc" | yq -M '[.resources[] | {"apiGroups":["'$apiGroup'"], "resources":[.name],"verbs":.verbs}] | .. style="double" | .[].* style="flow"' 2>/dev/null ||:);
    
    # TODO: group resources from the same apiGroup with the same verbs together

    # If document is empty, skip it
    [ "$yaml" == "[]" ] && continue

    echo ""
    echo "# $url"
    echo "$yaml"
done
@elonmir
Copy link

elonmir commented Feb 28, 2024

Very useful, thanks, safed me some serious time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment