来源:跨座位转移件。 Part of objectstack-ai/cloud#621(Enterprise Identity SCIM — V1 follow-ups)的第 1 项。cloud#621 的其余各项留在 cloud 队列;这一项落点在本仓 (packages/plugins/plugin-auth),按 One-main-backlog 规则转来。
设计依据:ADR-0024 D5.2 (cloud ADR-0071 的 SCIM V1 已落地,机制在 framework plugin-auth,OS_SCIM_ENABLED 默认关)。原单把本项标为 non-negotiable 。
问题
SCIM / ban 路径必须永远不能 停用环境 owner 或最后一个本地管理员。一次 IdP 误配置、或一次过宽的 deprovision,就足以让整个组织把自己锁在门外 —— 而 SCIM 的写入是外部系统驱动 的,没有人在回车前看一眼。
要求(照抄原单)
sys_user 的 beforeUpdate 钩子 :当一次更新会导致剩余 0 个未被 ban 的管理员 时,拒绝 banned=true;
enforced SSO 模式不得停用最后一个本地管理员的密码 —— 这是 IdP 故障时的逃生口;
测试:尝试 ban 最后一个管理员 → 被拒;IdP 故障路径下 owner 的本地登录仍可用。
⚠️ 派发前必做的前提核对(分诊座位已做一轮,结论是「部分可能已存在」)
origin/main 上 packages/plugins/plugin-auth/src/auth-manager.ts 已经有 break-glass 相关代码,但只覆盖密码那一半 :
:1241 // env owner / a local admin keeps one as the break-glass escape hatch
:3846 * owner back, so the break-glass admin never loses self-service password
⇒ 第 2 项(密码逃生口)看起来已有实现 ;而第 1 项(ban 守卫)未搜到对应逻辑 —— 未命中「剩余 0 个未 ban 管理员则拒绝」这一形状的判定。
⛔ 请 dev 在动手前逐条复核这三项的现状 ,只实现真正缺失的部分:范围可能显著小于正文。核对方法用 git grep <pattern> origin/main -- packages/plugins/plugin-auth,⛔ 不要在共享主检出的工作树里 grep(它的 HEAD 由别的 agent 摆布,可能落后数十提交)。
相关
原单:objectstack-ai/cloud#621(其余各项:token-admin UI、cloud-managed gate 验证、source-marking 归并、真实 IdP E2E)
⚠️ SCIM: 停在 @better-auth/scim rc.1,等正式版再整体迁移 —— rc.2 换掉了整套模型 #3653 (SCIM 停在 @better-auth/scim rc.1 等正式版,pm:on-hold)—— 本项是本仓自己的 sys_user 钩子 ,⛔ 不依赖 @better-auth/scim 的版本,故不受 SCIM: 停在 @better-auth/scim rc.1,等正式版再整体迁移 —— rc.2 换掉了整套模型 #3653 挂起影响 ,可独立落地。若实现中发现必须触碰 @better-auth/scim 的模型面,请停下并回报,那一刻 SCIM: 停在 @better-auth/scim rc.1,等正式版再整体迁移 —— rc.2 换掉了整套模型 #3653 才成为前置。
plugin-auth: convertWhere() 整体忽略 better-auth 的 Where.mode: 'insensitive'(SCIM 会发它) #5814 (convertWhere() 忽略 Where.mode,SCIM 会发它,domain:identity / pm:blocked)—— 同为 SCIM 相邻缺陷,不同落点,无依赖。
Generated by Claude Code
来源:跨座位转移件。
Part of objectstack-ai/cloud#621(Enterprise Identity SCIM — V1 follow-ups)的第 1 项。cloud#621 的其余各项留在 cloud 队列;这一项落点在本仓(packages/plugins/plugin-auth),按 One-main-backlog 规则转来。设计依据:ADR-0024 D5.2(cloud ADR-0071 的 SCIM V1 已落地,机制在 framework
plugin-auth,OS_SCIM_ENABLED默认关)。原单把本项标为 non-negotiable。问题
SCIM / ban 路径必须永远不能停用环境 owner 或最后一个本地管理员。一次 IdP 误配置、或一次过宽的 deprovision,就足以让整个组织把自己锁在门外 —— 而 SCIM 的写入是外部系统驱动的,没有人在回车前看一眼。
要求(照抄原单)
sys_user的beforeUpdate钩子:当一次更新会导致剩余 0 个未被 ban 的管理员时,拒绝banned=true;enforcedSSO 模式不得停用最后一个本地管理员的密码 —— 这是 IdP 故障时的逃生口;origin/main上packages/plugins/plugin-auth/src/auth-manager.ts已经有 break-glass 相关代码,但只覆盖密码那一半:⇒ 第 2 项(密码逃生口)看起来已有实现;而第 1 项(ban 守卫)未搜到对应逻辑 —— 未命中「剩余 0 个未 ban 管理员则拒绝」这一形状的判定。
⛔ 请 dev 在动手前逐条复核这三项的现状,只实现真正缺失的部分:范围可能显著小于正文。核对方法用
git grep <pattern> origin/main -- packages/plugins/plugin-auth,⛔ 不要在共享主检出的工作树里 grep(它的 HEAD 由别的 agent 摆布,可能落后数十提交)。相关
objectstack-ai/cloud#621(其余各项:token-admin UI、cloud-managed gate 验证、source-marking 归并、真实 IdP E2E)@better-auth/scimrc.1 等正式版,pm:on-hold)—— 本项是本仓自己的sys_user钩子,⛔ 不依赖@better-auth/scim的版本,故不受 SCIM: 停在 @better-auth/scim rc.1,等正式版再整体迁移 —— rc.2 换掉了整套模型 #3653 挂起影响,可独立落地。若实现中发现必须触碰@better-auth/scim的模型面,请停下并回报,那一刻 SCIM: 停在 @better-auth/scim rc.1,等正式版再整体迁移 —— rc.2 换掉了整套模型 #3653 才成为前置。convertWhere()整体忽略 better-auth 的Where.mode: 'insensitive'(SCIM 会发它) #5814(convertWhere()忽略Where.mode,SCIM 会发它,domain:identity/pm:blocked)—— 同为 SCIM 相邻缺陷,不同落点,无依赖。Generated by Claude Code