Skip to main content
Policy-based MFA allows you to configure MFA requirements for certain high value actions, while allowing other actions to be performed without additional verification. You can use this to enable various use cases, like:
  • Require MFA for transactions larger than 1000 USDC
  • Require MFA for withdrawals, or on specific actions

How it works

Policy-based MFA combines user authentication with server-side transaction authorization to provide selective MFA enforcement:
  • Users enroll in MFA on their wallets for high-security protection
  • Define policies that specify which transactions are considered “safe” (e.g., USDC transfers under 1000)
  • An authorization key (controlled by your server) is added as a signer on the user’s wallet with the policy attached
  • Transactions that satisfy the policy are signed by your authorization key without prompting the user for MFA
  • Transactions outside the policy (e.g., larger amounts, different tokens) cannot be signed with the authorization key due to the policy, and require the user to sign which prompts MFA
This approach ensures users are always protected by MFA while reducing friction for routine, low-risk operations that meet your defined criteria.
1

Enable MFA for your app

First, enable MFA in the Privy Dashboard by navigating to Dashboard → Authentication → MFA and enabling your preferred MFA method(s).
You can enable SMS, TOTP (authenticator apps), or passkey-based MFA depending on your security requirements.
2

Enroll user in MFA

Once MFA is enabled, prompt your users to enroll in MFA. You can use Privy’s default UI or build a custom enrollment flow.
Once a user enrolls in MFA, it will remain enabled even if you disable MFA for your app. Users must manually disable MFA on their wallets if they wish to remove it.
Using default UI (recommended):
Custom SMS enrollment:
Learn more about MFA enrollment.
3

Create a policy to bypass MFA

Create a policy that defines which transactions can be executed without MFA. For example, allow USDC transfers under 1000 USDC without MFA.Policies can also be created in the Dashboard. When creating via the Dashboard, you’ll receive a policy ID that you can reference in your code.Alternatively, you can create a policy programmatically using the NodeJS SDK:
This policy allows transactions to the USDC contract with transfer amounts up to 1000 USDC. Transactions that satisfy this policy can be signed without MFA. Save the policy.id as you’ll need it to attach the policy to a signer in the next step.Learn more about creating policies.
4

Add a signer to the wallet

Create an authorization key in the Dashboard, then add it as a signer to the user’s wallet with the policy you created:1. Create an authorization key:Go to the Dashboard and create a new authorization key. Save the private key securely.2. Add the signer to the wallet:
Learn more about adding signers.
5

Route transactions through the appropriate endpoint

On your server, create an endpoint to send transactions using your authorization key:
On the client, route transactions based on whether they satisfy the policy:
Transactions that satisfy the policy (USDC transfers under 1000) are signed by your authorization key without prompting the user for MFA. All other transactions require MFA.

Summary

With policy-based MFA, you can:
  • Enable MFA for additional security on user wallets
  • Create policies that define transaction limits and conditions
  • Add signers with scoped permissions to execute policy-approved transactions
  • Route transactions based on whether they satisfy policy conditions, requiring MFA only when necessary
This approach provides a balance between security and user experience, reducing friction for transactions within policy limits while maintaining strong protection for transactions outside those limits.