Skip to content

Instantly share code, notes, and snippets.

@ericreeves
Last active January 2, 2024 22:02
Show Gist options
  • Save ericreeves/aafd9c27cebb343fbb5a13ae1f562b77 to your computer and use it in GitHub Desktop.
Save ericreeves/aafd9c27cebb343fbb5a13ae1f562b77 to your computer and use it in GitHub Desktop.
Audit HashiCorp Vault for Unique Bound Service Account Names in Each Namespace
#!/bin/bash
# Ensure VAULT_ADDR and VAULT_TOKEN are exported.
# Ensure VAULT_NAMESPACE is unset
# Function to list namespaces recursively
function list_namespaces {
entry_point=$(echo ${1} | sed 's/\/$//')
echo "${entry_point}/"
## first, check if root ns, and if so collect children slightly differently due to path specification
#
if [[ "${entry_point}" == "root" ]]
then
child_namespaces=$(vault namespace list -format=json | jq -r .[] | tr '\012' ' ' | tr -d '/')
entry_point=
else
child_namespaces=$(vault namespace list -namespace ${entry_point} -format=json | jq -r .[] | tr '\012' ' ')
child_namespaces=$(echo ${child_namespaces} | sed 's/ $//')
if [[ -n ${child_namespaces} ]]
then
child_namespaces=$(echo ${child_namespaces} | sed -e "s~^~${entry_point}/~" -e "s~ ~ ${entry_point}/~g")
fi
fi
## iterate found child namespaces
#
if [[ -n ${child_namespaces} ]]
then
for namespace in $(echo ${child_namespaces})
do
list_namespaces "${namespace}"
done
fi
}
# Function to list Kubernetes auth methods in a namespace
list_k8s_auth_methods() {
local namespace=$1
vault auth list -format=json -namespace="$namespace" | jq -r 'to_entries[] | select(.value.type == "kubernetes") | .key'
}
# Function to list roles in a Kubernetes auth method
list_roles() {
local namespace=$1
local auth_method=$2
vault list -format=json -namespace="$namespace" "auth/${auth_method}role" | jq -r '.[]'
}
# Function to get bound_service_account_names for a role
get_bound_service_account_names() {
local namespace=$1
local auth_method=$2
local role=$3
vault read -format=json -namespace="$namespace" "auth/${auth_method}role/$role" | jq -r '.data.bound_service_account_names[]'
}
# Declare variables
declare -A unique_bound_service_accounts
declare -i ns_count=0
declare -i am_count=0
declare -i r_count=0
declare -i ubsa_count=0
###############################################################################################
# Main script starts here
###############################################################################################
for namespace in $(list_namespaces root); do
ns_count=$ns_count+1
# echo "--- Namespace: $namespace"
for auth_method in $(list_k8s_auth_methods "${namespace}"); do
am_count=$am_count+1
# echo "--- Auth Method: $auth_method"
for role in $(list_roles "${namespace}" "${auth_method}"); do
r_count=$r_count+1
# echo "--- Role: $role"
for service_account in $(get_bound_service_account_names "${namespace}" "${auth_method}" "${role}"); do
echo "Namespace: $namespace, Auth Method: $auth_method, Role: $role, Service Account: $service_account"
unique_bound_service_accounts["${namespace}${service_account}"]=1
done
done
done
done
echo
echo "----------------------------------------------"
echo "Unique 'Namespace/Bound Service Account Names'"
echo "----------------------------------------------"
for account in "${!unique_bound_service_accounts[@]}"; do
ubsa_count=$ubsa_count+1
done
# Print them sorted alphabetically
echo "${!unique_bound_service_accounts[@]}" | tr ' ' '\n' | sort -n
echo
echo "------"
echo "Totals"
echo "------"
echo "Total Namespaces : $ns_count"
echo "Total Kubernetes Auth Methods : $am_count"
echo "Total Roles : $r_count"
echo
echo "==============="
echo "Billable Metric"
echo "==============="
echo "Total Unique Bound Service Accounts: $ubsa_count"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment