| [ Web Proxy ] |
| Viewing: https://developers.cloudflare.com/cloudflare-one/access-controls/policies/mfa-requirements/ | [Back] [Original] |
Cloudflare Access supports two methods of enforcing multi-factor authentication (MFA):
For SSH connections to infrastructure applications, Access also supports independent MFA with PIV and FIDO2 keys.
You can require that users log in with specific MFA methods provided by their identity provider. For example, you can create rules that only allow users to reach a given application if they authenticate with a security key through their IdP.
IdP-based MFA enforcement is only available with the following identity providers:
To enforce an IdP MFA requirement on an application:
In the Cloudflare dashboard , go to Zero Trust > Access controls > Applications.
Find the application for which you want to enforce MFA and select Configure. Alternatively, create a new application.
Go to Policies.
If your application already has a policy containing an identity requirement, find it and select Configure.
Note
The policy should contain an Include rule that uses identity-based selectors. For example, the Include rule could allow users who are part of a rule group, email domain, or identity provider group.
Add the following rule to the policy:
| Rule type | Selector | Value |
|---|---|---|
| Require | Authentication method | mfa - multiple-factor authentication |
Save the policy.
Important
If the user fails to present the required MFA method, Cloudflare Access rejects the user, even if they successfully log in to the identity provider with an alternative method.
When users authenticate with their identity provider, the IdP shares their username with Cloudflare Access. Access writes that value into the JSON Web Token (JWT) generated for the user.
Certain identity providers also share the MFA method presented by the user. Access can add these values into the JWT. For example, if the user authenticated with their password and a security key, the IdP can send a confirmation to Cloudflare Access. Access then stores that method in the JWT issued to the user.
Cloudflare Access follows RFC 8176 , Authentication Method Reference Values, to define authentication methods.
Independent MFA prompts users for a second factor directly in Access. This allows you to enforce MFA requirements without relying on your IdP's MFA configuration.
You can configure MFA requirements at three levels:
| Level | Description |
|---|---|
| Organization | Enforce MFA by default for all applications in your account. |
| Application | Require or turn off MFA for a specific application. |
| Policy | Require or turn off MFA for users who match a specific policy. |
MFA settings use this precedence: Policy > Application > Organization.
Before you configure independent MFA on applications or policies, you must turn on independent MFA at the organization level.
Tip
At the organization level, you can also restrict which authenticators can be enrolled using AAGUIDs and [skip independent MFA when the identity provider already performed MFA](/cloudflare-one/access-controls/access-settings/independent-mfa/#use-identity-provider-mfa.
Each application has three MFA options:
| Option | Behavior |
|---|---|
| Respect global enforcement setting | Uses the organization-level MFA configuration. If MFA is required globally, users must complete MFA. If MFA is not required globally, users are not prompted. This is the default. |
| Custom MFA settings | Overrides the organization setting with application-specific allowed authenticators and session duration. |
| Disable MFA | Users are not prompted for independent MFA when accessing this application, even if MFA is required globally. |
To configure MFA for an application:
To configure MFA for an infrastructure application, refer to Infrastructure applications.
Each policy has the same three MFA options described in Configure independent MFA for an application. Policy-level settings override application-level settings.
To configure MFA for an infrastructure application policy, refer to Infrastructure applications.
The MFA session duration determines how long a successful MFA authentication remains valid. After the MFA session expires, the user must complete MFA again on their next Cloudflare Access login in addition to completing IdP authentication. You can require users to complete MFA on each Access login or set a custom duration. MFA session durations are only checked during the login flow and do not affect a user's existing session.
Access checks MFA sessions from most specific to least specific:
To require MFA every time a user logs in to an application, set the authentication duration to Require every login. This prevents Access from caching a successful MFA session.
To configure this for an application via the API, first send a GET request to retrieve the full application configuration, then send a PUT request with the complete application body including the updated mfa_config. Set session_duration to "0m":
curl --request PUT \
https://api.cloudflare.com/client/v4/accounts/{account_id}/access/apps/{app_id} \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data '{
"mfa_config": {
"mfa_disabled": false,
"session_duration": "0m"
}
}'
Consider the following configuration:
flowchart TD
subgraph org["Organization"]
orgSettings["**Apply global MFA settings by default**, <br/>**MFA methods**: Authenticator app + Security key, <br/>**Authentication duration**: 24 hours"]
end
subgraph appA["Application A"]
appASettings["**Respect global enforcement setting**<br/>(inherits organization settings)"]
subgraph policies["Policies"]
policy1["Policy 1<br/>**Custom MFA settings**,<br/>**MFA methods**: Security keys only,<br/>**Authentication duration**: 1 hour"]
policy2["Policy 2<br/>**Disable MFA**"]
end
end
subgraph appB["Application B"]
appBSettings["**Disable MFA**"]
end
orgSettings --> appASettings
orgSettings -.->|"overridden"| appBSettings
appASettings -.->|"overridden by"| policy1
appASettings -.->|"overridden by"| policy2
In this example:
Infrastructure applications that use SSH support two infrastructure-only MFA methods. piv_key uses an enrolled Personal Identity Verification (PIV) key. ssh_fido2_key uses an enrolled FIDO2 key. Neither method applies to other Access application types or browser WebAuthn authentication.
You can configure MFA for infrastructure apps at the application level or at the policy level.
Select PIV key, FIDO2 key, or both when configuring custom MFA. The corresponding API arrays are ["piv_key"], ["ssh_fido2_key"], and ["piv_key", "ssh_fido2_key"].
Note
PIV and FIDO2 key authenticators only work with infrastructure applications.
Non-infrastructure applications: If PIV and FIDO2 keys are the only allowed MFA methods in your global settings, users cannot log in to non-infrastructure applications. To fix this, add at least one other authenticator type to your global settings (for example, TOTP or biometrics), or configure custom MFA settings for non-infrastructure applications.
Infrastructure applications: If MFA is globally required but your global settings do not include the infrastructure authenticator you want to use, users cannot access infrastructure applications that require MFA. To fix this, add the authenticator to your global MFA settings, or disable MFA for the specific application or policy.
Dashboard
API
To update MFA settings for an infrastructure application, first send a GET request to retrieve the full application configuration, then send a PUT request with the complete application body including the mfa_config object. The PUT request must contain all fields returned by the GET to avoid overwriting existing settings.
curl --request PUT \
https://api.cloudflare.com/client/v4/accounts/{account_id}/access/apps/{app_id} \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data '{
"mfa_config": {
"mfa_disabled": false,
"session_duration": "12h",
"allowed_authenticators": ["piv_key", "ssh_fido2_key"]
}
}'| Field | Type | Description |
|---|---|---|
mfa_disabled |
Boolean | If true, MFA is not required for this application, even if global settings enforce MFA. |
session_duration |
String | Duration before the user must re-authenticate with MFA (for example, 30m, 1h, 24h). Set to 0m to require MFA on every SSH connection. |
allowed_authenticators |
Array | Use ["piv_key"], ["ssh_fido2_key"], or ["piv_key", "ssh_fido2_key"]. |
You can set different MFA requirements for different SSH usernames by configuring MFA at the policy level. Policy-level MFA settings override application-level settings.
Dashboard
API
To update MFA settings for a policy, first send a GET request to retrieve the full policy configuration, then send a PUT request with the complete policy body including the mfa_config object. The mfa_config object uses the same fields as the application-level configuration.
curl --request PUT \
https://api.cloudflare.com/client/v4/accounts/{account_id}/access/policies/{policy_id} \
--header "Authorization: Bearer <API_TOKEN>" \
--header "Content-Type: application/json" \
--data '{
"name": "Require MFA for root",
"decision": "allow",
"include": [
{
"email": {
"email": "jdoe@company.com"
}
}
],
"mfa_config": {
"mfa_disabled": false,
"session_duration": "1h",
"allowed_authenticators": ["piv_key", "ssh_fido2_key"]
},
"connection_rules": {
"ssh": {
"usernames": ["root"],
"allow_email_alias": false
}
}
}'
The MFA session duration determines how long users can open new SSH connections without another MFA prompt. Set the duration to 0m to require MFA for every new connection. Expiration does not terminate an active connection.
MFA sessions are bound to the user's device. If a user switches to a different device, they must re-authenticate regardless of the remaining session duration.
Session duration is evaluated in the following order:
When a user matches multiple policies that each define a session duration, Access uses the shortest duration across all matching policies.
MFA configuration is evaluated from most specific to least specific: policy > application > organization.
| Organization MFA | Application MFA | Policy MFA | Result |
|---|---|---|---|
| Required | Required | Required | MFA required |
| Required | Required | Disabled | MFA not required (policy wins) |
| Required | Disabled | (not set) | MFA not required (application wins) |
| Required | (not set) | (not set) | MFA required (organization setting applies) |
Organization-level MFA must be enabled for users to enroll PIV keys. Explicit settings at a lower level (policy or application) override higher levels. If no explicit setting exists at a level, the next higher level applies.
| Web Proxy Viewer | New URL | Original Page |