Lion Cipher Lab
Catch orphaned access with a joiner-mover-leaver offboarding audit
- Identity & Access Management
- Intermediate
- ~50 min
- Free · no account required
Why it matters
Joiner-mover-leaver (JML) is the identity lifecycle: a joiner is given access, a mover's access changes with their role, and a LEAVER's access is supposed to be shut off the day they go. The leaver is where real organisations fail. HR marks someone terminated, the IdP maybe disables their single sign-on, and then the VPN account, the finance SaaS login and three other apps quietly stay enabled for weeks because nobody wired those systems to the HR event. That is 'orphaned access' -- an enabled login that belongs to someone who no longer works here -- and it is one of the quietest ways an…
What you'll learn
- defining the joiner-mover-leaver (JML) identity lifecycle and why the LEAVER is where it fails: an employee marked terminated in HR whose accounts stay enabled downstream is 'orphaned access', a top account-takeover and insider-risk vector
- reconciling one authoritative HR roster against several independent account exports (IdP/SSO, VPN, SaaS) by joining on a stable employee_id, never on name
- measuring orphaned access PER SYSTEM, because deprovisioning that fired in the IdP routinely misses the VPN and the SaaS app -- the same leaver can be clean in one system and wide open in another
- measuring the DEPROVISION LAG -- days between an employee's termination_date and the account actually being disabled -- and scoring mean and max against a 24-hour SLA so 'we offboard people' becomes a number you can defend
- separating true orphans from accounts with NO HR match at all (service accounts, shared logins, ghosts) and using an allowlist so the alert is actionable rather than a wall of false positives
- showing why a naive 'disable anything not tied to an active employee' sweep is dangerous (it breaks service and shared accounts) and why reconciliation plus an allowlist is the control that is safe to automate
- knowing the judgment: why name-matching breaks on rehires, name changes and duplicates; why 'no HR match' is never automatically 'delete'; and the pro pattern of authoritative HR source -> automated deprovision on the leaver event -> periodic reconciliation to catch the misses
Steps in this lab
- The leaver is where the lifecycle fails -- every term, defined once
- What this is NOT: where this sits next to its neighbours
- Create the HR roster and three system exports
- Write the reconciler -- and join on employee_id, not name
- Run it: orphaned access per system, and the deprovision lag
- The honest negative: the naive 'disable anything terminated' sweep
- Reconcile with an allowlist: disable the orphans, flag the unknowns
- Why employee_id, and why 'no HR match' is never 'delete'
- The judgment: the pattern a mature team actually runs