feat: rekey only specific identity

Currently rekey re-encrypts all files.

For my personal use-case, agenix would ideally only files that require rekeying, i.e. files where the identities changed.
But I don’t think there’s an (easy) way to achieve that with `age` currently, as there’s no way to get the current recipients from an encrypted file?

This change would allow the user to manually specifiy that only secrets that contain a given identity should be rekeyed.

In my use-case this is handy as when I add a new server I want all secrets that are shared between servers (where the new identity was added) to be rekeyed, but I don’t want all secrets that are personal to different servers to also be rekeyed.
This commit is contained in:
Felix Scheinost 2024-10-25 14:55:28 +02:00
parent f6291c5935
commit dddc664d4a

View file

@ -13,7 +13,7 @@ function show_help () {
echo '-h, --help show help' echo '-h, --help show help'
# shellcheck disable=SC2016 # shellcheck disable=SC2016
echo '-e, --edit FILE edits FILE using $EDITOR' echo '-e, --edit FILE edits FILE using $EDITOR'
echo '-r, --rekey re-encrypts all secrets with specified recipients' echo '-r, --rekey [PUBLIC_KEY] re-encrypts all secrets with specified recipients'
echo '-d, --decrypt FILE decrypts FILE to STDOUT' echo '-d, --decrypt FILE decrypts FILE to STDOUT'
echo '-i, --identity identity to use when decrypting' echo '-i, --identity identity to use when decrypting'
echo '-v, --verbose verbose output' echo '-v, --verbose verbose output'
@ -46,6 +46,7 @@ function err() {
test $# -eq 0 && (show_help && exit 1) test $# -eq 0 && (show_help && exit 1)
REKEY=0 REKEY=0
REKEY_PUBLIC_KEY=
DECRYPT_ONLY=0 DECRYPT_ONLY=0
DEFAULT_DECRYPT=(--decrypt) DEFAULT_DECRYPT=(--decrypt)
@ -77,6 +78,10 @@ while test $# -gt 0; do
;; ;;
-r|--rekey) -r|--rekey)
shift shift
if test $# -gt 0; then
REKEY_PUBLIC_KEY="$1"
shift
fi
REKEY=1 REKEY=1
;; ;;
-d|--decrypt) -d|--decrypt)
@ -189,7 +194,22 @@ function edit {
} }
function rekey { function rekey {
FILES=$( (@nixInstantiate@ --json --eval -E "(let rules = import $RULES; in builtins.attrNames rules)" | @jqBin@ -r .[]) || exit 1) if test ! -z "$REKEY_PUBLIC_KEY"; then
FILTER_EXPRESSION="builtins.elem \"$REKEY_PUBLIC_KEY\" rules.\${file}.publicKeys";
else
FILTER_EXPRESSION="true";
fi
RULES_EXPRESSION=$(cat <<EOF
let
rules = import $RULES;
filter = file: $FILTER_EXPRESSION;
in
builtins.filter filter (builtins.attrNames rules)
EOF
)
FILES=$( (@nixInstantiate@ --json --eval -E "$RULES_EXPRESSION" | @jqBin@ -r .[]) || exit 1)
for FILE in $FILES for FILE in $FILES
do do