Hi @sclark1
You are trying to configure MFA settings to change a factor to "preferred" using the Auth0 Management API. You have found that you can set webauthn-roaming, but this is not sufficient for your use case.
To set a preferred MFA factor via the Management API, you need to use the /api/v2/users/{id}/authentication-methods endpoint to manage user authentication methods, or use a Post-Login Action to challenge users with a specific factor. The Management API does not have a direct "preferred factor" setting; instead, you control MFA behavior through factor enrollment, challenge logic, and user metadata.
Root Cause:
The Auth0 Management API does not expose a direct "preferred MFA factor" setting. Instead, MFA preference is controlled through:
- User enrollment — Which factors the user has enrolled in
- Challenge logic — Which factor is presented during login (via Actions or Rules)
- User metadata — Storing preference information that your application logic can read
Solution: Set Preferred MFA Factor Using User Metadata and Post-Login Actions
Step 1: Store the Preferred Factor in User Metadata
Use the Management API to add a preferred factor to the user's user_metadata:
PATCH /api/v2/users/{user_id}
Content-Type: application/json
{
"user_metadata": {
"preferred_mfa_factor": "otp"
}
}
Supported factor types:
otp — One-Time Password (Google Authenticator, Microsoft Authenticator, etc.)
sms — SMS text message
email — Email verification code
webauthn — WebAuthn/FIDO2 device
phone — Phone call
Step 2: Create a Post-Login Action to Challenge with the Preferred Factor
Create a Post-Login Action that reads the preferred factor from user metadata and challenges the user with that factor:
exports.onExecutePostLogin = async (event, api) => {
// Check if user has a preferred MFA factor set
const preferredFactor = event.user.user_metadata?.preferred_mfa_factor;
// Only proceed if user is enrolled in MFA
if (!event.user.enrolledFactors || event.user.enrolledFactors.length === 0) {
return;
}
// If user has a preferred factor, challenge with it
if (preferredFactor) {
console.log(`Challenging user with preferred factor: ${preferredFactor}`);
try {
api.authentication.challengeWith({
type: preferredFactor
});
} catch (error) {
console.error(`Failed to challenge with ${preferredFactor}:`, error);
// Fall back to any available factor
api.multifactor.enable('any', { allowRememberBrowser: false });
}
} else {
// No preference set; allow user to choose or use default
api.multifactor.enable('any', { allowRememberBrowser: false });
}
};
Step 3: Deploy and Add the Action to Your Login Flow
- Navigate to Actions → Library → Deploy Action
- Go to Actions → Flows → Login
- Add your action to the flow
- Save the flow
Step 4: Allow Users to Set Their Preferred Factor
In your application, provide a settings page where users can select their preferred MFA factor:
// Example: Update user's preferred MFA factor via Management API
async function setPreferredMfaFactor(userId, factor) {
const response = await fetch(`https://${AUTH0_DOMAIN}/api/v2/users/${userId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${managementApiToken}`
},
body: JSON.stringify({
user_metadata: {
preferred_mfa_factor: factor
}
})
});
return response.json();
}
Alternative: Use app_metadata for Admin-Controlled Preferences
If you want to control preferences as an admin (not user-controlled), use app_metadata instead:
PATCH /api/v2/users/{user_id}
Content-Type: application/json
{
"app_metadata": {
"preferred_mfa_factor": "otp"
}
}
Then update your Action to read from app_metadata:
const preferredFactor = event.user.app_metadata?.preferred_mfa_factor;
Managing WebAuthn Roaming Factors
If you specifically want to configure webauthn-roaming factors, use the authentication methods endpoint:
GET /api/v2/users/{user_id}/authentication-methods
This returns all enrolled factors for the user. You can then use api.authentication.challengeWith({ type: 'webauthn' }) in your Post-Login Action.
This approach allows you to set and enforce a preferred MFA factor for each user while maintaining flexibility for fallback options.
Kind Regards,
Nik