
Require another proof when it matters
Add a second proof to sign-in for the accounts that need it. Wildo connects the policy, enrollment, challenge and recovery-code flow, so people are offered methods the application will actually accept.
You choose which factors qualify, whether MFA is required and how enrollment is introduced. A passkey can satisfy the policy without an extra challenge when you allow that.
Example — Protect privileged accounts
An administrator signs in with a password and confirms an authenticator code. Members can have a different policy, while recovery codes provide a way back when an enrolled device is unavailable.
For engineers
Choose acceptable factors, not just an MFA switch
The factor must be enabled as well as accepted by the MFA policy. Put both declarations under userTypes.<type>.auth in backend-api/src/saas-config.backend.ts; changing only acceptableMFAMethods does not enable an authenticator.
Example: require an authenticator app after password sign-in. existingAdminAuth is the application’s existing complete policy. Import AuthMethod from @wildo-ai/saas-models and merge this result back into that user type.
const adminAuth = {
...existingAdminAuth,
authMethodsEnabled: {
...existingAdminAuth.authMethodsEnabled,
[AuthMethod.PASSWORD]: true,
[AuthMethod.TOTP]: true,
},
mfaPolicy: {
...existingAdminAuth.mfaPolicy,
requireMFA: true,
requireStrongMFA: true,
acceptableMFAMethods: [AuthMethod.TOTP],
enrollmentGracePeriodDays: 0,
passkeyExemptFromMFA: false,
},
};
This example preserves other enabled first factors. Review those deliberately if the application must require password specifically. TOTP is a second factor, not an alternative first-factor login. The account must enroll it through the standard setup flow; enabling the method does not create a secret for anyone.
| Setting | Effect |
|---|---|
requireMFA | Requires additional proof for the applicable sign-in flow |
requireStrongMFA | Excludes factors the engine does not classify as strong |
acceptableMFAMethods | Restricts which enabled second factors qualify |
enrollmentGracePeriodDays | Controls the enrollment transition; zero provides no grace interval |
passkeyExemptFromMFA | Controls whether a passkey avoids another challenge |
Decide what an external login must demonstrate
The same user type can receive social logins, whose evidence is assessed separately from native challenges. Set externalAssuranceEnforcement: ExternalAssuranceEnforcement.STRICT inside its mfaPolicy to refuse missing or insufficient required assurance; import the enum from @wildo-ai/saas-models. Omission means warn and audit, not strict refusal.
The TOTP-specific policy above cannot be satisfied merely by a provider saying “MFA happened.” Generic upstream MFA does not establish that a particular local factor was used. A configured enterprise OIDC connection instead delegates MFA enforcement to the customer’s IdP. It still must pass identity and token validation. Organization overrides can tighten the applicable policy; they cannot weaken strict enforcement.
Enrollment and verification are different steps
The TOTP setup service creates a secret, a QR-code URI and recovery codes. The person must prove a generated code before setup is marked verified. Recovery codes are shown for the person to retain; stored recovery values are hashed. TOTP acceptance atomically claims its absolute time step in Redis. Recovery-code consumption uses a conditional credential update, so a concurrent second consumption cannot also succeed.
The engine uses resolveAcceptedSecondFactorMethods for both offered and accepted methods. This prevents a flow from asking someone to enroll a factor that the next challenge refuses. In the native sign-in flow, the orchestrator carries the first-factor state into the second-factor step and issues the session after the required proof completes.
Registration completion is also distinct from a returning user’s login challenge. It can complete with an already-enrolled factor or under configured enrollment grace; otherwise it directs the person to enrollment.
Plan the recovery route
An enrolled TOTP code and an unused recovery code are checked through the same verification service. A used recovery code is removed from the stored set. The standard flow supplies enrollment and challenge interfaces; the application still decides which account types require protection and which factors are appropriate for their users.