Skip to content

fix(auth): close the sso/scim parity hole; provision sys_scim_provider.provider_key (#3653) - #3688

Merged
os-zhuang merged 1 commit into
mainfrom
claude/org-creation-http-500-teams-gocypm
Jul 27, 2026
Merged

fix(auth): close the sso/scim parity hole; provision sys_scim_provider.provider_key (#3653)#3688
os-zhuang merged 1 commit into
mainfrom
claude/org-creation-http-500-teams-gocypm

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

关掉 #3647 那个 parity gate 自己留下的洞

背景

gate 上线时明确排除了 @better-auth/sso@better-auth/scim,理由是它们不接受 schema option、getAuthTables() 看不见。当时我把这条写成了代码注释 —— 但注释不是 gate,所以按 Prime Directive #10 开了 #3653 记账,现在补上。

怎么补的

这两个 plugin 确实暴露了自己的 .schema;而 adapter 对 bridged model 的处理是机械地 camelCase → snake_case(objectql-adapter.ts)。真正决定它们写哪一列的是后面这条机械规则,不是任何手写映射。所以 gate 现在:读前者 → 套后者 → 与平台对象比对。

第一次跑出来的结果

plugin 结果
@better-auth/sso 完全干净 —— ssoProvider 的 7 个字段全部已 provision
@better-auth/scim sys_scim_providerprovider_key

providerKey 在 upstream 声明为 required: true, unique: true,每次 provider insert 都写(派生的 <organization>:<provider_id> 键,和 sys_team_member.membership_key 同一形状)。缺这个列,SCIM 一打开、创建 provider 就失败 —— 又是 #3624,只是躲在 OS_SCIM_ENABLED 后面。

已补上列 + 镜像 upstream 的 UNIQUE 索引。存量环境走 additive schema sync,老行保持 null(可空 UNIQUE 允许重复 NULL)。

没有假装覆盖的部分

@better-auth/scim四个 group model(scimGroup / scimGroupMember / scimGroupRole / scimGroupRoleGrant)完全没有平台对象。这是功能级缺口(SCIM group 供给),不是少个列,所以我没有把它悄悄跳过:

const KNOWN_UNMAPPED_MODELS = new Set([...]);   // 精确集合,本身被断言
  • 冒出新的无对象 model → 构建失败(不会再长出第二个洞)
  • 某个 model 离开集合(说明已 provision)→ 也失败,提示把它纳入列检查

#3653 现在追踪这块功能工作,正文已更新为完整的列清单。

一处刻意没动的地方

sys_scim_provider 上有 { fields: ['provider_id'], unique: true },而 upstream 的唯一性边界是 <organization>:<provider_id> —— 同一个 provider_id 在两个组织下,upstream 认为合法,这个索引会拒绝

比库假设的更严。我没有在本 PR 放宽它 —— 动一个已生效的唯一约束是独立决定,也可能当初就是有意为之。已在代码注释和 #3653 里都记了。

测试

parity gate 18 passed(新增 sso/scim 块)
@objectstack/plugin-auth 539 passed (24 files)
@objectstack/platform-objects 223 passed (6 files)
pnpm check:i18n ✅ in sync

顺带一提:新加 provider_key 时,#3683 刚合并的 i18n gate 立刻把我自己拦下来了(bundle 少了这个字段的翻译)—— 按提示重新生成后通过。第一次实战就生效了。

Refs #3653, #3624, #3647, ADR-0071。


Generated by Claude Code

…r.provider_key (#3653)

The better-auth parity gate (#3647) shipped with a known hole: `@better-auth/sso`
and `@better-auth/scim` accept no `schema` option, so `getAuthTables()` cannot
see them and they were excluded with a comment. A comment is not a gate — filed
as #3653 rather than left buried, and closed here.

Both plugins DO expose their own `.schema`, and the adapter bridges them by
mechanically camelCase→snake_casing every field of a bridged model
(`objectql-adapter.ts`). That mechanical rule — not any hand-written mapping —
is what decides the column they write, so the gate now reads the former and
applies the latter.

What it found on first run:

  @better-auth/sso    clean. All 7 ssoProvider fields already provisioned.
  @better-auth/scim   sys_scim_provider was missing `provider_key`.

`providerKey` is declared `required: true, unique: true` upstream and written on
every provider insert (a derived `<organization>:<provider_id>` key, same shape
as `sys_team_member.membership_key`). Without the column, creating a SCIM
provider fails the moment SCIM is switched on — #3624 again, behind a flag.

The four SCIM **group** models (`scimGroup`, `scimGroupMember`, `scimGroupRole`,
`scimGroupRoleGrant`) have no platform object at all. That is a feature-sized
gap, not a missing column, so it is NOT silently skipped: `KNOWN_UNMAPPED_MODELS`
pins them as an exact set and the set itself is asserted. A new unmapped model
fails the build, and a model that gains an object also fails — telling whoever
provisioned it to move it into the column check. #3653 now tracks that work.

Also raised there, deliberately NOT changed here: `sys_scim_provider` carries a
UNIQUE index on `provider_id` alone, while upstream's boundary is
`<organization>:<provider_id>` — so the same provider id in two organizations is
legal upstream and rejected here. Relaxing a live uniqueness constraint is its
own decision.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYLC8TfjzHGwatNxZKdX7H
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Jul 27, 2026 2:30pm

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Jul 27, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

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

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

  • content/docs/deployment/cli.mdx (via @objectstack/plugin-auth)
  • content/docs/deployment/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/plugin-auth)
  • content/docs/permissions/authentication.mdx (via @objectstack/plugin-auth)
  • content/docs/permissions/sso.mdx (via @objectstack/plugin-auth)
  • content/docs/plugins/index.mdx (via @objectstack/plugin-auth)
  • content/docs/plugins/packages.mdx (via @objectstack/platform-objects, @objectstack/plugin-auth)
  • content/docs/releases/implementation-status.mdx (via @objectstack/plugin-auth)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth)
  • content/docs/ui/setup-app.mdx (via @objectstack/platform-objects)

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.

@os-zhuang
os-zhuang marked this pull request as ready for review July 27, 2026 14:39
@os-zhuang
os-zhuang merged commit 5487c20 into main Jul 27, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the claude/org-creation-http-500-teams-gocypm branch July 27, 2026 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants