Getting accounts into applications
Five applications, five ways
By the end of Dana Okafor's first shift on the pediatrics unit, Dana has opened a patient's chart, checked next week's rota, read a welcome email, and finished the first mandatory training module. Each of those applications recognized Dana. Three already held an account, and one created an account the moment Dana arrived. None of this happened by chance, and no two of those accounts arrived the same way.
The identity system learned about Dana from the HR system, as Joining an organization described. Knowing about a person is not the same as every application having an account for them. Creating accounts in applications, keeping their attributes and access current, and disabling them when people leave is provisioning, which Trust across systems introduced alongside SCIM.
Five of Harbor's applications show the main ways it happens. The patient records system receives each change from the identity system's provisioning service. Email and files keeps no user list of its own and uses the staff directory's accounts. Scheduling imports a file every night. The staff learning portal, at learning.harborclinic.example, creates an account when someone first signs in. And in the billing system, Jordan Ellis, an IT administrator, makes every change by hand from a ticket. All five work on someone's first day. The differences appear later, when people change jobs or leave.
| Application | How accounts arrive | When a change arrives | Hears about leavers? |
|---|---|---|---|
| Patient records | The provisioning service calls its API | Within minutes | Yes, when the call succeeds |
| Email and files | Uses staff directory accounts | As soon as the directory changes | Yes, when the directory account is disabled |
| Scheduling | Nightly file import | At 02:00 the next night | Only if the file and the import handle departures |
| Staff learning portal | Created at the first sign-in | At the person's next sign-in | No |
| Billing | Tickets completed by a person | When someone finishes the ticket | Only if a ticket is raised and completed |
Creating accounts at sign-in
Dr. Lee Moreau started a three-month locum contract in the emergency department on 1 September. Nobody created a learning portal account in advance. When Dr. Moreau opened the portal to complete the clinic's mandatory training, the portal sent the browser to Harbor's sign-in service. Dr. Moreau signed in there, and the portal received a sign-in message with claims about Dr. Moreau: a stable identifier, a name, an email address, and a department. The portal found no account linked to that identifier, so it created one on the spot.
Creating an account during someone's first federated sign-in is called just-in-time provisioning. For joiners it works well. There is no integration to build, nobody gets an account in an application they never use, and the account appears at the moment it is needed.
The trouble starts at 18:00 on Friday 27 November, when Dr. Moreau's contract ends. The identity system disables Dr. Moreau's identity, and the sign-in service stops accepting Dr. Moreau. The learning portal hears nothing. It only ever learned about Dr. Moreau from sign-ins, and no sign-in will arrive to say that Dr. Moreau has gone.
Blocking new sign-ins helps, but it removes nothing. A portal session that began at 17:30 keeps working until it expires, because the portal checks its own session rather than asking the sign-in service again, as Staying signed in explained. A local password or a phone app's long-lived token would keep working too. And the account stays on the portal's user list, with access to the clinic's internal procedures, long after anyone remembers why it is there.
Just-in-time provisioning therefore needs a partner for leavers: a call from the provisioning service that disables the account, a regular comparison of the application's user list with the identity system's records, or at the very least a tracked ticket. Leaving an organization followed what happens to sessions when access ends. Here the problem starts earlier: the application is never told.
Pushing changes
The patient records system works the other way round. When HR recorded Dana's hire, the identity system worked out that a nurse joining pediatrics needs a patient records account, and it created that account a week before the start date, disabled until the morning Dana started. When Sam Reyes moves to oncology on 9 November, the identity system sends the change that morning. When Dr. Moreau's contract ends at 18:00, it sends the deactivation two minutes later. The records system never waits for anyone to sign in. The identity system pushes each change to it as the change happens.
A push integration has four parts:
- A client: the provisioning service, which sends the requests.
- The client's credentials and scopes, which prove who is calling and limit what it may change.
- A target API in the application that accepts the changes. The records system offers a SCIM API at
https://records.harborclinic.example/scim/v2. - An attribute mapping, which decides how Harbor's information about a person becomes the application's account.
Pushing tells the application about every change within minutes, which suits the application that holds the clinic's most sensitive data. It also has costs. The application must offer an API, someone must maintain the connection, and every call can fail. A failed call is a change that has not happened: a leaver whose deactivation fails still has access, whatever the identity system's records say. The next two lessons show what the SCIM requests contain, and Keeping systems in sync covers retries and the checks that catch failures.
Files and tickets
Scheduling offers no API for accounts, but it can import a file. Each night, the identity system writes a list of everyone who should have a scheduling account to a protected file share, and scheduling imports it at 02:00. The file written on the night of Dr. Moreau's departure starts like this:
email,given_name,family_name,department,status
[email protected],Dana,Okafor,Pediatrics,active
[email protected],Sam,Reyes,Oncology,active
[email protected],Lee,Moreau,Emergency,inactive
All names and identifiers in these examples are fictional.
Scheduling has nowhere to store an employee number, so the file identifies each person by email address, which is why a name change trips it up, as What a directory holds showed. A file import does hear about leavers, with two catches. The first is time. Dr. Moreau's contract ended at 18:00 on Friday, and scheduling finds out at 02:00 on Saturday. For eight hours, a scheduling account belongs to someone who no longer works at the clinic. Importing more often narrows that gap without closing it.
The second catch is what the import does with each row. Harbor's file lists Dr. Moreau with the status inactive, and the import disables the account. Some imports only add and update, so a person who simply disappears from the file keeps their account indefinitely. Before relying on a file, find out how the import handles departures, and send them explicitly. Check the results too, because an import that skips rows it cannot read may still report success. And protect the file like the systems at either end, since it is one more copy of personal information.
The billing system has neither an API nor an import. When a new clerk on Priya Nair's billing team needs the Create suppliers permission, the identity system opens a ticket, Jordan Ellis makes the change, and Jordan closes the ticket.
That is still provisioning, carried out by a person, and the governance part is following each ticket to completion. The identity system records the change as pending until the ticket closes, and the closed ticket records who made the change and when. A ticket still open after its deadline is escalated, and removals get the shortest deadlines: when a billing clerk leaves, the removal ticket is all that stands between a former employee and the Approve supplier payments permission. Because a ticket can be closed without the work being done, Harbor also compares the billing system's user list with the identity system's records every month.
Mapping attributes
Whatever the route, someone has to decide which information goes where. An attribute mapping is the set of rules that turns what the identity system and its sources know about a person into the attributes of an account in one application. Some rules copy a value. Others transform it, look it up, or combine several values. Here is part of Harbor's mapping for the patient records system:
| Source | Patient records attribute | Rule |
|---|---|---|
| HR employee number, or register ID for contractors | externalId | Copied |
| Legal given and family names | name.givenName, name.familyName | Copied |
| Legal given and family names | displayName | Joined with a space, such as Dana Okafor |
| Username from the identity system | userName | Copied. Created once from the names, such as dana.okafor |
| Work email from the identity system | emails | Copied with the type work and marked primary |
| HR department | department | Copied |
| HR manager | manager | Looked up: the manager's own account ID in the records system |
| HR employment status and start date | active | true from the start date while employment is active, otherwise false |
| Salary, bank details, home address, date of birth | None | Never sent |
The transformations carry small decisions. The manager is looked up because the records system identifies a manager by that person's account in the records system, not by an HR number it has never seen. And active is calculated rather than copied, which is how an account created a week early stays disabled until the start date.
The last row matters as much as the others. The HR system holds salary, bank details, home addresses, and dates of birth, and the records system has no use for any of them. A mapping is a list of what leaves the source, and anything not on the list stays behind. Sending every available attribute because a tool offers to would create another copy of sensitive data in a system whose access controls were never designed around it.
Mappings also fail quietly. Suppose the HR department had been mapped to title, the job title attribute, instead of department. No request would be rejected, because a unit name is a valid job title. Every nurse's title would become a unit name, and the department would stay empty. If the records system builds each nurse's patient list from the department, Dana's list on the first morning would be empty, and so would everyone else's. Test a mapping against a few real records in a test copy of the application before switching it on, and record who approved each change to it, because one mapping change can alter what every account can see.