Auth is the project's primary security boundary. This package is built to an
enterprise baseline and scanned on every push (govulncheck + gosec).
- JWT: HS256 only (alg-confusion rejected), expiry required, issuer pinned
(
togo),iat/nbfset. Forged-secret, expired, unexpiring, andalg=nonetokens are rejected (seeauth_test.go). - Secrets: fail-closed in production —
AUTH_SECRET(>= 32 bytes) is required; dev generates an ephemeral random secret (no hardcoded credential). - Passwords: bcrypt (cost 10), min length policy (
AUTH_MIN_PASSWORD, default 8), 72-byte cap enforced. Constant-time login (dummy-hash compare on unknown email) prevents user enumeration. Registration returns generic errors (no enumeration). - Brute force: per-IP rate limiting on login/register (10 / 5 min).
- CSRF: double-submit cookie +
X-CSRF-Tokenfor cookie-authed mutations (bearer/API requests are exempt). - CORS: credential-aware, allowlisted via
CORS_ORIGINS(default: same-origin). - Sessions / SSR:
HttpOnly+SameSite=Laxsession cookie (Securein prod, viaCOOKIE_SECURE), token TTL (AUTH_TTL_HOURS), real logout that clears it. Token is read from the bearer header or the session cookie (SSR-friendly). - SQL injection: the ORM parameterizes values and validates column/operator/ ORDER BY identifiers against an allowlist.
- RBAC / multi-guard: roles + permissions on the identity;
RequireRole/RequirePermissionmiddleware; named guards.
AUTH_SECRET, AUTH_DRIVER (base|supabase), AUTH_TTL_HOURS, AUTH_MIN_PASSWORD,
CORS_ORIGINS, COOKIE_SECURE, APP_ENV, SUPABASE_URL, SUPABASE_ANON_KEY.
Report vulnerabilities privately via a GitHub security advisory on this repo.