Skip to content

finding: SCIMMemberReferenceSchema.type admits 'Group' (RFC 7643 §4.2) but stable @better-auth/scim rejects it twice over — declaration-vs-contract fork, latent (zero runtime consumers) #11820

Description

@os-warren

Filed unassigned — recording, not claiming. Surfaced by the #11697 field-level parity measurement (card comment 5399511853, executed probe against a real constructed @better-auth/scim@1.7.1 plugin); filed by the spec PM seat so the fork survives #11697's closure. Awaiting first-touch triage.

Measured

  • Ours: SCIMMemberReferenceSchema.type (packages/spec/src/identity/scim.zod.ts) admits 'User' | 'Group' — RFC 7643 §4.2 canonical values — and the nested-group case is pinned green (packages/spec/src/identity/scim.test.ts:380, "should support nested groups").
  • Stable upstream: @better-auth/scim@1.7.1 rejects 'Group' twice over — a zod refine (dist/index.mjs:22) and a BAD_REQUEST/invalidValue throw (:4594) — and its own discovery document advertises canonicalValues: ['User']. Probe case C (nested group) was REJECTED by the real endpoint.

So published spec surface (with a rendered docs page) advertises a capability the shipped implementation answers with a 400. The divergence is latent, not live: SCIMGroupSchema has zero runtime consumers repo-wide and in objectui (docs pages only) — nothing routes group payloads through packages/spec today, and no leg of #11632 does.

The fork (from the measurement report, verbatim options)

  • A — keep 'User' | 'Group': RFC-faithful and portable to any SCIM peer; cost is docs advertising what our own deployment refuses.
  • B — narrow to 'User': declared = enforced; a generated app is stopped at authoring time rather than by the IdP; cost is a knowing RFC 7643 §4.2 divergence plus retiring the pinned nested-group case. If taken, it is its own Clause-② card with the RFC divergence recorded — never a rider.
  • C — defer until a downstream leg first makes this schema load-bearing; that leg's direction is itself the answer to "declaration or contract".

Measurement's recommendation: C, with B if the maintainer wants it closed now (the make-AI-metadata-hard-to-get-wrong axis favours B; the zero-consumer reading and startup scope discipline favour C).

Refs: #11697 (the measurement, comment 5399511853) · #11632 (SCIM epic) · #3653 (question A = implement).

Blocked-by: #11632


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions