B端权限矩阵不能只在“作者、审核者、管理员”下面打勾。一个完整的允许条件至少要说清:谁,以什么角色,对哪一份数据,在什么状态下,执行哪个动作。只写“编辑可以修改文章”,没有回答他能否修改其他部门的文章、待审文章和已经发布的版本。
先把这些条件写成业务规则,再配置菜单和按钮。需要与研发、测试一起走查时,可以在产品经理协作画布中把权限矩阵、内容状态和反例放在一起,避免每张页面原型各自解释权限。

先定一套具体制度,不从“超级管理员”开始
下面以企业内容审核后台为例。系统内有作者、编辑、审核者和账户管理员四种角色;内容经历“草稿—待审—已发布”三个状态。退回时回到草稿,撤回发布时也回到草稿,重新修改后再次提交审核。本例不展开删除、导出、定时发布和跨部门借调,这些需求出现时应另列规则。
先确认四条制度:
- 作者只处理自己创建的内容;编辑处理本部门内容;审核者审核本部门内容,但不能批准自己创建或最后编辑的版本。
- 待审和已发布内容不能直接编辑。需要修改时,先由有权人员退回或撤回,避免审核中的版本被悄悄改掉。
- 账户管理员负责账户与角色配置,默认不因此获得业务内容的查看、修改或发布权。
- 所有业务操作都限定在用户当前获授权的企业内;部门或角色符合,不能抵消企业范围不符。
角色不是职位高低的总开关。NIST对RBAC的说明将用户、角色和权限区分开,同时允许在访问时附加约束。落到本例,就是“审核者”给出可能执行的动作,企业、部门、内容状态和本人参与情况继续限制它。
矩阵先列动作,再给每个“允许”补条件
行写“编辑草稿、提交审核、发布内容”这类可以验收的动作,不写含义不清的“管理文章”。列写业务角色。表中的“—”表示该角色不授予此动作;它不是一个覆盖其他角色的全局拒绝规则。若用户兼有多种角色,仍须满足后文的共同约束。
| 动作 | 作者 | 编辑 | 审核者 | 账户管理员 |
|---|---|---|---|---|
| 查看内容详情 | 本人创建的内容 | 本部门内容 | 本部门待审或已发布内容 | — |
| 编辑草稿 | 本人创建且为草稿 | 本部门且为草稿 | — | — |
| 提交审核 | 本人创建且为草稿 | 本部门且为草稿 | — | — |
| 退回修改 | — | — | 本部门待审内容;本人既非创建者,也非最后编辑者 | — |
| 发布内容 | — | — | 本部门待审内容;本人既非创建者,也非最后编辑者 | — |
| 撤回发布 | — | — | 本部门已发布内容 | — |
| 配置账户与角色 | — | — | — | 限本企业;按独立的授权审批规则执行 |
“查看”也需要范围,而不只是“编辑”需要。列表、搜索结果和详情页应遵循同一套业务范围。若详情页禁止查看,却在搜索摘要里展示了全文片段,用户仍可能看到不该看到的内容。
这张表刻意没有写“管理员全部允许”。账户治理与内容审核是两种职责;如果确有紧急接管需要,应为接管单独说明授权人、对象、有效时间和记录要求,而不是藏在一个永远有效的万能角色里。
一行权限,还要经过对象、状态和版本三次核对
假设林编辑负责市场部,准备修改文章A。A属于同一企业,但属于销售部。虽然林编辑有“编辑”角色,部门范围不满足,不能修改。把A换成市场部文章B,若B已进入待审状态,依然不能直接改正文。这是两种独立的拒绝原因,不能只测试其中一种。

对每个操作,按下面顺序补全需求:
- 对象范围:文章属于哪家企业、哪个部门,创建者是谁?范围来自受信任的数据,不让页面随意传一个部门名就获得授权。
- 动作与状态:当前状态是否允许这个动作?“有编辑权”和“此刻可编辑”不是同一句话。
- 职责约束:本例审核者是否创建或最后编辑了待审版本?如果是,就由另一位有权审核者处理,不能靠切换角色名自审。
- 版本一致:审核者看到的是哪一版?提交发布时,内容版本和状态是否仍与待审对象一致?不能把刚看过的旧版本结论用于另一份内容。
可以把一条规则写成完整句子:“当前仍具有审核权限的市场部审核者,可发布本企业市场部的待审文章,前提是他不是该文章创建者或待审版本最后编辑者,且提交的版本仍为当前待审版本。”研发据此选择实现方式,测试也有明确的正向和反向条件。
若一个人同时是编辑和审核者,本例允许两种角色分别授予动作,但“不能审核自己创建或最后编辑的版本”仍然生效。不要简单地把两列合并成更多勾选,然后丢掉这条职责约束。
用反例审表,比只测按钮能否点击更有效
先为每个动作准备一个允许场景,再只改变一个条件,得到应该拒绝的场景。这样出现分歧时,能定位究竟是角色、数据范围、状态还是版本约定不清。
| 场景 | 期望 | 必须核对的结果 |
|---|---|---|
| 市场部编辑修改本企业市场部草稿 | 允许 | 只更新指定草稿,记录当前版本及操作者 |
| 同一编辑修改销售部草稿 | 拒绝 | 目标内容不发生变化,不泄露受限正文 |
| 同一编辑修改市场部待审内容 | 拒绝 | 状态不被暗中改回草稿,正文不变 |
| 审核者发布自己最后编辑的待审版本 | 拒绝 | 职责约束生效,不能因同时有两种角色而放行 |
| 审核者发布本企业、本部门当前待审版本;本人既非创建者,也非最后编辑者,且审核权限仍有效 | 允许 | 发布的就是已审核版本,状态变为已发布 |
| 页面打开后审核角色被撤销,再提交发布 | 拒绝 | 按当前授权判断,不沿用打开页面时的权限 |
| 审核者提交旧版本,内容已被另一人退回 | 拒绝并提示重新确认 | 不把旧请求套到新状态,不误发布 |
| 同名部门、同名角色,但目标文章属于另一企业 | 拒绝 | 企业隔离条件优先满足,名称相同无效 |
这些场景应在受控测试环境中用明确获授权的测试账户执行。每条留下角色、对象编号、内容状态、版本、预期与实际结果。矩阵评审只是把需求说清,并不等于系统已经通过权限测试。
按钮隐藏或置灰可以帮助用户理解当前能做什么,却不能作为最终授权。OWASP授权指南强调默认拒绝、逐请求校验及在可信服务端执行授权检查;因此,需求不能只要求“前端看不到发布按钮”,还要要求不满足授权条件的提交不能改变内容。
让权限讨论和业务流程保持同一份口径
在Boardmix画布中,把矩阵放在中央,上方列四条制度,下方放“草稿→待审→已发布”的状态关系,右侧放反例卡。每张卡只变一个条件,例如“同企业、不同部门”,并连到受影响的动作行。
产品负责人先解释为什么授予某个动作;业务负责人核对数据范围和职责分离;研发补充状态与版本如何判断;测试把允许和拒绝场景配对。如果某格需要写半页说明,就把共用条件提取为规则编号,再在格子中引用,而不是继续缩小字体。
讨论结束时,保留三类结论:已经确认的授权、明确不授予的动作,以及尚未决定的问题。尚未决定不能被理解为默认开放。将确认后的矩阵和对应验收场景纳入产品需求评审材料,并让页面原型与服务端实现使用相同的动作名称。
以后新增“导出”、加入外部协作者或允许跨部门审核时,不要只添一个菜单项。新增动作意味着重新说明对象范围、状态限制、撤销后的行为和反向用例。权限矩阵的价值,正是在需求变化时让这些影响仍然看得见。

