# Architect — F-028 Security hardening ## Feature F-028 introduces rate limiting, audit log, and admin MFA enrollment gate. ## Design ### Module boundaries Create `project/src/modules/security/` with domain/application/infrastructure/api/tests. The module owns an in-memory rate limiter and audit log table. ### Data model Add migration `021_security.js`: - `security_audit_log`: id, actor_id uuid nullable, action text, target text, metadata jsonb, created_at. ### Behavior - `RateLimiter` per-key sliding window (in-memory for v1). - `AuditLogger.log(actor, action, target, metadata)` writes row. - Admin login gate: existing `login` route checks `security_admin_mfa` flag; MFA enrollment required for admin login. ### API - `GET /admin/mfa/status` returns whether current admin has MFA enrolled. - `POST /admin/mfa/enroll` admin-only flips the flag. ## Acceptance trace - Rate limit above threshold -> HTTP 429. - Admin login without MFA -> blocked. - Admin mutation -> audit log row.