You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
communication-keys/bin/update_sops.sh

93 lines
3.4 KiB
Bash

#/usr/bin/env bash
# Purpose: manage .sops.yaml based on gpg keys in the same dir _and_ verify correct configuration
set -euo pipefail
sops_config_dir="$(realpath "${1?"E: specify dir containing .sops.yaml"}")"; shift;
keyfiles_dir="$(realpath "${1?"E: specify dir containing keyfiles"}")"; 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
creation_rules:
# list of keys for encryption in stage
- pgp: >-
EOM
for gpgkeyfile in *automation*gpg.pub; do
echo " $(fn_extract_fpr "${gpgkeyfile}"),"
done
# HACK: TODO: yq update the list in the foldable code block scalar thingy (automating yaml always hard...)
# HACK: all but last line get comma
for gpgkeyfile in $(ls *gpg.pub | grep -v automation | sed '$d'); do
echo " $(fn_extract_fpr "${gpgkeyfile}"),"
done
# HACK: last line no comma
for gpgkeyfile in $(ls *gpg.pub | grep -v automation | tail -n 1); do
echo " $(fn_extract_fpr "${gpgkeyfile}")"
done
}
# UPDATE SOPS CONFIG
pushd "${keyfiles_dir}" > /dev/null 2>&1
(fn_update_sops_config) > "${sops_config}"
popd > /dev/null 2>&1
# VERIFY
fn_verify_sops_config(){
sops_enc_file="${1}";shift;
# update keys in mock secret file
# prereq: create a file with a mock secret, src: https://bash-org-archive.com/?244321
test -e "${sops_enc_file}" || (yq -n '.demo.credentials.secret = "hunter2"' > "${sops_enc_file}" && sops -e -i "${sops_enc_file}" )
# "update the keys of SOPS files using the config file"
sops updatekeys "${sops_enc_file}"
# 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
pushd "${sops_config_dir}" > /dev/null 2>&1
fn_verify_sops_config "${secrets_file}"
popd > /dev/null 2>&1
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