← All projects
Case study · Identity and access management · Employee offboarding

AccessOps

Automated employee offboarding that proves the person's access is really gone. When someone leaves, an HR event shuts off their access in Microsoft Entra ID, Keycloak and an Active Directory-compatible directory, and each system is checked to confirm the change.

Status
Public source and demo, signed v0.4.0 release
Timeline
October 2026
Stack
Python, Django, PostgreSQL, React, TypeScript, Docker
Works with
Microsoft Entra ID (Graph), Keycloak, Samba directory (LDAPS, Kerberos), OPA
A departure case in the public demo: the next step, required actions grouped by phase and the evidence source of each action
A departure case in the public demo, which runs in your browser with synthetic data.

Key decisionMeasure what disabling an account leaves behind instead of assuming it, and never let a statement count as proof.

What it shows

Real identity systems

Offboarding runs against Microsoft Entra ID (through Microsoft Graph), Keycloak and a Samba directory, not mock-ups.

Testing that finds real gaps

Before-and-after checks found 6 gaps, like sessions and Kerberos tickets that kept working after the account was disabled.

Security engineering

MFA for operators, policy checks that deny when unsure, signing-key rotation and a leaked-key drill.

Audit-ready controls

Nobody can close their own case, every step records its proof, and controls map to NIST SP 800-53.

How it works

Offboarding usually ends when someone disables the main account. AccessOps turns each departure into a case with an owner, a four-hour target and a step for every system the person could still reach.

AccessOps flow: an HR event opens a case in the Django and PostgreSQL backend; every action is checked by OPA; a durable worker applies and reads back changes in Keycloak, the Samba directory and a Microsoft Entra test tenant; an independent reviewer closes the evidence packet. HR departure owner, 4-hour target Case backend Django + PostgreSQL Policy check AuthZEN → OPA Durable worker apply, then read back Independent closure exact packet, immutable Real providers, read back after every change Keycloak · SCIM Samba · LDAPS Entra · Graph

Keycloak and the directory run in a local Docker lab; Entra is a free test tenant. The public demo is a separate browser simulation and never calls either.

Explore the case flow Choose a stage

  1. 01Shut off access
  2. 02Check it worked
  3. 03Track the rest
  4. 04Close

Stage 01 / Shut off access

Can the person still act right now?

One step disables the account, removes group rights, ends sessions and suspends any automated agents the person sponsors. Apps that check tokens themselves get a signed signal to refuse the person's tokens.

Boundary

Work an agent already started is not recalled.

Stage 02 / Check it worked

Did each system actually change?

Each system is read again before the step counts. For a day afterward, any sign-in by the person blocks closure until someone investigates it.

Boundary

Unknown, partial or two-hour-old readings keep the step open.

Stage 03 / Track the rest

What can't be reached directly?

GitHub, Microsoft 365 handover and shared credentials become steps with an owner. Imported reports and owner statements are labeled as what they are.

Boundary

Missing from a GitHub list doesn't prove access was removed.

Stage 04 / Close

Who can say it's done?

Someone who doesn't own the case reviews the exact evidence and closes it. The closed record can't be changed.

Boundary

Closure records reviewed evidence; it doesn't prove every copy or session is gone.

What testing found

Each gap came from a check that failed against the live systems. The failed runs stay published next to the fix.

Gaps found by testing, what happened before the fix, and what happens now
GapBefore the fixNow
Group membershipStayed after the account was disabledEvery grant is removed and re-checked
App sessionsThe person stayed signed in to the appSessions end; done only at zero
Tokens apps check themselvesAccepted for 2 more minutesRefused 3 s after the cut-off
A leaked signing keyA forged token was accepted; apps trusted a removed key for 5 minutesApps drop a removed key in 60 s
Key rotationValid tokens refused for 30 sNew key published first; none refused
Kerberos ticketsKept the removed group's rightsCan't be revoked; the case shows when they expire (up to 10 h)

One failed check was right. The test backdated a departure and then signed in, which counts as access after departure. The test changed, not the rule.

Results

October 5, 2026, with synthetic users. Every live suite passed on its latest run.

Recorded checks and their results
CheckPassed
Departure case through Keycloak18 / 18
Departure case with a Samba directory account28 / 28
Sessions and tokens, before and after22 / 22
HR event to access shut off10 / 10
Microsoft Entra ID, free test tenant11 / 11
Sign-in after departure7 / 7
Operator MFA14 / 14
Key rotation and leaked-key drill13 / 13
Signed v0.4.0 release (GitHub CI)401 / 401, provenance and SBOM verified

Design choices

Proof labels that never upgrade

Each step shows where its proof came from: a live reading, an imported report, an owner statement or the browser simulation.

Approvals tied to the exact change

New access needs a second person's approval for that exact change, valid for 15 minutes. Cutting access needs none.

Connectors limited to their own objects

The directory and Entra connectors can touch only their test objects; live runs confirmed they refuse anything else.

One next step per case

Each case shows the next step and who can take it, in dark and light themes checked for accessibility.

Overview ranking open departures by urgency, with the next step for each
Departures ranked by urgency, each with its next step.
Evidence page: what each kind of evidence can prove, the signed release and recorded runs including failures
Recorded runs, failed attempts included, beside the signed release.

Limits

Discuss AccessOps

Ask about what disabling an account left behind, the leaked-key drill or how the Entra connector is kept to its test objects. Email me at aagarwalcollege@gmail.com.

Project screenshot

Open original ↗

View full size to read details. Scroll or swipe to move around the enlarged image.