9d43e4b113
CRITICAL — Authentication & Access: - TOTP MFA: otpauth-based, QR setup UI, sign-in flow integration, admin disable override, /account/security self-service page - Session Timeouts: 8h absolute (maxAge), 30min idle (updateAge) - Failed Auth Logging: Pino warn for invalid password/user/totp, info for successful login, audit entries for all auth events - Concurrent Session Limit: ActiveSession model, oldest-kick strategy, max 3 per user (configurable in SystemSettings) CRITICAL — HTTP Security: - HSTS: max-age=31536000; includeSubDomains - CSP: script/style/img/font/connect-src with Gemini/OpenAI whitelist - X-XSS-Protection: 0 (CSP replaces legacy) - Auth page cache: no-store, no-cache, must-revalidate - Rate Limiting: 100/15min general API, 5/15min auth (Map-based) Data Protection: - XSS Sanitization: DOMPurify on comment bodies - autocomplete="new-password" on all password/secret fields - SameSite=Strict on all cookies (Credentials-only, no OAuth) - File Upload Magic Bytes validation (PNG/JPEG/WebP/GIF/BMP/TIFF) Logging & Monitoring: - Login/Logout audit entries (Auth entityType) - External API call logging with timing (OpenAI, Gemini) - Input validation failure logging at warn level - Concurrent session tracking in ActiveSession table Documentation: - docs/security-architecture.md (11 sections) - docs/sdlc.md (CI pipeline, security gates, incident response) - .gitea/PULL_REQUEST_TEMPLATE.md (security checklist) Schema: User.totpSecret/totpEnabled, SystemSettings.sessionMaxAge/ sessionIdleTimeout/maxConcurrentSessions, ActiveSession model Tests: 310 engine + 37 staffing pass. TypeScript clean. Co-Authored-By: claude-flow <ruv@ruv.net>
6.1 KiB
6.1 KiB
Security Architecture — CapaKraken
Version: 1.0 | Date: 2026-03-27
1. Authentication
- Auth.js v5 (NextAuth) with Credentials provider
- Password hashing: Argon2id via
@node-rs/argon2(memory cost 65536, time cost 3) - Multi-Factor Authentication: TOTP (RFC 6238) via
otpauthlibrary- Configurable per user (enable/disable via admin or self-service)
- 30-second window, SHA-1, 6-digit codes with 1-step tolerance
- Rate limiting: 5 login attempts per 15 minutes per email address (in-memory sliding window)
- Session strategy: JWT with server-side validation
- Absolute timeout: 8 hours (configurable via
sessionMaxAge) - Idle timeout: 30 minutes (configurable via
sessionIdleTimeout)
- Absolute timeout: 8 hours (configurable via
- Concurrent session limit: configurable
maxConcurrentSessions(default 3), kick-oldest strategy - Login/logout audit: all authentication events (success, failure, rate-limit, invalid TOTP, logout) are recorded in the audit log
2. Authorization
Role-Based Access Control (RBAC)
Five-level role hierarchy:
| Role | Level | Capabilities |
|---|---|---|
| ADMIN | 5 | Full system access, user management, system settings |
| MANAGER | 4 | Project management, resource allocation, vacation approval |
| CONTROLLER | 3 | Financial views, budget management, reporting |
| USER | 2 | Self-service (own vacations, own resource profile) |
| VIEWER | 1 | Read-only access to permitted areas |
Per-User Permission Overrides
permissionOverridesJSONB field on User modelresolvePermissions(role, overrides)computes effective permissionsrequirePermission(ctx, key)enforced on every tRPC procedure- Granular
PermissionKeyenum covering all domain actions
tRPC Middleware Stack
publicProcedure
-> protectedProcedure (requires authenticated session)
-> controllerProcedure (ADMIN + MANAGER + CONTROLLER)
-> managerProcedure (ADMIN + MANAGER)
-> adminProcedure (ADMIN only)
3. Data Protection
Database Security
- PostgreSQL with TLS in production
- Prisma ORM: parameterized queries by default — no SQL injection risk
- Database not exposed to the internet (Docker internal network only)
- All monetary values stored as integer cents (no floating-point precision issues)
Data at Rest
- Passwords: Argon2id hash (never stored in plaintext)
- TOTP secrets: stored in DB (encrypted at-rest via PostgreSQL TDE when available)
- API keys (Azure OpenAI, Gemini, SMTP): stored in
SystemSettingstable, accessible only to ADMIN role
Anonymization
- Configurable global anonymization for VIEWER role
- Resource names, emails replaced with deterministic pseudonyms (seeded hash)
- Anonymization domain and mode configurable in SystemSettings
4. Session Management
- Server-side JWT with
SameSite=Strictcookies httpOnlycookies prevent XSS-based session theftsecureflag enforced in production (HTTPS only)- CSRF protection via Auth.js built-in CSRF token
- Configurable session timeouts (absolute + idle) via SystemSettings
- Active session registry with concurrent session limit enforcement
5. Input Validation
- Zod schemas on every tRPC procedure input
- Strict TypeScript (
strict: true,exactOptionalPropertyTypes: true) - Blueprint dynamic fields validated at runtime against stored Zod schema definitions
- File uploads validated by:
- MIME type whitelist (
image/png,image/jpeg,image/webp,image/tiff,image/bmp) - Size limit (10 MB client-side, 4 MB server-side after compression)
- Magic byte verification (actual file content matched against declared MIME)
- MIME type whitelist (
6. Audit Logging
Activity History System
- Centralized
createAuditEntry()function (fire-and-forget, never blocks) - Covers 29+ of 36 tRPC routers
- Logged fields:
entityType,entityId,action,userId,changes(JSONB with before/after/diff),source,summary - Authentication events: login success/failure, logout, rate limiting, MFA failures
External API Call Logging
- All OpenAI/Azure/Gemini API calls logged via
loggedAiCall()wrapper - Structured Pino logs:
{ provider, model, promptLength, responseTimeMs } - Failed calls logged at
warnlevel with error details
tRPC Request Logging
- Every tRPC call logged with request ID, user ID, path, duration
- Slow calls (>500ms) logged at
warnlevel
7. HTTP Security Headers
Configured in next.config.ts:
| Header | Value |
|---|---|
| Strict-Transport-Security | max-age=63072000; includeSubDomains; preload |
| Content-Security-Policy | Restrictive CSP with nonce-based script-src |
| X-Frame-Options | DENY |
| X-Content-Type-Options | nosniff |
| X-XSS-Protection | 1; mode=block |
| Referrer-Policy | strict-origin-when-cross-origin |
| Permissions-Policy | Camera, microphone, geolocation disabled |
8. Rate Limiting
- Per-IP rate limiting: via middleware on all API routes
- Per-user rate limiting: configurable per-procedure
- Auth-specific rate limiting: 5 attempts / 15 min per email (in-memory sliding window)
- AI API call rate limits: upstream provider limits surfaced as user-friendly errors
9. Error Handling
- Sentry integration for production error tracking
- Pino structured logging (JSON in production, pretty-print in development)
- tRPC errors mapped to appropriate HTTP status codes
- AI API errors translated to human-readable messages via
parseAiError()/parseGeminiError() - Internal errors never leak stack traces to the client
10. Dependency Security
- Dependabot configured for automated dependency updates
pnpm auditas part of CI pipeline- Lockfile integrity verified on install
11. Network Architecture
Browser -> Next.js (port 3100) -> tRPC -> Prisma -> PostgreSQL (port 5433)
-> Redis (port 6380, SSE pub/sub)
-> Azure OpenAI / Gemini (external HTTPS)
-> SMTP (email notifications)
- PostgreSQL and Redis accessible only within Docker network
- External API calls (AI, SMTP) over TLS
- No direct database access from the internet