docs: update documentation for passkey MFA feature
- Add V002/V003 migrations and VendorAuthPolicy classes to CLAUDE.md - Document MFA & passkey enforcement model in config CLAUDE.md - Mark passkey MFA design spec as Implemented Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,24 @@
|
||||
- Org roles: `owner` -> `server:admin` + `tenant:manage`, `operator` -> `server:operator`, `viewer` -> `server:viewer`
|
||||
- `saas-vendor` global role created by bootstrap Phase 12 and always assigned to the admin user — has `platform:admin` + all tenant scopes
|
||||
- Custom `JwtDecoder` in `SecurityConfig.java` — ES384 algorithm, `at+jwt` token type, split issuer-uri (string validation) / jwk-set-uri (Docker-internal fetch), audience validation (`https://api.cameleer.local`)
|
||||
- Logto Custom JWT (Phase 7b in bootstrap) injects a `roles` claim into access tokens based on org roles and global roles — this makes role data available to the server without Logto-specific code
|
||||
- Logto Custom JWT (Phase 7b in bootstrap) injects claims into access tokens: `roles` (org role mapping), `mfa_enrolled` (true if TOTP or WebAuthn factor), `passkey_enrolled` (true if WebAuthn factor), `mfa_method_preference` (from user custom data)
|
||||
|
||||
## MFA & Passkey enforcement
|
||||
|
||||
Two independent policy domains — **no inheritance**, vendor and tenant policies are separate scopes:
|
||||
|
||||
| Policy | Scope | Who it affects | Stored in |
|
||||
|--------|-------|---------------|-----------|
|
||||
| **Vendor auth policy** | Platform logins (`/api/vendor/**`, `/api/portal/**`) | Tenant admins | `vendor_auth_policy` table (single-row) |
|
||||
| **Tenant auth policy** | Org user logins (`/api/tenant/**`) | Org members | `tenants.settings` JSONB (`mfaMode`, `passkeyEnabled`, `passkeyMode`) |
|
||||
|
||||
- `MfaEnforcementFilter` (after `BearerTokenAuthenticationFilter`) checks JWT claims `mfa_enrolled` and `passkey_enrolled` against effective policy
|
||||
- Error codes: `APP_MFA_REQUIRED`, `APP_PASSKEY_REQUIRED` (returned via `X-Cameleer-Error` header)
|
||||
- Exempt routes: `/api/tenant/mfa/`, `/api/config`, `/api/me`, `/api/onboarding`, `/api/vendor/auth-policy`, `/api/tenant/auth-settings`
|
||||
- Backward-compatible: legacy `mfaRequired: true` in settings treated as `mfaMode: "required"`
|
||||
- Policy settings: `mfa_mode` (off/optional/required), `passkey_enabled` (bool), `passkey_mode` (optional/preferred/required)
|
||||
- Passkey registration only via Logto Experience API during sign-in (Approach A: Logto-native WebAuthn)
|
||||
- Passkey management (list/rename/delete) via Logto Management API through SaaS backend endpoints
|
||||
|
||||
## Auth routing by persona
|
||||
|
||||
|
||||
Reference in New Issue
Block a user