摘要

  • RFC 3341 会从同一 owner 下匹配 actor 的多条访问记录中选择最具体者;删除精确记录可能让较宽的通配记录重新成为赢家。
  • 撤销因此可能需要保留一条更具体的 all:none;条目删除、变更受理、owner 通知、有效决策和实际执行是五份不同回执。

RFC 3341 自己给出的例子没有模糊空间。一条精确记录允许某个 actor 发送核心数据,并订阅、观察在线状态;另一条同域通配记录允许域内任意 actor 发送核心数据。删除第一条后,这个 actor 确实失去了订阅和观察能力,却仍能通过第二条发送数据。

数据库变更成功,目标行也确实不存在了。权限之所以仍在,不是删除失败,而是匹配集合和优先级发生了变化。先前被精确记录压住的通配记录升为最佳匹配。若管理员真正想清空该 actor 的权限,规范要求把精确记录改为 all:none,让一个更具体的明确拒绝继续挡在宽授权之前。

权限不是某一行,而是一次计算

每条 APEX 访问记录包含 owner、actor、允许的动作,以及由服务维护的 lastUpdate 时间。owner 是策略所属的端点或子地址;actor 是在该 owner 语境中获得能力的实体或实体集合;动作由服务与操作两部分组成,例如 core:data 表示能通过中继网向 owner 发送数据。

actor 的本地部分和域部分都允许有限通配,因此一个具体地址可以同时命中多条记录。算法先限定同一 owner,再保留 actor 匹配者;域部分的精确程度是第一排序键,本地部分是第二排序键。精确匹配优先;若都是通配,匹配范围较短、较具体者优先。

所以,有效权限来自候选集、匹配算法、默认项和所问动作的组合。仅查看某一行无法得出最终结论。删除截图能证明管理界面少了一项,不能证明下一次查询会返回拒绝。

默认记录也属于有效状态。每个 owner 默认允许自己和同域 APEX 服务执行广泛操作,允许任意域的 APEX 服务发送核心数据,并对其他全局 actor 使用 all:none。显式记录只覆盖 actor 值完全相同的默认项,而不是抹掉所有别的匹配。因此审计既要看到存储项,也要看到规范或实现注入的默认项。

为什么明确拒绝不能被清理掉

删除已有记录时,应用发送 set,其中保留 owner、actor 和当前 lastUpdate,但省略 actions。访问服务删除条目,向变更发起方返回成功回复,并另向 owner 发送一条没有动作的 set 通知,使 owner 得知这条记录已删除。

紧接着,RFC 3341 警告:由于 actor 使用通配,删除某个 owner/actor 组合可能只是修改权限,而不是移除权限。all:none 的作用就是表达“任何操作都不允许”。它作为精确记录继续存在,以更高优先级压住宽通配授权。

这是一种必须被保存的负面事实。缺席只表示“这里没有特例”,并不表示“这个主体被拒绝”。如果通用清理任务把明确拒绝当作无效墓碑删除,权限可能在没有新增任何授权的情况下复活。策略表看起来更干净,实际边界却更宽。

lastUpdate 保护写入,却没有证明全网撤销

更新或删除前,应用通常先 get 当前记录,拿到 lastUpdate。后续 set 必须带上语义相同的值。若带着版本去更新一个已不存在的精确记录,或值与服务当前版本不同,服务返回代码 555。创建新记录则不带 lastUpdate。

这是一条比较后替换的并发边界。它阻止晚到的管理者覆盖别人已经修改过的内容。服务在创建或更新后写入自己的当前时间,且新值应不同于旧值。

但版本匹配只证明服务接受的写入基于那一版记录。它没有证明 owner 已收到通知,也没有证明每个中继、缓存或副本都按新候选集作出决定。完整回执应依次记录:读到的条目和版本、提交的变更、服务接受或冲突、新条目或删除状态、通知发出、通知到达、有效决策重算、执行点观察到新状态,以及真实操作被允许或拒绝。

查询权限本身也需要权限

应用能访问 apex=access 并不代表它能任意查看别人策略。服务收到查询后,先确认 subject 属于本管理域且地址有效;随后查 subject 下与查询发起方匹配的记录,要求其中包含 access:query。只有通过这一步,服务才选择与“被查询 actor”匹配的记录,并检查请求列出的所有动作是否都在其中。

因此要分开两种主体:谁在询问,和询问谁的权限。能问不等于能做。服务返回 allow,也只证明那次评估所列动作都包含于所选条目;它不证明稍后的数据操作看到同一策略版本,更不证明最终业务成功。

规范还要求把访问记录持久保存,而且无论 owner 是否当前附着于中继网都要维护。断开端点不会撤销策略。持久化使策略超越在线状态,但不自动证明磁盘耐久、复制一致、读取新鲜或执行正确。

成为 Historic 之后仍然清楚的证据边界

RFC 3341 于 2002 年 7 月以标准轨文档发表,是 APEX 核心、访问、选项与在线状态四篇 RFC 之一。IETF Datatracker 记录,2012 年 7 月 29 日四篇文档被改列 Historic;据 IETF 所知没有实现投入部署,而相应功能已由 RFC 6120 与 RFC 6121 所定义、广泛部署的 XMPP 提供。

这段记录只支持带限定语的采用结论。它没有说通配规则导致 APEX 未部署,也没有证明漏洞或事故。历史地位和机制的证据价值必须分开。RFC 3341 留下的精确教训是:删除策略对象、撤销有效权限、让执行点实施拒绝,是三件不同的事。

审计任何分层授权系统时都可以沿用这种纪律,却不能声称它就是 APEX。记录完整候选集和匹配算法,别只记录被编辑的一行;若优先级依赖明确拒绝,就为这类拒绝设定独立保留规则;变更后重新读取有效决策,并在真正执行点测试。变更成功回答“服务接受了什么”,撤销证明必须回答“主体如今已经不能做什么”。

来源