feat(security): add response security headers + make CI security gates real #19
Closed
admin
wants to merge 2 commits from
ci/security-headers-and-scanning into main
pull from: ci/security-headers-and-scanning
merge into: :main
:main
:fix/prod-restore-2026-09-29
:chore/design-conformance-20261104
:fix/source-bundle-20261104
:fix/prod-evidence-2026-09-29
:docs/deploy-runbook
:fix/keycloak-portal-trust-20261102
:fix/smoke-main-sha
:chore/optimize-pipelines
:chore/remove-stale-package-lock-20261101
:fix/trivy-skip-sbom-evidence-20261101
:fix/doctor-fixture-v3-20261101
:fix/next-16.4.1-20261031
:wip/asus-20261005/Documents_0pt-9cad5f9
:feat/import-dispatch-policy
:opt-vehiq-work-salvage-20260927/0pt-p060-p068_0pt-uncommitted-wip
:fix-chore/normalize-sax3l-ci-refs-20260925
:salvage/20260925/siax-arkiv/siax-work/0pt-feature/0pt-remove-noncompliant-scrapers
:salvage/20260925/siax-arkiv/siax-platforms-work/0pt-feat/p014-data-os-hardening
:salvage/20260925/siax-arkiv/siax-work/0pt-oai/devos-band29-0pt
:salvage/20260925/siax-arkiv/siax-work/0pt-stash-stash0
:feat/golden-standard-scaffold
:docs/coolify-deploy-hook-is-live-opus5
:docs/bi-canonical-stack-correction-opus5
:feat/p060-p068-ingestion-plane
:chore/siax-repo-v3-manifest
:feat/p014-data-os-hardening
:feat/p010-data-os-completion
:feat/siax-platforms-p0-data-os
:fix/coolify-app-id
:docs/repo-hygiene-v2-standard
:fix/honest-health-check
:docs/compliance-blockers-2026-08-11
:security/auth-gate-anonymous-api-routes
:fix/remove-vercel-deploy-target
:unify/github-main-2026-07-28
:docs/1p-egress-measurement-point
:foundation/hardening
Reference in New Issue
Block a user
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.
Summary
next.config.mjsnow sets HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and a same-origin CSP on every route. Previously the only header came from Vercel's platform default (HSTS) — nothing was set by the app itself, so it would have silently disappeared on cutover to Coolify/Traefik. Verified at runtime (curl -Iagainst a real production build), not just that the build compiles.security.yml/nightly.ymlnow actually fails the build on HIGH/CRITICAL findings (--exit-code 1) instead of the previous--exit-code 0(purely advisory, never blocked a merge).security.yml/trivyjob is currently RED. Verified locally against this repo's real dependency tree: 19 HIGH findings exist today inpnpm-lock.yaml— several in Next.js itself relating to middleware/auth bypass, information disclosure, and SSRF (plusnanoid,postcss,sharp). This is the fix working as intended (surfacing what--exit-code 0was hiding), not a regression this PR caused — but it needs a human decision on timing, especially given the sibling auth-gate PR #11's reliance onmiddleware.ts. Recommend triaging the Next.js bump as a fast, separate follow-up.services/scrapers/stays explicitly excluded from the scan (--skip-dirs) — that tree is a dated, attributed, account-owner keep-decision under active review in a separate thread (BACKLOG P3-3) and is out of scope here; not touched, not commented on beyond preserving the existing note.gitleaksjob added, full git history (--log-opts=--all), pinned + checksum-verified binary. Verified locally against this repo's actual history first (81 commits, no leaks) so this blocking gate doesn't open red on day one — confirmed green on the real Gitea run too.pnpm licenses list) as CI artifacts (informational,continue-on-error). Allactions/*pinned to commit SHA (were floating@v4tags) across every workflow file; Trivy/gitleaks pinned to specific released versions.cosignimage-signing explicitly not added — there's no container-registry publish step in this repo's CI to attach a signature to yet (Coolify builds directly from git); flagged as a real follow-up once that pipeline exists.permissions: contents: read+concurrencyadded everywhere it was missing. Pinned pnpm-store cache added toci.yml's quality job. RootCODEOWNERSadded. The "doctor step" part of P1-15 is deliberately left for the follow-up repo-hygiene PR, alongside thesiax:doctorscript it invokes (avoids referencing a script this PR doesn't contain).A real compatibility bug found and fixed mid-PR
actions/upload-artifact@v4(pinned SHA) failed on this Gitea Actions runner — verified by pushing and inspecting the real run.continue-on-errorkept it from breaking the build, but artifacts silently weren't being saved. Swapped tov3.2.2, re-pushed, re-verified: now succeeds. Left in as a code comment for the next person who hits this.Test plan
pnpm run typecheck/pnpm run test/pnpm run build— all pass.quality✅ (including the new pnpm-store cache step),gitleaks✅,license-inventory✅ (including artifact upload after the v3 fix),trivy❌ (expected — see above),security(ci.yml's advisory copy) ✅.Not merged
Per instructions. The red
trivyjob is expected and documented above — please read that note before assuming this PR is broken.🤖 Generated with Claude Code
Status: BLOCKED by branch protection. The red CI was genuine — and PR #26 has now cleared it.
Re-verified against
main=364b7643.1. The hard blocker (unchanged)
Five of the eight changed files are under
.gitea/workflows/(cd.yml,ci.yml,health-check.yml,nightly.yml,security.yml), which matchesprotected_file_patterns = ".gitea/workflows/**;.gitignore"onmain. That closes both the mergeAPI and direct push.
Worth noting for a possible split: three of the eight files are not protected —
next.config.mjs,CODEOWNERS, and.github/workflows/ci.yml(the pattern names.gitea/, not.github/). A PR carrying only those three would be mergeable today. That is Simon's call, notmine; I have not created one.
2. The red check was real, and is now fixed by something else
Security Scan (SIAX Cloud) / trivyfailed on headd6adad7c(jobs 11796 / 11825):This PR failed on its own new gate — it is the change that flips trivy from
--exit-code 0to--exit-code 1. So the failure was honest, not infrastructure: no ENOSPC, no sibling-containerDNS problem, no
workflow_dispatchstatus gap. The findings were realnext/nanoid/postcss/sharpCVEs.Measured today with the same tool and flags:
So once this branch is brought up to today's
main, its own blocking trivy gate passes. Thefailurestatus still shown here is from 2026-08-11 and is stale.Also note:
trivyis not instatus_check_contexts, so that red never gated anything anyway.Neither does the whole
Security Scan (SIAX Cloud)workflow, norCI (SIAX Cloud) / integration.Only
quality (push)andsecurity (push)gate — and both are green here.3. Not superseded — three independent content proofs against today's
maingit merge-tree --write-tree origin/main pr/19merges cleanly (exit 0) despite being 32 commitsbehind; landing set = 8 files, 221 insertions / 42 deletions, no reverts.
mergeable: falseinthe API is the same stale artifact as on PR #22 (
pull_request.status = 1,conflicted_files = NULL).4.
main's CHANGELOG already claims this work is done. It is not.CHANGELOG.mdonmain,[Unreleased]:and, two bullets down,
CODEOWNERSin the repo-hygiene list. Neither exists onmain. The onlyplace any of
Strict-Transport-Security/X-Frame-Options/Content-Security-Policyappears inthe entire tree is that CHANGELOG line:
It was written by
328f8a4 docs+chore: repo hygiene ..., a pure documentation commit. Anyonereading the CHANGELOG would close this PR as already-landed. It is not. (
node scripts/siax-doctor.mjsonmainagrees:[FAIL] P1-15 CODEOWNERS exists -- missing: CODEOWNERS.)What Simon has to do: decide whether to relax
protected_file_patternsonmainfor onemerge, or to land the three unprotected files first and keep the workflow half waiting. Either
way, this branch should be brought up to today's
mainso CI re-runs and the stale red clears.Generated with Claude Code
Pull request closed