Last active
March 20, 2025 20:57
-
-
Save ericreeves/9f7ab1afdcc942ebb54a17abc2fa5fb1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Search HashiCorp Vault for a Secret Value, Traversing all Nested namespaces | |
# | |
########################################################################## | |
# DISCLAIMER: THIS SCRIPT IS PROVIDED STRICTLY AS A PROOF OF CONCEPT. | |
# EXECUTING THIS SCRIPT ASSUMES ALL LIABILITY. | |
########################################################################## | |
# | |
cat <<EOF | |
########################################################################## | |
# DISCLAIMER: THIS SCRIPT IS PROVIDED STRICTLY AS A PROOF OF CONCEPT. | |
# EXECUTING THIS SCRIPT ASSUMES ALL LIABILITY. | |
########################################################################## | |
Press Enter to Continue... | |
EOF | |
read -n 1 | |
# Define the secret to search for | |
SECRET_TO_FIND="findme" | |
FOUND=() | |
echo "--- Searching for Secret with Value: $SECRET_TO_FIND" | |
echo | |
# Function to search for the secret in a given path | |
search_secret() { | |
local namespace=$1 | |
local path=$2 | |
# List all secrets in the KV2 secret engine | |
secrets=$(vault kv list -namespace="$namespace" -format=json "$path" | jq -r '.[]') | |
for secret in $secrets; do | |
# Read the secret data | |
secret_data=$(vault kv get -namespace="$namespace" -format=json "$path/$secret" | jq -r '.data.data') | |
# Iterate over each key-value pair in the secret data | |
for secret_key in $(echo "$secret_data" | jq -r 'keys[]'); do | |
secret_value=$(echo "$secret_data" | jq -r --arg key "$secret_key" '.[$key]') | |
# Check if the secret value matches the specified secret | |
if [[ "$secret_value" == "$SECRET_TO_FIND" ]]; then | |
echo " + ${namespace}${path}${secret}/${secret_key} == $secret_value" | |
FOUND+=("${namespace}${path}${secret}/${secret_key}") | |
else | |
echo " - ${namespace}${path}${secret}/${secret_key} == $secret_value" | |
fi | |
done | |
done | |
} | |
# Recursive function to traverse namespaces | |
traverse_namespaces() { | |
local parent_namespace=$1 | |
# List all namespaces under the current namespace | |
namespaces=$(vault namespace list -namespace="$parent_namespace" -format=json | jq -r '.[]') | |
for namespace in $namespaces; do | |
#echo "- ${parent_namespace}${namespace}" | |
# List all KV2 secret engines in the namespace | |
secret_engines=$(vault secrets list -namespace="${parent_namespace}${namespace}" -format=json | jq -r 'to_entries[] | select(.value.type == "kv") | .key') | |
for engine in $secret_engines; do | |
# Search for the secret in each engine | |
search_secret "${parent_namespace}${namespace}" "$engine" | |
done | |
# Recursively traverse child namespaces | |
traverse_namespaces "${parent_namespace}${namespace}" | |
done | |
} | |
# Start traversal from the root namespace | |
traverse_namespaces "" | |
if ((${#FOUND[@]})); then | |
echo | |
echo "----------------------------------------------" | |
echo " Secret Found in the Following Secret Engines" | |
echo "----------------------------------------------" | |
printf '%s\n' "${FOUND[@]}" | |
else | |
echo "Secret Not Found" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment