Skip to content

feat(identity): ADR-0092 实现 A — 通用身份表写守卫(registry 驱动 default-deny + sys_user 档案白名单) #2816

Closed

Description

@os-zhuang

背景

ADR-0092(docs/adr/0092-sys-user-profile-field-delegation.md,经 #2787 + #2808 落地)的实现工作第一阶段。这是关键路径:既是放开 sys_user 档案编辑的前置,也在堵一个现存安全洞 —— admin_full_access(通配符、无 RLS)今天可经通用 data API 裸写全部 managedBy: 'better-auth' 表的任意列(裸插 sys_member 自授成员身份、裸改 sys_api_key、裸删 sys_session),全部绕过 better-auth 副作用。

范围(ADR-0092 D2 / D3 / D6)

D2 — 通用守卫(plugin-auth,kernel:ready 注册,模式同 SCIM provenance hook)

  • before{Insert,Update,Delete} 引擎 hook,按 schema registry 的 managedBy === 'better-auth' 标志判定适用对象(不硬编码表清单;default-permission-sets.ts 的 BETTER_AUTH_MANAGED_OBJECTS 保持现状 = 权限集种子)。
  • 仅拦截用户上下文写入(context 带真实用户且非 isSystem);better-auth adapter(无 context)、插件 SYSTEM_CTX、import 引擎调用直通。
  • default-deny:用户上下文的 insert / delete,以及无白名单注册对象的 update,一律 FORBIDDEN 级报错,错误信息要指路("use Invite / Create User / better-auth API")。
  • 唯一开口:registerManagedUpdateWhitelist(object, fields) registry,beforeUpdate 据此剥离名单外字段;剥空则抛错(响亮失败,非静默 no-op)。首条目:sys_user → SYS_USER_PROFILE_EDIT_FIELDS。
  • 覆盖单 id 与 options.multi 两种 update 形态。

D3 — 白名单同源模块

  • 新模块(如 sys-user-writable-fields.ts):SYS_USER_PROFILE_EDIT_FIELDS = {name, image};SYS_USER_IMPORT_UPDATE_FIELDS = {...PROFILE, phone_number, role}(spread 派生,subset-by-construction)。
  • admin-import-users.ts 的私有 UPDATE_ALLOWED_FIELDS 替换为共享常量。

D6 — 会话缓存一致性

  • afterUpdate hook(object: 'sys_user'):用户上下文写入改动 Tier-1 字段后,令该用户在 secondary storage 的会话快照失效(具体键由 auth manager 负责);未接 secondary storage 时 no-op。

测试矩阵

  • 逐表:用户上下文 insert/delete/update 被拒(含错误信息指路断言)
  • sys_user update:名单外字段被剥离、纯名单外整包抛错、{name, image} 通过
  • system-context / 无 context(better-auth adapter 路径)直通不受影响
  • options.multi 批量 update 同样被过滤
  • import upsert 全流程回归(SYSTEM_CTX 直通 + 共享常量约束字段)
  • 白名单 registry 注册/未注册行为

合并前硬性验证(ADR Risks 第 1 条)

default-deny 最大风险是砸中未知的合法用户上下文写路径。合并前必须:

  1. 全量扫描仓库内对身份表的 engine.update/insert/delete 调用点,逐一确认上下文类型;
  2. dogfood 跑通:登录、邀请、建用户(含临时密码)、set-password、ban/unban/unlock、组织/团队生命周期、import-users、SSO/SCIM(若可用)。

发现的合法路径不得反射性加白名单:真属内部写的改 system context,属管理操作的走/新建专用端点。

交付物

守卫 + registry + 共享模块 + import 重构 + 上述测试 + changeset(功能变更)。

相关

Activity

  1. added a commit that references this issue on Jul 11, 2026
    a348394
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions