Tests / test (pull_request) Successful in 1m8s
The login page, failed logins, redirects, and rate-limit/error pages could be stored by the browser (Symfony's default 'no-cache, private' still permits storage — it only requires revalidation). Older Safari builds may then replay a stale pre-auth response on refresh, appearing to log the user back out, or show a previous session after logging in again. - SecurityHeadersListener: send strict anti-caching headers on non-2xx responses only (no-store/no-cache/must-revalidate/proxy-revalidate, max-age=0, s-maxage=0 + Pragma, Expires, Surrogate-Control, Vary: *). 2xx grants (already-authenticated / public access) are consumed by Caddy's forward_auth check and never reach the browser, and protected services' own cache headers must stay untouched. - templates/_script.html.twig: fetch() with cache: 'no-store'; follow redirects with location.replace() to keep the login page out of history and the back-forward cache. - docs/Caddyfile: reusable (preauth_no_store) snippet imported into every forward_auth block, using header_down so the guarantee holds at the edge (verified: replaces conflicting upstream values, leaves service responses alone). - tests: unit coverage for the listener and functional coverage for the full HTTP kernel (login/failure/redirect/rate-limit not cacheable; 200 grants untouched); asserts the rendered page carries the JS changes. - readme/CHANGELOG updates.