一键导入
auth-flows
Detailed documentation of the 4 authentication systems, token lifecycle, middleware pipeline, session management, and RBAC authorization.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Detailed documentation of the 4 authentication systems, token lifecycle, middleware pipeline, session management, and RBAC authorization.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Complete module inventory of the Auth API project with file paths, dependencies, and architecture overview. Load this first in any new session.
Complete HTTP route structure with auth layers, middleware chains, rate limiting, and handler mappings for all API and GUI endpoints.
Documentation of the HTMX admin GUI including template rendering, session management, CRUD patterns, and the GUIHandler structure.
All 17 GORM database models with fields, relationships, indexes, and the entity relationship diagram for the Auth API.
Complete documentation of the email subsystem including template resolution, variable pipeline, rendering engines, SMTP config, and default templates.
| name | auth-flows |
| description | Detailed documentation of the 4 authentication systems, token lifecycle, middleware pipeline, session management, and RBAC authorization. |
| license | MIT |
The project has 4 independent authentication systems:
| System | Mechanism | Middleware File | Context Keys Set |
|---|---|---|---|
| User JWT | Bearer token | internal/middleware/auth.go | userID, appID, roles, sessionID |
| Admin API Key | Static env + DB keys | internal/middleware/admin_auth.go | auth_type = "admin" |
| App API Key | DB-backed per-app keys | internal/middleware/app_api_key.go | auth_type = "app" |
| Admin GUI Session | HTTP-only cookie + Redis | internal/middleware/gui_auth.go | admin_id, admin_username, admin_session_id |
Access Token:
ACCESS_TOKEN_EXPIRATION_MINUTES)AuthMiddleware() on every protected requestRefresh Token:
REFRESH_TOKEN_EXPIRATION_HOURS)POST /refresh-token to get a new access+refresh pairToken Blacklisting (Redis):
internal/middleware/auth.go)1. Extract "Authorization" header, strip "Bearer " prefix
2. Parse JWT via jwt.ParseToken()
3. Reject if TokenType is "refresh" (prevents refresh token misuse)
4. Check Redis: is this specific access token blacklisted?
5. Check Redis: are ALL tokens for this user blacklisted?
6. If claims.SessionID exists: check session still exists in Redis
7. Set context: userID, appID, roles, sessionID
1. POST /login with email + password
2. userHandler.Login -> userService.Login
3. Verify password with bcrypt
4. Check if 2FA is enabled for user
- If YES: return temp 2FA token, require POST /2fa/login-verify
- If NO: generate access+refresh tokens, create session, return tokens
5. On success: activity log "USER_LOGIN"
1. User logs in, gets temp 2FA token
2. POST /2fa/login-verify with temp token + code (TOTP/email/recovery)
OR POST /2fa/passkey/begin + /finish for passkey 2FA
3. Verify code against:
- TOTP: pquerna/otp library validation
- Email: 6-digit code stored in Redis (10 min TTL)
- Recovery: bcrypt-hashed codes stored in user record
- Passkey: WebAuthn assertion ceremony
4. On success: generate real access+refresh tokens, create session
1. GET /auth/{provider}/login -> redirect to OAuth provider
2. Provider redirects to GET /auth/{provider}/callback
3. Exchange code for tokens, fetch user profile
4. Find or create user (match by provider+provider_user_id+app_id)
5. Generate access+refresh tokens, create session
6. If 2FA enabled: same 2FA flow as above
1. POST /magic-link/request with email
2. Generate single-use token, store in Redis (10 min TTL)
3. Send email with magic link URL
4. POST /magic-link/verify with token
5. Validate token from Redis, delete after use
6. Generate access+refresh tokens, create session
1. POST /passkey/login/begin -> return WebAuthn challenge
2. Client performs assertion with authenticator
3. POST /passkey/login/finish with assertion response
4. Validate credential, look up user
5. Generate access+refresh tokens, create session
internal/middleware/admin_auth.go)1. Read X-Admin-API-Key header
2. Fast path: compare against ADMIN_API_KEY env var (constant-time)
3. Fallback: SHA-256 hash the key, look up in api_keys table
- Validate key_type == "admin"
- Async update last_used_at
4. Set context: auth_type = "admin"
ak_ + 24 random bytes base64-encodedinternal/admin/apikey_util.gointernal/middleware/app_api_key.go)1. Read X-App-API-Key header
2. Read app_id from context (set by AppIDMiddleware)
3. SHA-256 hash the key, look up in api_keys table
4. Validate key_type == "app"
5. Validate key.AppID matches context app_id (cross-app prevention)
6. Async update last_used_at
7. Set context: auth_type = "app"
internal/middleware/app_route_guard.go)Additional guard that ensures the :id URL parameter matches the X-App-ID header, preventing URL manipulation attacks on /app/:id/* routes.
internal/middleware/gui_auth.go)1. Read "admin_session" cookie
2. Call sessionValidator.ValidateSession(sessionID) -> *AdminAccount
3. If invalid: clear cookie, redirect to /gui/login
4. Set context: admin_id, admin_username, admin_session_id
1. POST /gui/login with username + password
2. accountService.Authenticate(username, password) via bcrypt
3. If 2FA enabled:
- Create pending 2FA session in Redis
- Redirect to /gui/2fa-verify
- POST /gui/2fa-verify with code
- Promote pending session to full session
4. If no 2FA:
- Create full session in Redis
- Set admin_session cookie (HttpOnly, SameSite=Strict, Secure)
internal/middleware/csrf.go)Safe methods (GET/HEAD/OPTIONS):
-> Generate CSRF token, store in context for template rendering
State-changing methods (POST/PUT/DELETE):
-> Read token from X-CSRF-Token header (HTMX) OR _csrf form field
-> Validate against session's stored token
-> 403 on mismatch
Permissions are resource:action pairs (e.g., user:read, settings:write).
internal/middleware/auth.go)1. Read userID and appID from context
2. Call rbacService.HasPermission(appID, userID, resource, action)
3. RBAC service checks Redis cache first, then DB
4. Cache key: rbac:{appID}:{userID}
5. Cache TTL: matches access token TTL
6. Returns 403 on failure
| Role | Permissions |
|---|---|
| admin | All permissions |
| member | Read + limited write |
| viewer | Read-only |
user, settings, log -- used with actions read, write, delete.
internal/session/service.go)Redis storage:
session:{appID}:{sessionID} -- hash with user_id, refresh_token, ip, user_agent, created_at, last_activeuser_sessions:{appID}:{userID} -- set of session IDsLifecycle:
internal/redis/redis.go)blacklist:access:{tokenHash} -- individual token blacklist (TTL = remaining token life)blacklist:user:{userID} -- user-wide blacklist (TTL = access token TTL)internal/middleware/app_id.go)1. Skip for /swagger, /admin, /gui paths
2. Read X-App-ID header
3. Fallback: app_id query parameter
4. Skip for /auth/*/callback (OAuth state carries app_id)
5. Parse as UUID, set in context
Default: 00000000-0000-0000-0000-000000000001
web/context_keys.go)type SessionValidator interface {
ValidateSession(sessionID string) (*models.AdminAccount, error)
GenerateCSRFToken(sessionID string) (string, error)
ValidateCSRFToken(sessionID, token string) bool
}
type ApiKeyValidator interface {
FindActiveKeyByHash(keyHash string) (*models.ApiKey, error)
UpdateApiKeyLastUsed(id uuid.UUID)
}
Load this skill when working on authentication, authorization, middleware, token handling, session management, or any security-related feature.