Security posture
Cookies & CSRF
The only cookies in the system are the auth service’s refresh_token cookie (httpOnly, SameSite=Lax, Secure when COOKIE_SECURE=true). CSRF exposure is bounded by construction:
- Cookie-bearing endpoints are POST-only (
/auth/refresh,/auth/logout, and login which sets the cookie). No state-changing GET exists. - JSON-only bodies: cross-site form posts send
text/plain/application/x-www-form-urlencoded; handlers decode JSON bodies, so a forged form submit yields a binding error before any effect. - SameSite=Lax blocks the cookie on cross-site POST navigations outright.
- The access token is never in a cookie (see TOKEN_POLICY.md), so forged top-level requests cannot authorize API calls beyond the cookie endpoints.
If an endpoint ever needs to accept cookie auth with side effects from non-JSON content types, add an Origin/Referer allowlist check against TRUSTED_DOMAINS at the gateway first — that’s the trigger, noted here.
Headers
Every Go service sets helmet-parity headers via platform.SecurityHeaders. The nginx edge adds a complete CSP, COOP/COEP/CORP, granular Permissions-Policy, two-year preload HSTS on TLS, and a strict referrer policy. Scalar is version-pinned with SRI; Cabinet Grotesk is bundled locally.
Scanning
gosecruns inside golangci-lint on every PR.- Trivy vulnerability and Kubernetes config scans, default and project Semgrep rules, gitleaks, SBOM generation, and dependency-license policy run in CI.
Secrets
- Secrets accept
NAME_FILEand rotating key rings; production templates use External Secrets/Vault and API-server KMS encryption. - Identity headers are bound by the shared internal secret — a leaked network position alone grants nothing (CONTRACTS.md).
Kubernetes network boundary
infra/k8s/security/network-policies.yaml starts with default-deny. Before exposing the stack, label only the ingress-controller namespace with networking.platform/ingress=allowed; that namespace can reach gateway and web pods, while service, data-store, DNS, and approved public egress remain separately scoped.
See SECRETS.md, THREAT_MODEL.md, PENTEST_CHECKLIST.md, and the root SECURITY.md responsible-disclosure policy.