SCIM (System for Cross-domain Identity Management) is the standard that lets an identity provider automatically provision and deprovision users in a SaaS application. It works cleanly for Salesforce, Slack, and most modern SaaS tools. It does nothing for the internal admin panel your engineering team built three years ago, the legacy support tool with its own user table, or the vendor system whose only provisioning interface is a support ticket. Those systems still need joiner-mover-leaver automation — they just need a different pattern to get it.
Why This Gap Matters for SOC 2
Auditors sampling access reviews don't distinguish between "this system has SCIM" and "this system doesn't" — they expect evidence that access was granted appropriately and revoked promptly when someone leaves, regardless of the underlying technology. A company with clean SCIM-based deprovisioning for its SaaS stack but a manual, forgotten process for an internal tool still has a real control gap, and it's usually the internal tool that shows up in the auditor's sample.
The Adapter Pattern
Instead of building SCIM support into every internal application (rarely worth the engineering investment for a tool with a handful of admin users), we build export adapters that connect the identity provider's lifecycle events to whatever provisioning interface the target system actually offers — a REST API, a database write, or in some cases a scripted UI automation for systems with no API at all.
import boto3
def handle_leaver_event(user_email, target_systems):
"""Triggered by an IdP webhook or scheduled reconciliation job when
a user is deactivated in the source of truth (HRIS or IdP)."""
results = []
for system in target_systems:
if system["provisioning_type"] == "rest_api":
response = deactivate_via_api(system["endpoint"], system["api_key"], user_email)
elif system["provisioning_type"] == "database_write":
response = deactivate_via_db_flag(system["connection_string"], user_email)
elif system["provisioning_type"] == "ticket":
response = create_deprovisioning_ticket(system["ticket_queue"], user_email)
results.append({"system": system["name"], "result": response, "user": user_email})
log_deprovisioning_evidence(results) # immutable log for audit sampling
return results
The critical design decision is the immutable decision log — every provisioning and deprovisioning action, however it's executed, gets logged with a timestamp, the triggering event, and the target system, so evidence exists even for systems where the actual deactivation happens via a database flag or a support ticket rather than a clean API call.
Owner Maps Matter Here Too
Custom applications without SCIM usually also lack a clear entitlement owner mapped anywhere — see our related piece on entitlement owner mapping for access reviews for how we typically pair this adapter pattern with clear ownership so the review, not just the provisioning, has a home.
What This Looks Like in Practice
For a mid-market company running a mix of SaaS tools and 3-4 internal or legacy applications, a typical engagement builds adapters for the highest-risk internal systems first — anything touching customer data or financial systems — while leaving lower-risk internal tools on a documented manual process with a clear owner and review cadence, since not every system needs full automation to close the audit gap.
Frequently Asked Questions
Does this require the internal application to have any API at all?
No — for systems with zero API, the adapter can trigger a tracked ticket workflow instead of a direct API call, which still produces the evidence trail auditors need, even though the actual deactivation step remains manual.
How is this different from building full SCIM support into the application?
Full SCIM support means the application implements the SCIM protocol itself, which is a real engineering investment most internal tools don't warrant. The adapter pattern achieves the same governance outcome — automated or tracked lifecycle events — without requiring protocol-level changes to the target application.
What SOC 2 control does this evidence support?
This primarily supports CC6.2 and CC6.3, covering timely provisioning and deprovisioning of access, especially for the "non-standard systems" gap auditors specifically probe for once they see a company has SCIM coverage elsewhere.
How long does building one of these adapters typically take?
For a system with a usable REST API, an adapter is often a matter of days. For systems requiring database-level integration or UI automation, it can take longer and requires more careful testing to avoid unintended side effects.
See what an Access & Credential Governance Diagnostic finds in your non-standard systems → rutagon.com/contact or call 907-841-8407.