mirror of
https://github.com/azaion/admin.git
synced 2026-06-21 14:11:10 +00:00
[AZ-529] [AZ-530] Cycle-2 documentation refresh
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>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
# 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` — returns `MfaRequiredResponse` when `user.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
|
||||
- `Password` fields carry plaintext credentials; HTTPS is mandatory in Production (AZ-538 HSTS / HTTPS-redirect).
|
||||
- `Secret` and `RecoveryCodes` are returned ONCE in `MfaEnrollResponse` — the client must show them immediately and never send them back.
|
||||
- `MfaToken` is narrowly-scoped (audience `azaion-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).
|
||||
Reference in New Issue
Block a user