Skip to main content

Permission sets, profiles and the 2026 MFA mandate: a least-privilege checklist

Salesforce is enforcing MFA for every employee-licence user from June 2026. According to Salesforce Ben's preparation guide, published 2026-05-01 and updated 2026-06-22, the System Administrator profile and its equivalents, meaning anyone holding Modify All Data or Manage Users, need phishing-resistant MFA: built-in authenticators or FIDO2 and WebAuthn security keys. TOTP codes and push notifications do not qualify for admins. Step-up authentication applies to sensitive actions after login.

The mandate turns a vague question into an urgent one. "Who are our admins" used to be answered by counting the System Administrator profile. Now the answer has to include everyone whose effective permissions are admin-equivalent, however they got there, because those users need a different authenticator. Permission set groups make that harder, not easier: the group is a union, and the union is what the user holds.

The attackers already treat it this way. In the UNC6040 campaign CSO Online described in June 2025, callers talked employees into entering a connection code that authorised a modified Data Loader. The mitigations Google's Threat Intelligence Group listed were least privilege, MFA, IP-based restrictions and monitoring connected app access. A user with narrow permissions and a hardware key is a poor target for that call; an over-privileged one with a push notification is a good one.

What the mandate requires

Three things, in order of difficulty. All employee-licence users need MFA of some kind. Users with admin-level permissions need phishing-resistant MFA, which in practice means a security key or a platform authenticator, not an authenticator app. Sensitive post-login actions get step-up authentication.

The first is a rollout. The third is a platform setting. The second is an inventory problem, and the inventory is where most orgs are wrong, because "admin-level" is defined by permissions, not by profile name.

Who is admin-equivalent

Three permissions define the top of the hierarchy: Modify All Data, Author Apex and Manage Users. Each on its own is powerful. Together, with API Enabled, they let a single account read and change every record, deploy code and create other admins, from a script. Vulkro's least-privilege detectors flag that combination as sf-lp-toxic-combo at Critical when one profile or permission set grants Author Apex, Modify All Data and API Enabled together.

The harder case is the group. A permission set group composed of three ordinary-looking sets can be admin-equivalent even though no single member is. The profiles and permission sets detectors include psg-composition-grants-effective-modify-all-data, which computes the union of each group's members and reports the groups whose combined grant reaches Modify All Data. Those groups define users who need a security key, and they will not appear in any list filtered by profile.

vulkro-sf org effective-perms does the same calculation per user against the live org: profile plus permission sets plus groups, resolved to what the user can actually do. That list, filtered to the three permissions, is the population the mandate is about.

Dormant admins and weak sessions

An admin who has not logged in for three months still holds the permissions and still has a password that can be phished or reused. SF-PERM-002 reports dormant admins in the live org: users with Modify All Data and no login in 90 days. The fix is removal, not an MFA reminder.

The mandate's phishing-resistant requirement has a sibling in session policy. sf-lp-session-not-high-assurance (Medium) fires when sensitive permissions are granted without a high-assurance session requirement, so a user who authenticated weakly can still exercise them. sf-lp-integration-user-no-ip flags integration users with no login IP ranges, which is the IP restriction from the UNC6040 mitigation list, missing. And for orgs using single sign-on, saml-weak-signature-algorithm reports SHA-1 SAML signing, where the strength of the identity provider's MFA is undercut by the assertion that carries it.

Fields, not only objects

Least privilege is usually discussed at the object level, but the mandate's concern is sensitive data, and sensitive data lives in fields. SF-FLS-USER-001 and SF-FLS-USER-002 report a sensitive field that is effectively readable or editable by more users than a bar you set. The bar is VULKRO_SF_FLS_USER_BROAD_BAR, default 5, so a field such as a tax identifier or a bank account readable by six or more users is reported with the count.

This is the same union problem at a finer grain. A field hidden on every profile can still be readable through a permission set in a group, and the only way to know is to resolve the effective field-level security per user.

Reading the live org

Source metadata tells you what was deployed. For MFA the org is the only truth, because authenticator enrolment and login history do not exist in a repository.

vulkro-sf org mfa reports MFA status across users. org session reads the session settings, including the high-assurance requirements. org login-history shows who authenticated, how and from where. All three run through the Salesforce CLI against an alias you already authorised, so the credential stays in the sf token store. The live-org setup page lists what the connected user needs, which is API Enabled and View Setup and Configuration. Anything the user cannot read is reported as not covered, not as clean, so a limited integration user never produces a falsely reassuring report.

vulkro-sf org perms -o <alias> lists the permission assignments, and vulkro-sf org least-privilege -o <alias> runs the least-privilege checks above against the live state. For teams driving this from an AI assistant, the same reads are available as the MCP tools sf_org_perms and sf_org_mfa described in the vulkro-sf MCP docs.

One limit: these reads report who holds a permission and who has enrolled in MFA. They do not tell you which authenticator type a user registered, so the phishing-resistant check is one you confirm in Setup for the population the report gives you.

The checklist

  • Produce the admin-equivalent population from effective permissions, not from profile names. Include every user whose permission set groups reach Modify All Data, Author Apex or Manage Users.
  • Remove dormant admins before enrolling anyone. A permission nobody uses needs no authenticator; it needs deletion.
  • Break every toxic combination: no single profile or permission set should grant Author Apex, Modify All Data and API Enabled together unless it is the named break-glass account.
  • Require high-assurance sessions for sensitive permissions, and login IP ranges for every integration user.
  • Resolve field-level security for the fields that hold identifiers and financial data, and lower the reader count to the people who need it.
  • Enrol the admin-equivalent population on security keys or platform authenticators, then verify with org mfa and login history rather than with a spreadsheet.

What to do this week

  • Run vulkro-sf org effective-perms and vulkro-sf org perms -o <alias> and count the users whose effective grant includes Modify All Data.
  • Run vulkro-sf org least-privilege -o <alias> and fix every sf-lp-toxic-combo and every SF-PERM-002 dormant admin.
  • Run vulkro-sf org mfa and compare its population against the one from step one. The difference is your enrolment list.
  • Check org session for high-assurance requirements on the sensitive permissions.
  • Put the effective-permissions report on the change calendar so the population is recomputed after every permission set change.

The live-org setup docs cover the read-only connection and the permissions each report needs. To run it against your own org, start the 14-day trial.