epheterson/assay

GitHub: epheterson/assay

这是一个通过AI审查GitHub仓库发布差异、自动判断其安全意图的监控工具,用于防范软件供应链攻击。

Stars: 1 | Forks: 0

# 检测 监控 GitHub 仓库的发布。每次新发布时,运行一系列检查(URL 清单、提交者差异等),由 LLM 判断差异是否符合声明的意图,并将结构化判定结果发送至 **电子邮件 + GitHub Issues**。 适用于依赖自动更新软件的情况——侧载应用、npm 包、Homebrew 安装脚本、容器镜像——并希望在供应链攻击发生时引入人工审核机制。 ## 历史 [**LEDGER.md**](LEDGER.md) — assay 已给出的每个判定结果的绿/红名单,按最新排序,附有每个发布的链接。 ## 判定结果 每个发布都会得到以下之一: | 判定结果 | 含义 | Issue 状态 | |---|---|---| | ✅ **clean** | 差异与声明意图一致。无值得您关注的异常。 | 自动关闭 | | ⚠️ **review** | 存在值得人工审查的异常——新提交者、新 URL 等。 | 保持打开 | | 🚨 **blocked** | 高置信度问题。请勿自动更新。 | 保持打开 | 状态存储在 assay 仓库自身的 GitHub Issues 中。每个判定结果会打开一个 Issue,标签为 `assay:{owner}/{repo}` + `verdict:{class}`。带有该标签的最新 Issue *即* 当前状态——原子化、可审计、无冲突,并可通过 GitHub 移动应用原生推送到您的手机。 ## 工作原理 ``` every 30 min cron │ ▼ ┌─────────────────────────┐ │ poll upstream releases │ cheap; no LLM, no download └────────────┬────────────┘ │ new tag? ▼ ┌────────────────────────────────────────┐ │ run check modules (committer_diff, │ expensive; only fires │ url_inventory, …) │ on new release └────────────────────┬───────────────────┘ ▼ ┌────────────────────────────────────────┐ │ judge: GitHub Models LLM call, │ │ produces structured verdict │ │ ★ rule-based override: │ │ hard_flag from any module │ │ forces verdict ≥ review │ └────────────────────┬───────────────────┘ ▼ ┌────────────────────────────────────────┐ │ write GH issue (state + audit log │ │ + native push notification) │ │ send email │ │ commit verdict JSON to repo │ └────────────────────────────────────────┘ ``` ## 模块 | 模块 | 检查内容 | 硬性标记条件 | |---|---|---| | `committer_diff` | 在此时间窗口内新增的作者 | 任何首次提交者 | | `url_inventory` | 二进制文件或源代码中新增/移除的主机名 | 新主机不在允许列表中 | (路线图:`dependency_diff`、`file_tree_diff`、`entitlement_diff`、`framework_diff`、`secret_scan_diff`、`osv_scan`。) ## 评判器 调用 **GitHub Models** 端点 `https://models.github.ai/inference/chat/completions` — 对公开仓库免费,除工作流内置的具有 `models: read` 权限的 `GITHUB_TOKEN` 外,无需其他 API 密钥。默认模型:`openai/gpt-4o-mini`。使用 `response_format=json_object` 输出结构化数据。 如果 LLM 调用失败或设置了 `USE_FAKE_JUDGE=1`,则回退到启发式判定。**任何模块的硬性标记都会强制判定结果 ≥ review** — LLM 的职责是*解释*,而非*把关*。 ## 参考用例:Reddit 的 Apollo Reddit 的 Apollo 于 2023 年 6 月停止运营。一个社区分支([`JeffreyCA/Apollo-ImprovedCustomApi`](https://github.com/JeffreyCA/Apollo-ImprovedCustomApi))使其保持可用;[`Balackburn/Apollo`](https://github.com/Balackburn/Apollo) 通过一个 AltStore 源构建并分发 IPA 文件。 这涉及 5 个以上的信任节点(调整插件作者、分发者、AltStore 源、AltServer、您的开发者证书)。Apple 的 App Store 审查机制在设计中已被移除。`assay` 在这条链条前端充当看门人。 参见 [`examples/apollo/`](examples/apollo) 和 [`.github/workflows/assay-apollo.yml`](.github/workflows/assay-apollo.yml)。 ## 添加新的上游仓库 1. 在 `.github/workflows/assay-{name}.yml` 中放置一个工作流,参照 `assay-apollo.yml` 的格式。 2. (可选)在 `examples/{name}/allowlist.json` 中放置一个列出预期主机的允许列表文件。 3. 推送代码。定时任务会捕获它;首次运行会写入一个基线 Issue。第二次新发布时会写入真正的判定结果。 ## 通知 | 通道 | 设置方式 | |---|---| | **GitHub 原生推送** | 在 github.com 订阅您的 `assay` 仓库分支。每个判定结果都会打开一个 Issue → 通过 GitHub 移动应用即时推送。已关闭的 Issue = 清洁判定;打开的 Issue = 需要关注。 | | **电子邮件** | 添加 `GMAIL_USERNAME` + `GMAIL_APP_PASSWORD` 仓库密钥。详见下文。 | | **Webhook** | 路线图规划中。 | ### 设置 Gmail 电子邮件(2 分钟设置) 1. 前往 https://myaccount.google.com/apppasswords(需要账户启用两步验证) 2. 生成一个标记为 "assay" 的应用密码 — 复制 16 位字符串 3. 在仓库中:设置 → 密钥和变量 → 操作 → 新建仓库密钥 4. 添加 `GMAIL_USERNAME` = your-gmail-address@gmail.com 5. 添加 `GMAIL_APP_PASSWORD` = 16 位应用密码(无空格) 6. 下一个判定结果触发时,将向 `.github/workflows/assay-apollo.yml` 中 `to:` 地址发送一封电子邮件。 ## 为何不直接使用 {工具}? | 现有工具 | 覆盖范围 | `assay` 的补充 | |---|---|---| | OpenSSF Scorecard | 仓库卫生元数据 | 每次发布的行为差异 | | Dependabot / OSV-Scanner | 声明依赖中的已知 CVE | 新颖变更;二进制文件 | | Trufflehog / Gitleaks | 泄露的密钥 | 带 AI 评判器的行为差异 | | Socket.dev | npm/pypi 供应链 | 与生态系统无关 | | Sigstore / SLSA | 构建来源 | "二进制文件做什么?"的判断 | `assay` 的定位是:**"监视此上游仓库的发布,通过 AI 根据声明意图评判差异,并根据判定结果把关下游使用。"** ## 许可证 MIT。祝您使用愉快。
标签:AI代码审查, GitHub Issues集成, GitHub仓库监控, URL发现, 供应链信任, 供应链攻击防护, 侧载应用安全, 发布管理, 大语言模型应用, 安全检测, 安全网关, 定时任务, 差异分析, 持续监控, 结构化查询, 自动化安全, 软件供应链, 软件更新监控, 逆向工具, 邮件通知