Debugging kubernetes service account RBAC

You can use the kubectl auth can-i to debug access issues related to yourself. but what if you need to debug access issues for your application running in kubernetes?

This handy script creates a kubeconfig that you can use, that uses a specified service account as the user.

Just run this script with namespace and service account.

then just use your app with this kube config! usually via export KUBECONFIG

#!/bin/bash

# script by http://github.com/yuval-k/ to get a kubeconfig with service account permissions
# this is useful to test\debug RBAC issues locally.
# get the latest version here: https://gist.github.com/yuval-k/1604b99f2ecd767c29983acc6470d5d6
# license: public domain.

NS=${NS:-$1}
SVCACCNT=${SVCACCNT:-$2}


if [ -z "$NS" ] || [ -z "$SVCACCNT" ]; then 
  echo "Run like so: $0 namespace name"
  echo "Where namespace and name refer to the service account you want to use."
  exit 1
fi

echo "Creating a kubeconfig for service account $SVCACCNT in namespace $NS"

KUBECONFIG=${KUBECONFIG:-$HOME/.kube/config}
SVCKUBECONFIG=${SVCKUBECONFIG:-tmp-kube-config.yaml}

# Copy the original kubeconfig so it is unmodified
cp $KUBECONFIG $SVCKUBECONFIG

# find the name of the service account secret
# first we filter by type == "kubernetes.io/service-account-token"
# and then using json format we output the secret name, followed by the service account name between two pipes (to prevent ambiguity as we use grep).
# we grep for the service account name with the pipes, and get the first field that has the secret name.
SECRET=$(kubectl get secret -n $NS -o=jsonpath='{range .items[?(@.type=="kubernetes.io/service-account-token")]}{.metadata.name}{"\t"}|{.metadata.annotations.kubernetes\.io/service-account\.name}|{"\n" }{end}' | grep "|${SVCACCNT}|"|cut -f1)

if [ -z "$SECRET" ]; then 
  echo No secret was found - please check the service account name and namespace.
  exit 1
fi

# Create a new context user named svcaccountuser with the token from the secret.
kubectl --kubeconfig=$SVCKUBECONFIG config set-credentials svcaccountuser --token=$(kubectl get secrets -n $NS $SECRET -o jsonpath="{.data.token}" | base64 --decode)
# Set the current context to use svcaccountuser.
kubectl --kubeconfig=$SVCKUBECONFIG config set-context --current --user=svcaccountuser

# now that we have the breaer token set, we need to attach the service account CA to the cluster.

# get the name of the current context.
CTX=$(kubectl config current-context)

# Fetch the current conext from the list of contexts, and get the cluster name that's used by it.
CLUSTER_NAME=$(kubectl config view -o jsonpath='{.contexts[?(.name == "'${CTX}'")].context.cluster}')

if [ -z "$CLUSTER_NAME" ]; then 
  echo "Cant find cluster for context ${CTX}"
  exit 1
fi

# Set the CA of this cluster to the one from the service account.
kubectl --kubeconfig=$SVCKUBECONFIG config set clusters.${CLUSTER_NAME}.certificate-authority-data $(kubectl get secrets -n $NS $SECRET -o jsonpath="{.data['ca\.crt']}")

# That's it! When using this modified kubeconfig you will have the same permissions as your service account.
echo 'Now run:'
echo 'export KUBECONFIG="'$PWD/$SVCKUBECONFIG'"'