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?
When the standard isn’t enough
Section titled “When the standard isn’t enough”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.
The custom JIT handler
Section titled “The custom JIT handler”It’s the same setting as module 2, with one change (S1):
- For User Provisioning Type, choose Custom SAML JIT with Apex handler.
- 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.” - 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):
| Method | When it runs | What it does |
|---|---|---|
createUser(samlSsoProviderId, communityId, portalId, federationId, attributes, assertion) | Her first SAML login | Returns 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 after | Updates 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.
Three doors, one job
Section titled “Three doors, one job”Does this sound familiar? It should. You’ve now met this same job three times.
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.
Who decides her access?
Section titled “Who decides her access?”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,createUserandupdateUser, just like the registration handler.
What’s next
Section titled “What’s next”Module 4: out, as well as in. What happens when she leaves.
What an architect decides here
Section titled “What an architect decides here”- 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.
Explore
Section titled “Explore”- Enable Just-in-Time Provisioning (opens in a new tab) (Salesforce Help, Winter ‘27; checked 2026-11-07)
- SamlJitHandler Interface (opens in a new tab) (Apex Reference Guide; checked 2026-11-07)
