设计 Capability 安全执行
显式建模权限、衰减子 Run、分类风险与 Effect、执行策略,并避免把身份当成权限。
权限模型
Runifold 用 CapabilityDescriptor 表达可执行权限,其中包含稳定 Identity、Kind、Schema、
语义版本、Effect Class 与 Risk Level。CapabilitySet 属于某次 Run。Callable、Resource、
子 Agent 或 Extension 不会因为应用代码能够访问就自动可用。
Authentication 回答调用者是谁;Authorization Policy 把身份和请求转换成 Capability Set。 这些决策不能放在 Prompt 文本中。
注册与授权
注册说明 Agent、MCP Server 或 Registry 知道如何调用什么;授权说明本次执行可以调用 什么。终端边界必须同时通过两项检查。
Tool Name、Route Name、URI、Task ID、Tenant ID、Worker ID 或 Model Hint 都不是权限证明。 Identifier 只能在授权后选择对象。
权限衰减
子 Run 接收显式 Capability Set,必须等于或窄于 Parent。Delegation、Workflow Branch、 MCP Handler、Tool 与 Retrieval Lookup 都只获得当前操作所需的最小权限。
Middleware 可以修改输入或拒绝工作,但不能替换已经解析的 Route 或 Parent Authority。 Retry 会创建新的终端尝试,并重新检查取消、Deadline、Capability、Depth 与 Budget。
策略边界
Approval、DLP、Tenant Access、Rate Limit、高风险写与治理使用类型化 Policy Decision。 区分 Denial 与 Policy Backend Failure;两者都关闭式失败,但运维处理不同。
准确分类 Effect:Pure、ReadOnly、IdempotentWrite、NonIdempotentWrite、Destructive 或 Unknown。Risk Level 支持审核与遥测;Effect Class 决定恢复与 Race 资格。
安全检查
- Authentication 后构建根 Capability;
- 每个 Child 都执行权限衰减;
- 在实际执行边界重新检查;
- Store Query 绑定 Tenant Scope;
- Credential 不进入 Run Metadata 与模型内容;
- 破坏性治理要求独立审批;
- 记录安全 Denial Reason 与 Policy Outcome;
- 测试未知、未授权、陈旧、重复与跨租户 Identity;
- 新 Capability Kind 与未知 Effect 默认拒绝。
在根 Run 授予权限
let weather = Arc::new(current_weather_tool());
let mut capabilities = CapabilitySet::new();
capabilities.grant(weather.descriptor().capability());
let run = RunContext::root(
BudgetTracker::new(Budget::default()),
capabilities,
);
let agent = runtime
.agent("assistant")
.shared_tool(weather)
.build()?;
let outcome = agent.prompt("Weather in Shanghai?", &run).await?;Registration 让 Tool 对 Agent 可发现;Grant 让同一 Descriptor 在当前 Run 中可调用。 缺少任意一个都必须拒绝执行。认证 Request 后再构造 Root Capability,并为每个 Child Agent、Workflow Branch、MCP Session 或 Retrieval Source 缩减权限。绝不能根据模型 提供的 Name 构造 Authority。