#/usr/bin/env bash # Purpose: manage .sops.yaml based on gpg keys in the same dir _and_ verify correct configuration set -euo pipefail keyfiles_dir="$(realpath "${1?"E: specify dir containing keyfiles"}")"; shift; sops_config_dir="$(realpath "${1?"E: specify dir containing .sops.yaml"}")"; shift; sops_config="${sops_config_dir}/.sops.yaml" secrets_file="${1:-0}" function fn_extract_fpr(){ gpgkeyfile=$1;shift; # fingerprint # caveat: restrict to netgo.de email, use-case: # uid ... <...@mehrwerk.net> # uid ... <...@netgo.de> # fancy gpg src: https://unix.stackexchange.com/a/731872 fpr="$(gpg --show-keys --list-options show-only-fpr-mbox "${gpgkeyfile}" | grep '@netgo.de' | awk "{print \$1}")" echo "${fpr}" } function fn_extract_uid(){ gpgkeyfile=$1;shift; # user id # caveat: restrict to netgo.de email, use-case: # uid ... <...@mehrwerk.net> # uid ... <...@netgo.de> # fancy gpg src: https://unix.stackexchange.com/a/731872 uid="$(gpg --show-keys --with-colons "${gpgkeyfile}" | awk -F':' '$1=="uid" {print $10}' | grep '@netgo.de')" echo "${uid}" } function fn_update_sops_config(){ # sops.yaml doc: https://github.com/getsops/sops?tab=readme-ov-file#using-sops-yaml-conf-to-select-kms-pgp-and-age-for-new-files # CAVEAT: dirty hacks, just get it done. Not DRY, very WET. echo "# Fingerprint | User Type | User ID" for gpgkeyfile in *automation*gpg.pub; do u_type="autom" echo "# $(fn_extract_fpr "${gpgkeyfile}") | ${u_type} | $(fn_extract_uid "${gpgkeyfile}")" done for gpgkeyfile in $(ls *gpg.pub | grep -v automation); do u_type="human" echo "# $(fn_extract_fpr "${gpgkeyfile}") | ${u_type} | $(fn_extract_uid "${gpgkeyfile}")" done echo "# keys in https://git.dev-at.de/smardigo-hetzner/communication-keys" cat <- EOM fpr_list=() for gpgkeyfile in *automation*gpg.pub; do fpr_list+=( $(fn_extract_fpr "${gpgkeyfile}") ) done for gpgkeyfile in $(ls *gpg.pub | grep -v automation); do fpr_list+=( $(fn_extract_fpr "${gpgkeyfile}") ) done # all but last line get comma ind_2nd_last=$((${#fpr_list[@]} - 1)) for fpr in ${fpr_list[@]:0:${ind_2nd_last}}; do echo " ${fpr}," done # last line no comma # echo " ${fpr_list[-1]}," # requires bash v4.1 echo " ${fpr_list[${ind_2nd_last}]}" } # UPDATE SOPS CONFIG # TODO: remove the 'pushd;popd' workaround and make the functions aware of the dir being read pushd "${keyfiles_dir}" > /dev/null 2>&1 (fn_update_sops_config) > "${sops_config}" popd > /dev/null 2>&1 # VERIFY fn_sops_updatekeys_and_verify(){ sops_enc_file="${1}";shift; # update keys in secrets file test -e "${sops_enc_file}" || exit 1 # "update the keys of SOPS files using the config file" sops updatekeys "${sops_enc_file}" # verify: dump secrets, GPG_TTY src: https://www.varokas.com/secrets-in-code-with-mozilla-sops/ GPG_TTY=$(tty) sops -d "${sops_enc_file}" } if [[ "${secrets_file}" != "0" ]]; then fn_sops_updatekeys_and_verify "${secrets_file}" echo "# SUCESS: all users with keys in this dir should have functional keys" else echo "# WARN: no secrets file passed in, make sure to call 'sops updatekeys' on secrets files" fi