Skip to content

Create User, Update User, Everywhere

Module 3 of 5 in the chapter Getting Users In and Out: Provisioning, chapter 12 of Securing Salesforce: Identity and Access. Each module stands on its own.

The question this module answers: When the standard rules aren’t enough, where does your own logic go, and who decides her access?

Standard just-in-time copies attributes into fields. That’s often enough. But what if you need to:

  • Choose her profile by a rule: say, by her department, not by a profile name the identity provider has to know.
  • Give her permission sets, which the standard fields can’t (module 2).
  • Match her more carefully, or refuse her.
  • Create her account and contact too, for a customer or partner user.

Then you write the logic yourself, in a custom SAML JIT handler.

It’s the same setting as module 2, with one change (S1):

  1. For User Provisioning Type, choose Custom SAML JIT with Apex handler.
  2. For SAML JIT Handler, choose an Apex class that implements Auth.SamlJitHandler. If you don’t have one, Setup can automatically create a SAML JIT handler template. In Salesforce’s words: “Edit this class, and modify the default content before you use it.”
  3. For Execute Handler As, choose the user it runs as, who “must have the Manage Users permission”.

It’s not available in Professional Edition, where you get standard JIT only (S1).

And the class? If I’m implementing just-in-time with my own logic, what two methods do I override? Create user and update user (S3):

MethodWhen it runsWhat it does
createUser(samlSsoProviderId, communityId, portalId, federationId, attributes, assertion)Her first SAML loginReturns a User: “a new user that hasn’t been inserted in the database or an existing user record”
updateUser(userId, samlSsoProviderId, communityId, portalId, federationId, attributes, assertion)Every login afterUpdates her user: “called if the user has logged in before with SAML single sign-on and then logs in again”

The attributes map holds every attribute from the assertion, and the names are case-sensitive (S3). And Salesforce is clear about whose job it is: “your class must perform the logic of creating and updating user data as appropriate, including any associated account and contact records” (S3).

Here’s the heart of the update in my video, as a sketch: find her user, copy her phone across.

global void updateUser(Id userId, Id samlSsoProviderId, Id communityId,
Id portalId, String federationId, Map<String, String> attributes,
String assertion) {
if (attributes.containsKey('User.Phone')) {
User u = new User(Id = userId, Phone = attributes.get('User.Phone'));
update u;
}
}

It’s a sketch to read, not production code. This chapter’s practice uses it; before you use anything like it in a real org, run it in a sandbox and write its tests.

Does this sound familiar? It should. You’ve now met this same job three times.

Three handlers, one job Three handlers, one job. A SAML assertion from single sign-on, with attributes, is handed to the SAML JIT handler, Auth.SamlJitHandler, with createUser and updateUser, this chapter, which decides her user, created or updated, at every SAML login. An auth provider login, from Google, another org or any OpenID Connect provider, is handed to the registration handler, Auth.RegistrationHandler, with createUser and updateUser, chapter 10, which decides her user, created or updated, at every login through it. A token from another provider, exchanged by an app, is handed to the token exchange handler, which validates the token and maps the person, chapter 11, and decides her user, found or made, at every exchange. Green marks that each happens only if your checks let her in. Footnote: three doors, one job: decide which Salesforce user she is, and whether she gets one at all. {"author": "Steve Simpson", "blueprint": "1.0.0", "builder": "standard 1.58.0", "built": "2026-11-05", "id": "DGM-IAM-PRV-03", "rights": "\u00a9 2026 Twinshark LLC. All rights reserved.", "template": "cells 0.5.0", "theme": "stevetecharc 1.4.0"} WHAT ARRIVES YOUR HANDLER THE RESULT A SAML assertion single sign-on, with attributes SAML JIT handler Auth.SamlJitHandler: createUser, updateUser · this chapter Her user, created or updated at every SAML login An auth provider login Google, another org, any OpenID Connect provider Registration handler Auth.RegistrationHandler: createUser, updateUser · ch 10 Her user, created or updated at every login through it A token from another provider exchanged by an app Token exchange handler validates the token, maps the person · ch 11 Her user, found or made at every exchange handed to decides handed to decides handed to decides Three doors, one job: decide which Salesforce user she is, and whether she gets one at all. HOW TO READ IT only if your checks let her in © 2026 Twinshark LLC · stevetecharc.com
Click to enlarge

Three ways in: a SAML assertion, an auth provider login, a token from somewhere else. One job: take what arrives, decide which Salesforce user she is, and whether she gets one at all. Create user, update user. The SAML JIT handler and chapter 10’s registration handler even have the same two method names.

So the checks from chapter 10, module 3 apply to all three. May she come in at all? Is she someone you already have? As whom, with which licence? Can you trust what you’re matching on? And each runs as a user with Manage Users: in production, a system user made for the job, not a person.

Now the question the exam calls assigning and maintaining roles, profiles and permission sets during single sign-on. When Priya arrives, who decides what she can do?

Here’s the principle I’d use: the identity provider says who she is; Salesforce decides what that means.

The identity provider knows her department, her title, her manager, maybe the groups she’s in. It shouldn’t need to know Salesforce’s profile names or permission sets: those change with your Salesforce design, and the identity provider team shouldn’t have to keep up. So send who she is, and map it in Salesforce:

  • Standard JIT can set her profile and role straight from attributes (S2). Simple, but the identity provider then has to send Salesforce’s names.
  • A handler can read her department and choose the profile, role and permission sets itself. In my video I hard-coded System Administrator to keep the demo short. You’d never do that: you’d write your own logic to choose the profile, most likely from one of the attributes.
  • The identity provider pushing (module 4) can manage profiles and permission sets directly, as part of each join and move.

Whichever you choose, write the rules down once, in one place, and make sure a move is handled too: when she changes department, her access should change with her, not just grow.

One trap to know about. Creating or updating a user and assigning permission sets in the same transaction can hit what’s called a mixed DML error: Salesforce only allows changes to setup records, like users and permission set assignments, together with other records under certain conditions (chapter 10’s S4). Chapter 10 noted that a Flow registration handler avoids it. A JIT handler is Apex only, so plan for it: if your handler assigns permission sets, test that part in a sandbox before you rely on it.

Test knowledge. In my experience, know the custom SAML JIT handler, Auth.SamlJitHandler, and its two methods, createUser and updateUser, just like the registration handler.

Module 4: out, as well as in. What happens when she leaves.

  • Standard JIT or a handler, for each single sign-on setting.
  • Who maps who she is to what she can do, and where those rules live.
  • How a move changes her access, not just how a join sets it.
  • The system user each handler runs as.