docs: capture history-rewrite-under-live-git-sync + secrets-audit tooling

Update the git-sync secret-exposure solution doc with today's operational
lesson: untracking an already-committed secret under a live bidirectional
sync. Covers the direction:both force-push-revert trap, the freeze-every-
server-first sequence, audit-before-reset (authoritative secret in env/),
the stale origin/main ref + sparse-checkout gotchas, and the ignore:-field
mechanism.

Add Makefile targets that supported the fix:
- remote-secrets-audit: secret-safe (existence + size + git ls-files, never
  contents) audit of config/ vs env/<host>/config secret locations
- remote-content-status: also show the .gitignore diff git-sync regenerates

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-05 19:25:32 +02:00
co-authored by Claude Opus 4.8
parent 3cb7dfbd8b
commit 9295914238
2 changed files with 88 additions and 2 deletions
+12 -2
View File
@@ -27,7 +27,7 @@ REMOTE_TARGETS := remote-env-setup remote-env-remove remote-wipe remote-install
remote-fetch remote-fetch-content remote-install-plugins remote-update-plugins \
remote-upgrade-grav remote-git-sync-disable remote-git-sync-enable \
remote-content-status remote-clean remote-diag remote-apply-env \
remote-seed-api-salt \
remote-seed-api-salt remote-secrets-audit \
remote-gpm-install remote-maintenance-on remote-maintenance-off
ENVS := test prod
@@ -174,7 +174,7 @@ remote-git-sync-enable: guard-env
$(SSH) "bash -s -- '$(WEBROOT)' true" < scripts/git-sync-toggle.sh
remote-content-status: guard-env
$(SSH) "cd $(WEBROOT)/user && echo '--- HEAD ---' && git log -1 --oneline && echo '--- working tree ---' && git status --short && echo '--- config diff ---' && git diff -- config/"
$(SSH) "cd $(WEBROOT)/user && echo '--- HEAD ---' && git log -1 --oneline && echo '--- working tree ---' && git status --short && echo '--- config diff ---' && git diff -- config/ && echo '--- .gitignore diff ---' && git diff -- .gitignore"
remote-clean: guard-env
$(SSH) "cd $(WEBROOT) && php bin/grav clearcache"
@@ -235,6 +235,16 @@ remote-diag: guard-env
echo '=== git-sync config (secrets redacted) ==='; grep -vaiE 'password|token|secret' user/config/plugins/git-sync.yaml user/env/*/config/plugins/git-sync.yaml 2>/dev/null; \
echo '=== grav.log tail ==='; tail -8 logs/grav.log 2>/dev/null"
# Secret-safe audit: lists WHERE per-host secret/config files live (config/ vs
# env/<host>/config/) and their sizes — never prints contents. Used to decide
# whether a `reset --hard` would clobber a live runtime secret.
remote-secrets-audit: guard-env
$(SSH) "cd $(WEBROOT)/user && \
echo '=== tracked in git? (git ls-files) ==='; git ls-files config/security-private.php config/security.yaml config/versions.yaml config/plugins/api-private.php config/plugins/git-sync.yaml; \
echo '=== config/ copies (size only) ==='; ls -la config/security.yaml config/security-private.php config/versions.yaml config/plugins/api-private.php config/plugins/git-sync.yaml 2>&1; \
echo '=== env/<host>/config copies (size only) ==='; ls -la env/*/config/security.yaml env/*/config/security-private.php env/*/config/plugins/api-private.php env/*/config/plugins/git-sync.yaml 2>&1; \
echo '=== does security.yaml reference the private php? (key names only) ==='; grep -aoE '^[a-z_]+:' config/security.yaml 2>/dev/null; for f in env/*/config/security.yaml; do echo \"\$$f:\"; grep -aoE '^[a-z_]+:' \"\$$f\" 2>/dev/null; done; true"
remote-maintenance-on: guard-env
$(SSH) "bash -s on $(WEBROOT)" < scripts/server-maintenance.sh