mirror of
https://github.com/ryantm/agenix.git
synced 2024-11-24 18:48:29 +03:00
feature: add -d/--decrypt option to decrypt a file to stdout
This commit is contained in:
parent
2d735d6518
commit
9cf1967039
3 changed files with 45 additions and 5 deletions
|
@ -483,6 +483,8 @@ Overriding `age.secretsMountPoint` example:
|
||||||
### agenix CLI reference
|
### agenix CLI reference
|
||||||
|
|
||||||
```
|
```
|
||||||
|
agenix - edit and rekey age secret files
|
||||||
|
|
||||||
agenix -e FILE [-i PRIVATE_KEY]
|
agenix -e FILE [-i PRIVATE_KEY]
|
||||||
agenix -r [-i PRIVATE_KEY]
|
agenix -r [-i PRIVATE_KEY]
|
||||||
|
|
||||||
|
@ -490,6 +492,7 @@ options:
|
||||||
-h, --help show help
|
-h, --help show help
|
||||||
-e, --edit FILE edits FILE using $EDITOR
|
-e, --edit FILE edits FILE using $EDITOR
|
||||||
-r, --rekey re-encrypts all secrets with specified recipients
|
-r, --rekey re-encrypts all secrets with specified recipients
|
||||||
|
-d, --decrypt FILE decrypts FILE to STDOUT
|
||||||
-i, --identity identity to use when decrypting
|
-i, --identity identity to use when decrypting
|
||||||
-v, --verbose verbose output
|
-v, --verbose verbose output
|
||||||
|
|
||||||
|
@ -499,6 +502,8 @@ PRIVATE_KEY a path to a private SSH key used to decrypt file
|
||||||
|
|
||||||
EDITOR environment variable of editor to use when editing FILE
|
EDITOR environment variable of editor to use when editing FILE
|
||||||
|
|
||||||
|
If STDIN is not interactive, EDITOR will be set to "cp /dev/stdin"
|
||||||
|
|
||||||
RULES environment variable with path to Nix file specifying recipient public keys.
|
RULES environment variable with path to Nix file specifying recipient public keys.
|
||||||
Defaults to './secrets.nix'
|
Defaults to './secrets.nix'
|
||||||
```
|
```
|
||||||
|
|
|
@ -14,6 +14,7 @@ function 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 re-encrypts all secrets with specified recipients'
|
||||||
|
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'
|
||||||
echo ' '
|
echo ' '
|
||||||
|
@ -45,6 +46,7 @@ function err() {
|
||||||
test $# -eq 0 && (show_help && exit 1)
|
test $# -eq 0 && (show_help && exit 1)
|
||||||
|
|
||||||
REKEY=0
|
REKEY=0
|
||||||
|
DECRYPT_ONLY=0
|
||||||
DEFAULT_DECRYPT=(--decrypt)
|
DEFAULT_DECRYPT=(--decrypt)
|
||||||
|
|
||||||
while test $# -gt 0; do
|
while test $# -gt 0; do
|
||||||
|
@ -77,6 +79,17 @@ while test $# -gt 0; do
|
||||||
shift
|
shift
|
||||||
REKEY=1
|
REKEY=1
|
||||||
;;
|
;;
|
||||||
|
-d|--decrypt)
|
||||||
|
shift
|
||||||
|
DECRYPT_ONLY=1
|
||||||
|
if test $# -gt 0; then
|
||||||
|
export FILE=$1
|
||||||
|
else
|
||||||
|
echo "no FILE specified"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
;;
|
||||||
-v|--verbose)
|
-v|--verbose)
|
||||||
shift
|
shift
|
||||||
set -x
|
set -x
|
||||||
|
@ -89,7 +102,6 @@ while test $# -gt 0; do
|
||||||
done
|
done
|
||||||
|
|
||||||
RULES=${RULES:-./secrets.nix}
|
RULES=${RULES:-./secrets.nix}
|
||||||
|
|
||||||
function cleanup {
|
function cleanup {
|
||||||
if [ -n "${CLEARTEXT_DIR+x}" ]
|
if [ -n "${CLEARTEXT_DIR+x}" ]
|
||||||
then
|
then
|
||||||
|
@ -102,10 +114,13 @@ function cleanup {
|
||||||
}
|
}
|
||||||
trap "cleanup" 0 2 3 15
|
trap "cleanup" 0 2 3 15
|
||||||
|
|
||||||
function edit {
|
function keys {
|
||||||
FILE=$1
|
(@nixInstantiate@ --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" rules.\"$1\".publicKeys)" | @sedBin@ 's/"//g' | @sedBin@ 's/\\n/\n/g') | @sedBin@ '/^$/d' || exit 1
|
||||||
KEYS=$( (@nixInstantiate@ --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" rules.\"$FILE\".publicKeys)" | @sedBin@ 's/"//g' | @sedBin@ 's/\\n/\n/g') | @sedBin@ '/^$/d' || exit 1)
|
}
|
||||||
|
|
||||||
|
function decrypt {
|
||||||
|
FILE=$1
|
||||||
|
KEYS=$2
|
||||||
if [ -z "$KEYS" ]
|
if [ -z "$KEYS" ]
|
||||||
then
|
then
|
||||||
err "There is no rule for $FILE in $RULES."
|
err "There is no rule for $FILE in $RULES."
|
||||||
|
@ -132,6 +147,12 @@ function edit {
|
||||||
@ageBin@ "${DECRYPT[@]}" || exit 1
|
@ageBin@ "${DECRYPT[@]}" || exit 1
|
||||||
cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
|
cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
|
||||||
fi
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function edit {
|
||||||
|
FILE=$1
|
||||||
|
KEYS=$(keys "$FILE") || exit 1
|
||||||
|
decrypt "$FILE" "$KEYS" || exit 1
|
||||||
|
|
||||||
[ -t 0 ] || EDITOR='cp /dev/stdin'
|
[ -t 0 ] || EDITOR='cp /dev/stdin'
|
||||||
|
|
||||||
|
@ -160,6 +181,14 @@ function edit {
|
||||||
mv -f "$REENCRYPTED_FILE" "$1"
|
mv -f "$REENCRYPTED_FILE" "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function decrypt_only {
|
||||||
|
FILE=$1
|
||||||
|
KEYS=$(keys "$FILE") || exit 1
|
||||||
|
decrypt "$FILE" "$KEYS"
|
||||||
|
printf "%s" "$(<"${CLEARTEXT_FILE}")"
|
||||||
|
cleanup
|
||||||
|
}
|
||||||
|
|
||||||
function rekey {
|
function rekey {
|
||||||
FILES=$( (@nixInstantiate@ --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" (builtins.attrNames rules))" | @sedBin@ 's/"//g' | @sedBin@ 's/\\n/\n/g') || exit 1)
|
FILES=$( (@nixInstantiate@ --eval -E "(let rules = import $RULES; in builtins.concatStringsSep \"\n\" (builtins.attrNames rules))" | @sedBin@ 's/"//g' | @sedBin@ 's/\\n/\n/g') || exit 1)
|
||||||
|
|
||||||
|
@ -172,4 +201,5 @@ function rekey {
|
||||||
}
|
}
|
||||||
|
|
||||||
[ $REKEY -eq 1 ] && rekey && exit 0
|
[ $REKEY -eq 1 ] && rekey && exit 0
|
||||||
|
[ $DECRYPT_ONLY -eq 1 ] && decrypt_only "${FILE}" && exit 0
|
||||||
edit "$FILE" && cleanup && exit 0
|
edit "$FILE" && cleanup && exit 0
|
||||||
|
|
|
@ -90,6 +90,11 @@ pkgs.nixosTest {
|
||||||
|
|
||||||
# user1 can edit a secret by piping in contents
|
# user1 can edit a secret by piping in contents
|
||||||
system1.succeed(userDo("echo 'secret1234' | agenix -e passwordfile-user1.age"))
|
system1.succeed(userDo("echo 'secret1234' | agenix -e passwordfile-user1.age"))
|
||||||
assert "secret1234" in system1.succeed(userDo("EDITOR=cat agenix -e passwordfile-user1.age"))
|
|
||||||
|
# and get it back out via --decrypt
|
||||||
|
assert "secret1234" in system1.succeed(userDo("agenix -d passwordfile-user1.age"))
|
||||||
|
|
||||||
|
# finally, the plain text should not linger around anywhere in the filesystem.
|
||||||
|
system1.fail("grep -r secret1234 /tmp")
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue