The threat model is a public SaaS on the open internet, run by a small team. Everything below ships enabled — none of it is a checklist left to the buyer.
- Argon2id (64 MiB, 3 iterations) for passwords; timing-safe comparisons everywhere they matter.
- Server-side sessions (database-backed),
SameSite=Lax,HttpOnly,Securein production. Users list their signed-in devices and revoke them; a password change invalidates other sessions. - One-time tokens (verification, reset, magic link, invitations) are stored as SHA-256 hashes, single-use, expiring. A database leak exposes no usable link.
- TOTP two-factor with one-shot recovery codes, enforced on every sign-in path, anti-replay.
- CSRF on every mutating request (
gorilla/csrf+ a header check on multipart uploads). - Rate limiting per IP and per account on login, signup, reset, contact.
- No account enumeration: signup, login and reset answer neutrally whether the account exists or not — and the tests assert it.
- Security headers: HSTS, CSP, X-Content-Type-Options, X-Frame-Options.
X-Forwarded-Foris honoured only fromTRUSTED_PROXIES.
Row-level: every business table carries organization_id, middleware
resolves the org through the caller's membership, and outsiders get a
404 indistinguishable from a nonexistent org. Cross-tenant probes are part
of the integration suite.
internal/safehttp is the only client allowed to fetch configurable URLs
(OIDC issuers, S3 endpoints, error collectors): https-only by default,
private and link-local ranges blocked at dial time, redirects re-checked,
response sizes capped. SSRF is handled where it starts — in the client —
not in each caller.
Type sniffed server-side against a short allowlist — SVG refused, it executes script when served inline — size-capped, stored under server-built keys, served by the app so buckets stay private.
CI pins every action to a full commit SHA, starts jobs from zero
permissions, runs govulncheck, Trivy and npm audit, and CodeQL analyses
Go and TypeScript on every push. Releases ship checksums.txt, a
CycloneDX SBOM, SLSA provenance and a keyless Cosign signature.
The details, the verification commands and the disclosure policy live in
the repository's SECURITY.md.