Kata Containers Agent Policy 实战:用 Rego 策略对 Guest 内 ttRPC 请求实施细粒度访问控制
云原生容器运行时【免费下载链接】kata-containersKata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/项目地址https://gitcode.com/gh_mirrors/ka/kata-containers点击查看免费下载Agent Policy 是 Kata Containers 中允许 Guest VM 内的 Kata Agent 对每一个 ttRPC API 请求做额外验证的功能其典型应用场景是机密容器——宿主侧的 Kata Shim 与 Guest 侧的 Kata Agent 处于不同的信任域。读完本文你将能够理解 Agent Policy 的信任模型、掌握AGENT_POLICYyes构建参数对 Guest rootfs 与 Agent 的影响、完整走通“手工编写 Rego 策略 / genpolicy 自动生成 / Kubernetes annotation 下发”的完整流程并能结合仓库源码看懂策略校验的底层调用链与调试方法。1. Agent Policy 是什么信任模型与适用场景Agent Policy 是 Kata Containers 的一项特性Guest VM 会针对每一个 ttRPC API 请求执行额外的验证只有策略允许的请求才会真正被执行。它最常用于实现机密容器confidential containers在机密计算场景下运行在宿主机上的 Kata Shim 与运行在加密 VM 内的 Kata Agent 具有不同的信任属性——Shim 发送的请求不能被 Agent 无条件信任。策略让 Agent 可以拒绝与 Pod 规格不一致的 API 调用。不过策略同样适用于非机密容器例如作为基本的纵深防御手段阻止宿主向 Guest 内启动任意应用。但官方文档明确提醒对于非机密容器宿主有可能修改策略文件、或替换 Agent 从而禁用策略规则因此策略的价值在机密容器中更充分。2. 构建时启用 Agent Policy 代码默认配置下编译的 Kata Containers 代码不包含Policy 功能。构建 Guest rootfs 时必须显式指定AGENT_POLICYyes构建脚本为 rootfs.sh该参数会产生三个连锁效果Open Policy Agent (OPA)二进制会被安装进 rootfs如果未同时指定AGENT_INITyes构建参数Guest rootfs 会包含kata-opa服务OPA 在 Kata 沙箱创建过程中由systemd启动Kata Agent 会以AGENT_POLICYyes参与构建从而包含 Policy 支持。若在AGENT_POLICYyes的同时指定了AGENT_INITyes则 Kata Agent 会在沙箱创建时自行启动 OPA。2.1 构建脚本中的具体行为从 rootfs.sh 可以看到AGENT_POLICYyes时会解析出默认策略文件路径可用AGENT_POLICY_FILE参数覆盖默认指向 allow-all.rego随后在 rootfs.sh 中完成安装if [[ ${AGENT_POLICY} yes ]]; then info Install the default policy # Install default settings for the kata-opa service. local opa_settings_dir/etc/kata-opa local policy_file_name policy_file_name$(basename ${agent_policy_file}) local policy_dir${ROOTFS_DIR}/${opa_settings_dir} mkdir -p ${policy_dir} install -D -o root -g root -m 0644 ${agent_policy_file} -T ${policy_dir}/${policy_file_name} ln -sf ${policy_file_name} ${policy_dir}/default-policy.rego fi关键点默认策略被安装到/etc/kata-opa/目录并且default-policy.rego是一个符号链接。这一结构直接决定了后文“修改 Guest 内默认策略”的操作方式。Agent 侧的开关位于 src/agent/Makefile##VAR AGENT_POLICYyes|no define if agent enables the policy feature AGENT_POLICY ? no即 Agent 的 Policy 支持是一个可选编译开关默认关闭只有 rootfs 构建脚本把AGENT_POLICYyes透传给make时rootfs.sh 中的make ... AGENT_POLICY${AGENT_POLICY}Agent 才会携带该特性。3. Policy 格式Rego 语言策略文档是一个文本文件使用Rego策略语言编写Open Policy Agent 的策略语言。所有 Kata Agent Policy 文档必须以如下包名开头package agent_policy这一点在源码中得到印证Agent 在求值时查询的正是data.agent_policy.端点名见 src/agent/policy/src/policy.rs 中allow_request对format!(data.agent_policy.{ep})的查询运行时通过SetPolicyRequest动态下发的策略也会以agent_policy为包名加载src/agent/policy/src/policy.rs。4. 向 Kata Agent 提供策略的两种及一种补充方式4.1 方式一将策略包含在 Guest rootfs 中使用AGENT_POLICYyes构建时默认策略文件 会自动包含进 Guest rootfs。该默认策略非常宽松——允许所有ttRPC API 请求执行。查看 allow-all.rego 的内容可以确认它对CreateSandboxRequest、ExecProcessRequest、CopyFileRequest、PullImageRequest、SetPolicyRequest等共 39 个端点全部定义了default ... : true。若要修改默认策略授予的权限用户需要把自己的策略文件加入 Guest 镜像并把/etc/kata-opa/default-policy.rego符号链接指向自定义策略文件——这正是第 2.1 节中ln -sf ${policy_file_name} ${policy_dir}/default-policy.rego所建立的结构只需替换链接目标即可切换生效策略。4.2 方式二通过 Kubernetes YAML annotation 下发策略Kubernetes 用户可以把策略文档编码为base64作为 annotation 附加到 Pod 上注解键为io.katacontainers.config.hypervisor.cc_init_data。步骤 1编码策略文件以示例策略allow-all-except-exec-process.rego为例它与 默认策略 的唯一区别是把ExecProcessRequest的默认值改为拒绝# 与 allow-all.rego 相同但最后一行为 default ExecProcessRequest : false编码流程为三步将策略嵌入 init data 结构 → 压缩gzip→ Base64 编码。完整命令如下$ STRING$( allow-all-except-exec-process.rego) $ cat EOF | gzip -c | base64 -w0 version 0.1.0 algorithm sha256 [data] policy.rego $STRING EOF H4sIAAAAAAAAA42UTW/TQBCG7/4Vq/QQOCQKQXCo1ENIAkRqiGWnpBJCaGKP7RXrXTM7DnV/PRMiVUh07R582J3H8/XO7AnJa2fVjRrNpmms1EEpnSkuarPd76Cbv3oyj6lgPD92jUOKOzbkpYupEA4/E4ulJL13Sky4rVqy1ms/mb9VWZS8K1iM1DgClijRlcBpvLqf3OoMrcfJJkfLutBI12rRQFbhZD6dCRfJ4SeUqOSz/OMSNopyLKA1rBZ5vkjiLyhBj458gr9a9KyubxRTi/9i6W9oQualcR5TzrUNElLZR20waCcExqWzDNoi9WMp2PzoHkLQSi7JdQPUJQtMuksWLQQu912fZKBZHz7QolaRN0c6s9bywjFZBhL5W4lsPEFuvPjhvTlh6mNwx2MudNdLDZXwnf4SYGFo/3O64NWZTySEgAQhT1lECQZKsHan4UgXLGUwFWTzHjh0woIt661HGxJgh4xT0RoV6/w1IO19XAOKfJFTxmxva6DRQsX/12jIKBLC0Y0Er2DuUutxMM5nak9QaZt2cOwf4En1ww42nN3OKw14/B4ua/CWLesHWTYU1EphGS/w0470Y/1LcgDNA40/yKOMzw/tE7NwOx/NwUYj9H5qf4DsX93tO4FAAA注意 init data 结构本身带有version和algorithm字段策略文本放在data段的policy.rego键中。步骤 2把策略挂到 Pod 上将编码后的字符串写入 Pod YAML例如pod1.yamlapiVersion: v1 kind: Pod metadata: name: policy-exec-rejected annotations: io.katacontainers.config.hypervisor.cc_init_data: H4sIAAAAAAAAA42UTW/TQBCG7/4Vq/QQOCQKQXCo1ENIAkRqiGWnpBJCaGKP7RXrXTM7DnV/PRMiVUh07R582J3H8/XO7AnJa2fVjRrNpmms1EEpnSkuarPd76Cbv3oyj6lgPD92jUOKOzbkpYupEA4/E4ulJL13Sky4rVqy1ms/mb9VWZS8K1iM1DgClijRlcBpvLqf3OoMrcfJJkfLutBI12rRQFbhZD6dCRfJ4SeUqOSz/OMSNopyLKA1rBZ5vkjiLyhBj458gr9a9KyubxRTi/9i6W9oQualcR5TzrUNElLZR20waCcExqWzDNoi9WMp2PzoHkLQSi7JdQPUJQtMuksWLQQu912fZKBZHz7QolaRN0c6s9bywjFZBhL5W4lsPEFuvPjhvTlh6mNwx2MudNdLDZXwnf4SYGFo/3O64NWZTySEgAQhT1lECQZKsHan4UgXLGUwFWTzHjh0woIt661HGxJgh4xT0RoV6/w1IO19XAOKfJFTxmxva6DRQsX/12jIKBLC0Y0Er2DuUutxMM5nak9QaZt2cOwf4En1ww42nN3OKw14/B4ua/CWLesHWTYU1EphGS/w0470Y/1LcgDNA40/yKOMzw/tE7NwOx/NwUYj9H5qf4DsX93tO4FAAA spec: runtimeClassName: kata containers: - name: first-test-container image: quay.io/prometheus/busybox:latest command: - sleep - 120然后创建 Pod$ kubectl apply -f pod1.yaml整条链路的运行过程在创建 Pod 沙箱时Kata Shim 会注意到io.katacontainers.config.hypervisor.cc_init_data注解在宿主机上创建 init data 设备并将其以块设备形式挂载到 Guest。Kata Agent 启动后从该设备读取 init data 结构若其中存在策略则将其设置为当前生效策略。此外从源码结构看还存在一条运行时下发路径agent.proto 定义了SetPolicyRequestRPCsrc/agent/src/policy.rs 中的do_set_policy会先经策略自身校验SetPolicyRequest端点再调用AgentPolicy::set_policy用new_engine()重建引擎并整体替换策略。默认策略列表中default SetPolicyRequest : true即表示允许这种动态替换机密容器场景下通常把该端点收紧防止宿主随意改写策略。5. 策略是如何被强制执行的5.1 文档描述的机制Kata Agent 负责执行策略Agent 对每一个ttRPC API 请求在执行对应动作之前先查询策略引擎Open Policy Agent判断允许还是阻止凡是不被允许的一律拒绝。5.2 源码级的执行细节结合仓库源码可以进一步看清校验链路请求入口以copy_file为例src/agent/src/rpc.rs 在#[cfg(feature agent-policy)]分支中先把原始请求转换为PolicyCopyFileRequest再调用is_allowed_with_entrypoint(req.descriptor_dyn().name(), req_for_policy)。端点名就是 proto 消息名如CopyFileRequest与 Rego 中规则名一一对应。策略求值src/agent/src/policy.rs 把请求参数序列化为 JSON 字符串交给全局单例AGENT_POLICY定义于 src/agent/src/main.rs最终由 src/agent/policy/src/policy.rs 的allow_request以查询data.agent_policy.端点名的方式求值。从源码结构看当前实现使用进程内的 Rego 引擎regorus完成评估与文档中 OPA REST API 的查询语义一致寻找同名规则中是否有返回true的分支。拒绝行为策略返回不允许时Agent 返回 ttrpc 的PERMISSION_DENIED错误错误信息形如{ep} is blocked by policy: {prints}其中prints是 Rego 规则中print()语句收集的诊断输出src/agent/src/policy.rs。这正是下节规则示例中大量print调用的用途——被拒请求的拒绝原因会带上这些打印内容。结果形态求值结果可以是普通布尔值也可以是{allowed: bool, ops: JSON Patch}形式的对象。当allowed为真且携带ops时Agent 会把 JSON Patch 应用到引擎的内部状态pstatesrc/agent/policy/src/policy.rs这使得策略可以在多个请求之间维护状态例如 genpolicy 自动生成的状态机规则。调试开关策略可以定义AllowRequestsFailingPolicy规则若其求值为真Agent 会忽略策略错误与拒绝结果用于排障见 src/agent/policy/src/policy.rs。另外src/agent/src/config.rs 中的KATA_AGENT_POLICY_FILE环境变量可覆盖默认策略文件路径默认值即 policy.rs 中定义的/etc/kata-opa/default-policy.rego调试日志JSON Lines 格式写入/tmp/policy.jsonl。值得注意的一个工程细节CopyFileRequest进入策略前会先被转换为精简结构PolicyCopyFileRequestsrc/agent/policy/src/policy.rs把file_mode位解析为file_typeRegular/Directory/Symlink/Unknown并提取符号链接目标避免在 Rego 里做繁琐的位运算同时刻意不传入data字段以减小序列化开销。该转换有完整单测覆盖test_copyfile_translationsrc/agent/policy/src/policy.rs。6. 创建策略文档6.1 手工编写对于相对简单的用例可以直接参考 Rego 策略语言文档手工编写策略文本。策略文档的完整构成见下文第 7 节。6.2 使用 genpolicy 自动生成genpolicy工具可以基于输入的 Kubernetes YAML 文件自动生成匹配的策略其工作流程是读取用户的 Kubernetes YAML 文件根据文件内容推断用户意图生成对应的 Rego 格式 Policy 文件将策略文本 base64 编码后作为 annotation 追加到用户的 YAML 文件中。用法示例$ genpolicy -y test.yaml支持自动策略生成的 YAML 类型包括DaemonSet、Deployment、Job、Pod、ReplicaSet、ReplicationController、StatefulSet。更高级的命令行参数见 genpolicy 高级参数文档自动生成策略的细节见 genpolicy-auto-generated-policy-details。警告自动生成的策略上线前务必仔细审查必要时按自身用例修改再投入使用。重要 — User / Group / 补充组使用 nydus guest-pull 等特性时应在 Pod spec 中显式设置 user/group ID参见 Limitations 中 guest-pulled-container-images 一节。7. 策略文档内容详解7.1 默认值Default values当 Kata Shim 向 Agent 发送 ttRPC 请求时与该请求类型对应的规则名会被求值例如收到CopyFile请求时策略中所有名为CopyFileRequest的规则都会被评估引擎尝试找到至少一条返回true的规则至少一条CopyFileRequest规则返回true引擎向 Agent 返回trueAgent 执行 Shim 要求的文件拷贝所有规则均返回false或无匹配时若策略包含CopyFileRequest的默认值则返回该默认值若策略没有该默认值引擎返回空响应。Agent 把空响应等同于false即拒绝请求。建议虽然 Agent 对空响应按false处理仍建议始终提供默认值——有了默认值策略文档和引擎/Agent 日志都更易于理解。默认值示例default WaitProcessRequest : true default ExecProcessRequest : false7.2 策略数据Policy data策略数据是可选的通常包含供规则与请求输入参数比较的值基于比较结果规则返回true或false来决定放行/拒绝。示例policy_data : { common: { cpath: /run/kata-containers/shared/containers }, request_defaults: { CopyFileRequest: [ ^$(cpath)/ ], ExecProcessRequest: { commands: [ /bin/foo ], regex: [] } } }其中cpath是 Guest 内容器共享目录前缀$(cpath)为规则中的占位符写法。7.3 规则Rules规则同样是可选的通常把请求输入参数与策略数据中的值做比较。同名规则可以定义多条Agent 查询时引擎会尝试找到至少一条“给定 API 输入参数下返回true”的同名规则。下面是针对CopyFile与ExecProcess请求的规则示例其中print输出会随请求日志一起记录并在被拒时出现在错误信息中import future.keywords.in import input CopyFileRequest { print(CopyFileRequest: input.path , input.path) some regex1 in policy_data.request_defaults.CopyFileRequest regex2 : replace(regex1, $(cpath), policy_data.common.cpath) regex.match(regex2, input.path) print(CopyFileRequest: true) } ExecProcessRequest { print(ExecProcessRequest 1: input , input) i_command concat( , input.process.Args) print(ExecProcessRequest 1: i_command , i_command) some p_command in policy_data.request_defaults.ExecProcessRequest.commands p_command i_command print(ExecProcessRequest 1: true) } ExecProcessRequest { print(ExecProcessRequest 2: input , input) i_command concat( , input.process.Args) print(ExecProcessRequest 2: i_command , i_command) some p_regex in policy_data.request_defaults.ExecProcessRequest.regex print(ExecProcessRequest 2: p_regex , p_regex) regex.match(p_regex, i_command) print(ExecProcessRequest 2: true) }这些规则中的input数据由 Kata Agent 以 JSON 形式提供给策略引擎即 API 请求参数的 JSON 表示。更多规则示例可以参考 genpolicy 使用的 rules.rego。8. 调试建议与延伸阅读观察拒绝原因策略规则中的print语句输出会被收集请求被拒时以{ep} is blocked by policy: ...形式随错误返回在调试日志级别下请求输入还会以 JSON Lines 追加到 Guest 内的/tmp/policy.jsonl见 policy.rs 中log_eval_input的说明StatsContainerRequest、ReadStreamRequest、SetPolicyRequest因高频或体积原因被排除。日志脱敏从 src/agent/src/rpc.rs 的结构看当策略不允许读取日志时Agent 会对日志消息做脱敏处理避免策略把日志通道当作旁路信息泄漏面。策略规模上限Agent 对策略长度设有保护性上限单行 64 KiB、单文件 16 MiB、20 万行policy.rs足以容纳 genpolicy 生成的现实规模策略同时拒绝病态输入。相关文档genpolicy 工具文档、Agent ttRPC 协议定义、guest-pull 限制说明。赞分享云原生容器运行时【免费下载链接】kata-containersKata Containers is an open source project and community working to build a standard implementation of lightweight Virtual Machines (VMs) that feel and perform like containers, but provide the workload isolation and security advantages of VMs. https://katacontainers.io/项目地址https://gitcode.com/gh_mirrors/ka/kata-containers点击查看免费下载相关推荐OpenCloud Policies 服务实战指南用 OPA rego 策略实现细粒度访问控制OpenCloud Policies 服务实战指南用 OPA rego 策略实现细粒度访问控制 OpenCloud 的 policies 服务是一个基于 Op后端微服务存储认证鉴权Traefik 中的 OPAOpen Policy Agent中间件用 Rego 策略控制访问与注入请求头Traefik 中的 OPAOpen Policy Agent中间件用 Rego 策略控制访问与注入请求头 OPAOpen Policy Agent中后端API网关负载均衡微服务网络云原生Google Developer Knowledge MCP 集成实战三个检索工具、资源名规范与 REST 回退方案Google Developer Knowledge MCP 集成实战三个检索工具、资源名规范与 REST 回退方案 本文基于仓库中 retrieving d后端认证鉴权云原生上一篇从理论到实践使用Visualizer分析Vision Transformer注意力模式下一篇DIY智能打印机完整制作指南三步快速组装与零基础配置技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考