Docs / Reference
OWASP ASVS L2
Implementation map for the highest-gap controls hardened in this tree. Not a certification claim — evidence of engineering against ASVS 5.0 Level 2 and OWASP API Security Top 10.
| Control ID | Area | What shipped |
|---|---|---|
| V4.1.1 / V4.1.3 · API1:2023 | Authz | POST …/public/preview-token requires authenticated mutate role; verify stays public. Opt-in host.publicAbac denies public content reads with ABAC_DENIED receipt + abac.denied audit (assets/GraphQL out of slice; off by default). |
| V4.2.2 · API2:2023 | CSRF | Double-submit HMAC CSRF on admin//api/me/preview-token mint for session-cookie requests; pure Bearer clients skip CSRF; session+Bearer still enforces. |
| V11.1.4 · API4:2023 | Rate limits | Existing per-caller/category limits; responses now expose X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (+ Retry-After on 429). |
| V14.4.1–V14.4.3 · API8:2023 | Secure headers | Existing nosniff / DENY / Referrer / CSP / Permissions-Policy; added Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Resource-Policy (same-origin, cross-origin on public/GraphQL). |
| V5.1 / V12.1.1 · API3:2023 / API4:2023 | Input validation | JSON bodies capped at 1 MiB (413 PAYLOAD_TOO_LARGE); preview-token body fields length-bounded via TypeBox. |
| V2.3.1 / V14.1.3 · API8:2023 | Secret handling | Fail-closed resolvePreviewSigningSecret / resolveHmacSigningSecret; removed hardcoded edgecms_*_secret fallbacks; no API-key reuse as HMAC material. |
Checks
bun test --isolate \
apps/api/src/tests/auth/secrets.test.ts \
apps/api/src/tests/auth/csrf.middleware.test.ts \
apps/api/src/tests/auth/authorization.test.ts \
apps/api/src/tests/auth/rate-limit.middleware.test.ts \
apps/api/src/tests/main.test.tsSee also Authentication and access and Operations and security.