Skip to content

Instantly share code, notes, and snippets.

@utoddl
Last active September 25, 2025 19:16
Show Gist options
  • Select an option

  • Save utoddl/69ff0baa35b4170df8d1eec61563a1ac to your computer and use it in GitHub Desktop.

Select an option

Save utoddl/69ff0baa35b4170df8d1eec61563a1ac to your computer and use it in GitHub Desktop.
Report configured Ansible Vault IDs and what vaulted blobs they can decrypt
#!/usr/bin/env bash
#
# Author: Todd Lewis (@utoddl on github.com), 2025-09-25
# License: CC-By, GNU General Public License v3.0 or later, BSD, Fishing
#
# vault-id-report.sh - Takes no parameters, not even "-h".
#
# Examines ansible-vaulted data in and below the current directory
# and reports which of your configured VAULT_IDENTITY_LIST Vault IDs
# can decrypt them.
shopt -s extglob
# Read configured vault identities from ansible-config
# shellcheck disable=SC2207
declare -a vault_identity_list=( $(ansible-config dump --only-changed \
| grep VAULT_IDENTITY_LIST \
| grep -P -o "'[^']+'" \
| tr -d "'"
)
)
declare -A vault_ids=()
max_vault_id_width=6
for id in "${vault_identity_list[@]}" ; do
id_key="${id/@*/}"
[ "$max_vault_id_width" -gt "${#id_key}" ] || max_vault_id_width="${#id_key}"
vault_ids["${id/@*/}"]="${id/*@/}"
done
printf "# Configured Vault IDs and Files\n"
for id in "${!vault_ids[@]}" ; do
printf "%-${max_vault_id_width}s %s\n" "$id" "${vault_ids[$id]}"
done
printf "\n# IDs decrypting discovered ANSIBLE_VAULT data\n"
# These exports are necessary to prevent subsequent ansible-vault
# invocations from using all the Vault IDs you normally have configured.
export ANSIBLE_VAULT_IDENTITY=''
export ANSIBLE_VAULT_IDENTITY_LIST=''
# shellcheck disable=SC2016
vault_header_rx='^( *)(\$ANSIBLE_VAULT;.*)$'
vault_data_rx='^( *)([0-9a]+)$'
vault_blob_init() {
blob_data=''
blob_leading_space='^'
blob_file_name=''
blob_line_no_first=0
blob_line_no_last=0
}
vault_blob_test() {
if [ -n "$blob_data" ] ; then
success=0
for id in "${!vault_ids[@]}" ; do
if ansible-vault decrypt --vault-password-file "${vault_ids[$id]}" > /dev/null 2>&1 < <(printf "%s\n" "$blob_data") ; then
success=$((success + 1))
printf "%-${max_vault_id_width}s %s:%d-%d %s\n" "$id" "$blob_file_name" "$blob_line_no_first" "$blob_line_no_last" "${blob_data%%$'\n'*}"
fi
done
if [ "$success" -eq 0 ] ; then
printf "%-${max_vault_id_width}s %s:%d-%d\n" "<none>" "$blob_file_name" "$blob_line_no_first" "$blob_line_no_last"
fi
fi
vault_blob_init
}
vault_blob_append() {
if [ "$file_name_in" != "$blob_file_name" ] ; then
vault_blob_test
fi
if [[ "$data_in" =~ $vault_header_rx ]] ; then
vault_blob_test
[[ "$data_in" =~ $vault_header_rx ]]
blob_data="${BASH_REMATCH[2]}"$'\n'
blob_leading_space="${BASH_REMATCH[1]}"
vault_data_rx="^(${blob_leading_space})([0-9a]+)$"
blob_file_name="$file_name_in"
blob_line_no_first="$line_no_in"
blob_line_no_last="$line_no_in"
return
fi
if [ -n "$blob_data" ] && [[ "$data_in" =~ $vault_data_rx ]] ; then
blob_data+="${BASH_REMATCH[2]}"$'\n'
blob_line_no_last="$line_no_in"
else
if [ -n "$vault_blob_data" ] ; then
vault_blob_test
fi
fi
}
# State machine for reading ansible-vault data blobs.
# shellcheck disable=SC2016
while IFS=':' read -r file_name_in line_no_in data_in ; do
vault_blob_append
done < <(grep -n -r -P '^( *)(\$ANSIBLE_VAULT;.*|[\da]+)$' . 2>/dev/null )
vault_blob_test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment