SecurityHeaders() (internal/middleware/middleware.go) sets HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, and Permissions-Policy, but no cache directives. Authenticated pages (source list/detail/logs, profile) can therefore be cached by browsers and intermediary proxies, potentially exposing webhook configuration and captured event data.
static assets served under /s are unaffected (they are safe to cache)
a test asserts the header is present on an authenticated page and absent/normal on static assets
Part of the road to 1.0 (see #33).
`SecurityHeaders()` (`internal/middleware/middleware.go`) sets HSTS, CSP, `X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy`, and `Permissions-Policy`, but no cache directives. Authenticated pages (source list/detail/logs, profile) can therefore be cached by browsers and intermediary proxies, potentially exposing webhook configuration and captured event data.
Definition of done:
- authenticated responses carry `Cache-Control: no-store` (and `Pragma: no-cache` for older intermediaries)
- static assets served under `/s` are unaffected (they are safe to cache)
- a test asserts the header is present on an authenticated page and absent/normal on static assets
clawbot
added this to the 1.0.0 milestone 2026-08-07 13:10:55 +02:00
Confine to internal/middleware/middleware.go (plus its test) and internal/server/routes.go only.
Add a NoCache() middleware to middleware.go that sets Cache-Control: no-store and Pragma: no-cache on every response it wraps, following the same constructor style as SecurityHeaders() / MaxBodySize() (returns a func(http.Handler) http.Handler).
Wire s.mw.NoCache() onto the dynamic app route groups in routes.go — the /pages, /user/{username}, /sources, and /source/{sourceID} groups (the same groups that already use CSRF()), placed adjacent to the existing CSRF() call for readability.
Do NOT apply it to the static file mount (/s), /metrics, /webhook/{uuid}, or /.well-known/healthcheck — those are not authenticated pages and static assets are safe to cache.
Definition of done:
authenticated pages (source list/detail/logs, profile, and the login page) carry Cache-Control: no-store
the static /s mount is not given no-store
a middleware unit test asserts NoCache() sets both headers
Gates and process:
make fmt; validate with docker build . (must exit 0; host Go 1.25 vs go.mod 1.26)
branch from main named issue-61-no-store; commit subject ends with (closes #61)
open a PR (base main) and comment on it with the diff summary and the docker build . result
no AI-assistant/tooling references anywhere
## Implementation instructions
Confine to `internal/middleware/middleware.go` (plus its test) and `internal/server/routes.go` only.
- Add a `NoCache()` middleware to `middleware.go` that sets `Cache-Control: no-store` and `Pragma: no-cache` on every response it wraps, following the same constructor style as `SecurityHeaders()` / `MaxBodySize()` (returns a `func(http.Handler) http.Handler`).
- Wire `s.mw.NoCache()` onto the dynamic app route groups in `routes.go` — the `/pages`, `/user/{username}`, `/sources`, and `/source/{sourceID}` groups (the same groups that already use `CSRF()`), placed adjacent to the existing `CSRF()` call for readability.
- Do NOT apply it to the static file mount (`/s`), `/metrics`, `/webhook/{uuid}`, or `/.well-known/healthcheck` — those are not authenticated pages and static assets are safe to cache.
Definition of done:
- authenticated pages (source list/detail/logs, profile, and the login page) carry `Cache-Control: no-store`
- the static `/s` mount is not given `no-store`
- a middleware unit test asserts `NoCache()` sets both headers
Gates and process:
- `make fmt`; validate with `docker build .` (must exit 0; host Go 1.25 vs go.mod 1.26)
- branch from `main` named `issue-61-no-store`; commit subject ends with ` (closes #61)`
- open a PR (base `main`) and comment on it with the diff summary and the `docker build .` result
- no AI-assistant/tooling references anywhere
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of the road to 1.0 (see #33).
SecurityHeaders()(internal/middleware/middleware.go) sets HSTS, CSP,X-Frame-Options,X-Content-Type-Options,Referrer-Policy, andPermissions-Policy, but no cache directives. Authenticated pages (source list/detail/logs, profile) can therefore be cached by browsers and intermediary proxies, potentially exposing webhook configuration and captured event data.Definition of done:
Cache-Control: no-store(andPragma: no-cachefor older intermediaries)/sare unaffected (they are safe to cache)Implementation instructions
Confine to
internal/middleware/middleware.go(plus its test) andinternal/server/routes.goonly.NoCache()middleware tomiddleware.gothat setsCache-Control: no-storeandPragma: no-cacheon every response it wraps, following the same constructor style asSecurityHeaders()/MaxBodySize()(returns afunc(http.Handler) http.Handler).s.mw.NoCache()onto the dynamic app route groups inroutes.go— the/pages,/user/{username},/sources, and/source/{sourceID}groups (the same groups that already useCSRF()), placed adjacent to the existingCSRF()call for readability./s),/metrics,/webhook/{uuid}, or/.well-known/healthcheck— those are not authenticated pages and static assets are safe to cache.Definition of done:
Cache-Control: no-store/smount is not givenno-storeNoCache()sets both headersGates and process:
make fmt; validate withdocker build .(must exit 0; host Go 1.25 vs go.mod 1.26)mainnamedissue-61-no-store; commit subject ends with(closes #61)main) and comment on it with the diff summary and thedocker build .result