forcedotcom/sf-skills6 files

Experience UI Bundle Mfa Configure

Configure Multi-Factor Authentication (MFA) for Salesforce Experience Site users. TRIGGER when: user wants to enable MFA on a community, enforce two-factor authentication for portal users, add MFA to a React Experience Site / Web App, configure ForceTwoFactor permission, create MFA permission sets for external users, or troubleshoot MFA not appearing on login. Also triggers on: MFA community, two-factor portal, ForceTwoFactor permission set, MFA Experience Cloud, MFA React site, identity verification community, MFA experience site, ForceTwoFactor permissionset-meta.xml, MFA permissionset-meta.xml. DO NOT TRIGGER when: configuring org-wide MFA for internal users (that's Setup > Identity Verification), building custom login UI components (use experience-ui-bundle-frontend-generate), or generating generic permission sets without MFA context (use platform-permission-set-generate).

Specification
Skill ID
forcedotcom/sf-skills/experience-ui-bundle-mfa-configure
Publisher
forcedotcom
Repository
sf-skills
Installs
0
Files
6
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

forcedotcom/sf-skills/experience-ui-bundle-mfa-configureInstalls these files
  • SKILL.md
  • assets/API_Enabled_For_Community.permissionset-meta.xml
  • assets/MFA_Required_For_Community.permissionset-meta.xml
  • references/branding.md
  • references/setup.md
  • references/social-login.md

What this skill tells the agent

Enabling MFA on Experience Sites

Enable Multi-Factor Authentication for Experience Site (Community) users by deploying the correct permission sets and verifying the platform-handled MFA challenge flow.

Scope

In scope:

  • Deploying ForceTwoFactor permission set for community users
  • Deploying ApiEnabled permission set (required for post-login API calls)
  • Assigning permission sets to community users
  • Troubleshooting MFA not appearing on login
  • Customizing MFA/login page branding via NetworkBranding metadata

Out of scope — delegate elsewhere:

  • Building custom login UI → experience-ui-bundle-frontend-generate
  • Creating generic permission sets → platform-permission-set-generate
  • Assigning permission sets (if already deployed) → dx-org-permission-set-assign
  • Deploying metadata to org → platform-metadata-deploy
  • Org-wide MFA for internal Salesforce users → Setup > Identity Verification (not a skill)

Prerequisites

Before using this skill, ensure the following are already in place:

PrerequisiteWhy
Experience Cloud site deployed and activeMFA applies to community login — no site means no login flow to protect
Community users exist (or will self-register)Permission sets are assigned to community users; the site must have a community-enabled profile
Customer Community or Customer Community Login license enabledRequired for community user profiles — without it, user creation and profile deployment will fail
Network/Site published at least onceThe site must be reachable at its URL for login + MFA challenge to appear
Note: This skill does NOT handle org setup, license provisioning, or Experience Cloud site creation. If these prerequisites are missing, set them up first via Setup > Digital Experiences > All Sites > New, or deploy your site's base app bundle.

Required Inputs

Gather before acting:

InputHow to determine
Target orgOrg alias for sf CLI commands
Site nameExperience Site (Network) name — resolve via SELECT Id, Name FROM Network (see Step 1); this is the site/Network name, NOT the uiBundles/ app name
Community usersWhich users or profiles to assign MFA to

Critical Domain Knowledge

These facts are non-obvious and frequently cause confusion:

FactDetail
No custom UI neededPlatform renders the MFA challenge page — no React/LWC component required
ForceTwoFactor permissionThe ONLY way to enforce MFA for community users at login
Org Identity Verification checkboxDoes NOT enforce MFA for community/portal users — only for internal users
vforcesite domainMFA challenge page is always served from the underlying Force.com Site domain — this is expected
Always deploy ApiEnabledReact Experience Sites make post-login REST/Connect API calls (sdk.graphql, sdk.fetch); without ApiEnabled they fail with API_DISABLED_FOR_ORG
Social Login / SSO is separate from MFAReact sites render configured Auth Providers via the built-in Social Login component (shipped in 264) — driven by Auth Provider setup, not by the MFA permission sets. See references/social-login.md.
Login-page branding works for React sitesSince 264, the NetworkBranding "Login & Registration" section is shown in Setup for Site Containers, so logo/color/footer can be customized in the UI — Metadata API still works too.

Workflow

Step 1: Resolve the target site (Network)

These are React Experience Sites, so both permission sets are always deployed — ForceTwoFactor (enforces MFA) and ApiEnabled (React sites make post-login API calls).

Resolve the Experience Site's real name and Id from the org — do not assume the uiBundles/ app folder name is the site name. They are frequently different, and the site name must come from the org (the deploy target), not the local project. <site-name> and <NETWORK_ID> below come from here:

sf data query --target-org <org-alias> \
  --query "SELECT Id, Name FROM Network" --json
  • One site → use its Name as <site-name> and Id as <NETWORK_ID>.
  • Multiple sites → ask the user which one (show the names).
  • Zero sites → the site isn't deployed yet; stop and tell the user (see Prerequisites).

Step 2: Generate permission set files

First, detect the project's source directory:

jq -r '.packageDirectories[0].path + "/main/default"' sfdx-project.json

Use the result as <source-dir> (e.g. force-app/main/default) for all commands below.

Write both permission sets (React Experience Sites always need both):

  1. Read assets/MFA_Required_For_Community.permissionset-meta.xml
  2. Write it to <source-dir>/permissionsets/MFA_Required_For_Community.permissionset-meta.xml in the user's project
  3. Read assets/API_Enabled_For_Community.permissionset-meta.xml
  4. Write it to <source-dir>/permissionsets/API_Enabled_For_Community.permissionset-meta.xml

Step 3: Deploy to org

sf project deploy start \
  --source-dir <source-dir>/permissionsets \
  --target-org <org-alias> --test-level NoTestRun

Step 3b: Validate community profile is a network member

Before assigning permission sets to users, verify that the community profile is registered as a site member. Without this, community users cannot log in at all (and MFA will never trigger).

  1. Query current network members:
sf data query --target-org <org-alias> \
  --query "SELECT Id, ParentId FROM NetworkMemberGroup WHERE NetworkId = '<NETWORK_ID>'" --json
  1. Check if the community profile is in the list:
sf data query --target-org <org-alias> \
  --query "SELECT Id, Name FROM Profile WHERE UserType IN ('CspLitePortal', 'PowerCustomerSuccess') AND Name LIKE '%Community%'" --json
  1. If the profile is NOT a member, add it to the .network-meta.xml:
<networkMemberGroups>
    <!-- Replace with the community profile name from Step 3b query above -->
    <profile>YOUR_COMMUNITY_PROFILE_NAME</profile>
    <!-- existing entries -->
</networkMemberGroups>
  1. Deploy the updated network metadata:
sf project deploy start \
  --source-dir <source-dir>/networks \
  --target-org <org-alias> --test-level NoTestRun
IMPORTANT: If the community profile is not a member of the network, users with that profile CANNOT log in — meaning MFA will never be triggered even if permission sets are correctly assigned. This is a common misconfiguration in freshly deployed orgs.

Step 3c: Validate guest profile has Apex class access for login

The site login page runs as the guest user (unauthenticated). If the guest profile doesn't have access to login Apex classes, users will get FORBIDDEN: You do not have access to the Apex class named: UIBundleLogin and can never reach the MFA challenge.

  1. Find the site guest user profile:
sf data query --target-org <org-alias> \
  --query "SELECT Id, Username, Profile.Name, Profile.Id FROM User WHERE UserType = 'Guest' AND IsActive = true" --json
  1. Grant access to any missing UIBundle login classes. The six classes are UIBundleLogin, UIBundleAuthUtils, UIBundleForgotPassword, UIBundleChangePassword, UIBundleRegistration, and UIBundleSocialLoginConfig. Run the anonymous Apex in references/setup.md ("Grant Guest Profile Apex Class Access") — it diffs existing access and inserts only what's missing — or deploy <classAccess> entries for the same classes to the guest profile metadata XML.
IMPORTANT: This is NOT MFA-specific, but without it the login page itself is broken. The skill must validate this to ensure MFA can actually be triggered. Common in freshly deployed orgs where the guest profile didn't get full class access.

Step 4: Assign permission sets

Find community users:

More from forcedotcom

Use this skill in a project

Open any RiverX project, search the Skills panel for forcedotcom/sf-skills/experience-ui-bundle-mfa-configure, and install it in one click.

Use this skill