RBAC permisiions assocaited with service account

what is the command to find RBAC permissions assocaited with service account ?

Thanks
Sakshi

There isn’t a single command. You need to account for two possibilities:

  1. The SA gets permissions from a cluster role.
  2. The SA gets permissions from a role.

For both you do something like this, for a service account my-sa in namespace myspace:

# get roles
k -n myspace get rolebinding -o wide | grep my-sa

# get cluster roles
k get clusterrolebinding -o wide | grep my-sa

You’d then look at the matching roles and clusterroles, and get their permissions from there.

To do a custom command, you’d need a fair bit of bash, but it’s doable.

Thanks rob . That worked :slight_smile:

I love a challenge :rofl:

./list-rbac.sh -s my-sa
./list-rbac.sh -s weave-net -n kube-system

list-rbac.sh

#!/usr/bin/env bash

usage() { echo "$0 usage:" && grep " .)\ #" $0; exit 1; }
[ $# -eq 0 ] && usage

service_account=

# Default to current namespace
service_account_namespace=$(kubectl config view --minify -o jsonpath='{..namespace}')

while getopts ":hs:n:" arg; do
  case $arg in
    n) # Specify namespace - uses current if not set.
      service_account_namespace=${OPTARG}
      ;;
    s) # Specify service account name
      service_account=${OPTARG}
      ;;
    h | *) # Display help.
      usage
      ;;
  esac
done

if [ -z "$service_account" ]
then
    echo "Must provide service account name"
    usage
fi

function print_binding {
    # Print the binding information for the given binding.

    binding=$1

    binding_name=$(cut -d / -f 1 <<< $binding)
    binding_namespace=$(cut -d / -f 2 <<< $binding)
    role_name=$(cut -d / -f 3 <<< $binding)
    role_kind=$(cut -d / -f 4 <<< $binding)

    if [ "$role_kind" == "Role" ]
    then
        echo "- Binding: ${binding_namespace}/${binding_name}"
    else
        echo "- Binding: ${binding_name}"
    fi

    echo -e "  - ${role_kind}: ${role_name}\n    rules:"

    if [ "$role_kind" == "Role" ]
    then
        kubectl get role -n $binding_namespace $role_name -o yaml | yq .rules | sed 's/\(.*\)/\     \1/'
    else
        kubectl get clusterrole $role_name -o yaml | yq .rules | sed 's/\(.*\)/\     \1/'
    fi
}

function list_bindings {
    # List all bindings of given type (role or clusterrole) given as an argument

    type=$1

    # Find all role/clusterrole bindings for the given service account
    # Output as a list in format:
    # binding_name/binding_namespace/role_name/role_kind
    bindings=($(kubectl get ${type}bindings -A -o json | jq -r '
    .items[] |
    select(
        .subjects[]? |
        select(.kind == "ServiceAccount" and .name == "'${service_account}'" and .namespace == "'${service_account_namespace}'")
    ) |
    "\(.metadata.name)/\(.metadata.namespace)/\(.roleRef.name)/\(.roleRef.kind)"
    '))

    if [ ${#bindings[@]} -eq 0 ]
    then
        echo "No $type bindings for system:serviceaccount:${service_account_namespace}:${service_account}"
        return
    fi

    echo -e "$type bindings for system:serviceaccount:${service_account_namespace}:${service_account} -\n"

    # Iterate and print results
    for binding in "${bindings[@]}"
    do
        print_binding $binding
    done

    echo
}

# Check user has YQ
if ! command -v yq &>/dev/null
then
    cat <<EOF
Cannot find yq on your system needed for formatting YAML.
You should be able to install with one of the following depending on your distro:

   1. sudo apt install -y yq
   2. sudo yum install -y yq
EOF
fi

# Check SA exists
if ! kubectl get serviceaccount -n $service_account_namespace $service_account &>/dev/null
then
    echo "Service account $service_account not found in namespace $service_account_namespace"
    exit 1
fi

# List RBAC
list_bindings "role"
list_bindings "clusterrole"