SCIM 2.0 Users provider (spec 015)#33
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Step 1 of spec 015. Adds the additive nullable/default `deleted` and `deleted_at` columns (+ accessors) to core's UserEntity so a SCIM DELETE can soft-delete a row while keeping it referentially intact, distinct from a merely deactivated user. Spec: docs/specs/015-scim-users-provider (#21) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Steps 2-7 of spec 015. New optional feature module (registered in the reactor, BOM
and -all), inert unless openelements.scim.token is set (@ConditionalOnProperty):
- Isolated /scim/v2/** security filter chain ordered ahead of the JWT chain, with a
constant-time static-token filter (ScimTokenAuthenticationFilter) and a SCIM-shaped
401 entry point.
- Reserved, permanently-inactive SCIM service principal (bootstrapped like the System
user) used as the audit actor for every SCIM write.
- Users resource: POST (201/409 uniqueness/400), GET/{id} (404 on missing/deleted),
GET list (userName eq / externalId eq, pagination, excludes soft-deleted + reserved),
PUT full-replace (undelete when deleted && active:true; never writes sub), DELETE
(soft: active=false/deleted=true/deleted_at=now), all in application/scim+json.
- Discovery (ServiceProviderConfig/ResourceTypes/Schemas), graceful Groups stub
(empty list + 501 on writes), SCIM Error envelope via a scoped @RestControllerAdvice.
- SCIM writes audited explicitly against the SCIM principal with the correct action.
Maps onto spec 012's UserEntity; SCIM never reads/writes sub, so JIT-login correlation
by externalId still adopts the row on first interactive login.
Spec: docs/specs/015-scim-users-provider (#21)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rovider Step 8 of spec 015. MockMvc + Testcontainers integration test covering the SCIM behaviors — token auth (valid/missing/wrong + no leak to the JWT chain), discovery, create/409/400, get/404/deleted, list/filter/pagination/exclusions, PUT replace/deactivate/undelete/404, soft DELETE + deactivation distinction, audit attribution to the SCIM principal, and the Groups stub — plus an ApplicationContextRunner test proving the module is inert without a token. 20 tests. Spec: docs/specs/015-scim-users-provider (#21) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ntry Step 9 of spec 015. docs/releases/upgrade-to-1.4.md documents enabling the optional SCIM module: depend on spring-services-scim (or -all), apply the additive deleted/deleted_at migration + reserved SCIM principal, and set openelements.scim.token, with the soft-delete/GDPR and Groups-stub/501 caveats. README lists the new module. Spec: docs/specs/015-scim-users-provider (#21) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The new NOT NULL deleted column has no DB default under Hibernate create-drop DDL, so SystemUserInitializer's raw INSERT (and the AuditLogIntegrationTest seed) must set it explicitly; otherwise the System user row fails to insert and audit actor lookup throws EntityNotFound. Sets deleted = FALSE. Spec: docs/specs/015-scim-users-provider (#21) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rovider # Conflicts: # docs/specs/INDEX.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the first slice of a SCIM 2.0 service provider as a new optional module
spring-services-scim: a bearer-token-authenticated, fully isolated/scim/v2/**surface that lets an IdP (Authentik / any RFC 7644 client) push-provision users onto spec 012'sUserEntity. Inert unlessopenelements.scim.tokenis set. Groups, PATCH, and Group→Role mapping are deferred to follow-ups.Spec
docs/specs/015-scim-users-provider/docs/specs/015-scim-users-provider/design.mddocs/specs/015-scim-users-provider/behaviors.mdChanges
deleted/deleted_atcolumns onUserEntity(soft delete, distinct from deactivation);SystemUserInitializerINSERT updated for the new column.spring-services-scim(registered in reactor, BOM,-all;@ConditionalOnProperty("openelements.scim.token")):/scim/v2/**security chain ordered ahead of the JWT chain; constant-time static-token filter; SCIM-shaped401entry point; reserved, inactive SCIM service principal as the audit actor.POST(201 / 409uniqueness/ 400invalidValue),GET/{id}(404 on missing/deleted),GETlist (userName eq/externalId eq, pagination, excludes soft-deleted + reserved principals),PUTfull-replace (undelete onactive:true; never writessub), softDELETE.ServiceProviderConfig/ResourceTypes/Schemas), Groups stub (empty list +501on writes), SCIMErrorenvelope via a scoped@RestControllerAdvice, allapplication/scim+json.docs/releases/upgrade-to-1.4.md(enable SCIM: dependency, migration SQL, token, caveats) + README module entry.Test coverage
-Pfull-build clean verify -Dmaven.javadoc.failOnWarnings=truegreen across all 10 modules (0 javadoc warnings).Notes
openelements.scim.token. SoftDELETEretains PII (FK integrity); GDPR erasure is a deferred module.upgrade-to-1.4.mdfor the 1.4.0 line; consolidate with the other 1.4 upgrade content as you see fit.Closes #21
🤖 Generated with Claude Code