Skip to content

feat(plugin-auth): env-side SCIM 2.0 via @better-auth/scim (ADR-0071, OPEN mechanism) - #2356

Merged
xuyushun441-sys merged 4 commits into
mainfrom
feat/scim-plugin
Jun 27, 2026
Merged

feat(plugin-auth): env-side SCIM 2.0 via @better-auth/scim (ADR-0071, OPEN mechanism)#2356
xuyushun441-sys merged 4 commits into
mainfrom
feat/scim-plugin

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

The OPEN per-environment SCIM mechanism for Enterprise Identity (design: cloud ADR-0071 / cloud#611, implementing the SCIM slice ADR-0024 D6 deferred). The environment becomes a SCIM 2.0 Service Provider so an external IdP (Okta / Entra) can auto-provision / deprovision its users. Off by default (OS_SCIM_ENABLED); the paid entitlement gate + token-admin UI land cloud-side, separately.

What's here (mirrors the @better-auth/sso wiring)

  • Install @better-auth/scim (MIT); push scim({ storeSCIMToken: 'hashed' }) under OS_SCIM_ENABLED; force the admin plugin on (active:false → ban needs it).
  • New sys_scim_provider object + registration in plugin-auth's authIdentityObjects manifest (export ≠ provisioning — the manifest drives schema sync, D7).
  • Map scimProvider → sys_scim_provider in AUTH_MODEL_TO_PROTOCOL; the adapter auto-bridges camelCase↔snake_case. Fixed the now-stale adapter TODO comment.
  • Source-marking fix: SCIM creates sys_account bypassing better-auth's account.create.after, so users landed source=env_native. Added an ObjectQL afterInsert hook on sys_account that stamps source=idp_provisioned for non-credential accounts (robust to the creation path; uses the QueryAST where key — filter is silently ignored).
  • Token stored hashed, never cleartext.

Verified E2E on the objectos-ee rig

generate-token ✅ · POST /Users201 ✅ · PATCH active:false204 + sys_user.banned=1 ✅ (compliance offboarding) · GET /Users ✅ · SCIM user → source=idp_provisioned ✅ · dev admin (credential) stays env_native ✅. Full plugin-auth suite: 137 passed, incl. new SCIM wiring tests.

🤖 Generated with Claude Code

os-zhuangand others added 4 commits June 27, 2026 14:57
…ice Provider (ADR-0071)
Adds the OPEN SCIM mechanism so an external IdP (Okta/Entra) can auto-
provision/deprovision this environment's users. Mirrors the @better-auth/sso
wiring:
- add @better-auth/scim dep; push scim({storeSCIMToken:'hashed'}) under
OS_SCIM_ENABLED; force the admin plugin on (active:false -> ban needs it)
- map scimProvider -> sys_scim_provider in AUTH_MODEL_TO_PROTOCOL (the adapter
auto-bridges camelCase->snake_case); fix the now-stale adapter TODO comment
- new sys_scim_provider object (token stored hashed, read-only over data API)
- AUTH_SCIM_PROVIDER_SCHEMA field map; export SysScimProvider
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Exporting the object from platform-objects/identity is necessary but not
sufficient — schema provisioning is driven by plugin-auth's explicit
authIdentityObjects list (the D7 compile-time + runtime registration). Without
this the table was never created and @better-auth/scim's generate-token 500'd
on `no such table: sys_scim_provider`. Verified E2E: token gen, provision (201),
deprovision (active:false -> banned), list — all green on the objectos-ee rig.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…sers
@better-auth/scim creates sys_account bypassing better-auth's
databaseHooks.account.create.after, so stampIdentitySource never fired and
SCIM users landed source=env_native instead of idp_provisioned (ADR-0024 D4).
Fix: register an ObjectQL afterInsert hook on sys_account at kernel:ready that
stamps idp_provisioned for any non-credential account whose user has no local
credential — robust to the creation path (catches SCIM and OAuth alike),
idempotent, and never breaks the insert. Uses ctx.getService('objectql') (the
auth manager's getDataEngine() is not wired at kernel:ready) and the QueryAST
`where` key (not `filter` — a wrong key is silently ignored and counts every
row, the latent bug also present in stampIdentitySource's federated branch).
Verified E2E on the objectos-ee rig: SCIM-provisioned user -> idp_provisioned;
local dev admin (credential) stays env_native.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…; OS_SCIM_ENABLED forces scim + admin)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 27, 2026 7:55am

Request Review

@github-actionsgithub-actionsBot added dependencies Pull requests that update a dependency file tests size/m labels Jun 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/plugin-auth.

11 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/implementation-status.mdx(via @objectstack/plugin-auth)
  • content/docs/concepts/packages.mdx(via @objectstack/platform-objects, @objectstack/plugin-auth)
  • content/docs/concepts/setup-app.mdx(via @objectstack/platform-objects)
  • content/docs/getting-started/cli.mdx(via @objectstack/plugin-auth)
  • content/docs/guides/auth-sso.mdx(via @objectstack/plugin-auth)
  • content/docs/guides/authentication.mdx(via @objectstack/plugin-auth)
  • content/docs/guides/kernel-services.mdx(via @objectstack/plugin-auth)
  • content/docs/guides/packages.mdx(via @objectstack/platform-objects, @objectstack/plugin-auth)
  • content/docs/guides/plugins.mdx(via @objectstack/plugin-auth)
  • content/docs/guides/production-readiness.mdx(via @objectstack/plugin-auth)
  • content/docs/releases/v9.mdx(via @objectstack/plugin-auth)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@xuyushun441-sys
xuyushun441-sys merged commit 911c7aa into mainJun 27, 2026
17 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the feat/scim-plugin branch June 27, 2026 08:00
os-zhuang added a commit that referenced this pull request Jul 9, 2026
Active-org nav context, related-list action bridges, first-run wizard fixes (cloud ADR-0081) (#2356)
objectui@b0aa25129542504b81589ee95bb81a5d6003f998
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependenciesPull requests that update a dependency filesize/mtests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@xuyushun441-sys@os-zhuang