security: stop tracking the per-host env/ secret tree

git-sync auto-commit stages everything not gitignored (git add -A over
user/), NOT just the pages/config/themes folders. Because /env/ was not
gitignored, prod's git-sync pushed the per-host env tree — including
api-private.php (JWT), security-private.php (CSRF salt), and the
git-sync token — to Gitea in commit 9337003. Gitignore /env/ and untrack
it so it can never round-trip again. (Working-tree files kept via
--cached; prod still needs them to run.) Leaked secrets rotated
separately; history purge TBD.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Np4cMQLF77i664CAQXySzU
This commit is contained in:
2026-07-05 00:52:42 +02:00
co-authored by Claude Opus 4.8
parent ca15bd8bd7
commit 6e8eadbab5
5 changed files with 4 additions and 85 deletions
+4
View File
@@ -11,4 +11,8 @@
/config/security.yaml
/config/security-private.php
/config/versions.yaml
# Per-host env override tree — holds LIVE secrets (JWT, CSRF salt, git-sync
# token) + per-host overrides. Never commit/sync: git-sync stages anything
# not gitignored, so an untracked /env/ would boomerang to Gitea.
/env/
/themes/intotheeast/node_modules/
-7
View File
@@ -1,7 +0,0 @@
<?php
// Auto-generated private secret. Do NOT commit to version control.
// Used to sign and verify API JWTs. Regenerate by deleting this file; the
// next request will write a new value (invalidating all existing tokens).
return 'b24a28b949941d16ef856a957f051831184a82ec15229dcd630183518bd0bca2';
-33
View File
@@ -1,33 +0,0 @@
enabled: true
folders:
- pages
- config
- themes
local_repository: ''
repository: 'https://git.gorinskat.nl/m038/intotheeast-com-content.git'
no_user: false
user: into-the-east-grav-sync
webhook: /_git-sync
webhook_enabled: 1
webhook_secret: '/RX{_*lU]dF&y_Pd!h+EZWjMP1{Np>$z>\%+G''Jo'
branch: main
logging: false
password: gitsync-def502005b5427cc6afd28ea66682788711e72b3e31bcb6bd302db4232e48a8783900ed76bf2cf891b3e4545dd925a5f5276fa683bf033797b5c6074f7ef0c520c455e34e27392be46615378e779cba61fe4a7f710fcbf157fb9709142794bce7d785e3738de84dd6887e0287f2923e96ae12ce446e4e61285a3ce48
sync:
direction: both
on_save: true
on_delete: true
on_media: true
cron_enable: false
cron_at: '0 12,23 * * *'
remote:
name: origin
branch: main
git:
author: gituser
message: '(Grav GitSync) Automatic Commit'
name: GitSync
email: mischa@gorinskat.nl
bin: git
ignore: ''
private_key: ''
-7
View File
@@ -1,7 +0,0 @@
<?php
// Auto-generated private secret. Do NOT commit to version control.
// Used for CSRF nonce signing and admin rate-limit hashing. Regenerate by
// deleting this file; the next request will write a new value.
return '7b82d740b30aafea06c98ee539ff5c2f1800cbd60f07754d131db7d80e687068';
-38
View File
@@ -1,38 +0,0 @@
# Production-only Grav config overrides.
#
# Deep-merged OVER the committed user/config/system.yaml via Grav's
# per-environment config mechanism: on the server this file is deployed to
# <webroot>/user/env/<hostname>/config/system.yaml
# and Grav's `environment://config` stream (keyed on the request hostname)
# layers it on top of `user://config`.
#
# These values are deliberately NOT in the committed system.yaml because they
# would break local development (see CLAUDE.md §1 — dev keeps twig.cache:false
# so theme edits take effect immediately). Prod is the only place they apply.
#
# Deploy with: make remote-apply-env-prod
# The user/env/ tree is outside the content repo's tracked folders, so it is
# NOT restored by content-push / git-sync / remote-fetch-content — re-run the
# target above after any fresh install.
twig:
cache: true
debug: false
auto_reload: false
# Compression / connection handling.
#
# This host is not FastCGI (no fastcgi_finish_request()), so Grav's shutdown
# "early connection close" falls back to emitting `Content-Encoding: identity`
# to ask the webserver not to compress. But Apache's mod_deflate compresses
# anyway and adds `Content-Encoding: gzip`, giving TWO conflicting headers —
# the browser can't decode the body and renders raw gzip bytes (a garbage
# page). Note: allow_webserver_gzip:true takes the SAME identity branch, so it
# does not help. The real fix is to disable the early-close path, so Grav never
# emits the bogus header and mod_deflate compresses cleanly (single header).
debugger:
shutdown:
close_connection: false
# Let the webserver own gzip; Grav does not compress or double-label.
cache:
gzip: false
allow_webserver_gzip: false