Skip to content
KEDBYTE
How Identity Works
Chapter
45

Provisioning and the Lifecycle

Part IV · Identity Between Systems|12,109 words|about 53 min read|Volume 4

45.0 What this chapter gives you#

  1. You will be able to name the three events every identity system must handle — joiner, mover, leaver — and say which of the three nearly every organization handles badly.
  2. You will be able to write a correct SCIM 2.0 request against a /Users endpoint, naming the schema identifier, the required attributes and the response codes.
  3. You will be able to explain SCIM PATCH semantics and say why two implementations that both follow the specification can still fail to work together.
  4. You will be able to tell push provisioning from pull provisioning, describe the reconciliation job between them, and say what each does when a link is broken for a day.
  5. You will be able to measure deprovisioning latency, define an orphan account in a way an auditor will accept, and quote audited figures for how common orphans are.
  6. You will be able to design a recertification campaign that produces a decision rather than a signature, and name the three ways campaigns are routinely gamed.
  7. You will be able to compare standing privilege with just-in-time elevation, and set up a break-glass account against the guidance current in August 2026.
  8. You will be able to bring a service account population under governance without stopping production on the first Monday.
  9. You will be able to write a segregation of duties rule as machine-checkable policy and run a set of audit queries that finds the accounts nobody owns.

An account is created because somebody wants something. A manager wants their new analyst productive on the first morning; a project wants a contractor in the system by Thursday; a vendor wants their support engineer able to log a ticket. Every one of those wants has a name attached to it, a deadline, and somebody who will complain if it is late. Creating accounts is therefore a well-resourced, enthusiastically performed activity in every organization in the world.

Removing an account is different in one decisive way: nobody is waiting for it. The person has gone. Their manager has a vacancy to fill and is not thinking about the mailbox. The application owner does not know the person has left, because there is no mechanism that tells them. The removal has no deadline anybody feels, no customer, and no complaint if it never happens. It has only a risk, and risks are silent until they are not.

That asymmetry is the whole of this chapter. Accounts are created enthusiastically and removed reluctantly, the gap between those two speeds is a quantity you can measure in your own organization this week, and it is where a large share of real intrusions live. When investigators publish how an attacker got in, the phrase that recurs is not a clever exploit. It is an account that should not have still existed, or should not have still worked, or should not have had that much power when it did.

We will build the idea in the usual three passes: the plain version with keys and a building, the places where that analogy lies to you, and then the technical version in exact vocabulary. We will follow one example organization the whole way. Larkfield Group is a logistics company with roughly nine thousand staff across the United Kingdom, Germany and India. Its human resources system is the record of who works there; its directory holds the accounts; between those two sits everything this chapter is about.

The plain version#

A building, a key cutter and a cabinet#

Imagine a large building with a great many locked doors. Some are ordinary: the office you work in, the stationery cupboard. Some are serious: the strongroom, the plant room, the room where the money is counted.

There is a key cutting machine in the basement and a cabinet of blanks. When somebody joins, a clerk cuts them keys according to the job they were hired to do: a payroll analyst gets the office, the payroll room and the filing room; a driver gets the yard gate and the fuel store. A list on the wall says which job gets which keys, and the clerk follows it.

Three things can then happen to that person, and only three. They arrive. They change job. They leave. Everything else — a holiday, a secondment, a promotion, a suspension, a transfer abroad — is one of those three wearing different clothes.

When somebody arrives, the clerk cuts keys, and this works well because everybody is watching: the new person cannot start work without keys, so if they are late she says so on the first morning, loudly, and her manager says so louder.

When somebody changes job, the clerk cuts the keys for the new job. This half works, because the new manager is waiting. The old keys are supposed to come back and usually do not, because nobody is waiting for a returned key and the person holding it is busy learning a new job. After fifteen years of internal moves, there are people carrying fourteen keys and using three.

When somebody leaves, the keys are supposed to be handed in at the door. Sometimes they are. Sometimes the person keeps them, not out of malice but because they were in a coat pocket and nobody asked. Nobody notices, because a door that opens for somebody who no longer works there looks exactly like a door that opens for somebody who does.

The three events, named plainly#

A person arriving is a joiner, a person changing job is a mover, a person going is a leaver. Those three words are the standard vocabulary of this field, used as one phrase, joiner-mover-leaver, or as three letters, JML. They need three different mechanisms, and an organization that has built only the first will tell you, sincerely, that it has an account management system. The joiner mechanism needs speed and a rule about what each job gets. The mover mechanism must add and remove in the same motion, and removal is the half that gets dropped. The leaver mechanism must reach into every place a key was ever cut, including the places nobody wrote down.

Why leaving is the hard one#

Here is the asymmetry stated as plainly as it can be. When a key is cut too slowly, a person complains on the first morning. When a key is collected too slowly, nothing happens at all: there is no signal, and the cost is paid, if it is ever paid, months later, by somebody else, in a form not obviously connected to it. Every organization therefore drifts to the same place, fast at cutting and slow at collecting, with no measurement of the second number because nobody has asked for it.

The most useful thing anybody can do about this, with no technology at all, is to measure one quantity: the time between a person’s last working day and the moment their access stops working. Not the time until somebody typed the instruction. The time until the door refused to open. Those two numbers are further apart than anybody expects.

The keys that were cut for a job, not a person#

Not every key belongs to a person. The automatic fuel delivery must open the fuel store at four in the morning without waking anybody, so a key was cut and hung on a hook in the plant room with a label reading “fuel deliveries”. Nobody owns it. It was cut in 2013 by a contractor who has retired. It is not on the list on the wall, because that list is a list of jobs and “fuel deliveries” is not a job. It has never been handed in, because nobody left. It never expires, because there is nobody to remind. And it opens a serious door.

Buildings are full of these. In the world of accounts they are called service accounts: accounts that exist so one program can talk to another. They usually have more power than a person’s account, a password unchanged in years, and no list anybody trusts. They are the ungoverned population, and we come back to them.

The sealed envelope behind glass#

There is one more key, and it is deliberate. Somewhere there is a sealed envelope holding a key that opens everything, because one day the locks will fail, or the person with the master keys will be unreachable. This is a break-glass account: an emergency account held in reserve and used almost never, whose rules are the opposite of every other rule here. It is deliberately excluded from the normal controls, because the normal controls are what might have failed. In exchange it is watched more closely than anything else, with every use raising an alarm, and it is tested regularly, because an emergency key that has quietly stopped working is worse than none.

The annual walk round the building#

Once a year, and in a careful organization more often, somebody walks round with a clipboard and asks each manager: these are the keys your people hold, are they all still needed? This is recertification, sometimes called attestation, and it is the only mechanism that catches keys that were never collected, because it starts from the keys rather than the people. Its famous failure mode is that the manager is handed four hundred lines, most of which mean nothing to them, and ticks all four hundred in six minutes. Nothing was found, and an auditor was told that recertification is performed annually, which is true and useless.

Larkfield’s Monday morning, with real values#

Priya Nair is hired as a payroll analyst at Larkfield Group’s Manchester office, starting Monday 7 September 2026. Her manager, Anita Bose, enters the hire into the human resources system at 12:20 on Monday 24 August, a fortnight ahead, which is unusually good and happens only because payroll insists. At that moment the system holds these facts:

worker id      : LKF-041882
legal name     : Priya Nair
job code       : PAY-ANL-2
department     : 4120 Payroll Operations
location       : GB-MAN
manager        : LKF-028114 (Anita Bose)
employment type: permanent
hire date      : 2026-09-07
termination    : (empty)

Nothing exists anywhere else yet. At 02:00 on Tuesday 25 August a scheduled job reads the human resources system, notices a worker record with no matching identity, and creates one: a permanent internal number that will never change and never be reused, id=7d4f1c8a, and a login name from a rule of first initial and surname. Priya gets pnair. Her job code PAY-ANL-2 maps to a set of access rights, pushed into eight systems: the directory, email, payroll, finance reporting, the intranet, expenses, ticketing and building access.

The account is created in all eight but disabled, dated to become active at 07:00 on 7 September, and Priya’s first morning works. Two numbers are worth keeping: fourteen hours from the manager pressing save to accounts existing everywhere, and zero delay from her start date to being able to work.

Now the other end. Kemi Adeyemi, a warehouse supervisor in the same company, leaves on Friday 31 July 2026. Her termination reaches the human resources system on 11 August, when the payroll cut-off forces somebody to deal with it, and her directory account is disabled that night. Her account in the transport management system, which nobody remembers is connected to anything, was still enabled and working seventeen days later, with a password she chose in 2023, reachable from anywhere on the internet, able to see every consignment the company is carrying.

That is an orphan account: still alive, no longer belonging to anybody who works there. Kemi is doing nothing at all. The account is simply lying there, working, with nobody’s name on it, waiting for whoever finds it first.

Where the plain version stops being true#

There is no single moment of joining#

The analogy has a clerk cutting keys on the day somebody arrives; real organizations have no such moment. A person can have a signed contract and no start date. A contractor can be working three weeks before a worker record exists, because the record is created by a purchasing process attached to an invoice. Somebody transferred from an acquired company exists in two human resources systems with two worker numbers and one face. A person can be hired, have accounts created, and never turn up.

The honest version: joining is not an event but a state change in whichever system your organization has decided is the authority for that population, and most organizations have several such systems, imperfectly joined, with rules about which one wins. The work is not “create an account when somebody joins” but “decide which system is the truth for each population, and detect changes in it reliably”.

Deleting the account is usually the wrong instruction#

In a computer system the equivalent of collecting the keys seems obvious and is usually wrong. Delete an account outright and files owned by it lose their owner or become inaccessible; audit records referencing it by internal number become records about a number that resolves to nothing; systems that discover people through your directory see the person vanish rather than depart, and some treat a vanished record as an error and do nothing, leaving their own copy alive. In most countries there are also legal reasons to retain a former employee’s mailbox for a period.

The honest version: the correct sequence for a leaver is almost never a delete. It is disable, revoke every credential and live session, reassign what they own, retain for a defined period, then delete. Each step has a different owner and a different clock, and a system that only knows how to delete cannot express any of them.

The keyring hides where the access actually lives#

The analogy puts all of a person’s access on one keyring, which is the most comfortable lie in the chapter. Access is scattered: a directory group, an application’s own user table, a row in a cloud provider’s policy document, a shared mailbox permission, a database role, a code repository’s collaborator list, an API key pasted into an automation script two years ago, a personal access token on a laptop, a saved password in a browser, an invitation to a supplier’s portal accepted with a work email address. Disabling the directory account switches off the first and may do nothing at all to the rest, because an application that keeps its own user table and checks its own passwords never asks the directory anything.

The honest version: there is no keyring, only a scattered set of independent records that each grant something, and deprovisioning is the problem of finding all of them. The finding is the hard part, not the removing, which is why this chapter spends so long on inventory and reconciliation.

A leaver is often not a person leaving#

An application is decommissioned and every account in it should end, but it is switched off rather than emptied and returns three years later in a migration with its accounts intact. A supplier contract ends and forty accounts belonging to that supplier’s staff should end at midnight, and nobody connects the contract’s end date to the accounts. A project finishes and access granted “just for the project” outlives it by a decade. A machine is retired and its service account is not.

The honest version: the leaver event must be defined for every population you have, not only for employees, and every population needs a system of record that can say authoritatively “this one is over”. The population with no system of record produces the orphans.

Recertification is a review only if it can produce a “no”#

Ask a manager whether their team member still needs SAP_FI_DISP_ALL. They do not know what it is and cannot find out in the time available, and the safe answer is yes, because approving carries no visible risk while revoking risks breaking somebody’s work. The exercise is rigged towards approval and produces a ninety-nine per cent approval rate no matter what is in the list.

The honest version: a campaign is a measurement instrument, and an instrument that returns the same reading regardless of input is broken. The question is not how often to run it but what would have to be true for a reviewer to say no.

The directory is not the whole picture, and neither is this chapter#

Two boundaries, stated once. Most large organizations hold their accounts in a directory, a specialized database of people, groups and machines that answers questions about who exists; how it is built and queried is the material of chapter 44, and here it is simply one of the systems we write into. Deciding what an account may do — roles, policies, permissions — is the material of chapter 46. Here we care about a narrower question: does an account exist, is it enabled, whose is it, and when should it stop. One more boundary deserves a line: when a user logs in through a federated identity provider and the application creates a local account on the spot, that is just-in-time provisioning at login, and its consequences for orphans belong to chapter 43 on federation.

The technical version#

Joiner, mover and leaver as a state machine over an authoritative source#

Everything begins with a decision that has nothing to do with software: for each population of people, which system is the authority.

An authoritative source, or system of record, is the system whose statement about a person is treated as true by definition. For permanent employees it is nearly always the human resources system; for contractors it may be a vendor management or purchasing system, or, in far too many organizations, a spreadsheet held by whoever manages the contract; for customers it is the customer database; for machines it is the configuration management database, if one exists and is accurate, which chapter 47 addresses for workloads.

The lifecycle is then a small state machine driven by changes in that source. Larkfield’s is typical.

State Entered when Access effect
pre-hire record created accounts built, disabled
active start date reached birthright access on
changed job or manager changes recalculate, add and remove
leave long absence recorded suspend, keep identity
terminated leaving date passes disable all, revoke sessions
retained after disable read-only retention window
deleted retention expires records removed

Three properties of that machine matter more than its shape.

It must be driven by a change feed, not by a nightly full comparison alone. A full comparison is the safety net, but if it is the only mechanism then your best possible deprovisioning latency is the interval between runs and your worst is that interval plus the length of the run.

It must treat the mover as one event with two halves. The common defect is that the add half is implemented and the remove half is not, so access accumulates over a career. The result is privilege creep, and it is not subtle: where people move internally every three years and nothing is ever removed, a long-serving employee holds several times the access of a new joiner in the same role.

It must have a defined answer for records that disappear from the source. A worker record that vanishes without a termination date, through a migration, a merge of duplicates or an error, is ambiguous. Treating disappearance as termination is dangerous, because a bad import can disable ten thousand people; treating it as nothing is equally dangerous, because that is how a real termination gets lost. Quarantine instead: flag the identity, disable nothing, alert a human, and process no further changes for that record until somebody resolves it.

SCIM 2.0: three documents, and what each one is for#

The System for Cross-domain Identity Management is the standard way for one system to tell another about users and groups. Three documents published in September 2015 define it:

RFC Title Status
7642 Definitions, overview Informational
7643 Core schema Proposed Standard
7644 Protocol Proposed Standard

Note the status column, because people misquote it. RFC 7643 and RFC 7644 are Proposed Standards, the first rung of the IETF standards track; SCIM 2.0 is not an Internet Standard in the formal sense and has never been advanced. That is no criticism — a great deal of the internet runs on Proposed Standards, including OAuth 2.0 — but somebody calling SCIM “a full standard” is speaking loosely.

The name has a history, because the acronym looks wrong. The work started in 2011 as Simple Cloud Identity Management, a vendor-led effort involving Salesforce, Google, Ping Identity, UnboundID and others; version 1.0 was published in December 2011 through the Open Web Foundation and 1.1 in July 2012. The work then moved into the IETF, the scope broadened, and the same letters were re-expanded to System for Cross-domain Identity Management. SCIM 1.1 and 2.0 are not compatible — the schema identifiers, the error format and the PATCH message all changed — and as of August 2026 there are still production 1.1 endpoints in the wild that will not talk to a 2.0 client.

Its predecessor failed instructively. The Service Provisioning Markup Language was approved by OASIS as version 1.0 in October 2003 and 2.0 in April 2006: an XML and SOAP design of great generality, able to express almost any provisioning operation against almost any target, that almost nobody implemented. The lesson the SCIM authors drew, stated in RFC 7643’s introduction, was that the earlier standards were hard to implement and did not sit naturally on ordinary web protocols. SCIM is deliberately smaller: plain HTTP, plain JSON, a fixed core schema, and an extension model most deployments barely use.

Three further documents have been added since, and they change what you can assume in 2026. RFC 9865, October 2025, adds cursor-based pagination for walking large result sets. RFC 9944, May 2026, adds a device schema. RFC 9967, also May 2026, defines a profile for Security Event Tokens, which turns SCIM from a request-response protocol into one that can also push asynchronous events; it is the specification’s answer to the latency problem this chapter is about. RFC 9865 and RFC 9967 both formally update RFC 7643 and RFC 7644. Two working group drafts that bear on this chapter, one on roles and entitlements and one revising the requirements document, had expired as of August 2026, which tells you something honest about the pace of the work.

The schema: what a User actually is#

A SCIM resource is a JSON object. Every resource carries a schemas array naming the schemas it uses, and three common attributes defined in RFC 7643 section 3.1. id is the service provider’s permanent identifier: read-only, unique within the provider, never reused. externalId is the client’s identifier for the same resource, in practice the identity system’s own key, which is how a client re-finds what it created. meta is a complex attribute holding resourceType, created, lastModified, location and version.

The core User schema is urn:ietf:params:scim:schemas:core:2.0:User, section 4.1. Its singular attributes include userName (required and unique within the provider), name with its sub-attributes, displayName, title, userType, preferredLanguage, locale, timezone, active and password; its multi-valued attributes include emails, phoneNumbers, addresses, groups, entitlements and roles.

Two of those carry the whole leaver problem. active is a boolean described as indicating the user’s administrative status, with its definitive meaning left to the service provider — a clause doing an enormous amount of work. Setting it to false is the standard way to disable an account, and what that does varies: some applications block login immediately, some block new logins but leave existing sessions running, some merely hide the user from search. Ask in writing what active: false does and whether it kills live sessions. And groups on a User is read-only: membership is asserted on the Group resource, so a client that adds a user to a group by PATCHing the user fails against a conforming server, which trips up nearly every first implementation.

The Group schema, section 4.2, is small: displayName and members, where each member carries value (the id of another resource) plus an optional $ref and display, and members may be added and removed although a member’s sub-attributes are immutable. The Enterprise User extension, section 4.3, adds what an employer needs: employeeNumber, costCenter, organization, division, department and manager. If you are provisioning employees without it, you are about to reinvent it. Every attribute also carries characteristics defined in section 7: mutability (readOnly, readWrite, immutable, writeOnly), returned (always, never, default, request), uniqueness (none, server, global) and caseExact. password is the canonical writeOnly attribute: you may write it and no read will return it.

Here is Priya’s record as Larkfield’s identity system sends it, trimmed to what matters.

{
  "schemas": [
    "urn:ietf:params:scim:schemas:core:2.0:User",
    "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
  ],
  "externalId": "LKF-041882",
  "userName": "pnair",
  "name": {
    "familyName": "Nair",
    "givenName": "Priya"
  },
  "displayName": "Priya Nair",
  "title": "Payroll Analyst",
  "active": false,
  "emails": [
    { "value": "priya.nair@larkfield.example",
      "type": "work", "primary": true }
  ],
  "urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
    "employeeNumber": "LKF-041882",
    "costCenter": "4120",
    "department": "Payroll Operations",
    "manager": { "value": "3ac1b0d9" }
  }
}

Note active: false: the account is created ahead of the start date and switched on later. Note also that manager.value is the target system’s id for Anita, not Larkfield’s worker number, so the client had to look Anita up first, and if Anita has not yet been provisioned into this application then Priya cannot be either. Ordering dependencies like that are the most common cause of provisioning failures in production.

The endpoints, and what each verb means#

RFC 7644 section 3.2, Table 2, defines the endpoints. Everything hangs below a base URL of the provider’s choosing.

Endpoint Methods Purpose
/Users GET POST PUT PATCH DELETE user resources
/Groups GET POST PUT PATCH DELETE group resources
/Me GET POST PUT PATCH DELETE the caller’s own record
/ServiceProviderConfig GET what this server supports
/ResourceTypes GET what resources exist
/Schemas GET attribute definitions
/Bulk POST many operations at once
/.search POST query with a body

The media type is application/scim+json, registered in section 8.1; use it in both Content-Type and Accept, because many servers behave differently given application/json.

POST to /Users creates, returning 201 with the created resource and a Location header, or 409 with a scimType of uniqueness on conflict, usually a duplicate userName. PUT replaces the whole resource and must not create; read-only attributes in the request are ignored rather than rejected, a deliberate kindness that lets a client read a resource, change one field and send it all back. PATCH modifies part of a resource. DELETE returns 204 and later GETs return 404 — but a provider is not obliged to destroy anything, and what happens underneath is its own business.

GET on a collection supports filtering, sorting and pagination. The filter language of section 3.4.2.2 has the operators eq, ne, co (contains), sw (starts with), ew (ends with), pr (present), gt, ge, lt and le, combined with and, or and not, with value filters in square brackets for multi-valued attributes. Pagination uses count and startIndex, which is one-based and catches out every developer once, and results arrive as a ListResponse carrying totalResults, itemsPerPage, startIndex and Resources.

Errors, section 3.12, are an HTTP status plus a body with a scimType keyword: invalidFilter, tooMany, uniqueness, mutability, invalidSyntax, invalidPath, noTarget, invalidValue, invalidVers and sensitive. A server that returns a bare 400 with an HTML error page is not conforming, and a fair share of endpoints do exactly that.

/ServiceProviderConfig is the endpoint nobody reads and everybody should. It reports whether the server supports patch, bulk (with maxOperations and maxPayloadSize), filter (with maxResults), changePassword, sort and etag, and which authentication schemes it accepts. Every one is optional, so a conforming server may refuse PATCH entirely, and a client that assumes PATCH finds out in production.

Here is the exchange that switches Priya on, at 07:00 on 7 September 2026.

PATCH /scim/v2/Users/7d4f1c8a HTTP/1.1
Host: payroll.larkfield.example
Content-Type: application/scim+json
Accept: application/scim+json
Authorization: Bearer <token>
If-Match: W/"3694e05e9dff591"

{
  "schemas":
    ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    { "op": "replace",
      "path": "active",
      "value": true }
  ]
}

PATCH semantics, and why conforming implementations still fail#

PATCH is defined in RFC 7644 section 3.5.2, with sections 3.5.2.1 to 3.5.2.3 defining the three operations. The body is a PatchOp message identified by urn:ietf:params:scim:api:messages:2.0:PatchOp containing an Operations array, and each operation has an op of add, remove or replace, an optional path, and, except for remove, a value.

The rules are short. An add with no path merges the value object into the resource; with a path on a singular attribute it behaves as a replace; with a path on a multi-valued attribute it appends without duplicating. A remove requires a path: removing a whole attribute removes all its values, and removing one element normally uses a value filter such as members[value eq "7d4f1c8a"]. A replace with no path merges, and with a path on a multi-valued attribute and no filter it replaces the entire set. On success the server returns 200 with the updated resource or 204 with no body, and must return 200 if the client asked for particular attributes; a remove whose path matches nothing gives 400 with scimType of noTarget.

That is the specification. The reality is that SCIM PATCH is where interoperability goes to die, for four structural reasons rather than the fault of any one vendor.

The same intent has two legal spellings. To remove one member from a group, a client may send a path filter with no value, or a path of members with a value array naming the member. Both appear in the wild, and a server that implemented only the first will reject the second with invalidPath or, worse, silently do nothing. The specification’s examples show one form and nothing forbids the other; the ambiguity has drawn errata reports against section 3.5.2 and remains unresolved in the published text as of August 2026.

An unfiltered replace is destructive. Read literally, {"op":"replace","path":"members","value":[...]} means the membership of this group is now exactly this list. A client meaning “add these” and a server reading “set to these” will between them empty a group, and this has happened in production to organizations you have heard of. Servers should treat an unfiltered replace on members as suspicious and log it loudly; clients should never send one.

Case is handled inconsistently. SCIM attribute names are case-insensitive, but op values, schema URNs and filter operators are treated differently by different implementations, so a client sending "op": "Replace" works against some servers and not others. And PATCH is optional: if /ServiceProviderConfig reports patch.supported as false, the only way to disable a user is a full PUT with active set to false, which means reading the resource first and handling attributes the client does not understand.

The practical consequence: write your client against three real service providers before believing it works, and write your server to accept both spellings of every ambiguous operation. Conformance to the letter of RFC 7644 is necessary and not sufficient.

Push, pull, and the reconciliation that has to sit between them#

There are exactly two ways to get a change from the system that knows about it into the system that needs it, and one way to find out that neither worked.

Push means the source calls the target: the identity system holds credentials for the application and, when something changes, makes a request — a SCIM POST or PATCH, a proprietary API call, an LDAP modify. Its latency is seconds to minutes, and it fails in one specific way: if the target is unreachable, the call errors or the token has expired, the change is lost unless the pusher has a durable queue and a retry policy. A push system without persistent retry silently drops changes during exactly the incidents when correctness matters most.

Pull means the target reads the source, or a job reads both, periodically fetching the list of users the target should have and adjusting it. Pull is robust, because a missed cycle is corrected by the next one, and slow, with latency equal to the polling interval. It scales badly too: pulling nine thousand users every fifteen minutes from forty applications is a great deal of load to produce nothing on most cycles.

Reconciliation is not an alternative to those two but the audit that catches what they missed. It reads the full state of source and target, compares them, and lists the differences: accounts in the target with no owner in the source, owners with no account, attributes that disagree, accounts enabled that should be disabled. The critical decision is which differences are corrected automatically and which are only reported, because automatic correction driven by a corrupted source is how you disable an entire company at three in the morning.

   HR system (authoritative source)
        |
        | 1. change feed  (push, seconds)
        v
   +-------------------+
   | identity system   |<---+
   +-------------------+    |
        |          ^        | 3. reconcile
        |          |        |    (nightly,
   2. push         | pull   |     full compare)
        v          |        |
   +-------------------+    |
   | target app / dir  |----+
   +-------------------+

  push  : fast, lossy if the target is down
  pull  : slow, self-healing
  recon : neither fast nor cheap; the only
          mechanism that finds what both missed

Larkfield runs all three. Push to SCIM-connected applications has a median latency of under two minutes; the pull path for four applications that only expose a nightly file export can take twenty-six hours; reconciliation runs at 02:00 daily and takes fifty minutes. In the three months to July 2026 it found 61 differences push had lost: 44 failed calls that had exhausted their retries, 12 changes made directly in a target by an administrator, and 5 accounts that existed in a target and had never existed in the source at all.

That last category deserves fear. An account in a target that the identity system did not create and does not know about is a rogue account, and reconciliation is the only mechanism that will ever find one. Every attacker who establishes persistence by creating an account produces exactly this signal.

Two things sit alongside those three. Some targets can be driven by a change feed rather than polled — a webhook, a message queue, or in SCIM’s case the Security Event Token profile of RFC 9967. And revoking a live session is a different problem from disabling an account: disabling does nothing to a token issued an hour ago and valid for eight.

Deprovisioning latency, measured#

Deprovisioning latency is the elapsed time from the moment a person’s entitlement to access ends — their last working day, the end of a contract, the closure of a project — to the moment each individual access no longer works. It is not one number but a distribution with a long tail, and the tail is what matters. Note what it excludes: it does not start when somebody told the identity system, and that gap is usually the largest single component, a human process problem rather than a technical one.

Larkfield measured it in July 2026 for the 217 people who left in the preceding six months.

Path Median 95th percentile
HR notified of leaving 3 days 19 days
Directory disabled 3 days 19 days
SCIM-connected apps 3 days 19 days
File-fed apps 4 days 21 days
Unconnected apps 74 days never

Read that table carefully, because it contains the argument of the chapter. Once told, everything connected is off within minutes, which is why the first four rows are dominated by the three-day human delay. The last row is where the breaches live: nineteen applications at Larkfield are connected to nothing, their accounts go when somebody remembers, and the only reason the median is 74 days rather than infinity is that a quarterly recertification catches most of them.

Published audits find the same shape. American agencies are audited annually against the Federal Information Security Modernization Act, and those reports are public and contain hard counts. The audit of the National Archives and Records Administration for fiscal year 2025 — OIG Audit Report No. 25-AUD-08, dated 30 September 2025, performed by Sikich CPA LLC — found that 406 of 3,890 network user accounts had not been logged into for more than 90 days and had not been disabled as the agency’s own policy required, and that of the staff who left between 1 October 2024 and 31 March 2025, 20 still had enabled accounts. The agency’s own procedure, in a version dated 31 December 2024, states that accounts will be disabled after 60 days and de-provisioned after 90.

The most instructive line in that report is not a number. The agency explained that gaps in its operations team’s understanding of its own account management scripts “led to an unintended re-enabling of accounts that NARA had previously disabled due to inactivity, including accounts of separated users”. Automation had turned accounts back on. If you take one operational lesson from this chapter, let it be that the disable step must be verified afterwards by an independent job, because the thing that disabled the account and the thing that re-enabled it can both be yours.

Vendor surveys report much larger numbers and read differently. A study published by Beyond Identity on 10 February 2022 surveyed 1,121 people and reported that 83 per cent of former employees had continued to access accounts at a previous employer; its authors state plainly that the data are self-reported and subject to exaggeration. That is a claim about what people say, not a measurement of accounts.

For how often credentials feature in real intrusions, the annual Verizon Data Breach Investigations Report is the standard reference, and the 2026 edition — the nineteenth, covering October 2024 to November 2025, examining more than 31,000 incidents of which more than 22,000 were confirmed breaches across 145 countries — records a shift. Exploitation of vulnerabilities is now the most common initial access vector for breaches at 31 per cent, while credential abuse, the previous leader, fell to 13 per cent from 22 per cent in the 2025 edition. Two cautions before concluding that credentials no longer matter: regional figures range from 25 per cent of initial access in Asia and the Pacific to 6 per cent in Europe, the Middle East and Africa, and an initial access vector is only the first step, since credentials are used at every later stage.

The same report contains a figure that belongs precisely here. In third-party cloud exposures, only 23 per cent of organizations fully remediated missing or improperly secured multi-factor authentication on their cloud accounts, and while half of those findings were resolved within a month, for weak passwords and permission misconfigurations the time to resolve half of all findings was close to eight months. That is deprovisioning latency by another name: the interval between knowing about an access problem and it no longer being true.

The orphan account, in the wild#

Three incidents, all documented in primary sources, make the shape of the risk concrete.

Colonial Pipeline, May 2021. The intrusion that shut a fuel pipeline serving the eastern United States began, according to Mandiant’s investigation and the testimony of chief executive Joseph Blount to the United States Senate on 8 June 2021, with one set of credentials for a legacy virtual private network profile. The account was not in active use, its password was complicated — Blount said explicitly it was not a “Colonial123” type of password — and it had only single-factor authentication. An unused account that still worked.

Snowflake customers, 2024. In a campaign Mandiant tracks as UNC5537, attackers used credentials stolen years earlier by information-stealing malware to log into cloud data warehouse accounts at roughly 165 organizations; Mandiant reported that the affected instances did not require multi-factor authentication and that in many cases the credentials had not been rotated for as long as four years. Snowflake confirmed separately that a threat actor had obtained the personal credentials of a former employee and reached demo accounts with them, possible because those accounts were not behind the company’s single sign-on or multi-factor authentication, unlike its corporate and production systems. A former employee’s account on a system outside the governed estate is the archetype of this chapter.

Cisco, 2018. Sudhish Kasaba Ramesh resigned in approximately April 2018 and, five months later on 24 September 2018, accessed Cisco’s cloud infrastructure on Amazon Web Services without permission and deployed code that deleted 456 virtual machines supporting WebEx Teams, shutting down over 16,000 accounts for up to two weeks. According to the Department of Justice, Cisco spent approximately 1.4 million United States dollars in employee time on restoration and refunded over one million dollars to customers; Ramesh was sentenced on 9 December 2020 to 24 months in prison and a 15,000 dollar fine. Five months of retained access is the ordinary result of an account in a system the leaver process did not know existed.

The control frameworks all address this, and phrase the same requirement differently.

Framework Reference Requirement
NIST SP 800-53 AC-2(3) disable within a set period
NIST SP 800-53 PS-4 a. disable on termination
CIS Controls v8.1 5.3 dormant after 45 days
PCI DSS v4.0 8.2.5 terminated: immediate
PCI DSS v4.0 8.2.6 inactive: within 90 days

NIST Special Publication 800-53 is the American federal control catalogue; Revision 5 is current and NIST issued Release 5.2.0 on 27 August 2025. AC-2, Account Management, runs to twelve lettered requirements covering account types, account managers, approval for creation, monitoring of use, notification within a defined period when accounts are no longer required and when users are terminated or transferred, review at a defined frequency, and — the item everybody forgets — aligning account management with personnel termination and transfer processes. Its enhancements include AC-2(3) for disabling accounts that have expired, are no longer associated with a user, violate policy or have been inactive; AC-2(7) for privileged accounts; and AC-2(13) for disabling accounts on discovery of significant risk. Separation of duties is AC-5, least privilege AC-6, personnel termination PS-4, and personnel transfer PS-5, the control that covers the mover.

Note the honest disagreement in that table. PCI DSS says immediate for a termination, the CIS Controls say 45 days for dormancy, NIST leaves the number to you. They are not in conflict, because they answer different questions — how fast after a known event, against how long before we assume no event was recorded — but organizations routinely copy the 90-day dormancy figure into their termination procedure and then wonder why an auditor objects.

Access recertification that produces a decision#

Recertification, also called attestation or access review, is the periodic exercise of asking somebody responsible whether access that exists should continue to exist. Every serious framework requires it: NIST SP 800-53 AC-2 requires accounts to be reviewed at an organization-defined frequency; ISO/IEC 27001:2022 folds review and removal into Annex A control 5.18, Access rights, which absorbed three separate controls from the 2013 edition; PCI DSS v4.0 requirement 7.2.4 requires all user accounts and related privileges, including third-party accounts, to be reviewed at least once every six months, a best practice until 31 March 2025 and mandatory after it. In listed companies the pressure usually arrives through section 404 of the Sarbanes-Oxley Act of 2002, which requires management to assess internal control over financial reporting.

The mechanics are simple: choose a scope, generate for each reviewer the list of items they are responsible for, collect a keep-or-remove decision per item, act on the removals automatically, record everything. The failure has three shapes.

The first is volume. A reviewer given 400 lines will approve 400 lines, and decision quality collapses somewhere above thirty to fifty items per reviewer. Ask for less rather than more sternly: exclude access granted automatically by role and reviewed at role level, exclude what was reviewed within the period, campaign only on the exceptions.

The second is comprehension. SAP_FI_DISP_ALL means nothing to a line manager. Every item needs a business description written by the entitlement’s owner, and an item nobody can describe in a sentence is itself a finding.

The third is incentive. Approving is free and revoking is risky, so the default answer is yes. The counter-measures are structural: record the reviewer’s name against each decision, independently re-review a sample of approvals, report per-reviewer approval rates to their managers, and make removal cheap and reversible, because if a revoked entitlement can be restored in ten minutes the fear of revoking drops sharply.

Two campaign shapes are frequently confused. A user-centric campaign asks a manager about their staff; a resource-centric campaign asks an application owner about their system. Managers know their people, application owners their systems, and serious programmes run both. Micro-certification, triggered by an event rather than a calendar — a mover firing a review of only the access the move made questionable — is the most effective variant and the least often implemented, because it needs the mover event detected reliably first.

Larkfield’s numbers tell the story. Its 2025 annual campaign covered 9,140 identities and 214,000 entitlement lines, took eleven weeks and produced a 99.1 per cent approval rate. Its 2026 redesign campaigned only on privileged entitlements, entitlements with no owner, and access held by people who had changed job in the preceding year: 11,200 lines, four weeks, a 71 per cent approval rate. The second removed 3,248 entitlements; the first removed 1,926 from a population nearly twenty times the size.

Privileged access: standing, just-in-time, and the sealed envelope#

Privileged access can change the system rather than merely use it: create accounts, read every record, alter logs, deploy code, move money. Its risk is not proportional to its volume — usually under two per cent of the accounts and most of the damage.

Standing privilege means the privilege is attached to the account permanently, so the account is a member of the administrators group at midnight on a Sunday when nobody is working. It is the historical default, it is simple, and the window of exposure is the entire life of the account.

Just-in-time privilege means the account is eligible for the privilege but does not hold it. To use it the human requests activation, which may require a justification, a second factor, an approval from somebody else and a ticket reference; the privilege is granted for a bounded period and removed automatically. Microsoft’s Entra Privileged Identity Management, the most widely deployed implementation, allows the maximum activation duration to be set between one and 24 hours, with optional requirements for multi-factor authentication, a Conditional Access authentication context, a justification, a ticket number and an approver.

Measure the benefit as the reduction in standing privilege: count the accounts holding each privileged role at a random moment, not those that could hold it. An organization moving 300 standing administrators to eligibility, with an average of nine active at any time, has cut its exposure by a factor of thirty-three. Three caveats. Just-in-time does not reduce the damage available during an activated window; an attacker controlling an eligible account can usually activate it unless approval by a different human is required, which is why approval rather than activation is the control that matters for the most dangerous roles; and an approval workflow that approves within seconds is a rubber stamp with extra steps.

Break-glass accounts are the deliberate exception, existing so that the loss of the identity system does not lock everybody out permanently. The guidance has changed in ways that matter, so state it with a date. As of Microsoft’s guidance updated in June 2026: create two or more emergency access accounts, cloud-only on the tenant’s default domain, neither federated nor synchronized from on-premises; exclude them from any Conditional Access policy that would block or restrict sign-in; use a phishing-resistant passwordless method, with a FIDO2 passkey recommended and certificate-based authentication as the alternative; assign the Global Administrator role as a permanent active assignment rather than an eligible one, so the account does not depend on the privileged access system working; alert on every use and review it afterwards; store credentials in separate secure physical locations; and validate the accounts at least every 90 days and whenever IT staff or subscriptions change.

Note the direction of travel. The older advice was to exclude the emergency account from multi-factor authentication entirely; the current advice is a method that is both strong and independent of the systems that might have failed. A password in an envelope is no longer the recommendation, and a break-glass procedure that still describes one is dated.

Model Privilege held Main risk
Standing always full-life exposure
Just-in-time on activation window plus approval
Break-glass reserved undetected use

Service accounts: the ungoverned population#

A service account is used by a program rather than a person: an application connecting to a database, a scheduled job moving files, an integration calling an API. In a typical enterprise they are a large minority of the accounts and the majority of the privilege.

They are ungoverned for structural reasons, not lazy ones. They have no joiner event, because a project created them, and no leaver event, because nothing leaves. They are excluded from the password policy, because rotation breaks the thing that uses them; from multi-factor authentication, because there is nobody to present a factor; and from recertification, because a campaign built around managers has nowhere to put an account with no manager. The risks follow: the credential sits in plain text in a configuration file on more machines than anybody knows, the account has far more privilege than the task requires because the fastest way to make an integration work at two in the morning is to grant more, and the human who understood it has left, which makes it an orphan nobody dares disable.

Bringing them under governance is a well-trodden sequence in which the order matters.

First, inventory. Find them: accounts with no matching worker record, accounts flagged by naming convention, accounts whose password never expires, accounts authenticating from server addresses rather than workstations, and in Active Directory accounts with a service principal name. The CIS Critical Security Controls v8.1 make this its own safeguard, 5.5, alongside 5.1 for an inventory of all accounts and 5.3 for disabling dormant accounts after 45 days.

Second, ownership. Every service account gets a named human owner and team, with a rule that an owner who leaves triggers reassignment. This step alone converts the population from ungoverned to governed and replaces no technology. Third, purpose and dependency: record what the account is for, what calls it and what breaks if it stops, because without that nobody will ever agree to disable one.

Fourth, credential handling. Move from a password in a file to a managed credential. On Windows, group managed service accounts remove the human entirely: the domain controller generates and rotates the password and authorized hosts retrieve it, so no person ever knows it. Windows Server 2025 added delegated managed service accounts, intended to replace a conventional service account with a managed one that inherits its identity. That feature also shows why new machinery needs the same governance as old: in research published in 2025, Akamai researcher Yuval Gordon described an attack named BadSuccessor that abused delegated managed service accounts to escalate privilege in the default configuration, and reported that in 91 per cent of the environments examined, non-administrative users already held the permissions needed to perform it.

Fifth, expiry. Every service account gets a review date — not a password expiry, a date on which somebody must assert it is still required. Accounts whose owner does not respond are disabled, not deleted, with a window to reverse it. An organization that starts at step four, rotating credentials before knowing what depends on them, will cause an outage in the first week and lose the mandate to continue.

Segregation of duties as machine-checkable policy#

Segregation of duties — separation of duties in American documents — is the principle that no single person should be able to complete a sensitive transaction alone. It is older than computing: whoever orders the goods should not sign the cheque. NIST SP 800-53 AC-5 requires an organization to identify and document the duties of individuals and define system access authorizations to support that separation, noting that violations can span systems and application domains; ISO/IEC 27001:2022 carries it as Annex A control 5.3. Both are terse because these are business rules, not security rules, and only the business can write them.

A rule has three parts: two or more capabilities that must not be combined, the scope over which the combination is forbidden, and what to do about it. The classic example is procurement to payment, expressed in an SAP system with transaction codes: creating a vendor master record, XK01 centrally or FK01 in accounting, combined with entering an incoming invoice, FB60, or running the automatic payment program, F110. A person with both can create a supplier that does not exist and pay it, and SAP rule sets contain well over a hundred such combinations. The identity equivalents matter as much: creating accounts combined with granting privileged roles, granting access combined with approving requests, and administering a system combined with deleting its audit logs — exactly the case AC-5 calls out, that those who administer access control should not administer audit.

Written as policy, a rule looks like this. The syntax is illustrative rather than any product’s.

rule SOD-P2P-01
  name    "Create vendor and release payment"
  severity high
  scope   entity = "Larkfield Group"
  conflict
    set A = { SAP:XK01, SAP:FK01 }
    set B = { SAP:F110 }
  mitigating_control
    id     MC-114
    text   "Payment run reviewed by Treasury,
            evidence retained 12 months"
    expiry 2027-03-31
  on_detect  raise_violation, notify owner
  on_request block, allow_override_by CFO

Three things in that block are load-bearing. Scope matters because a conflict inside one legal entity may be acceptable across two, and a rule set that cannot express the boundary produces thousands of false violations and is ignored within a month. The mitigating control matters because in a small organization some conflicts cannot be removed — there are four people in the finance team and somebody must do both — so the mature answer is to record the conflict and the compensating control, name its owner, and give it an expiry date so it is re-examined rather than becoming permanent by silence.

The two actions, on_detect and on_request, are the point most often missed. Detective segregation of duties runs over what people already hold and reports violations. Preventive segregation of duties runs when access is requested and refuses the combination before it exists. They share conflict definitions and need different plumbing: detection needs a complete picture of current access from every system, prevention needs to sit inside the request workflow. Organizations build detection first, discover a four-figure violation count, and then find they cannot clear it faster than new violations arrive, because nothing is stopping them being created. Prevention stabilizes the number.

One honest caveat. These rules are only as good as the mapping from technical entitlements to business capabilities, and that mapping decays with every application upgrade. Budget for maintaining it, or the rule set becomes a document about a system you no longer run.

The audit query set that finds the accounts nobody owns#

This is the practical core of the chapter. They assume a small, boring data model any organization can assemble in a week: a table of accounts collected from every system, a table of people from the authoritative sources, and a link between them. The link is where the intellectual work lives; the queries are trivial.

-- Data model assumed by the queries below.
-- account : one row per account per system
--   (system_id, account_name, account_id,
--    enabled, last_used, owner_person_id,
--    is_service, created_at)
-- person  : one row per known human
--   (person_id, source, status, end_date)
-- entitlement : (system_id, account_id, ent_id)
-- ent_owner   : (system_id, ent_id, owner_person)

Query one finds accounts with no owner at all. That is the definition of an orphan, and it is the query most organizations have never run.

SELECT a.system_id, a.account_name, a.created_at,
       a.last_used
FROM   account a
LEFT   JOIN person p
       ON p.person_id = a.owner_person_id
WHERE  a.enabled = TRUE
  AND  (a.owner_person_id IS NULL
        OR p.person_id IS NULL)
ORDER  BY a.last_used NULLS FIRST;

Query two finds accounts whose owner has left, with the age of the failure in days. Read the top twenty aloud in a meeting; it is the most effective governance intervention available.

SELECT a.system_id, a.account_name,
       p.end_date,
       CURRENT_DATE - p.end_date AS days_late
FROM   account a
JOIN   person p ON p.person_id = a.owner_person_id
WHERE  a.enabled = TRUE
  AND  p.status = 'terminated'
  AND  p.end_date < CURRENT_DATE
ORDER  BY days_late DESC;

Query three finds dormancy against whatever threshold your policy claims. Accounts never used are separated out, because an account created and never used is a different failure from one used and abandoned.

SELECT a.system_id, a.account_name, a.last_used,
       CASE WHEN a.last_used IS NULL
            THEN 'never used'
            ELSE 'dormant' END AS kind
FROM   account a
WHERE  a.enabled = TRUE
  AND  (a.last_used IS NULL
        OR a.last_used < CURRENT_DATE - 90)
ORDER  BY a.last_used NULLS FIRST;

Query four finds service accounts with no active owner, which is the more common and more dangerous case than no owner recorded at all.

SELECT a.system_id, a.account_name,
       a.owner_person_id, p.status
FROM   account a
LEFT   JOIN person p
       ON p.person_id = a.owner_person_id
WHERE  a.is_service = TRUE
  AND  a.enabled = TRUE
  AND  (a.owner_person_id IS NULL
        OR p.status <> 'active');

Query five finds entitlements nobody owns — an entitlement with no owner cannot be described, and one that cannot be described cannot be reviewed — by joining entitlement to ent_owner and keeping the rows where no owner matches.

Query six is reconciliation in one statement: accounts that exist in a target and were never created by the identity system. These are the rogue accounts, including every account an attacker created for persistence.

SELECT a.system_id, a.account_name, a.created_at
FROM   account a
WHERE  a.enabled = TRUE
  AND  NOT EXISTS (
         SELECT 1 FROM provisioning_log l
         WHERE l.system_id  = a.system_id
           AND l.account_id = a.account_id);

Against a directory you can ask some of these directly. This LDAP filter finds enabled Active Directory accounts whose last recorded logon is older than a given timestamp; the bit-and matching rule 1.2.840.113556.1.4.803 tests bit 2 of userAccountControl, the disabled flag, so the negation selects enabled accounts.

(&(objectCategory=person)(objectClass=user)
  (!(userAccountControl:1.2.840.113556.1.4.803:=2))
  (|(lastLogonTimestamp<=133700000000000000)
    (!(lastLogonTimestamp=*))))

One correctness warning, because this implementation detail surprises people. In Active Directory lastLogonTimestamp is deliberately not updated on every logon: by default it is refreshed only when the stored value is more than about fourteen days old, so that it can replicate between domain controllers without constant traffic. It can therefore lag reality by a fortnight, which is adequate for finding accounts dormant for 90 days and wrong for asking whether somebody logged in this morning. For that, query the non-replicated lastLogon attribute on every domain controller and take the maximum.

In SCIM the equivalent question is a filter on the collection. This asks for inactive users, ten at a time, returning only the attributes a report needs.

GET /scim/v2/Users?filter=active%20eq%20false
    &attributes=userName,externalId,meta.lastModified
    &startIndex=1&count=10 HTTP/1.1
Host: payroll.larkfield.example
Accept: application/scim+json

Two operational notes. Run these as a scheduled job with results delivered to named owners, not as a one-off report to a security team, because a list nobody owns is the problem you are trying to solve. And record the count of each category over time against a target: what matters is not how many orphans you have today but whether the number is falling.

What SCIM does not do, and what arrived in 2025 and 2026#

The boundary of the standard is routinely oversold.

SCIM carries users and groups. It does not carry entitlements in any rich sense: the entitlements and roles attributes are in practice opaque strings meaning whatever the two ends agree, with no standard vocabulary for what a permission grants, and the working group draft on roles and entitlements had expired as of August 2026. Nor does SCIM carry approvals, requests or campaigns; it is the wire format for the result of a decision, not the decision.

The original specification also has no event or notification mechanism, which is the largest gap for our purposes and the reason so much of the industry polls. RFC 9967 of May 2026 closes it with SCIM events carried as Security Event Tokens under urn:ietf:params:scim:event, including prov:create, prov:patch, prov:put, prov:delete, prov:activate and prov:deactivate, plus feed events. A provider publishing a deactivate event and a receiver consuming it can reach deprovisioning latency measured in seconds with no polling. As of August 2026 that specification is three months old and implementations are early, so treat it as direction rather than something you can buy.

RFC 9865 of October 2025 added cursor-based pagination, which sounds minor and is not: the original startIndex and count scheme is unstable across a changing dataset, so a client walking 200,000 users a hundred at a time can see one twice and miss another as records shift between pages. RFC 9944, also May 2026, adds a device schema.

One note on active work rather than established practice: several individual drafts submitted in 2026 propose SCIM extensions for governing autonomous software agents as provisioned identities. They are individual submissions, not working group documents, and nothing in them should be relied on. They exist for the reason this chapter exists: a new population has appeared that gets created enthusiastically and removed reluctantly.

The whole lifecycle, once through, with Larkfield’s values#

Priya Nair’s joiner run creates accounts in all eight targets between 02:00 and 02:14 on 25 August with active set to false; two fail on the first attempt because the manager reference did not yet exist there, and the retry queue succeeds at 02:44. At 07:00 on 7 September a scheduled activation PATCHes active to true in each target and she logs in at 08:51.

On Thursday 1 October Anita Bose moves from Payroll to Treasury: four entitlements to add, six to remove. The four are added within three minutes, two removals happen automatically, and four are held for approval as high-risk, completing on 9 October, while a micro-certification fires on the same event. Without it, this company’s historical behaviour would have been to add four and remove none.

Kemi Adeyemi left on Friday 31 July; her termination was recorded on 11 August, and the directory account and seven of her eight application accounts were disabled that night at 02:06. The eighth, in the unconnected transport management system, was found on Monday 17 August by query two above, six days after the termination was recorded and seventeen days after she stopped working there. Connecting that application to the provisioning system is scheduled for the first quarter of 2027. That is the honest ending: the failure was found, the account was closed, and the underlying gap has a date on it further away than anybody would like. Not a solved problem, but a measured one, with the tail getting shorter each quarter.

45.98 Common wrong ideas#

Wrong: Disabling somebody’s directory account cuts off their access. Right: It cuts off the access that depends on that directory. Applications with their own user tables and passwords never ask the directory anything, cloud services holding their own credentials are unaffected, and tokens issued before the disable keep working until they expire, because a token is a bearer document not re-checked against the account.

Wrong: SCIM is a standard, so two SCIM implementations will interoperate. Right: RFC 7643 and 7644 are Proposed Standards with large optional areas — PATCH, bulk, filtering, sorting and ETags are all optional and advertised at /ServiceProviderConfig — and the PATCH rules for multi-valued attributes admit two legal spellings of the same intent. Interoperability requires testing against real endpoints, not conformance to the text.

Wrong: The right way to handle a leaver is to delete the account. Right: The sequence is disable, revoke credentials and live sessions, reassign the data and service accounts they owned, retain for the period the law and the business require, and only then delete. Deleting first destroys the audit trail’s ability to resolve identifiers and orphans the data.

Wrong: Just-in-time privileged access means nobody has standing privilege. Right: It means nobody holds the privilege continuously; eligibility is itself a standing capability, and an attacker in control of an eligible account can usually activate it. What makes a real difference is approval by a different human, a short maximum activation window, and a complete audit record of the activated period.

Wrong: Service accounts are low risk because nobody logs into them interactively. Right: They typically hold more privilege than human accounts, keep credentials in plain text on several machines, are excluded from password rotation and multi-factor authentication, and fall outside every recertification campaign because they have no manager. The first effective control is not technical: give each one a named human owner and a review date.

Wrong: Reconciliation is a backup for push provisioning and can be skipped if push is reliable. Right: Reconciliation is the only mechanism that detects accounts created directly in a target system, which includes every account an attacker creates for persistence, and changes made by administrators outside the identity system. Push, however reliable, can only report on the changes it made.

Wrong: A break-glass account should be a username and password in a sealed envelope, exempt from multi-factor authentication. Right: Current guidance, as of Microsoft’s June 2026 documentation, is two or more cloud-only accounts using a phishing-resistant method with a FIDO2 passkey recommended, permanently assigned rather than eligible so they do not depend on the privileged access system, excluded only from policies that would block sign-in, alerted on every use, and validated at least every 90 days.

Wrong: If our deprovisioning is automated then our latency is minutes. Right: Latency is measured from the person’s last day, not from the moment the system was told. In published measurements the human delay in recording the departure dominates everything technical, and the tail belongs to the applications not connected to the automation at all.

45.99 Chapter summary in 20 lines#

  1. Every identity system must handle exactly three events for every population it serves: a joiner, a mover and a leaver.
  2. Joiners work well everywhere because somebody complains on the first morning; leavers work badly because nobody is waiting for a removal.
  3. Deprovisioning latency runs from the moment access should have ended to the moment it stopped working, and it is a distribution with a long tail rather than one number.
  4. The mover event is two operations, an add and a remove, and the industry-wide defect is that only the add is implemented, which produces privilege creep.
  5. An orphan account is an enabled account with no living owner; a rogue account is one in a target system that the identity system never created.
  6. SCIM 2.0 is defined by RFC 7642, RFC 7643 and RFC 7644 of September 2015, of which the latter two are Proposed Standards rather than full Internet Standards.
  7. The core schema defines User and Group resources under urn:ietf:params:scim:schemas:core:2.0:, plus an enterprise extension carrying employee number, department, cost centre and manager.
  8. The active attribute is the standard way to disable a user, but the specification leaves its exact meaning to the provider, so its effect on live sessions must be established per application.
  9. SCIM PATCH uses a PatchOp message with add, remove and replace operations and an optional path with value filters, and it is the least interoperable part of the specification.
  10. An unfiltered replace on a group’s members attribute means “set the membership to exactly this”, and sending one by accident empties the group.
  11. Push provisioning is fast and loses changes when the target is unavailable, pull is slow and self-healing, and only reconciliation finds what both missed.
  12. RFC 9967 of May 2026 adds SCIM events carried as Security Event Tokens, including activate and deactivate, allowing near-real-time deprovisioning without polling.
  13. The fiscal year 2025 audit of the National Archives and Records Administration found 406 of 3,890 accounts unused for over 90 days and still enabled, and 20 belonging to people who had left.
  14. That audit also found the agency’s own automation re-enabling accounts it had disabled, which is why the disable step needs independent verification afterwards.
  15. The 2026 Verizon Data Breach Investigations Report puts vulnerability exploitation first among initial access vectors at 31 per cent, with credential abuse at 13 per cent, down from 22 per cent a year earlier.
  16. Colonial Pipeline in 2021, Snowflake customers in 2024 and Cisco in 2018 were all reached through accounts that still worked when they should not have.
  17. Recertification finds access no event ever flagged, but only with few enough items, described well enough, and revocation cheap enough that “no” is a realistic answer.
  18. Just-in-time privileged access converts permanent exposure into a bounded window plus an audit trail, and approval by a second human matters most for the highest-risk roles.
  19. Service accounts are the ungoverned population, and the sequence that works is inventory, named ownership, purpose and dependencies, managed credentials, then a review date.
  20. Segregation of duties must be encoded twice, as detection over access that exists and as prevention inside the request workflow, scoped by legal entity with mitigating controls that expire.

Chapter sources: RFC 7642, RFC 7643 and RFC 7644, “System for Cross-domain Identity Management” (Definitions and Requirements; Core Schema; Protocol), IETF, September 2015, using sections 3.1, 4.1, 4.2, 4.3 and 7 of RFC 7643 and sections 3.2, 3.4.2.2, 3.5.1, 3.5.2 with 3.5.2.1 to 3.5.2.3, 3.6, 3.7, 3.12 and 8.1 of RFC 7644; RFC 9865, “Cursor-Based Pagination of SCIM Resources”, October 2025; RFC 9944, “Device Schema Extensions to the SCIM Model”, May 2026; RFC 9967, “SCIM Profile for Security Event Tokens”, May 2026; the IETF SCIM working group document list as at August 2026, including the expired drafts draft-ietf-scim-roles-entitlements-01 and draft-ietf-scim-use-cases-reloaded-02; OASIS Service Provisioning Markup Language 1.0 of October 2003 and 2.0 of April 2006; NIST Special Publication 800-53 Revision 5, Release 5.2.0 of 27 August 2025, controls AC-2 with enhancements AC-2(1) to AC-2(3), AC-2(7) and AC-2(13), AC-5, AC-6, PS-4 and PS-5; ISO/IEC 27001:2022 Annex A controls 5.3, 5.16, 5.18 and 8.2; PCI DSS version 4.0 requirements 7.2.4, 8.2.5 and 8.2.6, with 7.2.4 mandatory after 31 March 2025; CIS Critical Security Controls version 8.1 safeguards 5.1, 5.3, 5.5 and 6.2; the Sarbanes-Oxley Act of 2002, section 404; the Verizon 2026 Data Breach Investigations Report, nineteenth edition, covering October 2024 to November 2025, with the credential abuse figure of its 2025 edition; National Archives and Records Administration Office of Inspector General Audit Report No. 25-AUD-08 of 30 September 2025, performed by Sikich CPA LLC; Mandiant, “UNC5537 Targets Snowflake Customer Instances for Data Theft and Extortion”, 2024, with Snowflake’s own statement of May 2024 on a former employee’s demo accounts; the testimony of Joseph Blount to the United States Senate of 8 June 2021 and Bloomberg’s report of 4 June 2021 on the Colonial Pipeline account; United States Department of Justice, Northern District of California, press release of 9 December 2020 on the sentencing of Sudhish Kasaba Ramesh; Akamai security research by Yuval Gordon, “BadSuccessor: Abusing dMSA to Escalate Privileges in Active Directory”, 2025; Microsoft Entra documentation on emergency access accounts as updated 5 June 2026, on Privileged Identity Management role settings as updated 23 April 2026, on application provisioning as updated 4 March 2025 and on the Entra Connect Sync scheduler as updated 9 April 2025; and the Beyond Identity survey of 1,121 respondents published 10 February 2022, cited only as a self-reported figure.