Skip to main content
INS // Insights

Access Deprovisioning Automation: Closing the JML Gap

Updated August 2026 · 7 min read

Incomplete or delayed access deprovisioning shows up in 30-40% of SOC 2 audits as the single most common finding — more common than missing quarterly reviews, more common than weak logging. It is also the easiest one to catch: an auditor pulls the HRIS termination list, cross-references it against active accounts in your identity provider, and finds three names that should have lost access on day one and didn't.

Access deprovisioning automation exists to close exactly that gap. Not another access review — a real-time trigger from the system of record for employment status (HRIS) into every downstream system that grants access, so "terminated" and "access revoked" happen in the same transaction instead of the same quarter.

Why Deprovisioning Fails Even When Access Reviews Pass

Most mid-market companies have a quarterly access review process. Fewer have automated deprovisioning. That gap matters because reviews are retrospective — they catch a stale account weeks or months after the fact — while deprovisioning failures create actual exposure in the window between termination and discovery.

The typical failure pattern:

  1. HR processes a termination in the HRIS (Workday, BambooHR, Rippling)
  2. IT is notified via a ticket, Slack message, or email — a manual, async step
  3. IT deprovisions the "known" systems: SSO, email, laptop MDM
  4. Systems provisioned outside the SSO flow — a database role granted directly, a GitHub org membership added manually, a legacy on-prem app with local accounts — are missed entirely

The third and fourth steps are where the audit finding lives. SSO-integrated SaaS deprovisions cleanly. Everything provisioned out-of-band survives the termination.

The Architecture: Event-Driven Deprovisioning, Not a Cron Job

The fix is not a nightly script that diffs the HRIS against every system — that still leaves a 24-hour exposure window and doesn't scale past a handful of integrations. The fix is an event-driven pipeline that treats HRIS termination as the trigger, not the audit source.

# hris_webhook_handler.py — receives termination events, fans out revocation
import json
import boto3

sns = boto3.client("sns")

REQUIRED_FIELDS = {"employee_id", "event_type", "effective_timestamp"}

def handle_hris_event(event, context):
    payload = json.loads(event["body"])
    if not REQUIRED_FIELDS.issubset(payload):
        raise ValueError(f"Malformed HRIS event: missing {REQUIRED_FIELDS - payload.keys()}")

    if payload["event_type"] != "termination":
        return {"statusCode": 200, "body": "ignored"}

    # Fan out to every downstream deprovisioning target in parallel —
    # SSO, AWS IAM, GitHub, database roles, VPN, physical badge system
    sns.publish(
        TopicArn="arn:aws:sns:us-east-1:123456789012:deprovision-fanout",
        Message=json.dumps({
            "employee_id": payload["employee_id"],
            "effective_timestamp": payload["effective_timestamp"],
            "trigger": "hris_termination",
        }),
    )
    return {"statusCode": 202, "body": "deprovisioning triggered"}

Each downstream system subscribes to the fanout topic with its own Lambda that knows how to revoke access for that specific system — an SSO deactivation call, an aws iam delete-login-profile + access key deactivation, a GitHub org membership removal, a database REVOKE statement. Every revocation writes a timestamped record to an immutable log, which becomes the deprovisioning-timeliness evidence an auditor actually wants: HRIS termination timestamp, revocation timestamp per system, and the delta between them.

The systems that resist this pattern — legacy on-prem apps with local user tables, vendor SaaS with no API, anything provisioned by hand — need an explicit compensating control: a documented manual runbook with the same timestamp logging, reviewed on the same cadence as the automated systems, not silently excluded from the evidence pack.

Movers Are Harder Than Leavers

Terminations get the attention because they're binary — access should go to zero. Role changes ("movers" in JML terminology) are the harder case: an engineer promoted to team lead should gain new access and lose the standing production database credentials they had as an IC, but most systems only add, never subtract, on a role change. This is where privilege creep actually accumulates — not from bad actors, from perfectly normal internal mobility that nobody circles back to clean up.

The pattern that works: define access as a function of current role, not a set of grants accumulated over time. Every role change re-derives the target entitlement set and diffs it against current entitlements — grants not implied by the new role get revoked automatically, not just flagged for a future review.

Frequently Asked Questions

What's the difference between access deprovisioning automation and an access review?

Access reviews are periodic and retrospective — they confirm existing access is still appropriate on a quarterly cadence. Deprovisioning automation is event-driven and immediate — it revokes access the moment a triggering event (termination, role change) occurs. Mature programs need both: automation to prevent the gap, reviews to catch anything automation missed.

How fast should deprovisioning happen after a termination?

Same-business-day is the standard most SOC 2 auditors expect to see evidence of; same-hour is achievable with event-driven automation and is increasingly the bar for privileged and production access specifically. The evidence that matters is the timestamp delta between the HRIS event and each system's revocation record, not a policy statement claiming a target.

What happens to systems that can't be automated?

Document them explicitly as manual-control systems with a named owner, a defined SLA, and the same timestamp-logging requirement as automated systems. An auditor will accept a documented compensating control; they will not accept an access review that silently excludes systems the automation doesn't reach.

Does this replace our GRC platform's offboarding checklist?

No — it feeds it. The GRC platform (Vanta, Drata, Secureframe, or whatever you run) is where the evidence gets stored and mapped to controls. This pipeline is the engineering layer that actually performs the revocation and generates the timestamped evidence the platform's checklist item is asking someone to manually confirm.

Where does joiner-mover-leaver automation start for a company that's never built any of this?

Start with terminations only — it's the highest-risk, most auditor-visible gap, and the HRIS-to-SSO integration is usually a single well-documented API. Add movers once terminations are reliably automated; movers require a defined role-to-entitlement mapping that most companies haven't built yet, and building it on a shaky foundation compounds the mess.


Rutagon builds the entitlement pipelines that connect HRIS termination and role-change events to real revocation across AWS IAM, SSO, and the internal systems your GRC platform can't reach on its own.

See what an Access & Credential Governance Diagnostic finds in your environment → rutagon.com/contact | 907-841-8407 | contact@rutagon.com

Related reading: User Access Review Automation · SOC 2 Access Review Failures Auditors Actually Flag · Security Automation Capability

External reference: AICPA Trust Services Criteria — CC6 Logical Access Controls