Introduction
In a Vault cluster where namespaces are heavily used, listing all secrets engines per namespace can be a time consuming task. This guide aims to provide a method of listing secrets engines of a selected type per namespace by means of a shell script.
Prerequisites (if applicable)
- Vault Enterprise - All versions.
- jq 1.7 or later.
- Bash 5.1 or later.
- Vault token with a policy allowing read and list operations on all namespaces and secrets engines.
Overview
The script interacts with Vault to list secrets engines within namespaces and performs the following tasks:
- Lists secret engines of a specific type in a given namespace derived from
vault namespace list
. - Flattens the namespace path to remove any duplicate or trailing slashes.
- Recursively traverses namespaces up to a specified depth to list secrets engines.
The script expects two command-line arguments:
-
depth
: The depth to which the script should traverse namespaces. For example:- A depth of 3 is required if namespace exist as
ns1/sub1/ns1
- A depth of 3 is required if namespace exist as
-
engine_type
: The type of secrets engines to list. For example:kv, database, aws, azure, ldap, ns_cubbyhole, ns_system, ns_identity
Please note that this script only processes secrets engines mounted inside a namespace and will not return data for secrets engines mounted outside of a namespace (ie. root)
Procedures
-
Copy, save to file and make the following script executable on your Vault server:
#!/bin/bash
#list_secrets_engines_per_ns.sh
function list_secrets_engines() {
local namespace=$1
local engine_type=$2
local result=$(vault secrets list -ns="$namespace" -format=json | jq -r --arg engine_type "$engine_type" '. | to_entries[] | select(.value.type == $engine_type)')
if [ -n "$result" ]; then
echo "Secrets Engines in Namespace: $namespace"
echo "$result" | jq -c '.'
echo
fi
}
function flatten_namespace() {
local namespace=$1
echo "$namespace" | sed -E 's#/{2,}#/#g; s#/$##'
}
function traverse_namespaces() {
local depth=$1
local current_depth=$2
local parent_namespace=$3
local engine_type=$4
if [ "$current_depth" -gt "$depth" ]; then
return
fi
local namespaces
if [ -z "$parent_namespace" ]; then
namespaces=$(vault namespace list -format=json | jq -r '.[]')
else
parent_namespace=$(flatten_namespace "$parent_namespace")
namespaces=$(vault namespace list -ns="$parent_namespace" -format=json | jq -r '.[]')
fi
for namespace in $namespaces; do
local full_namespace
if [ -z "$parent_namespace" ]; then
full_namespace="$namespace"
else
full_namespace="$parent_namespace/$namespace"
fi
full_namespace=$(flatten_namespace "$full_namespace")
list_secrets_engines "$full_namespace" "$engine_type"
traverse_namespaces "$depth" "$((current_depth + 1))" "$full_namespace" "$engine_type"
done
}
if [ "$#" -eq 2 ]; then
depth=$1
engine_type=$2
traverse_namespaces "$depth" 1 "" "$engine_type"
else
echo "Usage: $0 <depth> <engine_type>"
exit 1
fi
- Execute the script as follows:
./list_secrets_engines_per_ns.sh 3 kv
- Example output:
Secrets Engines in Namespace: ns1
{"key":"kv/","value":{"uuid":"2708f7ff-0ec3-b0e3-a095-944078f52bae","type":"kv","description":"","accessor":"kv_a38aab25","config":{"default_lease_ttl":0,"max_lease_ttl":0,"force_no_cache":false},"options":null,"local":false,"seal_wrap":false,"external_entropy_access":false,"plugin_version":"","running_plugin_version":"v0.16.1+builtin","running_sha256":"","deprecation_status":"supported"}}
Secrets Engines in Namespace: ns1/sub1/ns1
{"key":"kv/","value":{"uuid":"1b2548b2-adbe-81eb-e869-381c3173691d","type":"kv","description":"","accessor":"kv_98dcfeb5","config":{"default_lease_ttl":0,"max_lease_ttl":0,"force_no_cache":false},"options":null,"local":false,"seal_wrap":false,"external_entropy_access":false,"plugin_version":"","running_plugin_version":"v0.16.1+builtin","running_sha256":"","deprecation_status":"supported"}}
Secrets Engines in Namespace: ns4/sub1/ns1
{"key":"kv/","value":{"uuid":"a01fc96c-0690-3c74-21a8-b70963f767e2","type":"kv","description":"","accessor":"kv_3111ea1a","config":{"default_lease_ttl":0,"max_lease_ttl":0,"force_no_cache":false},"options":null,"local":false,"seal_wrap":false,"external_entropy_access":false,"plugin_version":"","running_plugin_version":"v0.16.1+builtin","running_sha256":"","deprecation_status":"supported"}}
Secrets Engines in Namespace: ns5/sub1
{"key":"kv/","value":{"uuid":"20994bfd-fd93-5bdd-5dbb-de56028200ac","type":"kv","description":"","accessor":"kv_0c05c46e","config":{"default_lease_ttl":0,"max_lease_ttl":0,"force_no_cache":false},"options":null,"local":false,"seal_wrap":false,"external_entropy_access":false,"plugin_version":"","running_plugin_version":"v0.16.1+builtin","running_sha256":"","deprecation_status":"supported"}}
Additional Information:
- Vault Documentation: Secrets Engines
- Vault Documentation: Vault Enterprise Namespaces
- Vault Article: How to list Vault child namespaces