e6d889b895044c4e757a481fa5bf4df8b33d64bf
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e6d889b895 |
feat(security): add response security headers + make CI security gates real
Security Scan (SIAX Cloud) / gitleaks (push) Failing after 21s
CI (SIAX Cloud) / security (push) Successful in 27s
Security Scan (SIAX Cloud) / trivy (push) Failing after 47s
CI (SIAX Cloud) / quality (push) Successful in 3m28s
Security Scan (SIAX Cloud) / license-inventory (push) Successful in 8m59s
BACKLOG P0-13: next.config.mjs now sets HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and a same-origin CSP on every route. Previously the only security 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 -I against a production build), not just that the build compiles. BACKLOG P0-16: Trivy in security.yml/nightly.yml now actually fails the build on HIGH/CRITICAL findings (`--exit-code 1`) instead of the previous `--exit-code 0` (purely advisory, never blocked a merge). Verified locally against this repo's real dependency tree -- 19 HIGH findings currently exist in pnpm-lock.yaml (next.js, postcss, sharp, nanoid), several in next.js itself relating to middleware/auth bypass. See PR description: this is expected to turn the security.yml `trivy` job red until those are bumped in a follow-up -- that's the fix working as intended, not a regression, but it needs a human decision on timing given the sibling auth-gate PR (#11). `services/scrapers/` stays explicitly excluded from the scan (--skip-dirs) -- that tree is a dated, deliberate keep-decision under active review in a separate thread (BACKLOG P3-3) and is out of scope here. BACKLOG P0-19: dedicated gitleaks job added to security.yml, 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. BACKLOG P1-14: SBOM (CycloneDX) + license inventory (`pnpm licenses list`) generated as informational, non-blocking build artifacts. actions/checkout, actions/setup-node, actions/cache, actions/upload-artifact all pinned to commit SHA (was floating @v4 tags) across every workflow file, Trivy/gitleaks pinned to specific released versions instead of floating install scripts. cosign image-signing explicitly NOT added -- there is no container-registry publish step in this repo's CI to attach a signature to yet (Coolify builds directly from git); flagging as a real follow-up once that pipeline exists. BACKLOG P1-15: explicit `permissions: contents: read` + `concurrency` added to every workflow that lacked them (only .github/workflows/ci.yml already had concurrency). Pinned pnpm-store cache added to ci.yml's quality job. Root CODEOWNERS added (`* @sax3l`) so Gitea has someone to assign once required-approvals is turned on (separate repo-settings change, not a file change). The "doctor step" part of P1-15 is added in the follow-up repo- hygiene PR, alongside the `siax:doctor` script it invokes. |
||
|
|
bcf285f057 |
merge: unify GitHub main into Gitea main (0pt)
Merges github/main (6 commits: 17-bug audit fix, CI quality gate,
.env.example + .gitignore fix, missing platform clients + registry
services, docs accuracy overhaul) into gitea/main (8 commits: Iceberg
write boundary + live ST0RE verification, lakehouse mapping routes,
Waves 1-4 foundational hardening).
16 conflicts. Both sides had independently written the four
src/clients/*.ts and the two registry services, so those are combined
rather than picked:
- st0re-client.ts: GitHub's endpoint wins on evidence. POST goes to
/v1/st0re/artifacts/register, not /v1/st0re/artifacts -- verified in
sax3l/st0re src/api/routes/artifacts.ts, where the bare path is a
GET-only list route. Gitea's URL normalisation, error-body text and
mock kept.
- n0d-client.ts: field is `status`, not `state`, with N0D's real 13-state
union -- verified in sax3l/n0d packages/schemas/n0d.job.schema.json,
which says explicitly not to add "succeeded". Gitea's mock echo,
URL normalisation and error-body text kept.
- cl0ud-client.ts: Gitea's fail-closed HTTP normalisation kept (a 200
with no `decision` reads as "deny", not as a silent allow). GitHub's
PolicyDecision/PolicyDecisionValue naming kept; PolicyResult retained
as an alias.
- aud0-client.ts: permissive union of both input types (optional
payload/metadata/correlation_id), GitHub's echo return, Gitea's URL
normalisation and error-body text, plus a JSON-parse fallback so a
successful POST with an empty body does not throw.
- dataset-service.ts / source-service.ts: GitHub's record/DTO split and
event naming (0pt.source_created / 0pt.create_source, which the merged
docs already reference) plus Gitea's name validation, description /
created_by fields and actor_id derivation. List filters are the union.
- lakehouse mapping routes: GitHub's shared lakehouse-mapping-registry
singletons (without which every write 400'd "mapping not found") AND
Gitea's Zod parseBody validation. Both, not either.
- src/types/source.ts, src/types/dataset.ts: unions of both vocabularies;
GitHub's `access` legal-sourcing field kept.
- .env.example: GitHub's audited inventory plus Gitea's Zitadel /
AUTH_ENFORCE block.
- CLAUDE.md, docs/ICEBERG_WRITE_BOUNDARY.md: GitHub's corrections kept,
Gitea's live-verification kept and marked as superseding the
"would 400 outright" finding (Gitea had already added the required
X-Tenant-Id/X-Actor-Id headers).
- pnpm-lock.yaml: regenerated with pnpm 9.15.9, not merged.
Also corrects CLAUDE.md's claim that the banned services/scrapers stack
was "since removed" -- the removal PR is open, not merged, and this
branch inherits that code from Gitea main. Nothing here resurrects,
extends or re-wires any of it; services/scrapers/ is byte-identical to
Gitea main.
Verified on the merged tree: typecheck (src/ + tests/) clean;
17 test files, 121 passed, 1 skipped (the realinfra test skipping
honestly on ST0RE HTTP 401), 0 failures. Gitea main baseline was the
same 121/1; GitHub main baseline could not even `pnpm install`
("packages field missing or empty") -- Gitea's pnpm-workspace.yaml fix
resolves that. Whole-repo `typecheck:app` reports 9 errors, an identical
set to Gitea main's baseline, so it is advisory in both CI workflows
rather than deleted. Lint: 16 problems, identical to Gitea baseline.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
5b725994ad |
ci: add typecheck/lint/test quality gate (#1)
* ci: add typecheck/lint/test quality gate (was deploying unguarded) * ci: make quality gate functional — typecheck + test, drop unwired lint The lint step ran `pnpm run lint` = `eslint .`, but eslint is not a dependency of this repo (absent from pnpm-lock.yaml), so the step failed on command-not-found and, since a failed step aborts the job, prevented typecheck from ever running — a red, useless gate on every PR. Replace it with the vitest suite (`pnpm run test`, 88 passing) so the gate matches the PR's stated 'typecheck + test' intent and is green on a clean tree. Typecheck now uses `pnpm run typecheck` (carries the `-p tsconfig.json` the script defines). Wiring eslint is left as a separate decision. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> |