Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a12d13-27f2-7163-b8c0-f682af02772c
48 lines
2.1 KiB
Bash
Executable file
48 lines
2.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Explicit attended custody input only. Publish plaintext only after all files
|
|
# decrypt successfully into a private staging directory; never emit values.
|
|
set +x
|
|
set -euo pipefail
|
|
umask 077
|
|
|
|
fail() { printf 'ERROR: %s\n' "$1" >&2; exit 1; }
|
|
OUTPUT_DIR="${1:-./secrets}"
|
|
AGE_KEY="${2:-${NETKINGDOM_CUSTODY_AGE_KEY_FILE:-}}"
|
|
[[ $# -le 2 ]] || fail "unsupported decrypt argument"
|
|
[[ -n "$AGE_KEY" && -f "$AGE_KEY" ]] || fail "explicit temporary custody key required"
|
|
ENC_DIR="$(dirname "$OUTPUT_DIR")/secrets.enc"
|
|
[[ -d "$ENC_DIR" && ! -L "$ENC_DIR" ]] || fail "encrypted source directory unavailable"
|
|
[[ ! -e "$OUTPUT_DIR" && ! -L "$OUTPUT_DIR" ]] || fail "output already exists"
|
|
[[ -d "$(dirname "$OUTPUT_DIR")" ]] || fail "output parent unavailable"
|
|
|
|
STAGING=$(mktemp -d "$(dirname "$OUTPUT_DIR")/.netkingdom-decrypt.XXXXXXXX")
|
|
cleanup() {
|
|
if [[ -d "$STAGING" ]]; then
|
|
find "$STAGING" -type f -exec shred -u {} \; 2>/dev/null || true
|
|
rm -rf -- "$STAGING"
|
|
fi
|
|
}
|
|
trap cleanup EXIT
|
|
trap 'exit 129' HUP
|
|
trap 'exit 130' INT
|
|
trap 'exit 143' TERM
|
|
|
|
count=0
|
|
for component_dir in "$ENC_DIR"/*; do
|
|
[[ -e "$component_dir" || -L "$component_dir" ]] || continue
|
|
[[ -d "$component_dir" && ! -L "$component_dir" ]] || fail "unexpected encrypted component"
|
|
component=$(basename "$component_dir")
|
|
mkdir "$STAGING/$component"
|
|
for file in "$component_dir"/*.age; do
|
|
[[ -e "$file" || -L "$file" ]] || continue
|
|
[[ -f "$file" && ! -L "$file" ]] || fail "unexpected encrypted input"
|
|
name=$(basename "${file%.age}")
|
|
age -d -i "$AGE_KEY" -o "$STAGING/$component/$name" "$file" 2>/dev/null || fail "decryption failed; partial plaintext removed"
|
|
count=$((count + 1))
|
|
done
|
|
done
|
|
[[ "$count" -gt 0 ]] || fail "no encrypted files found"
|
|
# Never replace an output created by another process during decryption.
|
|
mv -Tn -- "$STAGING" "$OUTPUT_DIR" || fail "could not publish private output"
|
|
[[ ! -d "$STAGING" ]] || fail "output appeared during decryption"
|
|
printf '%s file(s) decrypted to private output; remove plaintext after the approved operation.\n' "$count"
|