资讯动态

IronClaw 授权内核解析:ironclaw_authorization 的 Grant 匹配、Capability Lease 状态机与默认拒绝架构

发布时间:2026/9/24 13:50:46 来源:尧图企业网站定制
人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载IronClaw 是一个以隐私、安全与可扩展性为核心的 Agent OS。在其内核kernel流水线中ironclaw_authorization是授权决策阶段它把调用方的 grants授权凭证与活跃 leases租约匹配到请求的具体 effect效果并在有效信任上限authority ceiling之下给出 Allow / Deny / Require-Approval 结论整体默认拒绝default-deny。本文以该 crate 的 AGENTS.md 为主干结合 README.md 与 src/lib.rs 源码讲解其所有权边界、Authorizer 端口、能力租约状态机、跨进程安全的 CAS 持久化以及验证命令与工程守则。一、Crate 定位内核流水线中的授权决策阶段ironclaw_authorization属于kernel/层的 kernel 家族包名为ironclaw_authorization清单位于 crates/kernel/ironclaw_authorization/Cargo.tomlpublish false仅仓库内部使用。它的职责非常聚焦Grant 匹配判断请求的 capability 是否被某个活跃 grant 覆盖Capability lease 状态管理维护能力租约的签发、认领claim、消费consume、撤销revoke状态机Dispatch / Spawn 授权决策为 capability 分派与后台进程派生返回Decision默认拒绝。README 中明确区分了它与邻居 crate 的分工does a grant cover this一个 grant 是否覆盖此请求与 did a human agree to this人类是否同意是两个不同问题、失败模式不同且只有其中之一负责存储 leases。因此想把待审批的 approval 解析成 lease→ 去ironclaw_approvals想实际分派dispatch任何能力→ 去ironclaw_capabilities想推理信任上限→ 去ironclaw_trust。ironclaw_authorization只负责给出判决和管理租约状态绝不执行能力、不持久化运行状态、不解析审批、不预留资源、不向用户提问。依赖与消费方源码可验证常规依赖受测量约束Cargo.toml 中仅有ironclaw_host_api契约类型如Decision、ExecutionContext、ResourceScope、ironclaw_trust每个 grant 都必须满足的信任上限固定同层边、ironclaw_filesystem通过ScopedFilesystem做租约持久化以及async-trait、chrono、serde/serde_json、thiserror、tokio仅sync。常规消费者7 个ironclaw_approvals、ironclaw_capabilities、ironclaw_host_runtimekernel、ironclaw_assistant、ironclaw_composition、ironclaw_extension_host、ironclaw_extension_manager。依赖边界由reborn_dependency_boundaries.rs中的BoundaryRule固化禁止反向依赖ironclaw_approvals、ironclaw_capabilities、ironclaw_host_runtime、ironclaw_processes、ironclaw_resources、ironclaw_secrets、ironclaw_network及 lane crates——审批解析依赖本 crate而绝不反向依赖。二、What This Crate Owns授权器的端口与实现ironclaw_authorization拥有三类核心构件全部位于 src/lib.rs1. Authorizer 端口traitCapabilityDispatchAuthorizersrc/lib.rs#L52-L74核心方法是authorize_dispatch(context, descriptor, estimate) - Decision仅在上下文拥有匹配该 capability 及声明 effect 的授权时返回Allow否则 fail closedauthorize_spawn默认实现直接返回Deny { reason: MissingGrant }。TrustAwareCapabilityDispatchAuthorizersrc/lib.rs#L84-L109信任感知版本调用方额外传入经过策略校验的TrustDecision。它被单独拆出来是因为ironclaw_trust::EffectiveTrustClass有意不实现Deserialize不应直接嵌入 wire 形状的执行上下文中authorize_spawn_with_trust同样默认拒绝。两个端口都是async_trait且要求Send Sync便于在运行时中组合与并发使用。2. Authorizer 实现GrantAuthorizersrc/lib.rs#L111-L180纯 grant 驱动的授权器遍历context.grants中的 grant 做匹配spawn 场景会把SpawnProcesseffect 追加进描述符再匹配spawn_descriptor。LeaseBackedAuthorizera, Ssrc/lib.rs#L854-L969在请求级 grants 之上叠加活跃 leases 转化出的 grantsactive_grants_for_context即请求自带授权 已批准租约的联合判决进入匹配前会先做context.validate()校验失败直接InternalInvariantViolation拒绝。3. 信任上限检查grant_exceeds_authority_ceilingsrc/lib.rs#L1197-L1208 提供一个同步、与存储无关的谓词当某个已存在的 grant 超出当前策略推导出的AuthorityCeilingeffect 覆盖不足或资源上限超限时返回true供信任变更失效监听器ironclaw_trust::InvalidationBus做重新签发或撤销。之所以刻意保持同步是因为InvalidationBus同步执行监听器而本 crate 的持久化租约存储是异步的——高层 host 装配可以把它放进自己拥有的事务/对账路径而无需引入嵌套阻塞执行器或进程/运行时依赖。三、默认拒绝与授权匹配的判定逻辑授权核心函数是authorize_from_grants_with_authority_ceilingsrc/lib.rs#L1014-L1061判定过程可归纳为上下文校验context.validate()失败 →Deny { InternalInvariantViolation }Grant 过滤依次按grant.capability descriptor.id、principal_matches_contexttenant/user/agent/project/mission/thread/extension 逐类比对、grant_is_active未过期且max_invocations ! Some(0)过滤覆盖检查descriptor 声明的 effects 必须全部被 grant 的allowed_effects覆盖且若传入 authority ceiling还必须被 ceiling 的allowed_effects覆盖资源上限resource_estimate_is_covered校验请求的资源估算不超过grant 上限 ∩ authority ceiling 上限的交集intersect_resource_ceilings取更严格者sandbox 配额同理义务Obligations推导匹配成功时根据 effect 类型产出Obligations例如UseScopedMounts文件系统类 effect、ApplyNetworkPolicy网络受约束时、InjectSecretOnce/InjectCredentialAccountOnce需要密钥或产品认证账户且被 grant 覆盖、EnforceResourceCeiling/EnforceOutputLimit等src/lib.rs#L1063-L1143判决全部满足 →Allow { obligations }否则若存在匹配的活跃 grant 但被策略拒绝 →Deny { PolicyDenied }若根本不存在匹配 grant →Deny { MissingGrant }。关键不变量默认拒绝没有任何 fail-open 分支看到过匹配 grant 但被策略拒绝与压根没有 grant是两个不同的DenyReason便于上层区分问题根因。四、Capability Lease状态机与单赢家认领协议1. 为什么需要 lease一个已批准的请求可能被恢复重入auth-resume例如进程重启后之前已批准的一次调用需要重新进入并复用已批准授权但绝不能在并行路径上再发放第二个分派double dispatch。README 将这一机制称为single-winner claim protocol。这正是CapabilityLease存在的理由它承载已批准但尚未消费的一次性/受限次数授权。2. 数据结构与状态CapabilityLeasesrc/lib.rs#L182-L200包含scope: ResourceScope、grant: CapabilityGrant、invocation_fingerprint: OptionInvocationFingerprint与status。CapabilityLeaseStatussrc/lib.rs#L202-L213的状态机状态含义Active新签发可被授权器作为 ambient grant 使用仅非指纹租约Claimed已用匹配的 invocation fingerprint 原子认领等待消费Dispatchingbegin_dispatch_claimed设置的瞬态确保恰好一个并发 auth-resume 复用指纹租约第二个调用方看到非Claimed状态得到InactiveLease与并发Active租约claim()的失败路径一致Consumed一次性租约已消费或次数已耗尽Revoked被撤销CapabilityLeaseErrorsrc/lib.rs#L215-L246覆盖UnknownLease、ExpiredLease、ExhaustedLease、UnclaimedFingerprintLease、FingerprintMismatch、InactiveLease、Persistence、VersionMismatch内部 CAS 重试信号不会逃逸出公共 API与CasExhaustedCAS 重试预算耗尽属于可重试的瞬时错误。3. 存储端口与单赢家语义CapabilityLeaseStorePortsrc/lib.rs#L248-L317定义issue在审批记录标记为 approved之前持久化作用域租约revoke仅允许在拥有该租约的精确 resource-owner/invocation 作用域内撤销get按精确 scope ID 读取跨作用域查找必须表现为 unknownclaim(scope, id, fingerprint)原子地将活跃指纹租约在匹配重放指纹后标记为Claimedconsume成功分派后消费/递减begin_dispatch_claimed/abort_dispatch_claimedClaimed → Dispatching保证单赢家复用与Dispatching → Claimed非终态 auth 回弹后允许后续 auth-resume 复用leases_for_scope/active_leases_for_context作用域内列举与上下文过滤active_grants_for_contextsrc/lib.rs#L308-L316只把非指纹的活跃租约转化为 ambient grants——指纹租约是仅恢复使用的授权绝不允许变成常驻权限。五、跨进程安全的 CAS 持久化实现唯一的生产后端是CapabilityLeaseStoreFsrc/lib.rs#L339-L345以ArcScopedFilesystemF为底座并持有 per-owner 的进程内变更锁mutation_locks。其并发安全模型分两层1. 带版本期望的 compare-and-swap跨进程变更路径revoke/claim/consume/begin_dispatch_claimed/abort_dispatch_claimed统一走update_lease_cassrc/lib.rs#L491-L516先read_lease_versioned读取租约连同当前RecordVersion应用状态迁移谓词后用CasExpectation::Version(version)写回若收到FilesystemError::VersionMismatch经 src/lib.rs#L1614-L1625 映射为CapabilityLeaseError::VersionMismatch重新读取并重试预算为CAS_RETRY_ATTEMPTS 3src/lib.rs#L26预算耗尽返回CasExhausted调用方可视为瞬时错误在上层重试。这样即使两个进程共享同一后端根目录一个并发写者在读与写之间修改了租约行也会被 CAS 拦截重读后重新应用迁移——net effect 是逻辑并发迁移中的 last-writer-wins且没有静默覆盖。2. 进程内 per-owner 变更锁与降级路径mutation_locksrc/lib.rs#L358-L366按CapabilityLeaseOwnerKeytenant/user/agent/project/mission/thread 六元组给出一个进程内的tokio::sync::Mutex同一 owner 的变更在进程内串行化。issue走CasExpectation::Any 新生成的租约 id配合 per-owner 锁保证首写无冲突src/lib.rs#L680-L687。降级路径只有 byte-only/Unsupported文件系统根如DiskFilesystem不支持行级版本与索引投影才降级为进程内串行化 CasExpectation::Any见write_lease_raw的 fallbacksrc/lib.rs#L419-L468。AGENTS.md 明确警告这类根不适合真实的跨进程并发调用方。3. 租约的物理布局与租户隔离租约文件位于/authorizationmount 别名之下src/lib.rs#L1508-L1579/authorization/leases/within-tenant-scope/invocation_id/lease_id.json /authorization/leases/within-tenant-scope/_lease_index.json其中within-tenant-scope是[agents/agent_id/][projects/project_id/][missions/mission_id/][threads/thread_id]。租户/用户前缀tenants/tenant_id/users/user_id是MountView的职责而不是本 crate 手拼的——ScopedFilesystem在每个操作前把/authorization别名解析到租户/用户作用域的VirtualPath并执行 per-op ACL因此租户隔离是结构性的而非约定。此外每次写入还在 entry 上投影tenant_id索引authorization_by_tenant作为纵深防御便于管理端查询与暴露路径重写 bugsrc/lib.rs#L1631-L1680。4. 测试支撑in-memory是后端不是 bespoke store测试通过test-supportfeature 暴露的in_memory_backed_capability_lease_store()src/test_support.rs实例化与生产完全相同的CapabilityLeaseStoreInMemoryBackend——InMemoryBackend是一个内存文件系统后端而非独立实现的存储。此前手写的InMemoryCapabilityLeaseStore已被删除架构简化 §4.3。这样测试即生产租约契约测试tests/capability_lease_contract.rs用同一套存储验证了活跃租约可授权无 grant 上下文指纹租约不能授权普通分派claim 后从授权器隐藏指纹不匹配不改变状态跨租户/agent/project 隔离消费递减与一次性消费过期不再授权/消费等关键行为并用FaultInjectingop-recorder 模式断言leases_for_scope走 owner 索引而非逐个扫描 invocation 目录。六、Guardrails 与工程守则AGENTS.md 给出四条硬性护栏所有权边界只拥有 grant 匹配、lease 状态与 dispatch/spawn 授权决策不得执行 capabilities、持久化运行状态、解析 approvals、预留资源、提示用户也不得 import 运行时/进程/分派器/capability 工作流 crate。默认拒绝与作用域授权默认拒绝且按 resource-owner/invocation 作用域tenant/user/agent/project/mission/thread酌情含 invocation限定。异步纪律文件系统租约必须使用异步文件系统调用禁止嵌套block_on。降级与指纹纪律仅 byte-only/Unsupported根允许降级为进程内串行化指纹审批租约是仅恢复使用的授权不得变成 ambient grants。不得移入此处清单包括审批租约认领、运行时分派、义务执行、字符串化stringly权限逻辑以及错误/事件/快照/日志/文档中的 secrets、原始 host 路径、后端错误细节与未脱敏用户内容。七、验证与测试命令快速本地检查cargo test -p ironclaw_authorization依赖/API 变更后的边界检查cargo test -p ironclaw_architecture_tests生产持久化行为变更时维护 PostgreSQL 与 libSQL 的对等测试。从源码结构看其余契约测试分布在 tests/boundary_contract.rs、tests/capability_access_contract.rs、tests/runtime_credentials_contract.rs与 Reborn 契约文档capability-access.md、kernel-boundary.md、host-api.md一一对应可作为修改行为前的事实来源。八、给贡献者与集成方的操作建议保持编辑范围在 crate 内除非契约明确要求邻居 crate 变更否则不要把改动扩散到ironclaw_approvals、ironclaw_capabilities等。优先编写 caller 级测试当某个 helper 为 dispatch、持久化、网络、secrets、approvals、资源、事件或进程副作用把关时优先用调用方级测试验证而不是 mock 掉门禁本身。契约与代码冲突时停下来把任务当作契约变更请求处理而不是静默改变所有权——这正是 AGENTS.md 与 CLAUDE.md指向同一份工作规则的指针文件反复强调的协作原则。总结ironclaw_authorization用一组清晰的 trait 端口CapabilityDispatchAuthorizer/TrustAwareCapabilityDispatchAuthorizer、两个实现GrantAuthorizer/LeaseBackedAuthorizer与一个跨进程安全的文件系统租约存储把授权判决与已批准调用的安全重入固化成了默认拒绝、作用域隔离、CAS 单赢家的内核构件。它的核心价值在于把grant 是否覆盖与人类是否同意彻底分离前者只在这里发生后者只在ironclaw_approvals发生从而让每一次能力分派都能被精确审计、精确撤销、精确重入——这正是 Agent OS 在隐私与安全上的地基。赞分享人工智能AI 应用交互助手AI Agent【免费下载链接】ironclawIronClaw is an Agent OS focused on privacy, security and extensibility项目地址https://gitcode.com/gh_mirrors/iro/ironclaw点击查看免费下载相关推荐OmniRoute 授权机制全解基于路由分类的确定性、默认拒绝认证管线OmniRoute 授权机制全解基于路由分类的确定性、默认拒绝认证管线 OmniRoute 作为统一的 AI 网关同时承载着模型推理 API 与 Web 管后端API网关LLM 网关人工智能大模型MCP 服务桌面应用Puppeteer Browser.setPermission() 详解在默认浏览器上下文中按 Origin 授予与拒绝权限Puppeteer Browser.setPermission 详解在默认浏览器上下文中按 Origin 授予与拒绝权限 本文聚焦 Puppeteer 的 B浏览器控制测试网页爬虫开发工具GPUI Shell 能力模型实战从默认拒绝到最小授权 —— gpui-shell 的能力清单、存储与沙箱机制解析GPUI Shell 能力模型实战从默认拒绝到最小授权 —— gpui shell 的能力清单、存储与沙箱机制解析 本篇文章深入讲解 gpui kit 项目中桌面应用UI组件前端上一篇SIMD可视化终极指南如何轻松理解并行计算代码下一篇从零开始神奇弹幕如何让你的B站直播互动效率提升300%创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价