From 667edc8621797cc142e1b10876fbaa246c3c54b0 Mon Sep 17 00:00:00 2001 From: Andreas Wrede Date: Wed, 23 Sep 2026 16:41:31 -0400 Subject: [PATCH] deploy --diff: never diff seeded secret files, redact secret values Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01KqhjP7nud5gdBg25zCiRk9 --- deploy.sh | 19 ++++++++++++++++--- tests/check-templates.sh | 18 ++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/deploy.sh b/deploy.sh index cecb220..31e193c 100755 --- a/deploy.sh +++ b/deploy.sh @@ -6,6 +6,7 @@ # ./deploy.sh --check [conf] # validate conf + render all templates, no install # ./deploy.sh --diff [conf] # what would change in /etc # ./deploy.sh render # preview a templated file on stdout +# ./deploy.sh --redact # filter stdin, masking secret values (used by --diff; for tests) # Idempotent. Netplan (wlan0 + Starlink NIC = NM-managed WANs; eth0 is a LAN # port on br0) is NOT deployed here — reference copy in ap/50-van-wan.yaml, # applied once manually (apply flaps uplinks). We do check it for drift below. @@ -86,6 +87,12 @@ install_rendered() { # install_rendered [mode] rm -f "$tmp" } +redact_secrets() { # stdin -> stdout; mask values of secret-looking keys, keep key + diff markers + sed -E \ + -e 's/((pass(word|phrase)|secret|token)[A-Za-z_]*[[:space:]]*=).*/\1/I' \ + -e 's/("[A-Za-z_]*(pass(word|phrase)|secret|token|user)[A-Za-z_]*"[[:space:]]*:[[:space:]]*)"[^"]*"/\1""/I' +} + template_files() { # every repo file that carries an @TOKEN@ placeholder grep -rlE "$TOKEN_RE" --exclude-dir=.git --exclude-dir=__pycache__ --exclude-dir=.superpowers \ --exclude-dir=docs --exclude-dir=tests --exclude-dir=hosts \ @@ -114,23 +121,29 @@ case "${1:-}" in echo "NEW $dst" elif ! diff -q <(render "$src") "$dst" >/dev/null; then echo "CHANGED $dst" - diff -u "$dst" <(render "$src") | sed 's/^/ /' || true + diff -u "$dst" <(render "$src") | redact_secrets | sed 's/^/ /' || true fi done # Also lists plain `install` files and `rm -f` targets — these sections may be # flag-gated in the real run, but --diff reports them regardless of the flag. - grep -E '^[[:space:]]*install -D -m[0-9]+ +[^" ]+ +/' deploy.sh | while read -r _ _ _ src dst _; do + grep -E '^[[:space:]]*install -D -m[0-9]+ +[^" ]+ +/' deploy.sh | while read -r _ _ mode src dst _; do + # seed-if-absent secret files (from *.example, or 0600): never diff or print + case "$src" in *.example) continue ;; esac + [ "$mode" = -m0600 ] && continue if [ ! -e "$dst" ]; then echo "NEW $dst" elif ! cmp -s "$src" "$dst"; then echo "CHANGED $dst" - diff -u "$dst" "$src" | sed 's/^/ /' || true + diff -u "$dst" "$src" | redact_secrets | sed 's/^/ /' || true fi done grep -E '^[[:space:]]*rm -f +/' deploy.sh | while read -r _ _ path _; do [ -e "$path" ] && echo "REMOVE $path" done || true exit 0 ;; + --redact) # ./deploy.sh --redact — stdin through redact_secrets (no config, no root) + redact_secrets + exit 0 ;; render) [ -n "${2:-}" ] || { echo "Usage: $0 render "; exit 1; } load_conf "$VANLINK_CONF" diff --git a/tests/check-templates.sh b/tests/check-templates.sh index dab1921..c5af8d3 100755 --- a/tests/check-templates.sh +++ b/tests/check-templates.sh @@ -151,4 +151,22 @@ for c in hosts/*.conf; do done done +# 10. --diff never touches seed-if-absent secret files, and redacts secret values +out=$(./deploy.sh --diff hosts/wan.conf 2>&1) || true +leak=$(echo "$out" | grep -E '/etc/van-gps/config\.json|/etc/van-li3/config\.json|/etc/van-battery/pushover\.json') || true +if [ -z "$leak" ]; then + ok "--diff ignores seeded secret files" +else + bad "--diff mentions seeded secret files"; echo "$leak" | sed 's/^/ /' +fi +red=$(printf '%s\n' 'wpa_passphrase=hunter2' '+ "password": "hunter2",' '- "token": "abc123"' ' "user": "u123"' | ./deploy.sh --redact 2>&1) || true +if echo "$red" | grep -qE 'hunter2|abc123|u123'; then + bad "--redact leaks a secret value"; echo "$red" | sed 's/^/ /' +elif echo "$red" | grep -q '^wpa_passphrase=' && echo "$red" | grep -q '^+ "password"' \ + && echo "$red" | grep -q '^- "token"' && echo "$red" | grep -q '^ "user"'; then + ok "--redact masks values, keeps keys and diff markers" +else + bad "--redact lost keys or diff markers"; echo "$red" | sed 's/^/ /' +fi + exit "$fail"