ADR-006: Dual Enforcement Model (Site + FE Groups, Strictest Wins)
- Status
-
Accepted
- Date
-
2026-03-14
- Decision-makers
-
Sebastian Mendel
Context
nr-passkeys-be uses per-group enforcement on be_groups with four levels:
Off, Encourage, Required, Enforced. For frontend users, there is an additional
dimension: site-level enforcement, since TYPO3 can serve multiple sites with
different security requirements.
Decision
Dual enforcement: per ``fe_groups`` + per site configuration. Strictest wins.
Enforcement levels (reusing EnforcementLevel from nr-passkeys-be):
- Off: No passkey prompts or requirements.
- Encourage: Dismissible enrollment banner after login.
- Required: Enrollment interstitial after login. Skippable during grace period. After grace period, passkey enrollment is mandatory but password fallback remains.
- Enforced: Mandatory passkey enrollment, no skip. Password login blocked for users who have at least one passkey registered.
Resolution algorithm:
$effectiveLevel = max(
$siteEnforcementLevel->severity(),
$strictestGroupLevel->severity()
);
Site-level enforcement is set in config/sites/*/settings.yaml:
nr_passkeys_fe:
enforcement: 'encourage'
Group-level enforcement is set on fe_groups.passkey_enforcement.
Grace period is per-group (fe_groups.passkey_grace_period_days), tracked per-user
(fe_users.passkey_grace_period_start).
Consequences
Positive:
- Site-level gives integrators a global switch for the whole portal
- Group-level gives granular control for privileged user groups
- Consistent with nr-passkeys-be enforcement model
EnforcementLevelResolvedEventallows custom business logic to override
Negative:
- Two places to configure = potential admin confusion
- "Strictest wins" may surprise admins (group Required + site Off = Required)
Mitigation:
- Admin module shows effective enforcement per user with source breakdown
- Documentation with examples: "Site Off + Group Required = Required for that group"
FrontendEnforcementStatusDTO exposes bothsiteLevelandgroupLevelfor transparency
Alternatives Considered
Per-group only (Option A): No way to enforce site-wide without touching every group.
Per-site only (Option B): No granular control. Cannot require passkeys for admins but not regular users.