SfSkills Domains Docs GitHub

Home / security / session-high-assurance-policies

session-high-assurance-policies

Enforce step-up authentication for sensitive pages/objects using High Assurance session level and login flow policies. NOT for initial MFA enrollment UX — use admin/org-setup-and-configuration.

Open the skill folder on GitHub


Session High Assurance Policies

Every Salesforce session carries a security level. AuthSession.SessionSecurityLevel is documented as "Standard or High, depending upon the authentication method used." The level is decided by how the session was created, not by what the user is doing, so "require MFA to see this field" is never a single switch — it is a combination of a login-method mapping, a policy that names a protected operation, and (for anything Salesforce does not ship a policy for) Apex that reads and raises the level itself.


Before Starting


Core Concepts

Login method → default session security level

Set in Setup → Session Settings → Session Security Levels, which sorts each login method into a Standard or High Assurance column.

Login methodDocumented default level
Username and PasswordStandard
Delegated AuthenticationStandard
ActivationStandard
Lightning LoginStandard
Passwordless LoginStandard
Authentication Provider (social / OpenID Connect)Standard
SAMLStandard — the IdP can override per-assertion with the SessionLevel attribute
Two-Factor AuthenticationHigh Assurance

The practical consequence: in an org where everyone logs in with username + password and MFA is satisfied by a post-login verification, sessions can still be Standard. Moving Two-Factor Authentication out of the High Assurance column is the single change that silently disables every High Assurance policy in the org.

The three places a High Assurance requirement can be set

WhereSetup pathScopeWhat it does when unmet
Session security level policiesSetup → Identity Verification → Session Security Level PoliciesNamed Setup operations, org-widePrompts the user to raise the session level, or blocks the operation outright
Session Security Level Required at LoginProfile or permission set, Session Settings sectionEvery session for the assigned usersForces identity verification during login; the session starts High Assurance or not at all
Connected App session policyApp Manager → Connected App → Session PoliciesOne Connected App's tokensGoverned by security/connected-app-security-policies — read that skill, this one does not restate it

Operations Salesforce lets you gate declaratively

Session Security Level Policies covers a fixed list of Setup areas: Reports and Dashboards, Manage Encryption Keys, Manage Auth. Providers, Manage Certificates, Manage Connected Apps, Manage Data Export, Manage IP Addresses, Manage Login Access Policies, Manage Password Policies, Manage Permission Sets and Profiles, Manage Roles, Manage Sharing, Manage Two-Factor Authentication in API, Manage Two-Factor Authentication in User Interface, Unlock Users and Reset Passwords, View Event Log Files, View Health Check.

There is no entry for an sObject, a field, or a Visualforce/LWC page. Anything record-level is Apex work.

The Apex API — Auth.SessionManagement

UserInfo has no session-security accessor. Its only session method is getSessionId(). The session-level API lives on Auth.SessionManagement:

MemberSignatureUse
getCurrentSession()Map<String, String>Read SessionSecurityLevel, SessionType, LoginType, LoginHistoryId, SourceIp, NumSecondsValid, UsersId, ParentId
setSessionLevel(Auth.SessionLevel)voidRaise/lower with Auth.SessionLevel.HIGH_ASSURANCE or Auth.SessionLevel.STANDARD
generateVerificationUrl(Auth.VerificationPolicy, String, String)StringBuild the identity-verification URL to redirect a Standard session to; policy value Auth.VerificationPolicy.HIGH_ASSURANCE
getRequiredSessionLevelForProfile(String profileId)Auth.SessionLevelRead the profile's configured login requirement
validateTotpTokenForUser(String totpCode, String description)BooleanVerify a TOTP code inside a custom step-up UI
inOrgNetworkRange(String ipAddress) / isIpAllowedForProfile(String profileId, String ipAddress)BooleanCombine network posture with session level

The documented getCurrentSession() example returns SessionSecurityLevel=STANDARD — an upper-case token, not the Standard / High picklist form used by the AuthSession object. Do not reuse one comparison string for both surfaces.


Common Patterns

Pattern 1: Apex step-up gate in front of a sensitive controller

When to use: an LWC/Visualforce page or an Apex entry point exposes data that must never be read from a Standard session, and no Session Security Level Policy covers it.

// Returns null when the session is already elevated; otherwise the URL to redirect to.
public static String verificationUrlIfNeeded(String returnUrl) {
    String level = Auth.SessionManagement.getCurrentSession().get('SessionSecurityLevel');
    if (String.isNotBlank(level) && !'STANDARD'.equalsIgnoreCase(level)) {
        return null;
    }
    return Auth.SessionManagement.generateVerificationUrl(
        Auth.VerificationPolicy.HIGH_ASSURANCE, 'View compensation detail', returnUrl);
}

Full controller, including the WITH USER_MODE read and the failure path, is in references/examples.md.

Why not a permission set with "Session Security Level Required at Login": that raises the bar for every session those users open, including the ones that run their batch jobs. See references/gotchas.md Gotcha 1.

Pattern 2: Declarative gate for a Setup operation

When to use: the requirement is one of the 17 named operations — most commonly Reports and Dashboards, Manage Data Export, or View Event Log Files.

  1. Setup → Session Settings → Session Security Levels: confirm Two-Factor Authentication is in the High Assurance column.
  2. Setup → Identity Verification → Session Security Level Policies: pick the operation.
  3. Choose raise the session security level to high assurance when the user should be able to step up in place; choose block when there is no legitimate reason for that population to reach the operation at all.
  4. Verify with a test user whose profile has no MFA-satisfying login method — confirm the block/prompt actually appears.

Why not Apex here: the platform already enforces it at the Setup entry point, including API paths an Apex guard would not see.

Pattern 3: Elevate inside a login flow instead of at login

When to use: the session should be High Assurance for users who arrived by a specific route (a network range, a particular IdP) without a profile-wide login requirement.

Call Auth.SessionManagement.setSessionLevel(Auth.SessionLevel.HIGH_ASSURANCE) from the login-flow Apex once your own verification succeeds. setSessionLevel influences the level of sessions linked to the current one — including Visualforce and other UI entry points — so confirm the blast radius in a sandbox first. inOrgNetworkRange(ipAddress) and isIpAllowedForProfile(profileId, ipAddress) are the supported way to make that route decision in Apex.


Decision Guidance

SituationRecommended approachReason
Protect a named Setup area (reports, data export, event log files)Session Security Level PolicyEnforced by the platform at every entry point, including API
Protect one field or one record pageApex gate (Pattern 1) plus field-level securityNo declarative policy covers record data; FLS is still the access control
Users own batch/scheduled/@future jobsNever "Session Security Level Required at Login"High Assurance login is documented as unsupported in asynchronous contexts
Requirement is "everyone must use MFA"MFA permission / security/mfa-enforcement-strategyHigh Assurance is a session attribute, not an enrollment control
Requirement is scoped to one Connected AppConnected App session policysecurity/connected-app-security-policies owns the three-state policy
Integration / API-only profiles in scopeExplicitly exclude themThey have no interactive channel on which to satisfy a challenge

  1. Classify the requirement: named Setup operation, Connected App, or record/field/page. Only the first is declarative.
  2. Verify the login-method mapping in Setup → Session Settings → Session Security Levels. If no method your users actually use lands in the High Assurance column, nothing downstream will ever be satisfied.
  3. Apply the narrowest control that fits — a Session Security Level Policy for a named operation, an Apex gate built on Auth.SessionManagement for record data.
  4. Enumerate the async-Apex owners and integration/API-only profiles in scope and exclude them before enabling anything.
  5. Test with a real Standard-level session: confirm the prompt or block fires, and confirm that after stepping up the user is not re-prompted in the same session.
  6. Instrument: query AuthSession for SessionSecurityLevel by user, and correlate with LoginHistory via LoginHistoryId.

Review Checklist


Deep Dives

references/examples.md — Apex step-up gate, permission-set-scoped login requirement with the async carve-out, AuthSession audit query. references/gotchas.md — seven production failure modes. references/llm-anti-patterns.md — seven wrong/right code pairs.


Output Artifacts

ArtifactDescription
Session level policy matrixEach protected operation → policy action (raise / block) → affected profiles
Login-method mapping snapshotThe Session Settings Standard/High Assurance column assignment, captured before and after the change
Async-Apex exclusion listProfiles owning scheduled/batch/@future jobs that must not carry a login-level requirement
Step-up Apex gateController-level guard built on Auth.SessionManagement with its negative test

Package files