Properti-X/canary-truth-layer

GitHub: Properti-X/canary-truth-layer

一个公开的、Ed25519 签名的机器可读注册表,记录 MCP / AI Agent 工具的网络数据流向及文档披露情况,供开发者与 AI 在评估工具时查询和验证。

Stars: 0 | Forks: 0

# Canary Truth Layer **一个公开的、机器可读的注册表,记录 MCP / AI agent 工具如何处理数据 —— 通过网络发送到了哪里、发给了哪些主机和国家/地区,以及该工具自身的文档是否对此进行了说明。** 每个条目(即“判定”)都是一个已签名的 JSON 记录。它说明了观察到工具发送了什么内容、数据的去向、目的地的司法管辖区,以及该数据流是否在工具自身的界面中进行了披露 —— 每个声明都通过其确立方式(observed / documented / inferred / classified)进行标记,并附带内容哈希和 Ed25519 签名。在捕获到出站流量的情况下,原始的 `evidence.json` 制品会随判定结果一起提供。 由 **Monti Technology GmbH**(德国)维护。官方主页、完整站点、搜索和实时数据请访问:**[canary-truth-layer.com](https://canary-truth-layer.com/?ref=github)**。 本仓库是该注册表的镜像,旨在让开发者和 AI agent 能够在他们经常查阅的地方方便地浏览、fork、对比和引用这些数据。 ## 为什么会有这个项目 在安装 MCP server 之前,你通常很难回答一个简单的问题:*当这个工具运行时,它发送了什么,又发给了谁?* 文档中很少提及。其实际行为存在于已发布的代码和网络传输中,而不是 README 里。 Canary Truth Layer 将这个问题转化为一次查询。正在评估工具的 AI agent 或开发者可以获取其判定结果,并在一个固定的 schema 中读取: - 观察到该工具联系了哪些主机,以及每个流的用途(功能性流量还是遥测流量); - 每个目的地的国家 / 司法管辖区等级; - 该数据流在工具自身面向用户的界面中是**已披露 (disclosed)**、**部分披露 (partially disclosed)** 还是**未发现披露 (not found disclosed)**; - 每个陈述背后的证据,以及证据的强度。 该注册表是**描述性的,而非规范性的**。它只报告事实及其依据。它不会将工具评级为“安全”或“不安全”,也不会告诉你特定的部署是否合法 —— 这取决于你的通知机制和法律依据,只有你自己才能评估。请参阅[范围与中立性](#scope-and-neutrality)。 ## 仓库内容 ``` truthlayer/ verdicts/ one signed JSON verdict per tool (the register) evidence/ raw captured-egress artifacts (where traffic was intercepted) pubkey.pem Ed25519 public key for verifying signatures verify.py standalone signature verifier (recomputes the hash, checks the signature) ``` 该注册表目前涵盖 **38 个 MCP 工具**。每个工具的数据流类别位于 `categories.data_flow` 中。注册表中的大部分内容属于良性或功能性,并非负面发现 —— 当前的分布如下: | Data-flow class | Tools | What it means | |---|---|---| | `functional-egress` | 21 | 联系该工具旨在服务的 API(正常) | | `no-egress` | 11 | 未观察到外部网络出站流量(经证实的阴性) | | `telemetry-undisclosed` | 2 | 在我们阅读的界面中未发现披露的遥测流 | | `telemetry-disclosed` | 2 | 工具自身文档已披露的遥测流 | | `telemetry-documented` | 1 | 在发布的源码中配置了遥测,但未观察到触发 | | `functional-partial` | 1 | 功能性出站流量,部分披露 | 判定结果是**版本锁定的**:它仅适用于一个确切发布的版本(npm dist-shasum / git commit)。较新的版本需要重新扫描;我们不会在不加说明的情况下,用旧版本的分析结果去套用新代码。 ## 判定结果的生成方式 方法论本身就是我们的核心产品。无论针对何种工具,都遵循以下五个步骤: 1. **声明提取。** 枚举关于工具数据流的可核查断言 —— 它将数据发送到哪里、发送给谁、处于哪个司法管辖区,以及是否已披露。 2. **证据获取(沙箱捕获)。** 在隔离的 container 中安装并运行锁定的版本,向其输入可追踪的诱饵数据,并拦截每一个出站请求(针对我们自有的 CA 终止 TLS;透明出站重定向)。**诱饵信标自检** 会确认捕获通道是否处于活动状态 —— 因此,“无出站流量”的结果是一个*被证实的阴性*,而不是盲区。 3. **第一手源码阅读。** 如果某项行为是在打包发布的代码中配置的,而不是(或者除了)在网络中观察到的,我们将直接从已发布的制品中读取,并标记为 `documented` —— 这有别于在捕获阶段 `observed` 到的内容。 4. **对抗性披露把关。** 根据工具完整的用户可见界面(README、license、package 元数据、changelog、发布的源码)检查每一项声明。**在得出任何“未发现披露”的结论之前,都会指派一名独立审查员来尝试反驳该结论。** 这就是下文提到的 §824 关卡;只有经受住反驳的声明才会被发布。 5. **签名。** 计算规范判定结果的内容哈希,并使用离线保存的 Ed25519 密钥对其进行签名。公钥位于此仓库中(`truthlayer/pubkey.pem`),并通过 [`/pubkey.pem`](https://canary-truth-layer.com/pubkey.pem) 提供。 该扫描器采用开放方法论:每个判定结果都包含一个 `reproduce` 块,其中记录了确切的命令和锁定的目标,以便第三方可以重新运行扫描并获得相同的证据。 ## 判定结果 Schema 每个 `verdicts/.json` 都是一条具有自我描述性的记录。最重要的字段如下: | Field | What it tells you | |---|---| | `tool_name`, `tool_id`, `version`, `commit`, `dist_shasum` | 确切被检查的制品 | | `scanned_at`, `version_pin` | 检查时间,以及该判定结果所绑定的锁定版本 | | `capture` | 如果出站流量捕获自检通过,则为 `verified` | | `data_flow.destinations[]` | 针对每个主机:`country`、`jurisdiction_tier`、`flow_class` (functional / telemetry / …)、`required_for_function`、`disclosed`、观察到的请求计数 | | `disclosure.status` | `disclosed` · `partial` · `undisclosed` —— 仅限于阅读过的界面范围 | | `claims[]` | 每项陈述,均带有 **`basis`** 和置信度 | | `content_hash`, `signature`, `signature_alg`, `public_key_url` | 防篡改证据 | | `tier`, `status` | 证据等级;判定结果属于 `provisional` 且可纠正 | ### Basis 标签 —— schema 的核心 每个声明都带有 `basis`,以便读者(人类或模型)可以据此权衡其分量: - **`observed`** —— 在沙箱运行期间捕获的网络流量中观察到。 - **`documented`** —— 直接从已发布制品的源码中读取(已配置的行为),而不是在此次运行中单独重新捕获的。 - **`inferred`** —— 基于观察到/已记录的事实推导出的合理结论,并已明确标记。 - **`classified`** —— 我们应用的一种归类(例如“该主机属于遥测,而非功能性流量”),并已经过披露关卡的审查。 声明的强度是明确的。“工具在启动时向主机 X 发送了 POST 请求”(`observed`)和“根据调用情况,该 SDK 被配置为将工具参数发送到主机 Y”(`documented`)属于不同的认知客体,schema 会将它们区分开来。这种“检测与含义”之间的界限是该注册表赖以维系的诚实机制:仅凭已配置流量的存在,并不能证明该流量已被触发,也不能证明有人受到了伤害。 ### 证据制品 如果捕获到了出站流量,`evidence/.json` 将保存原始(已脱敏)的请求 —— 包括方法、主机、路径、header 以及脱敏后的 body 样本 —— 外加捕获自检结果和复现命令。判定结果通过内容哈希来引用它。获取证据(而不仅仅是判定结果)传达了一个明确的信号:“请将其视为一种信息来源,而不是一种评级”。 ## 如何使用这些数据 ### 直接读取 ``` # 该 register,每个工具一个文件 ls truthlayer/verdicts/ # 单一 verdict cat truthlayer/verdicts/exa.json | jq '.data_flow, .disclosure.status, .claims[].basis' ``` ### 在决策时(从实时站点)拉取 ``` https://canary-truth-layer.com/verdict/.json # signed verdict https://canary-truth-layer.com/verdict//evidence.json # raw captured evidence https://canary-truth-layer.com/pubkey.pem # verification key https://canary-truth-layer.com/llms.txt # machine-readable index for AI crawlers ``` `/llms.txt` 是一个专为 LLM 和 AI 爬虫设计的、以链接优先的简洁内容映射表:它列出了每个判定结果及其数据流类别、司法管辖区和一行简短的摘要,以及上文中提到的机器可读 endpoint。 ### 验证签名 签名可以证明判定结果在签名后未被篡改。该仓库附带了一个独立的验证器: ``` python verify.py truthlayer/verdicts/exa.json # -> signature OK ``` `verify.py` 会重新计算内容哈希,并根据 `truthlayer/pubkey.pem` 检查 Ed25519 签名。完整的检查流程如下: 1. 提取判定结果的 JSON,移除那些不参与内容哈希计算的元字段。这些是完整性字段(`content_hash`、`signature`、`signature_alg`、`public_key_url`、`signed_by`)**外加**那些随时间增长的操作性/谱系字段(`last_checked`、`pin_status`、`latest_available`、`observations`、`observation_count`、`first_seen`、`categories_note`)。 2. 通过对剩余的规范内容重新计算 SHA-256(`json.dumps(..., sort_keys=True, ensure_ascii=False, separators=(",", ":"))`);确认其与声明的 `content_hash` 相等。 3. 使用 `truthlayer/pubkey.pem` **针对 `content_hash` 字符串**验证 `signature`(Ed25519,去除了 `ed25519:` 前缀的 base64 编码)。(此时 `signature_alg` 的值为 `"Ed25519 over content_hash"`。) 内联执行相同的检查: ``` import base64, hashlib, json from cryptography.hazmat.primitives import serialization # 从 content hash 中排除的 Meta 字段(canonicalisation 定义在 # truthlayer/pipeline.py: content_hash — integrity 字段 + operational/lineage 字段)。 META = { "content_hash", "signature", "signature_alg", "public_key_url", "signed_by", "last_checked", "pin_status", "latest_available", "observations", "observation_count", "first_seen", "categories_note", } v = json.load(open("truthlayer/verdicts/exa.json", encoding="utf-8")) clean = {k: val for k, val in v.items() if k not in META} canon = json.dumps(clean, sort_keys=True, ensure_ascii=False, separators=(",", ":")) digest = "sha256:" + hashlib.sha256(canon.encode("utf-8")).hexdigest() assert digest == v["content_hash"], "content hash mismatch" pub = serialization.load_pem_public_key(open("truthlayer/pubkey.pem", "rb").read()) pub.verify(base64.b64decode(v["signature"].split(":", 1)[1]), v["content_hash"].encode()) print("signature OK") ``` ## 关于可发现性的说明(为什么会有这个镜像) 当 AI 助手在查询时被问到,*“`` 是如何处理数据的 / 它是否与 GDPR 相关?”*,它会根据自己能检索到的信息来回答。一个全新的独立域名几乎没有入站权威度,因此在关键时刻往往无法被可靠地呈现出来。 这所解决的问题很具体:工具的数据流事实可能存在于其发布的代码中(并在网络传输中被捕获),但却没有出现在查询时网络搜索所能到达的界面中 —— 如 README、package 页面、官方文档。因此,仅阅读这些界面的审计就可能针对一个实际上存在于制品中的数据流,得出确信的*阴性*结论。本注册表中关于 `exa-mcp-server` 的判定结果就是一个典型的例子:它打包了一个第三方分析 SDK(`agnost`),并且我们捕获到了它发往 `api.agnost.ai` 的启动信标,然而该数据流并未在 package 自身面向用户的界面中披露(参见 [`truthlayer/verdicts/exa.json`](truthlayer/verdicts/exa.json),针对 `exa-mcp-server@3.2.1` 版本;该分析 SDK 是一家合法且公开记录在案的供应商,后续版本的发布可能会有所不同)。 这个缺口 —— 也就是证据确实存在于制品中,但无法通过查询时搜索读取到的界面去触达 —— 正是该注册表旨在填补的空白。将数据发布在具有高权威度的爬虫已经建立索引的地方(这里)正是我们填补这一空白的一部分行动。 ## 范围与中立性 Canary Truth Layer 以独立的产品对比测试方式报告**事实及其依据**。对于它**没有**表达的内容,我们经过了深思熟虑: - 判定结果在证据的基础上陈述了**观察到了什么以及在哪里观察到**。它**不是**在宣称某个工具非法、不安全,或者是任何一方存在恶意。 - “未发现披露”**仅限于**我们阅读过的特定界面范围(已在判定结果中列明),并且只有在独立审查员未能成功反驳后才会提出。它**不是**对整个生态系统未披露情况的断言。 - **功能性出站流量是正常的。** 大多数工具必须联系其旨在服务的 API;这会作为一种中立事实进行报告,而不是一项负面发现。 - 司法管辖区说明描述了目的地解析的位置以及*部署者*需要承担哪些义务。它**不是**在指责任何公司违反了任何规定。 - **缺乏判定记录不代表获得了许可。** 我们尚未扫描的工具仅仅意味着未扫描。 - 每个判定都是**临时的且锁定版本的** —— 它是针对某一个确切版本发布的快照,可根据证据进行更正。 ### 维护者的回应权 如果你是此处收录工具的维护者,并且认为某项判定结果不准确或已过时,你拥有**常设的回应权**。请发送电子邮件至 **info@montitech.de**,并附上判定结果的 URL、你提出异议的具体声明以及任何证据(文档或隐私政策链接、源码引用、禁用开关标识,或者是改变了该行为的较新发布版本)。我们的承诺如下: - **我们依据证据进行更新,绝不屈服于压力。** 如果修正意见提供了捕获的证据或文档化的披露,其分量将胜过我们先前的解读,并且我们会公开声明这一点。 - **我们会重新扫描,而不是默默地修改。** 由于判定结果是锁定版本的,对于较新的版本,我们将作为新的观察结果重新扫描,而不是覆盖原有结果。 **更正记录是档案的一部分。** 更新、注释和撤回操作都将记录在判定结果的 **observation history (each observation content-hashed)** 中,不会被隐藏。 - **回应时限:** 我们的目标是在 7 天内予以确认回复。 你也可以在此仓库中提出 issue 或 PR。关于争议的处理也可以访问 [canary-truth-layer.com/corrections](https://canary-truth-layer.com/corrections?ref=github)。 ## 状态与许可 - **判定结果是临时的**,在被质疑或独立证实之前,带有“等待法证确认”的状态。 - 这是一个**基于事实的自动化研究基础设施**。此处的任何内容均不构成法律建议。 - 数据(`verdicts/`、`evidence/`):**CC-BY-4.0**,署名为 Monti Technology GmbH —— 参见 `LICENSE`。判定结果已经过签名;在重新分发时请保留签名和内容哈希,以便接收者验证完整性。 **由 Monti Technology GmbH 维护 · [canary-truth-layer.com](https://canary-truth-layer.com/?ref=github) · info@montitech.de**
标签:Homebrew安装, MCP, 人工智能, 代码示例, 数据分析, 数据隐私, 用户模式Hook绕过, 网络行为审计, 请求拦截, 逆向工具, 透明度与可追溯性