编写和验证 MXC 策略

MXC 策略描述工作负荷可以访问的内容。 从默认拒绝权限开始,仅添加特定任务所需的资源,并在应用支持的每个平台上使用具有代表性的输入来验证结果。 每个后端还提供启动工作负荷所需的操作系统资源;默认拒绝策略并不意味着进程在没有系统环境的情况下运行。

将策略决策保留在受信任的应用代码中。 工具、插件、脚本或 AI 生成的命令可以报告其需求,但不应选择自身的包含模型或扩展自身的访问权限。

了解策略和配置

MXC 将资源权限与运行命令的设置分开:

  • 策略 设置描述跨平台意图,例如可读路径、可写路径、网络目标、UI 访问和超时。
  • 执行设置可添加命令、工作目录、环境和包含选择。

在 V1 SDK 中,ContainerRequest 同时携带两者。 在 .NET 中,通过命令创建 ContainerRequest,设置其策略和执行属性,并调用 MxcContainer.RunAsync 或生成 API。 在 TypeScript 中,将 ContainerRequest 对象传递给 run 或 spawn 函数。 在 Rust 中,生成一个 ContainerRequest 结构并将其传递给 v1::run 或生成函数。 首选抽象 Process 包含意图,除非工作负荷需要使用特定的后端。

以下非特定语言的策略设置描述了存储库范围内的任务。 它们使用 TypeScript ContainerRequest 属性名称;.NET使用与 PascalCase 名称ReadonlyPaths相同的结构,Rust 使用snake_case名称,例如readonly_paths。 它们不是完整的请求:它们不包含命令或选择后端。 创建目录并替换路径,然后再进行调整。

{
  "filesystem": {
    "readonlyPaths": ["C:\\src\\my-app"],
    "readwritePaths": ["C:\\src\\mxc-output"],
    "deniedPaths": ["C:\\src\\my-app\\.env"]
  },
  "network": {
    "egress": { "default": "deny" },
    "ingress": { "default": "deny", "hostLoopback": "deny" }
  },
  "ui": {
    "disable": true,
    "clipboard": "none",
    "allowInputInjection": false
  },
  "timeoutMs": 30000
}

使用 SDK 类型,而不是将请求属性复制到原始执行配置中。 形状不同:例如,请求的 timeoutMs 映射到配置的 process.timeout,ui.allowInputInjection 映射到 ui.injection,而 network.runtimeConfig 映射到顶层 runtimeConfig 部分。 有关完整的 C#、TypeScript 和 Rust 示例,请参阅 SDK 快速入门 。

选择兼容的架构

将这三个问题分开:

兼容性轴 需要检查的事项
SDK 和产品发布 该包提供哪些 API 和运行时组件
策略架构 该版本接受的确切配置协定
主机功能 所选环境可以在运行时强制实施哪些限制

MXC 1.0 V1 SDK 在内部使用稳定的 1.0.0 架构,因此无需在 ContainerRequest 中指定架构版本。 仅当您编写原始 JSON 执行配置(例如用于 wxc-exec 命令行工具的文件)时,模式版本才适用。

原始配置必须声明一个确切的已注册 version。 MXC 1.0 接受 1.0.0 这个当前稳定的架构,以及 0.9.0-alpha 这个支持的最低版本架构。 MXC 拒绝缺失版本号的情况、早于 0.9.0-alpha 的已弃用版本(例如 0.8.0-alpha)以及未注册的拼写,例如 1.0 或 1.0.1。 1.1.0-alpha 开发协定在发布前可能会更改,因此不要将其用于生产配置。 选择它不会授权实验后端。

将 SDK 和本机运行时组件保持为同一版本。 有关已注册契约,请参阅MXC 架构版本控制。

限定文件访问范围

按工作负荷使用方式对每个路径进行分类:

Access 将其用于
只读 工作负荷必须检查但不能更改的源、工具、库和配置
读/写 特定于任务的输出、缓存或临时目录
已拒绝 凭据、不相关的存储库、敏感配置以及更广泛授权范围内的更窄路径

尽可能授予最窄的可行路径。 例如,当命令仅写入测试输出时,授予测试结果目录而不是存储库根目录。 将从环境变量、包管理器或工具搜索中发现的路径视为候选项进行评审,而不是自动批准。

包括工作负荷实际需要的工具二进制文件、库、配置和临时路径。 SDK 提供文件系统发现帮助程序,但其结果并不是经批准的策略。 在添加候选路径之前,请查看每个候选路径。

设置工作目录不会授予对该目录的访问权限。 将其显式添加到相应的文件系统列表。

除非已使用所选后端对其进行测试,否则请避免依赖重叠的路径规则。 后端使用不同的文件访问机制,有些则不能表示映射或装载的目录中的拒绝规则。

控制网络访问

除非任务需要网络访问,否则保持网络访问被拒绝。 选择所选后端可以强制实施的网络模型:

Model 将其用于
无法从外部访问 仅需要已获授权的本地资源的分析或转换
使用 IP/CIDR、协议和端口规则进行直接访问 需要特定直接连接的任务,例如 TCP 到已知服务终结点
HTTP(S)通过应用提供的代理 其目标或应用程序级权限由您的代理控制的请求

方向性网络策略区分为以下几类:

  • 从工作负荷到网络目标的流出量。
  • 从专用网络或本地网络到工作负荷中侦听器的流入量。
  • 工作负荷与主机上的服务之间的双向主机环回。

IP/CIDR 和端口规则不会标识应用程序协议或主机名。 允许 TCP 端口 443 并不能说明该连接使用 HTTPS,或只会访问某个特定的已命名服务。 当工作负荷直接解析目标时,DNS 请求也可能需要访问权限。

受支持的架构会拒绝已停用的网络字段,例如 defaultPolicy、allowedHosts、blockedHosts 和 network.proxy。 请改用 egress 和 ingress 方向字段。 请参阅 网络策略示例。

使用自定义网络代理

主机应用在启动工作负荷之前提供并启动代理。 MXC 不提供或管理生产代理。 代理决定允许哪些请求和目标;MXC 将支持的客户端配置为使用它,并应用后端的网络限制。

定向请求使用网络节的 runtimeConfig.networkProxy 设置来标识具有显式端口的 HTTP(S) 环回终结点。 在原始执行配置中,此设置是最顶层的 runtimeConfig.networkProxy。 此终结点是运行时配置,而不是应用程序层允许列表。 代理模式需要默认拒绝出口,不能与直接出口允许或拒绝规则结合使用。

客户端路由和强制执行有所不同。 代理环境变量或平台设置会告知兼容的 HTTP 客户端将请求发送到何处。 仅通过代理实施强制控制的路径还必须阻止直接 Internet 连接;仅协同代理配置并不能确立这种限制。

MXC 不会以透明方式通过 HTTP(S) 代理重定向 SSH、任意 TCP/UDP 或其他非 HTTP 协议。 主机环回和专用网络行为也因后端而异。 查看 自定义代理配置示例 及其先决条件,而不是假设同一片段可在任何地方工作。

限制 UI 访问

默认情况下,不允许后台工作负荷创建窗口、读取或写入剪贴板,或注入键盘和指针输入。 仅当它是工作负荷预期用户体验的一部分时,才添加 UI 访问权限。

输入注入是指合成键盘或指针输入,而不是任意代码注入到另一个进程中。

UI 控件取决于主机和后端。 使用运行时支持信息来验证安全设计所需的每个限制。

绑定执行

为应在已知时间段内完成的每个代理操作、工具调用或脚本设置超时。 仅提供进程所需的环境变量,并且不要将机密放在进程环境和可读文件路径中。 不要假设省略环境设置会创建一个空环境:后端默认值和 SDK 继承选项有所不同。

选择与任务匹配的生命周期。 对于独立命令,优先使用一次性执行。 仅当命令必须共享已安装的工具、标识、文件或操作系统状态时,才使用状态感知沙盒。

验证生效的策略

在交付策略之前:

  1. 使用 SDK 的 运行时发现 并检查所选后端的先决条件。
  2. 创建配置并处理策略验证或后端不可用错误,而不会削弱策略。
  3. 采用工作负荷应使用的资源运行具有代表性的成功用例。
  4. 运行尝试读取机密、在输出目录外写入、使用未经批准的网络路径或访问不允许的 UI 的负面情况。
  5. 使用 学习模式 调查缺少的访问权限,并在更改策略之前查看每个结果。
  6. 删除所有学习或审核设置,并运行一个最终强制测试。

当主机无法强制实施所需控制措施时失败。 不要以无提示方式选择具有更广泛访问权限的后端,也不要删除策略字段以运行工作负荷。 成功的解析或启动并不是所有预期限制都成立的证据。