摘要

  • Amoeba capability 共 128 位:48 位服务端口、24 位对象号、8 位权限位图和 48 位校验字段,把对象定位、允许的操作与防伪验证装进一份可由用户进程直接持有的引用。
  • 服务器接受 capability,说明所提交字段符合当前校验规则、请求操作落在权限位内;它并不确认具名持有人、组织授权、操作目的、下游动作完成或重启后的持久化状态。

四段位串里没有“谁”

在 Amoeba 中,客户端不是先向中央权限管理员证明身份,再领取一次性许可。它向服务器提交 capability。服务器端口把请求带到相应服务,对象号指向该服务管理的某个对象,权限位说明持有人可以请求哪些操作,校验字段让服务器识别伪造或擅自扩张的权限。

这份结构中没有“人”的字段。

缺少身份字段并非早期系统没有完成的待办项,而是设计选择。Amoeba 希望 capability 可以由用户进程直接保存、复制和传递,不需要内核成为中央 capability 管理器。授权跟随引用移动;服务器核验的是引用对某个对象携带的操作权,而不是操作者的简历、雇佣关系或法律身份。

这使 Amoeba 成为理解现代凭证边界的一份好材料。一个验证成功的凭证往往会在日志里被扩写成“已授权”“已批准”甚至“已完成”。实际上,Amoeba capability 只回答一个窄而清楚的问题:持有这份有效引用的进程,能否向这个服务器请求对这个对象执行这项操作?它没有回答谁作出了业务决定、请求是否符合变更窗口、后续系统是否执行、状态是否持久保存。

48、24、8、48,各自只做一件事

1986 年论文《Using Sparse Capabilities in a Distributed Operating System》给出了精确结构:服务端口 48 位,对象号 24 位,权限字段 8 位,校验字段 48 位,总计 128 位。

服务端口与对象号不能合并理解。端口对应服务,在 Amoeba 的 RPC 模型里帮助定位接收请求的服务器。对象号只在该服务器内部有意义;1991 年状态报告把文件服务器中的对象号类比为 UNIX 的 inode 编号。内核用端口寻找服务,其余字段交由服务器解释。因此,找到服务与解释对象仍是两层控制。

8 位权限字段也是位图,而不是跨所有服务通用的八条法律。文件对象可以把某些位解释成读、写、删除;进程对象可以把位解释成启动、停止、检查。字段宽度相同,不代表不同对象的操作含义相同。真正决定权限语义的是管理该对象的服务接口。

校验字段保护可见的对象号和权限组合。因为普通进程能够直接处理 capability,系统不能依赖“只有内核能触碰”的隐藏标签。服务器保留对象秘密,并通过单向函数核对 capability 中的校验值。客户端当然可以在内存里翻转权限位,但若无法同时给出相匹配的校验字段,令牌就会被拒绝。

因此,“不可伪造”必须放在历史假设中理解。该结构的目标是让伪造在当时模型下不可行,不是为 48 位字段颁发现代密码学合格证;它也不会保护一份从合法持有人处被复制的完整令牌。1991 年报告还明确提醒,在不安全环境里可能需要加密来避免 capability 意外泄露。防伪不等于保密。

收缩权限是做减法

新对象的 owner capability 起初打开全部权限位。若持有人只想交出较小权限,它可以把原 capability 与新权限掩码提交给服务器。服务器先验证原 capability,再把现有权限与掩码求交,保留同一对象号,并根据原始随机值生成新的校验字段。编程指南中的 std_restrict 示例把关键一步写得很直白:rights &= mask。

方向性是该机制的核心。限制操作能够删除权限,却不能借掩码添加原 capability 没有的权限。若用户直接把某个关闭的位改成开启,校验字段不会随之正确变化,服务器会拒绝它。

同样重要的是,不要把不同论文方案揉成一个故事。1986 年的 sparse capability 论文讨论了多种权限保护算法:把随机值与权限输入单向函数;由服务器重新签发较小权限;以及用一组可交换单向函数让客户端本地删除权限。1991 年状态报告讲述的是服务器参与的权限收缩路径。这些设计有共同思想,但不是一套同时运行的单一算法。

作者边界也应同样清楚。1986 年论文的作者是 Andrew S. Tanenbaum、Sape J. Mullender 与 Robbert van Renesse;1991 年状态报告的作者是 Tanenbaum、M. Frans Kaashoek、van Renesse 与 Henri E. Bal。Amoeba 是团队系统工程。以 Tanenbaum 为人物入口,不应把共同作者与实现者从机制史中抹去。

“持有即授权”不等于“持有人已识别”

1986 年论文直接说明,持有人可以把 capability 的位串复制给另一个进程;系统也不必维护一份“谁持有哪些 capability”的中央记录。这带来了可移植和位置透明的授权,也同时划定证据边界。

校验成功只能说明:在服务器当前对象秘密下,所提交令牌对这个对象和这些权限有效。它不能说明呈递令牌的进程是从对象创建者处直接获得、经目录继承、由另一个进程转交,还是从不应暴露的存储或网络位置复制而来。除非还有另一层绑定,它也不能把进程映射到具名员工、合同角色或法人主体。

权限位也不证明目的。同一份可写 capability 可以用于例行维护、应急恢复,也可能被用于未经批准的试验。服务器能限制可接受的动词,却不知道组织为什么允许此刻执行该动词。

撤销同样有限。改变服务器保存的对象随机值,可以让该对象既有 capability 一并失效。这是对象级重置,不是选择性地找到每位持有人,不会追溯证明谁曾使用令牌,也不能证明每份泄露副本已从进程、备份和日志里消失。

成功回执应停在服务器语义边缘

若服务器验证 capability 并返回成功,最强的可证明结论仍由该操作的协议语义决定。它可能证明服务器按照实现接受并处理了对象修改,却不自动证明修改已经越过持久化边界、到达全部副本、驱动物理设备、完成外部付款,或符合组织审批制度。

这些属于不同控制面。持久化应由存储与恢复证据证明;物理或网络动作应由执行并观测该动作的子系统证明;人类授权应由负责任的组织记录。一个紧凑令牌可以打开一个操作,但不应被当成操作之后所有世界状态的总回执。

这正是 Amoeba 的长久价值:它以极高的清晰度把命名与保护合在一起,然后在该停下的地方停下。边界不是缺陷,而是机制可理解、可审计的条件。

来源