Support opt-in MFA per browser client with authoritative enrollment checks
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 40s
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 40s
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
This commit is contained in:
parent
e1e292919a
commit
ac8ed65203
14 changed files with 298 additions and 12 deletions
59
docs/optional-mfa.md
Normal file
59
docs/optional-mfa.md
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Optional MFA for browser clients
|
||||
|
||||
Set `mfaOptional: true` on a reviewed browser registration to allow AAL1 login
|
||||
when privacyIDEA authoritatively reports no active enrolled factor. Once an
|
||||
active factor exists, require AAL2. A previous AAL1 session cannot satisfy that
|
||||
requirement. Explicit AAL2 requests still require MFA. Lookup errors deny login
|
||||
through the existing account-recovery path. This setting overrides only the
|
||||
provider `requireForAll` default for that client.
|
||||
|
||||
Do not combine this with `mfaRequired`. In particular, `mfaRequired: false`
|
||||
means unconditional AAL1 and is not an opt-in enrollment policy. Unchanged
|
||||
registrations keep their existing policy. Service clients reject mfaOptional.
|
||||
|
||||
The adapter sends the raw privacyIDEA JWT in Authorization, filters active
|
||||
factors before pagination, and requires a successful, complete response before
|
||||
concluding there is no active factor. The credential must have realm-scoped
|
||||
administrative tokenlist permission: a user-role token only lists its own factors
|
||||
regardless of the requested username. Never replace it with a self-service JWT.
|
||||
See the [provider API](https://privacyidea.readthedocs.io/en/stable/modules/api/token.html).
|
||||
|
||||
## Deployment gate — not yet enabled
|
||||
|
||||
Live inspection on 2026-09-13 found `requireForAll: true`; both the demo-company
|
||||
and account-portal registrations inherit it. Configured token-list credentials
|
||||
return HTTP 401, so enabling this setting now would replace the OTP prompt with
|
||||
a lookup failure. No live policy has been changed.
|
||||
|
||||
Credential owner: railiance-platform / OpenBao, route
|
||||
`net-kingdom-privacyidea-admin-token`. Its concrete delivery and renewal contract
|
||||
is unpublished (`resolvable: false`). Obtain an owner-approved realm-scoped
|
||||
factor-read credential through the native custody path, with renewal and
|
||||
revocation ownership. Do not put credentials in chat, arguments, work records,
|
||||
or config examples. The older refresh-pi-token-live.sh needs review before use.
|
||||
|
||||
After credential delivery:
|
||||
|
||||
1. Verify the deployed provider accepts the raw JWT and returns authoritative
|
||||
count/tokens results for controlled accounts with and without a factor.
|
||||
Confirm realm/resolver mapping and administrative tokenlist scope, including
|
||||
visibility of another user's factor; an empty list alone is not proof.
|
||||
2. Verify self-service at https://pink-account.coulomb.social: password login,
|
||||
TOTP enrollment with possession confirmation before activation, cancellation,
|
||||
and factor removal/recovery. This user-facing flow is not yet verified.
|
||||
3. Build and pin the reviewed issuer image. Migrate only the exact
|
||||
vergabe-demo-company registration to mfaOptional using the owner CAS rollout
|
||||
lane; keep unrelated registrations and Secret bytes intact. The current
|
||||
vergabe-client-rollout.py intentionally refuses registration differences and
|
||||
needs an explicit migration before this policy can be applied.
|
||||
4. Resolve account-portal access for unenrolled users without weakening privileged
|
||||
access. Review portal policy and self-service permissions before expanding the
|
||||
optional setting to this shared client. Add the verified enrollment link to
|
||||
account management once that flow works.
|
||||
5. Verify fresh password-only admission without a factor, enrollment confirmation,
|
||||
then OTP enforcement (including reuse of an old AAL1 session). Verify explicit
|
||||
AAL2 still challenges, lookup failures recover without issuing a code, logout
|
||||
permits identity switching, and other clients retain their policies.
|
||||
|
||||
Rollback: restore the exact previous client registration and image pin via CAS.
|
||||
This restores mandatory MFA for the demo client; it is not password-only access.
|
||||
Loading…
Add table
Add a link
Reference in a new issue