标签流转实战指南:Agent Control Specification 的无状态标签流模型)
信息流控制IFC标签流转实战指南Agent Control Specification 的无状态标签流模型【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkitAgent Control SpecificationACS将信息流控制Information Flow Control, IFC实现为一种无状态stateless标签流策略模型核心运行时只在干预点评估策略自身不存储标签、不传播污染taint也不内置任何 IFC 检查逻辑全部溯源provenance跟踪责任由宿主host承担。本文以 policy-engine/docs/ifc-label-flow.md 为主体结合 Rego 参考库、Cedar 镜像、manifest 示例与一致性测试用例完整讲解源标签如何在快照中进入、工具清单如何声明放行级别clearance、策略如何执行 no write down 判定、以及result_labels如何在不破坏无状态性的前提下跨轮次传递标签流。读完你将能够理解 ACS 的 IFC 快照契约与失败关闭fail-closed语义、为工具正确声明clearance/security_labels、用agent_control_specification.lib.ifc或 AGT 库存agt.ifc编写 no write down 策略、并通过verdict_propagating实现跨轮次标签传播。设计核心无状态判定 宿主持有溯源ACS 的 IFC 模型刻意把判定与溯源分离核心core负责判定在约定的干预点intervention point如pre_tool_call、input、output评估配置好的策略基于当次调用传入的快照数据返回 verdict。宿主host负责溯源宿主在数据流经 prompt、模型调用、工具结果tool results、记忆memory以及输出准备output preparation等环节时为数据附加标签在每一个 sink 处宿主调用 ACS 并把进入该 sink 的数据标签放在input.snapshot.ifc.source_labels中交给策略。这一分工的直接收益是运行时无需保存任何跨调用的状态水平扩展、无状态部署、缓存友好且策略结果完全由当前快照 策略决定具备可复现性。从源码结构看参考 Rego 库 policy/lib/ifc.rego 全部由纯函数构成dominates、max_sensitivity、flow_allowed、verdict等没有任何副作用或内部状态正是这种无状态模型的实现证据。关于无状态运行时的更完整讨论可参见 policy-engine/docs/stateless-runtime.md 与 policy-engine/docs/snapshot-contract.md。快照契约ifc.source_labels与失败关闭语义默认快照字段为ifc.source_labels其值必须是标签字符串数组。规范 SPECIFICATION.md 第 212 行附近明确约定The snapshot label convention isinput.snapshot.ifc.source_labels. The value MUST be an array of label strings. Policies MUST treat a missing field, a non array value, an empty array, or an unknown label as a denial unless a host specific policy proves a lower sensitivity by other means.也就是说以下任何情况都必须失败关闭fail closed即按拒绝处理情况处理source_labels字段缺失拒绝值不是数组拒绝数组为空拒绝包含未知标签不在格中拒绝标签之间不可比较incomparable拒绝AGT 快照路径与上游库的差异重要坑点需要特别注意的是快照中标签的具体路径随宿主 SDK 表面不同而不同。上游agent_control_specification.lib.ifc库读取的是input.snapshot.ifc.*而 AGTAgent Governance Toolkit宿主 SDK 按 AGT-SNAPSHOT-1.0.md §2.2 / §2.7 填充的是input干预点input.snapshot.input.ifc.source_labelsoutput干预点input.snapshot.response.ifc.result_labels因此如果 AGT 用户直接导入上游agent_control_specification.lib.ifc该库会在 AGT 宿主上永远读不到标签、每次都失败关闭。这正是 AGT 提供库存替代库 policy/lib/agt_ifc.rego包名agt.ifc的原因——其文件头注释明确指出AGT 用户必须导入data.agt.ifc而不是上游包。agt.ifc除了与上游函数表面完全对齐dominates、max_sensitivity、flow_allowed、allow、deny、verdict、verdict_propagating及其_with_lattice变体之外还额外提供三个便捷辅助函数source_labels读取input.snapshot.input.ifc.source_labels非数组时回退为[]result_labels读取input.snapshot.response.ifc.result_labels非数组时回退为[]allow_if_dominates(sink_clearance, labels)no write down 判定的 AGT 简写内部委托给verdict。对应的测试 policy/lib/agt_ifc_test.rego 中test_source_labels_reads_agt_input_path与test_does_not_read_upstream_ifc_path直接验证了这两条路径的差异即使上游路径input.snapshot.ifc.source_labels下放了[secret]AGT 辅助函数看到的依然是[]。工具清单元数据clearance与security_labels工具tool的放行级别是manifest 元数据声明在工具目录tools catalog中。规范 SPECIFICATION.md 第 186 行说明tools是按工具名索引的目录每个条目除类型与 ID 外不限制其他成员一个条目可以声明clearance标签、security_labels数组以及宿主自定义字段。第 214 行进一步明确clearance单个标签命名该 sink 能接收的最大敏感性maximum sensitivitysecurity_labels描述 sink 属性或能力的标签数组如external、controlled、retrieval。运行时把这两个字段直接投影进策略输入input.tool即input.tool.clearance与input.tool.security_labels无需核心代码改动。这是典型的清单驱动manifest-driven设计新增工具的 IFC 属性只需改清单不触碰运行时。以仓库自带的 IFC 示例 examples/ifc_agent/manifest.yaml 为例agent_control_specification_version: 0.4.0-alpha.1 metadata: name: ifc-agent policies: ifc_policy: type: rego bundle: ./policy data_paths: - ../../policy/lib/ifc.rego query: data.agent_control_specification.ifc_agent.verdict intervention_points: pre_tool_call: policy_target: $.tool_call.args policy_target_kind: tool_args tool_name_from: $.tool_call.name policy: id: ifc_policy query: data.agent_control_specification.ifc_agent.pre_tool_call_verdict tools: public_egress: type: Tool id: public_egress clearance: public security_labels: [external] trusted_archive: type: Tool id: trusted_archive clearance: confidential security_labels: [controlled]注意data_paths特意只指向policy/lib/ifc.rego这一单个文件而不是整个policy/lib/目录——因为该目录下的*_test.rego兄弟文件会被 OPA 的数据加载器一并加载manifest 中的注释明确记录了这一点。示例中public_egress工具仅允许接收public级数据对外出口trusted_archive工具允许接收至confidential级数据受控归档。默认格与 Rego 参考库库包agent_control_specification.lib.ifc提供默认的敏感性格latticepublic internal confidential secret并在此基础上提供支配dominance、最大敏感性maximum sensitivity、允许判定与拒绝判定辅助函数。集成者可以传入自己的格数据对象lattice data object以支持额外标签与偏序partial order。默认格在 policy/lib/ifc.rego 中定义为自反闭包形式每个标签支配自身及其以下所有标签default_lattice : {dominates: { public: [public], internal: [public, internal], confidential: [public, internal, confidential], secret: [public, internal, confidential, secret], }}库提供的主要函数及其语义函数语义dominates(clearance, label)/dominates_with_lattice(lattice, clearance, label)判断放行级别是否支配某标签要求两个参数都是字符串并在格中查找闭包max_sensitivity(labels)/_with_lattice计算一组标签的最大敏感性集合中存在一个标签支配其余所有标签flow_allowed(clearance, labels)/_with_lattice组合判定count(labels) 0且 clearance 支配最大敏感性allow(...)/deny(...)/verdict(...)/_with_lattice返回{decision: allow}或拒绝判定对象propagated_labels(labels)/_with_lattice返回[max_sensitivity(labels)]连接语义见下文verdict_propagating(...)/_with_lattice允许时额外携带result_labels的判定见下文dominates_with_lattice的实现通过object.get(lattice, dominates, {})读取格对象再在dominates[clearance]闭包列表中查找目标标签max_sensitivity_with_lattice用every other in labels保证被选中的标签支配集合内全部其余标签。AGT 库存库 policy/lib/agt_ifc.rego 的函数表面与上述完全一致只是快照路径改为 AGT 路径。violation函数统一生成拒绝判定violation(clearance, labels) : { decision: deny, reason: ifc_clearance_violation, message: sprintf(IFC clearance violation for sink clearance %v and data labels %v., [clearance, labels]), }No Write Downsink 处的判定规则策略在 sink 处强制no write down禁止向下写只有当 sink 的clearance支配传入的每一个源标签的最大敏感性时sink 才允许接收数据否则策略返回拒绝判定reason为ifc_clearance_violation。规范 SPECIFICATION.md 第 218 行给出了 MUST 级要求若标签不可比较比较必须失败关闭策略发出的拒绝判定应使用reason ifc_clearance_violation且decision deny。一个典型的 no write down 策略基于agt.ifc的 AGT 写法package my_app.ifc import data.agt.ifc import rego.v1 default verdict : {decision: allow} # 读取 AGT 快照上的源标签input 干预点 source_labels : ifc.source_labels # sink 放行级别来自清单投影 sink_clearance : input.tool.clearance # no write downclearance 必须支配所有源标签 verdict : ifc.verdict(sink_clearance, source_labels)也可以直接用agt.ifc.allow_if_dominates(sink_clearance, labels)简写。测试 policy/lib/agt_ifc_test.rego 中test_clearance_dominates_data_allowsflow_allowed(secret, [confidential])为真verdict(secret, [confidential]).decision allowtest_data_exceeds_clearance_deniesdeny(internal, [confidential])返回decision deny且reason ifc_clearance_violationtest_missing_and_empty_labels_deny_fail_closed即使 clearance 是最高级secret空标签数组依然拒绝test_incomparable_labels_deny_fail_closed自定义格public pii、public pci中pii与pci不可比较flow_allowed_with_lattice(lattice, pii, [pci])为假。result_labels无状态运行时的跨轮次标签通道这是本模型最巧妙的部分核心不保存任何状态但标签流依然可以跨轮次across turns延续。策略 MAY 在其输出中包含result_labels——一个描述 sink 产生数据的标签字符串数组。核心把这个数组原样verbatim返回在verdict.result_labels中除此之外不做任何事不存储、不传播污染、不自行做 IFC 检查。宿主负责把返回的标签与产生出来的数据工具结果或模型输出一起持久化并在后续、其策略目标派生于该数据的评估中把它们作为ifc.source_labels再次提供。这样标签流的延续完全由宿主的数据生命周期驱动运行时始终保持无状态。verdict 的 wire schema spec/schema/wire/verdict.schema.json 中result_labels的注释即描述了这一契约核心原样返回宿主持久化并在后续评估中重新供给核心不存储也不传播。规范 SPECIFICATION.md 第 296 / 308 行附近还给出两个重要补充规范化失败关闭当result_labels存在但不是字符串数组时输出规范化失败产生runtime_error:policy_output_invalid宿主不得为未发生的行为传播标签对于没有实际产生数据的判定如deny包括被审批缝approval seam否决的可升级deny宿主不得传播result_labels——该成员只在 sink 数据真正产出时才有意义。因此库辅助函数在非 allow 判定上省略result_labels。库辅助verdict_propagating的连接join语义verdict_propagating与verdict_propagating_with_lattice返回一个 allow 判定其result_labels是输入源标签的join最大敏感性verdict_propagating(clearance, labels) : verdict if { not flow_allowed(clearance, labels) verdict : violation(clearance, labels) } else : {decision: allow, result_labels: propagated_labels(labels)} if { flow_allowed(clearance, labels) }这些辅助函数假设敏感性格是全序的并把结果折叠成单个支配标签——对于public internal confidential secret这类有序链这是正确默认多个来源的数据取最高级标签不会丢失敏感性。测试test_verdict_propagating_returns_joined_label验证verdict_propagating(secret, [public, confidential, internal])返回decision allow且result_labels [confidential]。丰富格compartment / category下的注意事项如果策略运行在具有独立 compartment 或类别例如pii与pci的更丰富格上且没有任何单一输入标签支配其余标签不要使用verdict_propagating辅助函数——它们会把结果折叠为单一标签从而丢失溯源。此时策略应直接自行发出result_labels要么返回完整的源标签集合要么返回显式 join 后的标签保证溯源不丢失。这是原文档明确给出的边界条件也是编写自定义传播策略时必须遵守的规则。完整可运行示例Rust Rego 的 ifc_agent仓库提供了一个开箱即跑的 IFC 示例 examples/ifc_agent/README.md采用 Rego 策略包、无 annotator在pre_tool_call干预点通过比较snapshot.ifc.source_labels与投影的工具 clearance 执行 no write down 策略。运行方式opa必须在PATH上cargo run -p agent_control_specification --example ifc_agent --quiet策略本体 examples/ifc_agent/policy/ifc_agent.regopackage agent_control_specification.ifc_agent import data.agent_control_specification.lib.ifc import rego.v1 default verdict : {decision: allow} default pre_tool_call_verdict : {decision: allow} verdict : pre_tool_call_verdict if { input.intervention_point pre_tool_call } source_labels : object.get(object.get(input.snapshot, ifc, {}), source_labels, []) sink_clearance : object.get(input.tool, clearance, ) pre_tool_call_verdict : ifc.verdict_propagating(sink_clearance, source_labels) if { input.intervention_point pre_tool_call }驱动演示 examples/ifc_agent/demo.rs 展示了完整的零配置构建 标签传播闭环AgentControl::from_path(manifest.yaml)零配置构建——manifest 声明了 Rego 策略包且无 annotatorfrom_path直接接线捆绑的 OPA 策略分发器public数据发往public_egress允许且verdict.result_labels [public]传播标签下一轮把传播标签作为source_labels送回数据流向trusted_archiveclearanceconfidential支配public再次允许标签原样继续传播——演示了宿主跨轮次回灌标签、运行时保持无状态confidential数据发往public_egress拒绝reason Some(ifc_clearance_violation)。预期判定与 manifest、策略、演示代码的对应位置示例 README 的 Where to look 一节都做了标注便于对照学习。Cedar 镜像预计算闭包 containsAllAGS 在 policy/cedar-lib/ifc.cedar 中提供了 IFC 标签流库的 Cedar 镜像。由于Cedar 无法在策略评估过程中迭代集合来计算格闭包镜像采用宿主预计算策略宿主把格闭包预先计算为资源实体resource entity属性clearance_dominated_labels——一个字符串集合命名该 sink clearance 支配的每一个标签Cedar 策略用集合运算符.containsAll表达 IFC 规则当资源 clearance 没有支配快照上的每一个源标签或标签集合为空时forbid触发。该文件实现了四个 forbid 规则ifc_clearance_violation_inputinput 干预点源标签不被支配、ifc_clearance_violation_outputoutput 干预点结果标签不被支配、以及针对空标签集合的ifc_clearance_violation_empty_input/_empty_output——后两者把空标签失败关闭用显式 forbid 落到了 Cedar 语义里。选择建议文件头注释明确说明需要格灵活性在评估时选择格的作者留在 Rego 库data.agt.ifc它暴露了dominates_with_lattice、verdict_with_lattice等按调用时传入格文档的函数采用 Cedar 的作者当格变化时需要重新加载实体reload entities因为闭包是预计算进实体属性的。一致性测试与验证IFC 行为由两层测试覆盖Rego 单元测试policy/lib/agt_ifc_test.rego上文已多次引用覆盖支配允许、超限拒绝、不可比较失败关闭、空/缺失标签失败关闭、多标签取最大敏感性、传播连接、AGT 路径读取、上游路径不可见等全部关键语义一致性conformance用例tests/conformance/cases/spec-18-ifc.case-01.json 与 spec-18-ifc.case-02.json对应规范第 18 节case-01search工具 clearance 为internal快照源标签[internal]判定allowcase-02同样的工具与清单快照源标签改为[confidential]超过 clearance判定deny且reason ifc_clearance_violation。两个用例都声明 Rust / Python / Node SDK 为 required、.NET 为 optional并在references中同时指向 policy/lib/ifc.rego 与本文主体文档 docs/ifc-label-flow.md是理解规范意图最直接的对照样本。信任边界完整宿主插桩是前提原文档最后一句给出了模型的信任边界该模型依赖完整的宿主插桩。以下情形不在 ACS 的保证范围之内未插桩的数据路径数据绕过了宿主附加标签的环节宿主侧的标签丢失宿主没有把标签正确附加或持久化不调用 ACS 的 sink数据在未经策略评估的出口流出。换句话说ACS 的 IFC 保证是判定时刻的正确性而每个数据点都被标记、每个出口都被评估属于宿主责任。在设计系统时应把pre_tool_call、input、output等干预点全部接入 ACS并在数据生命周期中严格执行产生数据 → 持久化result_labels→ 后续作为source_labels回灌的循环否则标签流会在未插桩处静默断裂。相关宿主义务在 SPECIFICATION.md 第 17 节有完整定义可结合 policy-engine/docs/security-model.md 与 policy-engine/docs/stateless-runtime.md 进一步了解整体安全模型。【免费下载链接】agent-governance-toolkitAI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.项目地址: https://gitcode.com/GitHub_Trending/ag/agent-governance-toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考