0%

IAM 用户模型:多身份下资源归属的取舍

🌐 语言: 中文版 | English Version

摘要:业务用户(即你在一个业务中的参与身份)可以独立授权,一部分资源仍由所属登录用户统一持有。以多个项目身份共用个人实验计算额度为例,讨论操作身份、资源归属与一致性边界如何分别确定,以及未来如何沿着身份关系扩展到人员主体。

在《IAM 用户模型:登录用户与业务用户的拆分取舍》中,讨论的是一个登录用户如何关联多个独立的业务用户。资格、授权和业务关系可以分别管理,其中一份关系结束,也不必影响其他身份。

继续沿着这个模型设计,会遇到另一个问题:业务用户分开以后,资源是否也都应该按业务用户分开?

如果直接把业务用户标识作为所有数据的归属依据,实现会比较统一。但有些资源的归属范围比单个业务用户更大,同一个人切换身份,并不会因此获得另一份资源。反过来,把这类资源统一起来,也不意味着原有的业务数据和权限都应该合并。

业务用户分开,资源未必分开

以一家企业内部的实验计算平台为例。工程师同时参与项目 A 和项目 B,使用同一个登录用户,在两个项目中分别拥有业务用户。项目的代码、实验记录和访问权限各自管理。

平台另外提供个人实验额度:每人每月可以使用 20 小时计算资源,用于探索和验证。这份额度由企业统一分配,与参与几个项目无关,也不占用项目各自的预算。这里的场景仅用于说明模型。

工程师通过项目 A 的身份使用了 6 小时,再切换到项目 B,个人可用额度仍然是 14 小时。切换到项目 B 的业务用户后,个人不应因此重新获得 20 小时。

如果按业务用户分别建账,同一个人会得到两份额度。这时项目身份隔离虽然成立,个人额度却偏离了分配规则。

另一个选择是,所有数据都统一关联到登录用户。这样额度可以合并,但原本需要独立保存的业务关系和记录,也容易失去边界。

我最终让业务用户保留原有的职责,在确实需要统一归属的领域中,另外确定资源归属主体。

这意味着,数据归属需要逐个领域判断。身份模型提供可引用的主体,领域规则决定一项资源究竟属于谁。

一次操作,同时保留两种主体

在这个例子里,一次实验任务需要回答两个问题:当前以哪个项目身份操作,消耗的是谁的个人额度。

前者决定这份身份有没有操作资格,也用于记录行为发生时的业务上下文;后者决定去哪里查询可用量,以及把本次消耗记到哪里。

需要判断的问题 由谁决定 例子
当前能否发起或操作 当前业务用户 这个业务用户是否有提交实验任务的资格
操作记录挂在哪个身份下 当前业务用户 任务发起时记录的是哪一个业务用户
资源归属到哪个主体 业务用户所属的登录用户 个人额度由登录用户统一持有,不随身份切换而变
普通业务数据如何隔离 当前业务用户 项目数据按项目组织,当前业务用户的项目关系与权限决定访问范围
flowchart TD
    L[登录用户] --> A[业务用户 A]
    L --> B[业务用户 B]
    A --> PA[按业务用户 A 判断操作资格]
    B --> PB[按业务用户 B 判断操作资格]
    PA --> R[登录用户的个人资源额度]
    PB --> R

图中两条路径表示通过各自授权检查后的资源操作,不表示两个身份自动拥有相同权限。

操作记录可以同时保留业务用户与资源归属。这样,既能解释资源发生了什么变化,也能知道当时是哪个业务用户发起的。

我没有因此把所有业务记录都改成同一种归属。原本属于业务用户的关系继续保留,额度领域明确使用自己的归属主体。代价是,调用方需要理解两种标识的区别,不能再用一个含糊的”用户”覆盖所有含义。

业务用户固定归属到登录用户

这个模型中,每个业务用户都归属到一个确定的登录用户,创建以后不允许改挂到另一个登录用户。一个登录用户可以关联多个业务用户,反向关系则是唯一且固定的。

因此,从任何一个业务用户出发,都能找到其所属登录用户。项目 A 的身份被停用,只会改变它的操作资格,不会改变它属于哪个登录用户,也不会让原有的额度消耗转到别人名下。

在当前一个人对应一个登录用户的范围内,个人实验额度可以直接归到登录用户。它减少了一层人员实体及其映射维护,同时保留了业务用户各自独立的授权和业务关系。

以后如果同一个人允许拥有多个登录用户,这条业务用户到登录用户的关系仍然成立。需要补充的是登录用户到具体人员的关联:

flowchart LR
    A[业务用户 A] --> L1[登录用户 1]
    B[业务用户 B] --> L1
    C[业务用户 C] --> L2[登录用户 2]
    L1 --> P[同一人员主体]
    L2 --> P
    P --> R[个人资源额度]

业务系统仍然从业务用户找到登录用户,再沿着明确建立的人员关系确定额度归属。按人员统一额度时,需要相应调整资源账户与存量数据,但不需要改变业务用户的固定归属规则。

这里保留的扩展方向,是在已有关系后面增加人员层。人员关系需要经过明确确认,不能凭邮箱或显示名称相同自动合并。至于项目预算等按项目持有的资源,仍然沿用自己的归属规则。

接口同时表达身份和归属

模型里分清两种主体之后,接口也需要保留这个区别。

已有接入往往已经把某个用户标识用于授权和业务数据关联。如果为了新增共享额度,直接改变这个标识的含义,调用方可能仍然正常收发请求,却开始查询另一类主体的数据。这种变化很难通过字段类型发现。

我的取舍是保留已有标识的业务用户语义,在确实需要的调用中补充资源归属标识。领域方法的参数也分别表达操作身份和归属主体,减少靠调用方记忆约定的地方。

资源归属由服务端依据经过验证的身份关系确定。客户端可以选择业务操作的目标,但是否允许操作该目标,仍由服务端检查;不能把请求中携带的归属标识直接当成可信身份关系。

增加标识会增加接口契约的理解成本,但这个成本比同一个字段在不同服务里悄悄换义更容易管理。保留字段含义也只是兼容工作的起点,调用链中的授权判断和数据查询仍需要分别核对。

归属范围,也是并发判断的范围

把新增记录关联到正确主体,只完成了一部分工作。资源是否仍然满足规则,还取决于读写是否使用相同的范围。

假设个人额度还剩 4 小时,工程师分别通过项目 A、项目 B 的身份,同时提交两个各需 3 小时的任务。两个请求都读到剩余 4 小时,各自预占 3 小时成功后,合计预占已达 6 小时,超过 4 小时的余额。

如果并发控制只覆盖单个业务用户,两个请求就不会互相等待。额度由同一主体持有,竞争发生的范围也就落在这个主体及相应资源上。

具体可以采用带条件的原子更新,或在同一事务的锁定范围内完成读取、校验与写入。不同存储和资源规则会影响实现选择,但需要保护的约束相同:同一份资源的竞争操作,要在同一个一致性边界内完成判断。

也没有必要把一个人的全部业务操作都串行化。可以按归属主体与具体资源进一步划分范围。粒度越细,并行度越高;相应地,也需要确认没有把同一条约束拆到几个互不协调的范围里。

异步处理继续沿用同一条归属关系

实验任务可能由后台执行,提交时按预计时长预占额度,完成后再按实际时长结算并释放差额。后台执行者与发起任务的工程师不是同一个操作主体,但它处理的仍然是原任务对应、已经预占的个人额度。

任务保留发起时的业务用户,后续就可以通过它固定归属的登录用户,再结合任务对应的额度周期,定位到具体的资源账户。也可以在额度记录中直接保留对应账户的引用,便于结算和查询。是否冗余保存这个引用,可以根据领域记录和查询需求决定;固定的身份归属关系本身已经提供了确定的解析路径。

这里需要避免的是把后台执行者或当前查看任务的人当成额度归属人。它们是执行上下文中的角色,原任务的业务用户及其所属登录用户才提供了这笔资源操作的归属依据。

业务用户停用以后,任务仍然可以定位到原资源账户。至于任务是否继续执行、谁能取消,需要由任务规则和当前权限另行决定。身份归属解决定位问题,业务用户的状态和授权决定操作是否允许。

如果后台重复收到同一任务的完成通知,也需要按同一任务的结算事件去重,避免重复扣减。这与业务用户的归属是否固定是两个问题。

共享资源之后,权限仍分别判断

两个业务用户共用额度,解决的是资源归属问题。它们可以具有不同的查询、消耗或管理权限。

例如,项目 A 的身份允许提交实验任务,项目 B 的身份只允许查看项目结果。即使个人额度还剩 14 小时,工程师也不能因此通过项目 B 的身份提交任务。额度足够与项目身份有操作资格,是两个独立条件。共用个人额度也不会让项目 B 的身份自动获得项目 A 的实验记录。

这也是保留业务用户层的原因:资源领域可以统一记账,访问控制仍然能够表达不同业务关系的差异。

实现上需要同时处理两件事:当前业务用户是否允许执行这项操作,以及目标资源是否属于其获准操作的范围。只校验其中一项,都不足以表达这次访问的完整约束。

这次取舍留下的成本

引入资源归属主体以后,每个相关调用都需要明确:这里处理的是操作身份、资源归属,还是两者同时存在。接口、查询、审计和异步事件都要承载这层语义。

存量数据也不会因为新增一个标识就自动获得正确归属。历史记录原来引用的是哪种主体、同号标识是否掩盖了区别、原先分开的资源是否允许合并,都需要单独确认。新的模型可以指导后续写入,历史迁移仍然是另一项需要证据支持的工作。

因此,如果业务用户与资源归属始终一一对应,保留一个主体可能更直接。只有当两者确实出现不同的生命周期或管理范围时,增加这层区分才有实际价值。

这轮设计让我重新检查了”用户 ID”在领域里的含义。一个标识可以方便地关联很多表,却无法替代对归属规则的判断。我保留业务用户的独立性,同时在需要的领域明确资源归属,并接受由此增加的契约和一致性管理成本。