Identity systems fail gradually and then all at once. Under a few hundred users, manual group management and a shared spreadsheet of exceptions genuinely works. Somewhere past a thousand, the same practices produce an access model nobody can describe out loud.
Here is the order things came apart for us, roughly, and what actually held.
First to break: group membership by hand
Manual group assignment scales linearly with headcount and quadratically with reorgs. It is the first thing to go.
The fix is dynamic membership driven by attributes you already maintain — department, job title, location, employment type. The catch is that dynamic groups are only as good as the HR data behind them, which means the real project is data quality, not group rules.
If your directory attributes are inconsistent, dynamic groups will faithfully and automatically apply the wrong access to the right people.
We spent more time normalizing job titles than writing the rules. Worth it.
Second: the exception list
Every environment has one. A handful of people who need something outside the standard model, tracked informally, growing quietly.
Exceptions are not the problem. Untracked exceptions are. Once they live in a spreadsheet, they stop being reviewed, and by year two nobody remembers why a contractor has standing admin on a system they last used in a different role.
Move exceptions into access packages with an expiry and an approver. The exception still exists, but now it has a clock on it.
Third: joiner-mover-leaver
Joiners are easy — everyone notices when a new hire cannot log in. Leavers are mostly fine, because offboarding has a deadline and a checklist.
Movers are where access accumulates. Someone transfers teams and gains the new team's access without shedding the old. Do that a few times over four years and you have people whose permissions describe their career history rather than their job.
Attribute-driven groups solve this if you let them. The uncomfortable part is that removing access on transfer will break someone's workflow on day one, and you need leadership backing before it happens rather than after.
What held
Some things scaled better than expected.
- Conditional access. Written as a small number of broad policies rather than many narrow ones, it stayed comprehensible. Policy sprawl is a bigger risk than policy gaps.
- Single sign-on coverage. Every app onboarded to SSO stayed onboarded. This is the highest-durability work in the whole practice.
- Privileged access separated from daily accounts. Set up early, this never needed revisiting. Set up late, it is a migration.
Where to invest before you need it
If you are at a few hundred users and heading up, in order:
- Directory data quality. Everything downstream depends on it and it only gets harder to fix.
- SSO coverage. Every app you onboard now is one you do not migrate under pressure later.
- Access reviews with real owners. Not IT reviewing access — the people who understand the business context reviewing it, on a schedule.
- Lifecycle automation for movers, not just joiners and leavers.
None of this is exotic. It is the same four things every maturity model lists, which is exactly why it gets skipped: it reads as obvious right up until the point you need it and do not have it.