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_ATTEMPTSAUTH_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
- Catalog synced with DB at startup (
Catalog) application/authzresolves permissions (TTL cache; invalidate on mutation)- Middleware:
RequirePermission(HTTP + GoUI routepermissionfield)
Role CRUD: /api/v1/rbac/... and panel /dashboard/rbac/*.
Related code
internal/application/authinternal/application/authzinternal/adapters/http/handler/auth_*.gointernal/adapters/http/middleware/auth.gointernal/adapters/goui/controller_public_auth.gopkg/rbac