All checks were successful
check / check (push) Successful in 35s
Add SecurityHeaders() to internal/middleware and register it in the
global middleware stack so every response - dashboard, embedded static
assets, healthchecks, JSON API, and metrics - carries the six response
headers required by REPO_POLICIES.md before tagging 1.0:
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; script-src 'none';
style-src 'self'; img-src 'self';
font-src 'none'; connect-src 'none';
object-src 'none'; base-uri 'none';
form-action 'none'; frame-ancestors 'none'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: no-referrer
Permissions-Policy: unused browser features denied
The dashboard template ships no JavaScript, no inline styles, no inline
event handlers and no images, and its only subresource is the embedded
stylesheet at /s/css/tailwind.min.css, so the policy needs neither
unsafe-inline nor unsafe-eval. frame-ancestors 'none' is the primary
anti-framing control with X-Frame-Options as the legacy fallback.
HSTS is emitted unconditionally rather than gated on r.TLS, because the
service runs behind a TLS-terminating proxy and the browser must still
enforce HTTPS end to end.
The headers are set before the request reaches the next handler, so
they are present on error responses too, including recovered panics and
request timeouts.
Tests cover each header's exact value, the CSP's required and forbidden
directives, presence on a 500 response, and a render of the real
dashboard through the middleware confirming the page still references
its stylesheet.