Contents

Surfaces

Surface Session Prefix
GoUI HttpOnly cookie (access / refresh) /auth/*, /dashboard/*, /goui/ws
API Authorization: Bearer <access> /api/v1/auth/*, protected /api/v1/*
Live events Bearer, ?access_token=, or cookie /api/v1/ws

The same application/auth and application/user use cases are used throughout.

Panel notification bell and mobile clients receive inbox.updated from the same /api/v1/ws hub; GoUI WS is for UI patch/toast only.

JWT

Token Purpose Configuration
Access Short-lived API/panel access AUTH_ACCESS_TOKEN_TTL
Refresh Renewal with rotation AUTH_REFRESH_TOKEN_TTL
  • Issuer / audience: AUTH_JWT_ISSUER, AUTH_JWT_AUDIENCE
  • Secret: AUTH_JWT_SECRET (production ≥ 32 characters)
  • Refresh reuse detection → related session family revoked
  • Logout → refresh revoked

API endpoints (/api/v1/auth)

Method Path Notes
POST /login Email + password (+ Turnstile)
POST /refresh New access/refresh
POST /logout
POST /forgot-password
POST /reset-password
POST /verify-email
POST /resend-verification
GET /oauth/:provider google | github
GET /oauth/:provider/callback
POST /change-password Auth required
POST /mfa/setup | /mfa/enable | /mfa/disable Auth required
GET /permissions Current session permissions

Web counterparts: /auth/login, /auth/register, /auth/forgot-password, … and OAuth callbacks via utility_routes.

Brute-force protection

LoginGuard: attempt limits by email and IP.

  • AUTH_MAX_LOGIN_ATTEMPTS
  • AUTH_LOCKOUT_DURATION
  • Infrastructure: infrastructure/security (IP rate limiter)

MFA (TOTP)

RFC 6238. Secret field encryption: AUTH_MFA_ENCRYPTION_KEY (openssl rand -base64 32).

Flow: setup → user adds to authenticator → enable (code verification) → second step at login.

Email tokens

Verification / password reset: single-use, SHA-256 hashed, time-limited.

  • AUTH_VERIFY_TOKEN_TTL, AUTH_RESET_TOKEN_TTL
  • Link base: AUTH_EMAIL_LINK_BASE_URL
  • Without SMTP: LogMailer (log only)

OAuth

Provider is disabled when env vars are empty.

Variable Description
OAUTH_CALLBACK_BASE_URL API callback base
OAUTH_GOOGLE_* / OAUTH_GITHUB_* Client id/secret

Web callback example: http://localhost:8080/auth/oauth/google/callback
API callback example: http://localhost:8080/api/v1/auth/oauth/google/callback

Behavior: find-or-create (user role).

Turnstile

Public forms (login, register, contact, etc.): SEC_TURNSTILE_SITE_KEY / SEC_TURNSTILE_SECRET_KEY.
Empty in development → verification disabled. Required in production.

RBAC

Permission catalog (pkg/rbac)

Permission Meaning
users:list User list
users:read Another user's profile
users:activate Account activation
users:delete / users:restore Soft-delete / restore
users:role:change Role assignment
users:email:change:any Another user's email
uploads:create File upload
rbac:manage Role/permission management
notifications:send Single/bulk notification
notifications:settings SMS/payment settings selection
payments:charge 3DS charge
payments:list Transaction list
audit:list Audit records
contacts:list Contact messages

System roles (seed): admin (all), user (ownership-focused).

How it works

  1. Catalog synced with DB at startup (Catalog)
  2. application/authz resolves permissions (TTL cache; invalidate on mutation)
  3. Middleware: RequirePermission (HTTP + GoUI route permission field)

Role CRUD: /api/v1/rbac/... and panel /dashboard/rbac/*.

Related code

  • internal/application/auth
  • internal/application/authz
  • internal/adapters/http/handler/auth_*.go
  • internal/adapters/http/middleware/auth.go
  • internal/adapters/goui/controller_public_auth.go
  • pkg/rbac