Haserjian/assay
GitHub: Haserjian/assay
为 AI/LLM 系统提供密码学签名收据包的防篡改审计追踪工具,支持独立第三方离线验证。
Stars: 2 | Forks: 0
# Assay
AI 系统的防篡改审计追踪。
我们扫描了 30 个流行的 AI 项目,发现了 202 个高置信度的 LLM 调用点。其中零个具有防篡改审计追踪。
[完整结果](scripts/scan_study/results/report.md)。
Assay 为 AI 系统添加独立可验证的执行证据:加密签名的收据包,第三方无需信任您的服务器日志即可离线验证。两行代码。四个退出码。
```
pip install assay-ai && assay quickstart # requires Python 3.9+
```
想要确定性的安装路径?从这里开始:
[docs/START_HERE.md](docs/START_HERE.md)
## 眼见为实 —— 然后理解它
立即尝试(无需 API 密钥 —— 演示使用合成数据;对于真实调用,Assay 支持对 OpenAI、Anthropic、Gemini、LiteLLM、LangChain 和本地模型进行埋点):
```
pip install assay-ai
assay demo-challenge # tamper detection: one valid pack, one with a single byte changed
```
两个包,只修改了一个字节(收据中的 "gpt-4" -> "gpt-5")。以下是发生的情况(包 ID 和时间戳在您的机器上会有所不同):
```
$ assay verify-pack challenge_pack/good/
VERIFICATION PASSED
Pack ID: pack_20260222_ca2bb665
Integrity: PASS
Claims: PASS
Receipts: 3
Signature: Ed25519 valid
Exit code: 0
$ assay verify-pack challenge_pack/tampered/
VERIFICATION FAILED
Pack ID: pack_20260222_ca2bb665
Integrity: FAIL
Error: Hash mismatch for receipt_pack.jsonl
Exit code: 2
```
一个字节被修改。验证失败。无需服务器访问。无需信任。只有数学。
现在尝试策略违规演示:
```
assay demo-incident # two-act scenario: honest PASS vs honest FAIL
```
```
Act 1: Agent uses gpt-4 with guardian check
Integrity: PASS Claims: PASS Exit code: 0
Act 2: Someone swaps model to gpt-3.5-turbo, removes guardian
Integrity: PASS Claims: FAIL Exit code: 1
```
第二幕是一个**诚实的失败** —— 证明运行违反其声明的标准的真实证据。证据是真实的。失败是真实的。没人能编辑历史。退出码 1。
退出码 1 是**审计黄金**:控制失败,但失败是可检测且被保留的。审计人员喜欢这胜过那些总是声称通过的系统。
### 它是如何工作的
Assay 有意区分两个问题:
- **完整性**:“这些字节在创建后是否被篡改?”(签名、哈希、必需文件)
- **声明**:“此证据是否满足我们声明的治理检查?”(收据类型、计数、字段值)
| 完整性 | 声明 | 退出码 | 含义 |
|-----------|--------|------|---------|
| PASS | PASS | 0 | 证据验证通过,行为符合标准 |
| PASS | FAIL | 1 | 诚实失败:违反标准的真实证据 |
| FAIL | -- | 2 | 证据被篡改 |
| -- | -- | 3 | 输入错误(文件缺失、参数无效) |
这种分离是关键。能证明自己诚实失败的系统,比总是声称通过的系统更值得信任。
**对于真实调用:** `assay scan .` 查找您实际的 OpenAI / Anthropic / Gemini / LiteLLM / LangChain 调用点。`assay patch .` 对其进行埋点。每次真实的 LLM 调用都会发出签名收据。上面的演示使用合成数据,因此您无需配置任何东西即可查看验证。
## 添加到您的项目
```
# 1. 查找未插桩的 LLM 调用
assay scan . --report
# 2. Patch (每个 SDK 一行,或 auto-patch all)
assay patch .
# 3. Run + build a signed evidence pack
# -c receipt_completeness 运行内置完整性检查 (有关所有选项,请参阅 `assay cards list`)
# -- 之后的所有内容均为您的正常运行命令
assay run -c receipt_completeness -- python my_app.py
# 4. Verify
assay verify-pack ./proof_pack_*/
# 5. 为 security/compliance 审查生成报告 artifacts
assay report . -o evidence_report.html --sarif
# 6. 可选:在 CI 中设置并强制执行 score gates
assay gate save-baseline
assay gate check . --min-score 60 --fail-on-regression
```
`assay scan . --report` 查找每个 LLM 调用点(OpenAI、Anthropic、Google Gemini、LiteLLM、LangChain)并生成自包含的 HTML 差距报告。
`assay patch` 插入两行集成代码。`assay run` 包装您的命令,收集收据,并生成签名的 5 文件证据包。`assay verify-pack` 检查完整性 + 声明,并以上述四个代码之一退出。然后对任何包运行 `assay explain` 以获取简明英语摘要。
**本地模型**:任何 OpenAI 兼容服务器(Ollama、LM Studio、vLLM、llama.cpp)均可自动工作 —— Assay 在类级别对 OpenAI SDK 进行补丁,因此 `OpenAI(base_url="http://localhost:11434/v1")` 会像任何其他提供商一样发出收据。LiteLLM 用户通过 LiteLLM 集成获得相同的覆盖范围(`ollama/llama3` 等)。
## CI 关卡
最快路径(推荐):
```
assay ci init github --run-command "python my_app.py" --min-score 60
```
这将生成一个 3 作业的 GitHub Actions 工作流:
- `assay-gate`(分数强制执行、回归检查、JSON 关卡报告制品)
- `assay-verify`(证明包生成 + 加密验证)
- `assay-report`(HTML 证据报告制品 + SARIF 上传)
手动路径(高级):
```
assay gate save-baseline
assay gate check . --min-score 60 --fail-on-regression --save-report assay_gate_report.json --verbose --json
assay run -c receipt_completeness -- python my_app.py
assay verify-pack ./proof_pack_*/ --lock assay.lock --require-claim-pass
assay report . -o evidence_report.html --sarif
```
锁文件捕获配置漂移。Verify-pack 捕获篡改。Gate 强制执行分数回归。Report 生成可共享的制品 + SARIF。
`assay diff` 对于深度取证和预算/漂移分析仍然有用。有关协议模型,请参阅 [Decision Escrow](docs/decision-escrow.md)。
```
# 锁定您的验证 contract
assay lock write --cards receipt_completeness -o assay.lock
```
### CI 变绿后的日常使用
**回归取证**:
```
assay diff ./proof_pack_*/ --against-previous --why
```
`--against-previous` 自动发现基线包。
`--why` 跟踪收据链以解释发生了什么回归以及哪些调用点导致了它。
**成本/延迟漂移(来自收据)**:
```
assay analyze --history --since 7
```
显示成本、延迟百分位数、错误率以及来自本地跟踪历史的按模型细分。
## 信任模型
Assay 能检测什么,不能检测什么,以及如何加强保证。
**Assay 能检测:**
- 事后篡改(修改一个字节,验证即失败)
- 完整性契约下的选择性遗漏
- 声称运行了从未运行的检查
- 偏离锁定基线的策略漂移
**Assay 无法防止:**
- 完全捏造的虚假运行(攻击者控制机器)
- 不诚实的收据内容(收据是自证的)
- 没有外部时间锚点的时间戳欺诈
完整性是相对于扫描器枚举和/或策略声明的调用点强制执行的。未被检测到的调用点是一个已知的剩余风险,可通过多重检测扫描和 CI 关卡来降低。
**要加强保证:**
- [Transparency ledger](https://github.com/Haserjian/assay-ledger)(独立见证)
- CI 持有的组织密钥 + 分支保护(签名者和提交者分离)
- 外部时间戳(RFC 3161)
作弊的成本随着谎言的复杂性而增加。Assay 不会让欺诈变得不可能 —— 它让欺诈变得昂贵。
## 证据编译器
Assay 是 AI 执行的**证据编译器**。如果您使用过构建系统,您已经知道了这个心智模型:
| 概念 | 构建系统 | Assay |
|---------|-------------|-------|
| 源 | `.c` / `.ts` 文件 | 收据(每次 LLM 调用一个) |
| 制品 | 二进制 / 包 | 证据包(5 个文件,1 个签名) |
| 测试 | 单元 / 集成测试 | 验证(完整性 + 声明) |
| 锁定 | `package-lock.json` | `assay.lock` |
| 关卡 | CI 部署检查 | CI 证据关卡 |
## 命令
核心路径是 6 个命令:
```
assay quickstart # discover
assay scan / assay patch # instrument
assay run # produce evidence
assay verify-pack # verify evidence
assay diff # catch regressions
assay score # evidence readiness (0-100, A-F)
```
完整命令参考:
**入门**
| 命令 | 用途 |
|---------|---------|
| `assay quickstart` | 一个命令:演示 + 扫描 + 后续步骤 |
| `assay status` | 单屏操作仪表板 |
| `assay start demo\|ci\|mcp` | 尝试、CI 设置或 MCP 审计的引导入口 |
| `assay onboard` | 引导设置:诊断 -> 扫描 -> 首次运行计划 |
| `assay doctor` | 预检:Assay 在此处是否就绪? |
| `assay version` | 打印已安装的版本 |
**埋点 + 生成证据**
| 命令 | 用途 |
|---------|---------|
| `assay scan` | 查找未埋点的 LLM 调用点(`--report` 生成 HTML) |
| `assay patch` | 自动将 SDK 集成补丁插入您的入口点 |
| `assay run` | 包装命令,收集收据,构建签名证据包 |
**验证 + 分析**
| 命令 | 用途 |
|---------|---------|
| `assay verify-pack` | 验证完整性 + 声明(4 个退出码) |
| `assay verify-signer` | 从包清单中提取并验证签名者身份 |
| `assay explain` | 证据包的简明英语摘要 |
| `assay analyze` | 来自包或 `--history` 的成本、延迟、错误细分 |
| `assay diff` | 比较包:声明、成本、延迟(`--against-previous`、`--why`、`--gate-*`) |
| `assay score` | 证据准备度评分(0-100,A-F),具有反博弈上限 |
**工作流 + CI**
| 命令 | 用途 |
|---------|---------|
| `assay flow try\|adopt\|ci\|mcp\|audit` | 引导式工作流执行器(默认 dry-run,`--apply` 执行) |
| `assay ci init github` | 生成 GitHub Actions 工作流 |
| `assay ci doctor` | CI 配置文件预检 |
| `assay audit bundle` | 创建可移植审计包(tar.gz,含验证说明) |
| `assay compliance report` | 生成合规证据报告 |
**包 + 基线管理**
| 命令 | 用途 |
|---------|---------|
| `assay packs list` | 列出本地证明包 |
| `assay packs show` | 显示包详情 |
| `assay packs pin-baseline` | 将包固定为差异基线 |
| `assay baseline set\|get` | 设置或获取用于比较的基线包 |
**密钥管理**
| 命令 | 用途 |
|---------|---------|
| `assay key generate` | 生成新的 Ed25519 签名密钥 |
| `assay key list` | 列出本地签名密钥和活跃签名者 |
| `assay key info` | 显示密钥详情(指纹、创建日期) |
| `assay key set-active` | 设置活跃签名密钥用于后续运行 |
| `assay key rotate` | 生成新密钥并切换活跃签名者 |
| `assay key export\|import` | 导出或导入密钥以用于 CI 或团队共享 |
| `assay key revoke` | 吊销签名密钥 |
**Lockfile + cards**
| 命令 | 用途 |
|---------|---------|
| `assay lock write` | 将验证契约冻结到 lockfile |
| `assay lock check` | 根据 card 定义验证 lockfile |
| `assay lock init` | 交互式初始化新 lockfile |
| `assay cards list` | 列出内置 run cards 及其声明 |
| `assay cards show` | 显示 card 详情、声明和参数 |
**MCP + policy**
| 命令 | 用途 |
|---------|---------|
| `assay mcp-proxy` | 透明 MCP 代理:拦截工具调用,发出收据 |
| `assay mcp policy init` | 生成入门 MCP policy YAML 文件 |
| `assay mcp policy validate` | 根据 schema 验证 policy 文件 |
| `assay policy impact` | 分析 policy 对现有证据的影响 |
**事件取证**
| 命令 | 用途 |
|---------|---------|
| `assay incident timeline` | 从收据构建事件时间线 |
| `assay incident replay` | 从收据链重放事件 |
**演示**
| 命令 | 用途 |
|---------|---------|
| `assay demo-incident` | 两幕场景:通过运行 vs 失败运行 |
| `assay demo-challenge` | CTF 风格的良好 + 被篡改包对 |
| `assay demo-pack` | 生成演示包(无需配置) |
## 文档
- **[从这里开始](docs/START_HERE.md) -- 从安装到 CI 证据的 6 个步骤**
- [全景图](docs/FULL_PICTURE.md) -- 架构、信任层级、repo 边界、发布历史
- [快速入门](docs/README_quickstart.md) -- 安装、黄金路径、命令参考
- [致合规团队](docs/for-compliance.md) -- 审计人员看到什么、证据制品、框架对齐
- [合规引用](docs/compliance-citations.md) -- 确切的监管参考(EU AI Act、SOC 2、ISO 42001)
- [Decision Escrow](docs/decision-escrow.md) -- 协议模型:agent 操作在验证前不结算
- [路线图](docs/ROADMAP.md) -- 阶段、产品边界、执行栈
- [Repo 地图](docs/REPO_MAP.md) -- Assay 生态中各组件的位置
- [试点计划](docs/PILOT_PROGRAM.md) -- 早期采用者计划详情
## 常见问题
- **`assay run` 后“没有发出收据”**:首先,检查您的代码是否有调用点:`assay scan .` —— 如果扫描发现 0 个站点,您可能尚未使用受支持的 SDK。如果扫描发现了站点,请检查:(1) 文件中是否有 `# assay:patched`?运行 `assay scan . --report` 查看每个文件的补丁状态。(2) 您是否安装了 SDK 额外依赖(`pip install assayai[openai]`)?(3) 您是否在命令前使用了 `--`(`assay run -- python app.py`)?运行 `assay doctor` 进行全面诊断。
- **LangChain 项目**:`assay patch` 自动对 OpenAI 和 Anthropic SDK 进行埋点,但不会对 LangChain 进行埋点(LangChain 使用回调,而非 monkey-patching)。对于 LangChain,请手动将 `AssayCallbackHandler()` 添加到您链的 `callbacks` 参数中。有关 handler,请参阅 `src/assay/integrations/langchain.py`。
- **`assay run python app.py` 提示“No command provided”**:您需要 `--` 分隔符:`assay run -c receipt_completeness -- python app.py`。`--` 之后的所有内容都会传递给子进程。
- **快速入门在大型目录上受阻**:`assay quickstart` 会阻止扫描系统目录(>10K 个 Python 文件)。使用 `--force` 绕过:`assay quickstart --force`。
- **macOS:`assay run` 内部出现 `ModuleNotFoundError`,但在外部正常**:在 macOS 上,PATH 上的 `python3` 可能指向与安装 assay 和您的 SDK 不同的 Python 版本(例如 `python3` → 3.14,但包在 3.11 中)。使用虚拟环境(推荐),或指定确切的解释器:`assay run -- python3.11 app.py`。用 `python3 --version` 检查,并与您运行 `pip install` 的 Python 进行比较。
## 参与其中
- **试一试**:`pip install assay-ai && assay quickstart`
- **问题 / 反馈**:[GitHub Discussions](https://github.com/Haserjian/assay/discussions)
- **错误报告**:[Issues](https://github.com/Haserjian/assay/issues)
- **想要在 2 周内集成到您的技术栈中?** [试点计划](docs/PILOT_PROGRAM.md) —— 我们为您的 AI 工作流进行埋点,设置 CI 关卡,并交付一个可工作的证据流水线。[提出试点咨询](https://github.com/Haserjian/assay/issues/new?template=pilot-inquiry.md)。
## 相关仓库
| 仓库 | 用途 |
|------|---------|
| [assay](https://github.com/Haserjian/assay) | 核心 CLI、SDK、一致性语料库(本仓库) |
| [assay-verify-action](https://github.com/Haserjian/assay-verify-action) | 用于 CI 验证的 GitHub Action |
| [assay-ledger](https://github.com/Haserjian/assay-ledger) | 公共透明度账本 |
## 许可证
Apache-2.0
标签:AISec, AI安全, Anthropic, Chat Copilot, CIS基准, CVE, DNS 解析, Ed25519, Gemini, JSONLines, LangChain, LiteLLM, OpenAI, Python, 人工智能安全, 内存规避, 加密收据, 可解释性, 合规性, 威胁情报, 子域名变形, 完整性验证, 审计追踪, 密码学, 开发者工具, 手动系统调用, 数字签名, 无后门, 溯源, 轻量级, 逆向工具, 防篡改, 零信任