mirror of
https://github.com/azaion/admin.git
synced 2026-06-21 11:51:09 +00:00
a77b3f8a59
Refreshes _docs/02_document/ to reflect the cycle-2 auth-modernization
+ CMMC hardening landings (AZ-531..AZ-538). Authoritative source for
the ripple set is ripple_log_cycle2.md.
Covered:
- architecture.md (section 1 rewritten, ADRs 6-9 added)
- data_model.md (sessions, audit_events, user columns, migrations)
- system-flows.md (F1 rewritten; F11-F17 added; F2/F7/F9 minor)
- module-layout.md (cycle-2 sub-component table)
- diagrams/flows/flow_login.md (dual-token + MFA)
- components/{01_data_layer,03_auth_and_security,05_admin_api}
- modules/ (12 new, 8 modified — full Argon2id/ES256/MFA/refresh
/mission/session/audit/jwks rollup)
- tests/{blackbox,security,traceability-matrix}
Step 13 (Update Docs) output for cycle 2.
Co-authored-by: Cursor <cursoragent@cursor.com>
3.5 KiB
3.5 KiB
Module: Azaion.Common.Requests.MfaRequests
Purpose
Request and response DTOs for the MFA enrollment / login surface introduced in cycle 2 by AZ-534 (Epic AZ-529, TOTP-based 2FA at credential login). All DTOs live in a single MfaRequests.cs file.
Public Interface
MfaEnrollRequest
| Property | Type | Description |
|---|---|---|
Password |
string |
Re-auth required for enrollment (defends a stolen access token from silently flipping MFA on). |
MfaEnrollResponse
| Property | Type | Description |
|---|---|---|
Secret |
string |
32-char base32 TOTP shared secret. Shown once. |
OtpAuthUrl |
string |
Standard otpauth:// URL the authenticator app consumes. |
QrPngBase64 |
string |
PNG encoding of OtpAuthUrl (base64). UI inlines as data:image/png;base64,…. |
RecoveryCodes |
string[] |
10 single-use base32 codes (each ≥12 chars). Stored hashed in users.mfa_recovery_codes; the plaintext list is unrecoverable after this response. |
MfaConfirmRequest
| Property | Type | Description |
|---|---|---|
Code |
string |
TOTP code that validates the enrolled secret. On success users.mfa_enabled flips to true. |
MfaDisableRequest
| Property | Type | Description |
|---|---|---|
Password |
string |
Re-auth (same defence as enroll). |
Code |
string |
A valid TOTP code (recovery codes are NOT accepted here — disable should be deliberate). |
MfaRequiredResponse
Returned by POST /login when the user has MFA enabled instead of LoginResponse.
| Property | Type | Description |
|---|---|---|
MfaRequired |
bool |
Always true. Lets dual-shape clients branch on a single field. |
MfaToken |
string |
Short-lived (5 min) ES256 JWT with audience azaion-mfa-step2. Carry to /login/mfa. |
ExpiresIn |
int |
Step-1 token TTL in seconds (300). |
MfaLoginRequest
| Property | Type | Description |
|---|---|---|
MfaToken |
string |
The step-1 token from MfaRequiredResponse. |
Code |
string |
A valid TOTP code OR a single-use recovery code. |
Internal Logic
None — pure data classes.
Dependencies
None.
Consumers
Program.cs/users/me/mfa/enroll—MfaEnrollRequest→MfaEnrollResponse.Program.cs/users/me/mfa/confirm—MfaConfirmRequest.Program.cs/users/me/mfa/disable—MfaDisableRequest.Program.cs/login— returnsMfaRequiredResponsewhenuser.MfaEnabled.Program.cs/login/mfa—MfaLoginRequest→LoginResponse.MfaService— consumes every request type and produces the responses.
Data Models
None directly.
Configuration
None.
External Integrations
None — but MfaToken validation depends on IJwtSigningKeyProvider (ES256 keys) and JwtConfig.Issuer.
Security
Passwordfields carry plaintext credentials; HTTPS is mandatory in Production (AZ-538 HSTS / HTTPS-redirect).SecretandRecoveryCodesare returned ONCE inMfaEnrollResponse— the client must show them immediately and never send them back.MfaTokenis narrowly-scoped (audienceazaion-mfa-step2) so it cannot be used against any non-MFA endpoint even if leaked.
Tests
e2e/Azaion.E2E/Tests/MfaEnrollmentTests.cs— AC-1 (enroll shape), AC-2 (confirm), AC-5 (disable), AC-6 (encrypted at rest).e2e/Azaion.E2E/Tests/MfaLoginTests.cs— AC-3 (two-step + AMR claim), AC-4 (recovery code single-use).