SCIM: implementation status (SCIM-1 to SCIM-61)

Where each part lives, which suite covers each acceptance test, test 5
deferred to per-domain directories and test 31 unrun until a copy of
INBUXA's data, what was settled from the code, and the known limits.
This commit is contained in:
2026-09-19 09:59:53 -07:00
parent 3df72b355a
commit 00b2eb6f4b
+54
View File
@@ -855,6 +855,60 @@ cover the clients meanwhile.
tests imply `scim.example.com` and port 8899 (from addresses and URLs in tests imply `scim.example.com` and port 8899 (from addresses and URLs in
them). Confirm when rebuilding `mod.rs`. them). Confirm when rebuilding `mod.rs`.
## Implementation status
Built 2026-09-19 from this spec, clean-room, under the multi-tenancy hand-off
brief's rules. The wire contract is in `crates/scim-proto`, the service in
`crates/scim`, the endpoint and its authentication in
`crates/http/src/scim.rs`; upstream files carry hooks marked `inbuxa:`
(the domain flag in the domain cache, just-in-time sync in
`crates/common/src/cache/directory.rs`, session revocation in the push
router). Every SCIM operation is the same `x:Account` get, query or set
JMAP makes, as the service principal.
`scim::scim_tests` runs the rebuilt helpers (`tests/src/scim/mod.rs`), the
new `acceptance.rs` (tests 6 to 30, SCIM-14, and SCIM-58 to SCIM-60 through
`synchronize_account` itself) and the surviving `tenant.rs` (test 4); all
pass. With `SCIM_CONFORMANCE=1` it also runs the surviving
`conformance.rs` (tests 1 to 3), which passes: scim2-client's 12 lifecycle
steps, the 8 replayed Okta, Keycloak and Entra payloads, and scim2-tester
with errors only for its generated non-address `userName`.
- **SCIM-1 to SCIM-61:** built, with the limits below.
- **Test 5** (`oidc.rs`) is `scim_oidc_tests`, ignored until per-domain
directories (feature 9) are built (Decision, SCIM-61).
- **Test 31 (compat)** is `scim_compat`, ignored, and unrun until a copy of
INBUXA's data is provided. It checks observed 1.
- **Settled from the code, not a change of intent:**
- Locales are stored hyphenated (`en-US`, `ca-ES-valencia`), not with an
underscore as SCIM-26 assumed, so SCIM's form needs no conversion;
`ca-ES@valencia` is read as `ca-ES-valencia`. "A locale the server has
no translation for" is one outside the registry's locale list.
- `/Schemas` describes `meta` (as the mapping tables give it, without
`lastModified`): scim2-client builds its models from it.
- The five `scim.*` events (SCIM-54) have ids 637 to 641, the fork's own,
and are in the packaged schema's event list.
- **Known limits, not requirements of this spec:**
- Ending open sessions on suspension (SCIM-52) covers subscriptions to
changes (IMAP IDLE, JMAP event streams and WebSockets), and only on the
node that took the SCIM request. An IMAP, POP3 or ManageSieve session
already signed in and not idling isn't ended; by the code it keeps
working until it disconnects (not tested), and can't sign in again.
- A suspended account's cached HTTP credentials are refused with `403`
rather than `401`.
- Changing a group's membership writes each member in turn. Everything
is validated first, but a store failure midway leaves the change
partly made.
- `externalId` and group `displayName` uniqueness (SCIM-29, SCIM-34) are
checked before the write, without a lock, so two simultaneous writes
can both pass.
- With a `displayName` stored, a PATCH of only `name.givenName` or
`name.familyName` changes nothing, by SCIM-24's precedence.
- An email entry marked primary whose value isn't the `userName` is kept
as an alias.
- The conformance container runs on the host's network (a test-only
change), since a host firewall can drop the Docker bridge.
## Observed ## Observed
Settled on 2026-09-18 against INBUXA's live Enterprise server (Stalwart Settled on 2026-09-18 against INBUXA's live Enterprise server (Stalwart