DataScience-EngineeringExperts/mcp-warden

GitHub: DataScience-EngineeringExperts/mcp-warden

MCP 服务器接口锁定与 CI 漂移检测工具,通过签名 lockfile 固定声明接口并在发生未授权变更时阻断构建。

Stars: 2 | Forks: 0

# mcp-warden [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/DataScience-EngineeringExperts/mcp-warden/actions/workflows/integrity-gate.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-blue.svg)](https://www.python.org/downloads/) [![GitHub Action](https://img.shields.io/badge/GitHub%20Action-mcp--warden-2088FF?logo=githubactions&logoColor=white)](https://github.com/DataScience-EngineeringExperts/mcp-warden/blob/main/action.yml) [![Latest release](https://img.shields.io/github/v/release/DataScience-EngineeringExperts/mcp-warden?display_name=tag&sort=semver)](https://github.com/DataScience-EngineeringExperts/mcp-warden/releases) **mcp-warden 是 MCP 服务器的 lockfile 和 CI gate:它将服务器声明的 tool/resource/prompt 接口固定在已签名的 `warden.lock` 中,当该接口 发生漂移时导致 CI 失败。** `pin` 和 `check` 支持 stdio 和 Streamable HTTP;`guard` 仅支持 stdio。 如果你已经遵循了已发布的指南 —— *锁定版本、对 tool 定义进行哈希处理、对漂移发出警报* —— 那么 mcp-warden 就是实现此目标的确定性工具。 **心智模型(类比阶梯):** - **`package-lock.json` / `Cargo.lock`** —— 一个已提交、可重现的关于你所依赖内容的锁定。`warden.lock` 之于 MCP 服务器的*声明接口*,就是如此。 - **CI 中的 `gitleaks`** —— 一个集成到 pipeline 中的确定性、exit-non-zero gate。`mcp-warden check` 之于 MCP 接口漂移就是如此(并且提供了同样的 SARIF → code-scanning 集成)。 - **`Dependabot` / 锁定后审查** —— 在上游变更落地之前,由人工进行审批。`pin --approve` + 漂移 gate 强制要求在出现任何 MCP rug-pull 时必须有人的参与。 ## 60 秒快速入门 复制粘贴即可针对本仓库中提供的 fixtures 运行。需要 Python ≥ 3.11。 ``` # 1. 安装(从此 repo 的 clone 中) uv venv .venv uv pip install --python .venv/bin/python -e ".[dev]" # 2. 固定 server 声明的 surface 并批准它(TOFU 基线) -> 写入 lock .venv/bin/mcp-warden pin python tests/fixtures/clean_server.py \ --approve --approver you@example.com \ --lock warden.lock # 3. 根据 lock 检查相同的 surface -> 退出 0(无漂移) .venv/bin/mcp-warden check python tests/fixtures/clean_server.py --lock warden.lock # 4. 证明 gate 触发:一个遭遇 rug-pull 的 server 发生漂移 -> 检测到漂移,退出 1 .venv/bin/mcp-warden check python tests/fixtures/mutated_server.py --lock warden.lock ``` 对于已经在运行的 Streamable HTTP 服务器,请使用 `--url` 而不是服务器命令: ``` .venv/bin/mcp-warden pin --url https://example.com/mcp --approve --approver you@example.com --lock warden.lock .venv/bin/mcp-warden check --url https://example.com/mcp --lock warden.lock ``` 然后使用官方 GitHub Action 将其集成到 CI 中(将 `server-cmd` 指向*你的*服务器的启动 argv,并提交 `warden.lock`): ``` # .github/workflows/mcp-integrity.yml permissions: contents: read security-events: write # only needed when upload-sarif: true (the default) jobs: mcp-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: DataScience-EngineeringExperts/mcp-warden@v0 with: server-cmd: "node ./build/index.js" lock: "warden.lock" ``` 该 Action 会运行 `check`,在任何漂移时导致构建失败,并且(默认情况下)将 SARIF 报告上传到 GitHub code scanning。完整的输入表请参见下方的 [GitHub Action](#github-action-one-step-drop-in)。 ## mcp-warden 的适用场景 —— 是补充,而非替代 MCP 安全性分为三个在不同时间运行的不同工作。它们是 **互补的层**;将 mcp-warden *与* scanner 和/或 gateway *一起* 运行可以弥补它们各自无法覆盖的盲区。 | 类别 | 示例 | 运行时机 | 锁定内容 | 适用场景… | |----------|---------|--------------|--------------------|--------------| | **静态 tool-poisoning scanner** | [mcp-scan](https://github.com/invariantlabs-ai/mcp-scan) | pin-time / pre-flight | tool 定义中的可疑*内容*(注入式描述、已知的恶意模式) | 你希望在第一次看到恶意定义时就将其捕获 | | **运行时 gateway / proxy** | ContextForge, Lunar MCPX, TrueFoundry, Docker MCP Gateway | 每个实时请求 | 运行时调解 —— 针对进行中调用的 auth、速率限制、请求/响应策略 | 你需要调解或监管 agent 与服务器之间的实时流量 | | **Lockfile + CI gate** | **mcp-warden** | CI / pre-commit | *漂移* —— 在人工批准后声明的接口发生了变化(rug-pull / 静默重定义) | 你想要一个可重现的、经人工批准的 baseline,以便在接口发生变化时导致构建失败 | mcp-warden 并不替代 scanner 或 gateway —— 它增加了缺失的 **drift gate**:一个已签名的 baseline 加上确定性的 CI 检查,确保你批准的接口仍然是你正在运行的接口。有关这些层如何相互补充以及何时使用哪一层的完整的、有据可查的详细分析,请参阅文档站点上的 [**对比页面**](https://datascience-engineeringexperts.github.io/mcp-warden/comparison/) 。 ## 适用人群 它的普及会像 `package-lock.json` 那样产生复合效应 —— 作者采用,消费者自动 受益 —— 因此用例按杠杆作用排序: - **MCP 服务器作者(旗舰)。** 固定你*自己*服务器的接口,提交 `warden.lock`, 使任何未经重新批准就改变它的 PR 失败,并将已签名的 lock 与 版本一起作为**信任徽章**发布 —— 你拥有服务器 + CI,因此没有 auth/可用性方面的阻力。 - **服务器消费者 / 应用团队。** 固定你依赖的第三方服务器;当上游 静默重定义其接口时,CI(或 pre-commit hook)将失败 —— 这是核心的 rug-pull 防御。 - **安全 / 平台工程师。** 在整个集群中运行 [Action](#github-action-one-step-drop-in) ;SARIF → code scanning;已签名的 lock = 可审计的 human-approval 证据。 - **事件响应者 / 审计员。** `inspect` 离线 trace 并针对已知良好的 baseline 对可疑的 lock 进行 `warden diff` —— 无需实时服务器。 - **Agent-framework 集成商** *(发布后)*。强制要求只有 warden-locked 服务器才能注册到 LangGraph 风格的 orchestrator 中 —— 一次集成即可锁定整个下游生态。 ## 它的功能 mcp-warden 完全基于**定义**运行 —— 即由 `tools/list`、`resources/list` 和 `prompts/list` 返回的 `(name, description, inputSchema)` metadata —— 绝不涉及运行时 tool 的行为或结果。 | 威胁类别 | 控制 | |--------------|---------| | **定义漂移 / rug-pull** (`MCP-DRIFT`) | `check` 重新捕获并将接口与 `warden.lock` 进行 diff;tool `inputSchema` 的更改会被**结构性分类**(必填项被移除、enum 扩大/移除、类型扩大、约束放宽、`additionalProperties` 开启 → `WRD-DRIFT-SCHEMA-*`),而不是被标记为一个不透明的更改;任何漂移都会导致 CI 失败 | | **危险的能力接口** (`MCP-CAPSURF`) | 确定性的 `WRD-CAP-*` 静态检查 (shell/exec, fs-write, fs-read, http, sql) | | **定义中的敏感信息泄露** (`MCP-SECRET`) | `WRD-SEC-*` regex + 熵检查;代码片段会被始终打码 | | **未锁定的供应链引用** (`MCP-SUPPLY`) | `WRD-SUP-*` 标记未锁定的 `npx`/`uvx`/`pip`、`latest` 以及 `curl|sh` 启动 | | **恶意的 tool 结果** (`T-RESULT`, v0.2/v0.3) | `guard`/`inspect` 对 tool 结果运行 `WRD-RES-*` 目录:ANSI/control 转义、回显的 secret、exfil domain(确定性 BLOCK —— **在 v0.3 中默认开启**)、精选的注入短语(模糊 MONITOR,opt-in) | 可重现性是其核心保证:规范化采用 **RFC 8785 (JCS)** + **SHA-256** (`sha256:`),因此 `pin` 和 `check` 在字节级别上保持一致。v0.2 结果检查目录只定义一次,并由 `guard`(实时)和 `inspect`(离线)以相同方式运行。 ## 安装 需要 Python ≥ 3.11。 ``` # 从 PyPI 安装(分发包名 `mcp-warden-cli`): pip install mcp-warden-cli # 随后可通过以下命令使用 CLI: mcp-warden --help ``` ``` # 或者从此 repo 的 clone 中安装(用于开发): uv venv .venv uv pip install --python .venv/bin/python -e ".[dev]" .venv/bin/mcp-warden --help ``` 运行时依赖:`mcp` (官方 MCP Python SDK)、`rfc8785`、`pydantic`、 `typer`、`rich`、`pyyaml`、`anyio`。 ## pin / check CI 演示 mcp-warden 在 `tests/fixtures/` 下提供了两个 fixture MCP 服务器:一个 **clean** 服务器和一个 **mutated**(被 rug-pulled)服务器。端到端流程: ``` # 1. 固定干净 server 的 surface(TOFU 基线) -> 写入 warden.lock .venv/bin/mcp-warden pin python tests/fixtures/clean_server.py \ --approve --approver ci-bot@example.invalid \ --sarif pin.sarif # 2. 随后,上游 server 遭遇 rug-pull。对其重新运行 check。 # (在实际的 CI 中将使用相同的启动 argv;这里我们指向被修改的 fixture。) .venv/bin/mcp-warden check python tests/fixtures/mutated_server.py \ --sarif check.sarif # -> 打印检测到漂移,写入 SARIF,以非零状态退出(导致构建失败) ``` `check` **在任何漂移时退出 non-zero**(tool 被添加/移除/修改、capability 更改、服务器身份更改)。Tool `inputSchema` 的更改会被**结构性 diff**:每个与安全相关的突变都会按事实报告,并根据严重程度 (`docs/WARDEN_LOCK_SCHEMA.md` §6.2)进行确定性分类。规范化的 schema 骨架存储在 lock 中(`schema_version` 3);pre-skeleton (v1) 的 lock 会 回退到单一的 high-severity `schema-modified`,直到重新 pin。SARIF 报告 (`ruleId` == `WRD-*` / `WRD-DRIFT-*` 检查 ID)可直接上传到 GitHub code scanning。 ### GitHub Action (一步式 drop-in) 添加 integrity gate 最快的方法是使用官方可重用 action: ``` # .github/workflows/mcp-integrity.yml permissions: contents: read security-events: write # only needed when upload-sarif: true (the default) jobs: mcp-check: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: DataScience-EngineeringExperts/mcp-warden@v0 with: server-cmd: "node ./build/index.js" lock: "warden.lock" # upload-sarif: "false" # uncomment for private repos without GHAS ``` 该 action 会从你锁定的确切 `@ref` 安装 mcp-warden,运行 `check`, 将 SARIF 报告上传到 GitHub code scanning(可选),并将 原始 exit code(0 = clean / 1 = drift / 2 = error)作为输出提供给后续步骤提供。所有运行时依赖项都在 `action/requirements.lock` 中进行了哈希锁定, 因此不会在未锁定的情况下获取任何传递性包。 | 输入 | 默认值 | 备注 | |-------|---------|-------| | `server-cmd` | *(必填)* | 以空格分隔的 argv 字符串(例如 `node ./build/index.js`)。不支持带引号的参数,也不支持 shell 元字符(`;`, `\|`, `&`, `$`, `` ` ``, `\`, `<`, `>`, `(`, `)`, `{`, `}`, `'`, `"`)。guard 步骤会在展开前拒绝包含上述任何字符的输入。 | | `lock` | `warden.lock` | Baseline lock 路径(相对于 `working-directory`) | | `sarif` | `mcp-warden.sarif` | SARIF 输出路径 | | `upload-sarif` | `true` | 对于没有 GitHub Advanced Security 的 repo,请设置为 `false` | | `category` | `mcp-warden` | Code-scanning 类别;对每个服务器使用不同的值 | | `python-version` | `3.11` | 要使用的 Python 版本(要求 >= 3.11) | | `timeout` | `30` | 捕获超时时间(秒) | | `working-directory` | `.` | 运行检查的工作目录 | **输出:** `exit-code` (0/1/2)、`sarif`(解析出的绝对路径)。 ### 典型的多步模式(手动安装) ``` - name: MCP integrity gate run: | .venv/bin/mcp-warden check node ./build/index.js --sarif warden.sarif - name: Upload SARIF if: always() uses: github/codeql-action/upload-sarif@v3 with: sarif_file: warden.sarif ``` ## CI 用法 —— 你自己 repo 的 drop-in gate 只需三个步骤即可将 mcp-warden 添加为 CI integrity gate: **1. Pin 一次**(在本地运行,提交结果): ``` pip install mcp-warden-cli # PyPI dist name is `mcp-warden-cli`; the command is `mcp-warden` # 固定你的 server 并记录批准 mcp-warden pin node ./build/index.js \ --approve --approver you@example.com \ --lock warden.lock git add warden.lock && git commit -m "chore: pin MCP surface baseline" ``` **2. 将 check 步骤添加到你的工作流中**(`.github/workflows/integrity-gate.yml`): ``` - name: Install mcp-warden run: pip install mcp-warden-cli # PyPI dist `mcp-warden-cli`; CLI command `mcp-warden` - name: MCP integrity gate (pass path — exits 0 when surface matches lock) run: | mcp-warden check node ./build/index.js \ --lock warden.lock \ --sarif warden.sarif - name: Upload SARIF if: always() uses: actions/upload-artifact@v6 with: name: mcp-warden-sarif path: warden.sarif ``` **3. 在发生任何上游 rug-pull 时**,`mcp-warden check` 将退出 non-zero,并且 在发生漂移的服务器到达你的 agent 之前导致构建失败。只有在人工 审查并批准新接口后才重新 pin。 ## pre-commit hook —— CI 前的本地 gate mcp-warden 提供了一个 [pre-commit](https://pre-commit.com) hook,因此*相同*的漂移 判定会在每次提交时于本地运行,在 rug-pulled MCP 接口进入 CI 之前将其捕获。该 hook 重用与 `mcp-warden check` 相同的 capture → checks → drift 路径,因此本地 pass/fail 的结果永远不会与 CI 发生冲突。 将以下内容添加到你的 `.pre-commit-config.yaml` 中(一个完整的、可复制粘贴的示例): ``` repos: - repo: https://github.com/DataScience-EngineeringExperts/mcp-warden rev: v1.0.1 # pin to a release tag (supply-chain hygiene) hooks: - id: mcp-warden-check # Everything after `--` is your MCP server launch argv. # The `--lock` path is resolved relative to your git repo root. args: [--lock, warden.lock, --, node, ./build/index.js] ``` 然后运行一次 `pre-commit install`。该 hook 会在 每次提交时重新捕获你服务器的接口,并**在发生漂移时阻止提交** (exit 1),直到你审查并重新 pin。 ### `--` 分隔符(必填) pre-commit 是由文件触发的,但 `mcp-warden check` 接收的是一个 **MCP 服务器启动 argv**,而不是暂存的文件(该 hook 设置为 `pass_filenames: false`)。你使用 `--` 分隔符告诉 hook 你的服务器命令从哪里开始:`--` 之后的任何内容都将作为服务器启动。如果没有它,hook 将输出 exit 2 并给出指导。 行为(clean / drift / server-unavailable) | 情况 | 默认(非 strict) | `--strict` | |-----------|----------------------|------------| | 接口与 `warden.lock` 匹配 | exit 0(继续提交) | exit 0 | | 相对于 `warden.lock` 的**漂移** | **exit 1(阻止提交)** | **exit 1(阻止提交)** | | `warden.lock` 缺失 / 无效 | exit 2(阻止提交) | exit 2 | | 服务器无法 spawn / 超时 | **exit 0 + stderr 警告(继续提交)** | exit 2(阻止提交) | 默认设置容忍*在本地*无法 spawn 的服务器(没有安装正确 runtime 的团队成员不应该被阻止提交)—— **在两种模式下漂移总是被阻止**,只是对 infra-failure 的处理不同。CI 保持严格(它总是可以 spawn 服务器),因此漂移判定在任何地方都是一致的。在 `args:` 中添加 `--strict` 也可以在本地实现 fail closed。 ### 针对慢速服务器的 Opt-outs 在每次提交时 spawn 服务器会增加延迟。觉得这太慢的团队可以 仅在 push 时运行 gate: ``` - id: mcp-warden-check stages: [pre-push] # run on `git push`, not every commit args: [--lock, warden.lock, --, node, ./build/index.js] ``` …或者使用 `SKIP=mcp-warden-check git commit ...` 为单次提交临时跳过它。 ## CLI 参考 | 命令 | 用途 | Exit code | |---------|---------|-----------| | `mcp-warden pin \| --url URL [--approve --approver ] [--sign [--identity-token T]] [--sarif F] [--json]` | 通过 stdio 或 Streamable HTTP 进行捕获 + 写入 `warden.lock`(TOFU baseline)。**(#16)** `--sign` 使用 Sigstore 对 `overall_digest` 进行签名(out-of-digest;需要 `mcp-warden[sigstore]`) | 成功为 0,capture/IO 错误为 2,**签名失败为 1(fail closed,无部分 sidecar)** | | `mcp-warden check \| --url URL [--lock F] [--sarif F] [--json]` | 通过 stdio 或 Streamable HTTP 重新捕获 + 与 lock 进行 diff | **发生漂移时 non-zero**,错误时为 2 | | `mcp-warden check --verify --certificate-identity ID --certificate-oidc-issuer ISS [--lock F] [--offline-bundle P]` | **(#16)** 根据固定的 sidecar(lock 旁边的 `.sigstore`)验证 lock 的 Sigstore 签名;不 spawn 服务器。参见 [`docs/SIGNING.md`](docs/SIGNING.md) | **仅在验证 clean 时为 0**;发生任何失败时为 non-zero(fail closed) | | `mcp-warden policy lint [--lock F]` | Lint 策略文件(fail closed) | lint 错误时为 non-zero | | `mcp-warden policy eval [--lock F]` | 评估单个示例调用 | **deny 判定时为 non-zero**(CI 断言) | | `mcp-warden guard [--lock F] [--policy F] [--no-block-* / --allow-exfil-domain] [--block-inject-phrase] [--audit-only] [--strict] [--sarif F] [--record T]` | **(v0.3)** 透明 stdio proxy:在运行时检查 `tools/call` 的结果和参数。**确定性层默认阻止 (blocks)**;使用 `--no-block-` 按类别退出,或使用 `--audit-only` 完全退出。`--strict` 在内部检查错误时 fail CLOSED(exit `3`) | 子进程的 exit code;因 `--strict` 中止时为 `3`;否则永远不会中断 session | | `mcp-warden inspect [--lock F] [--sarif F]` | **(v0.2)** 针对已记录的 JSON-RPC session 的离线分析器 —— 与 `guard` 使用相同的 `WRD-RES-*` 目录(始终仅报告) | 任何 BLOCK 级别发现时为 non-zero;读取错误时为 2 | | `mcp-warden lock rotate [--approver ID] [--actor ID] [--note T] [--json]` | **(v0.3)** 在现有 baseline 上重新认证 provenance,而不重新捕获接口;`overall_digest` 保持**字节完全一致** (WARDEN_LOCK_SCHEMA §8.2)。如果 lock 被篡改/不一致,则 fail closed | 成功为 0,lock 缺失/无效/被篡改时为 2 | | `mcp-warden diff [--json] [--sarif F] [--no-provenance] [--exit-code]` | **(v0.3)** 基于漂移引擎的离线、**已打码**查看器:渲染两个现有 lock 之间的完整性漂移(A=baseline,B=current)+ 独立的信息性 provenance 部分。从不重新捕获,且从不打印原始的 `server.command`/`args`(secret-safe) | 0(查看器);使用 `--exit-code` 时,仅在发生**完整性**漂移时为 1;lock 缺失/无效时为 2 | | `mcp-warden-precommit [--lock F] [--timeout N] [--strict] -- ` | **(v0.3)** pre-commit hook 入口点(参见 [pre-commit hook](#pre-commit-hook--the-local-pre-ci-gate))。运行相同的 check 判定路径;仅执行检查(从不 pin,从不写入 lock) | 0 clean / **1 drift** / 2 配置错误;服务器不可用 → 0+警告(非 strict)或 2(`--strict`) | 对于 stdio,`` 作为 **argv array 传递给 OS,从不通过 shell。** `--url` 则连接到已经运行的 Streamable HTTP endpoint,并且 与服务器命令互斥。设置 `WARDEN_LOG_LEVEL=INFO` 以进行诊断。 ### 运行时结果检查(v0.3 —— 默认阻止) `guard` 透明地位于 MCP 客户端和服务器之间,并检查 tool *结果*。 **从 v0.3 开始,确定性层默认阻止**(委员会确定的字段 误报率约为 0): ``` # 默认值:ANSI 会被就地剥离;回显的机密信息 + exfil 域名会被错误替换; # 会话中途偏离 warden.lock 的 tools/list 替换将被阻止(需要 --lock); # argument-policy 拒绝将被阻止(需要 --policy)。fuzzy injection 层级保持仅记录日志。 mcp-warden guard node ./build/index.js --lock warden.lock --policy policy.yaml --sarif guard.sarif # 观察优先的发布:--audit-only 仅用一个标志即可恢复完整的 v0.2 shadow 模式(仅检测和记录日志)。 mcp-warden guard node ./build/index.js --lock warden.lock --audit-only # 将单个类别重新切回 shadow 模式(仍然会被检测/记录/SARIF,并转发 frame): mcp-warden guard node ./build/index.js --no-block-ansi --allow-exfil-domain # 或者将整个确定性层级 + 两个 gate 置于 shadow 模式: mcp-warden guard node ./build/index.js --no-block-deterministic # 选择加入 fuzzy injection 层级(绝非默认): mcp-warden guard node ./build/index.js --block-inject-phrase # Fail-CLOSED(高安全性):如果 # 内部检查(result / argument-policy / tools-list)无法完成,则 TERMINATE 会话(退出 3,向客户端返回 -32003),而不是 # 默认的 fail-open pass-through。需选择加入;完整性高于可用性。 mcp-warden guard node ./build/index.js --lock warden.lock --policy policy.yaml --strict # 使用相同的规则目录离线重新分析已记录的会话(始终为仅报告模式): mcp-warden inspect session.trace.jsonl --lock warden.lock --sarif inspect.sarif ``` **标记方案:** opt-out 是规范的 `--no-block-` (`ansi|secret-echo|exfil-domain|list-changed|policy`,加上针对整个层的 `--no-block-deterministic`);`--allow-exfil-domain` 是唯一的肯定别名。优先级: `--audit-only` > `--no-block-*` > default-block / `--block-inject-phrase`。v0.2 `--block-*` 启用标志被接受但**属于无效空操作**(一行 stderr 弃用提示), 因此旧脚本可以继续工作。**`--strict`**(opt-in,默认关闭)以牺牲可用性换取 完整性:在 result / argument-policy / tools-list 层出现内部检查错误时,会 **终止 session**(向客户端发送 exit `3`、`-32003` 不可重试错误),而不是 fail open —— framing/EOF/over-cap 在所有模式下保持 fail open(已知限制)。保留的 错误代码:**`-32001`**(policy/result 阻止),**`-32002`**(transport/lifecycle),**`-32003`** (`--strict` 中止,不可重试)。参见 [`docs/RESULT_INSPECTION.md`](docs/RESULT_INSPECTION.md)、 [`docs/GUARD_PROXY.md`](docs/GUARD_PROXY.md) 和 [`docs/GUARD_PROXY_V3.md`](docs/GUARD_PROXY_V3.md)。 ## 策略(仅限设计阶段) `policy` **lint** YAML 策略并**评估单个提供的示例调用**。 它**不会**拦截实时调用 —— 在 v0.1 中没有运行时强制执行 (推迟到 v0.2)。Fail-closed 默认设置:`shell_exec.allow=false`、 `http_request.deny_private=true`(SSRF 范围)、`sql_query.allow_readonly_only=true`、 空的 `allow_paths` = deny-all。参见 [`docs/POLICY_MODEL.md`](docs/POLICY_MODEL.md)。 ``` .venv/bin/mcp-warden policy eval policy.yaml ssrf_sample.json # -> 拒绝:主机 169.254.169.254 在 deny_private 范围 169.254.0.0/16 内 (退出 1) ``` ## 文档 请参阅 [`DOCUMENTATION_INDEX.md`](DOCUMENTATION_INDEX.md)。 `docs/` 下的 security-contract 规范 (包括关于 v0.3 default-block + lifecycle 合约的 [`GUARD_PROXY_V3.md`](docs/GUARD_PROXY_V3.md))是每种算法的真理来源; `warden.lock` 中的 schema 和 SARIF 输出与它们在字节上完全一致。 ## 测试 ``` .venv/bin/python -m pytest -q ``` 标题测试是一个真实的 stdio 往返:spawn clean fixture → `pin` → 针对 mutated fixture 重新运行 `check` → 断言 non-zero exit + 预期的 漂移 + SARIF 发现。 实时运行时攻击面 —— stdio JSON-RPC **framer**、ANSI/control **stripper**、exfil-**domain** 匹配器和 secret **redactor** —— 额外使用 [`hypothesis`](https://hypothesis.works/) 进行了 **property-fuzzed** ,位于 `tests/fuzz/` 下(基于构造的活性和健全性属性:已知恶意输入会被检测到,并且 解析器永远不会凭空发明、泄露或错误分类)。深度 soak 通过 `make fuzz` 运行;参见 [`CONTRIBUTING.md`](CONTRIBUTING.md#fuzzing)。 ## 贡献与安全 欢迎贡献 —— 有关开发 设置、确定性合约以及如何提出新检查,请参见 [`CONTRIBUTING.md`](CONTRIBUTING.md)。参与即表示 你同意遵守[行为准则](CODE_OF_CONDUCT.md)。 这是一个安全工具:**不要在公开 issues 中报告漏洞。** 请遵循 [`SECURITY.md`](SECURITY.md) 中的负责任披露流程。 ## 许可证 MIT —— 请参阅 [`LICENSE`](LICENSE)。版权所有 (c) 2026 Ernest Provo。
标签:DNS 反向解析, MCP, StruQ, 图数据库, 大模型安全, 运行时防护, 逆向工具