ndovuscim

SCIM GUIDE · LIFECYCLE

Lifecycle: deactivate, delete, and the hazards between

What DELETE means on each provider (deactivate, purge, refuse, never send, schedule), how soft delete and matching keys turn renames into deletions, and the ways a lifecycle can kill the integration that runs it.

01 · The DELETE-semantics arc

RFC 7644 Section 3.6 defines DELETE narrowly: a successful request returns 204 No Content, and resources SHOULD be deletable. Renaming or re-homing a user is PUT's job, not a delete followed by a create. What the section does not define is what "delete" means to the system of record behind the endpoint, and that meaning is entirely provider-specific. The same method deactivates in one provider, destroys in another, is refused by a third, is never sent by a fourth, and is scheduled for later by a fifth:

ProviderWhat DELETE doesSource
SalesforceA DELETE request to the Users endpoint does not delete the user. It has the same result as a PATCH that sets active to false, and it returns only HTTP 204 No Content. Hard delete is impossible through this API.mirror of the Salesforce platform-identity curriculum, corroborated by connector vendors, retrieved 2026-11-01 (lead-grade; official Help pages block automated retrieval)
GitHub (Enterprise Managed Users)DELETE removes all the user's data, anonymizes login, email, and display name, and erases PATs, SSH keys, OAuth authorizations, GPG keys, and SAML mappings. The action is irreversible. Deactivation is the separate PATCH active:false path.docs.github.com EMU SCIM reference, accessed 2026-11-01
SlackUsers can not be permanently deleted from Slack, they can only be deactivated. A duplicate email fails even when the existing user has been previously deactivated; freeing the email requires a manual edit.docs.slack.dev SCIM API docs, accessed 2026-11-01
Okta (as SCIM client)Okta uses a soft delete model: instead of sending a DELETE request it updates the user resource with active=false. Deleting an already-deactivated user sends nothing to the application at all.developer.okta.com SCIM concepts, accessed 2026-11-01
Google WorkspaceDeprovisioning is scheduled, not immediate: per app, suspend and/or hard delete run after a chosen delay of within 24 hours, 1, 7, or 21 days, set independently for app-off, user-suspended, and user-deleted events.Google Workspace provisioning help, published 2026-10-29, accessed 2026-11-01

An integration that assumes RFC semantics documents for one of these providers silently means something else on the next. A cleanup job that "deletes" test users against Salesforce has deactivated them; the same job pointed at GitHub EMU has destroyed them. Neither provider violates the RFC: 204 came back both times.

02 · Soft delete plus matching: every wrong choice is a duplicate or a deletion

Soft delete is the dominant model: Entra deactivates with active=false and expects the user to stay GET-able while inactive, exercising hard delete only when the application declares support for it (Entra provisioning tutorial, ms.date 2026-09-15). Soft delete couples lifecycle to matching, because a deactivated record still occupies its uniqueness space. The failure mode is documented in the wild: ssoready/ssoready #164 (October 2024) reports "SCIM sync with Entra leads to user being marked as deleted when changing email (userName)". The matching key changed on the source side, the client's correlation pass found no match, and the no-match path destroyed the account.

This is the same rule the primer starts: the matching key must be chosen for immutability before the first lifecycle event runs. The provider contracts differ in how much room they leave for the mistake. GitHub EMU requires the Entra objectid claim to equal externalId (docs.github.com, accessed 2026-11-01); Okta requires userName eq matching and adds an asymmetry on top: profile pushes never update status downstream, and Okta will not import users whose application-side status isactive=false, even on a full import (developer.okta.com SCIM concepts, accessed 2026-11-01). Entra's own soft delete mutates the source-side key by design: the UPN gets the object ID prepended on soft delete, a behavior Microsoft's Q&A confirms as intended (Microsoft Q&A 681860, January 2022).

The design rule that survives contact with all of them: treat deactivation as reversible and deletion as data-destructive, pick a matching key that never changes on either side, and decide explicitly what the client's "no match found" path does. Under that rule, a rename produces a PATCH; without it, the same rename produces a duplicate or a deletion.

03 · The lifecycle can kill the integration

The lifecycle the integration manages can reach back and break the integration itself. Three documented shapes:

Credential owned by a managed user. Datadog strongly recommends a dedicated service account for the SCIM application key, because a user-owned key "gets revoked" when that user is deprovisioned, which permanently breaks the integration (docs.datadoghq.com SCIM, accessed 2026-11-01). Provisioning turned itself off the first time it did its job on the wrong principal.

Scope that swallows deactivation. Rippling's connector applies provisioning only within its configured scope, and out-of-scope users stop receiving updates entirely, including theactive:false deactivation on termination (third-party connector guides, lead-grade, accessed 2026-11-01). The users most likely to need deactivation are the ones a narrow scope excludes.

Two writers, one store. Enabling SCIM in AWS IAM Identity Center locks manual user editing in the playground, and mixing Identity Store API mutations with SCIM causes directory drift; AWS ships an example SCP that denies those mutations while SCIM is on (AWS IAM Identity Center user guide, accessed 2026-11-01). AWS also expires SCIM bearer tokens after exactly one year, with sync stopping at expiry unless rotated (same guide). The lifecycle contract includes who may write, not only what is written.

04 · The availability risk: bot mitigation vs provisioning traffic

Provisioning traffic is automated traffic, and automated traffic is what WAFs and bot-mitigation rules are tuned to challenge. A Cloudflare community thread from February 2025 documents the collision: setting a "Managed Challenge" or "Block" for bots classified as definitely automated will challenge or block the Azure SCIM provisioning service, and the failure is hard to diagnose because no blocks show on the SCIM route (community.cloudflare.com thread 761399, February 2025). The provisioning service sees timeouts or connection failures; the application sees nothing at all.

The mitigation is allowlisting the client's published source ranges before the first sync, not after the first mystery outage. Entra publishes provisioning-service IP ranges under the AzureActiveDirectory service tag (Entra provisioning tutorial, accessed 2026-11-01). Availability engineering is part of the SCIM deployment even though no SCIM RFC mentions it.

05 · References

Normative - the documents this page's cites resolve to:

Secondary - the provider and incident documentation behind the page:

Prior art - the incident that names the failure class: