eitanity/kanonarion
GitHub: eitanity/kanonarion
一款 Go 依赖保障工具,为开发者和 AI 编程代理提供基于真实依赖树的本地确定性事实查询。
Stars: 1 | Forks: 0
# Kanonarion
**Go 的依赖保障软件。**
Kanonarion 是关于你的依赖项的一个确定性的、本地的单一事实来源——
它们包含什么,如何获得授权,如何调用它们,以及你的代码实际触及了哪些已知
漏洞。开发者通过 CLI 使用人类可读的输出进行查询;AI 编程代理获取 JSON。两者获得相同的答案,
该答案根据你真实的依赖树计算得出——而不是模型凭空猜测。那些你需要手动回答、
消耗大量 token,或者干脆跳过的问题,现在都能被快速准确地解答。
它展示的是证据,而非判决。如果答案是不确定的,它会如实说明,
并指出不确定的方式——绝不会将不确定性掩盖为“安全”。
一个单一的二进制文件。基于 SQLite 的本地存储。没有 SaaS,无需账号,也没有专有的
扫描器替你做决定。事实是公开的;判断权在本地,且属于你。
## 为什么选择 Kanonarion?
现代 AI 编程代理(Claude、Copilot、Cursor、Junie)应该不断询问关于
依赖项的问题——API 是什么,这个 CVE 是否可达,我能否在商业上使用
这个许可证,我该如何调用这个函数。如果没有本地事实存储,
代理通常根本不会问——而是靠猜。这就是我在编写
Kanonarion 时发现的情况。当你强制代理去寻找答案时,你需要消耗 token 并承受延迟。
Kanonarion 通过对每个
依赖集合运行一次 **walk → extract → query** pipeline 来解决这个问题,然后在查询时在本地提供所有
事实。代理询问 Kanonarion
而不是去猜。答案是确定且可复现的。
## 工作原理
```
walk → extract → query commands
```
1. **`walk `** - 解析完整的传递依赖图,并将 `WalkRecord` 持久化到本地 SQLite 存储中。
2. **`extract [walk-id]`** - 对 walk 中的每个模块运行所有的提取阶段(许可证、接口、调用图、示例、漏洞)。
3. **Query 命令** - 从本地存储中进行快速、离线读取。无需网络。
存储默认位于 `~/.kanonarion`。所有的元数据都在一个单一的 SQLite 数据库中;模块 ZIP 是内容寻址的 blob。每次获取都会与 Go checksum database 进行验证。
## 不确定性是第一-class 状态
Kanonarion 绝不会悄悄地将不确定性渲染为确定性。
漏洞的状态是 **可达**、**不可达** 或 **未知**——最后一种状态适用于那些无法提供符号级可达性数据的安全通告。许可证状态分为 **已检测**、**未分类** 或 **无**——分别是解析出的 SPDX 标识、无法分类的许可证文本,或者是未找到许可证证据——绝不会悄悄地将其渲染为“允许”。如果 Kanonarion 无法确定某事,它会如实说明。策略可以配置为将未知情况视为硬性失败,这样 CI gate 就会发出响亮的失败警报,而不是因为盲区而通过。
## 快速开始
```
# 安装(将 `kanonarion` 放入你的 PATH 中)
go install github.com/eitanity/kanonarion@latest
# 端到端分析单个模块(walk → extract → vuln-scan → context)。
# 一个模块 = 一个你可以在一屏内阅读并进行 sanity-check 的结果。
kanonarion inspect github.com/spf13/cobra@v1.8.1
# --- 查询 store(离线,无网络) ---
# 显示模块的 public API
kanonarion interface-show github.com/spf13/cobra@v1.8.1
# 查找 symbol 的使用示例
kanonarion examples-find GenManTree
# 列出 vulnerability scan 运行记录
kanonarion vuln-scan-list
# 检查 licences
kanonarion license-list
```
**分析你自己的项目。** 从你的项目根目录运行 Kanonarion,它会
默认使用你 `go.mod` 中的依赖集:
```
cd ~/my-project
kanonarion inspect # same as --gomod ./go.mod (your code-scope deps)
kanonarion audit # one-line-per-module fetch + licence + vuln report
```
这会遍历完整的传递闭包,因此可能需要几秒钟
到几十分钟不等,具体取决于你有多少依赖项——
漏洞扫描占用了大部分时间,因为 `govulncheck` 需要分析项目。使用 `--tool` / `--project` 缩小
或扩大范围;请参阅 CLI 参考。
`audit`、`inspect`(无参数)和 `vuln-scan --gomod` 是**以项目为根的**:
它们根据你项目真实构建的单次扫描结果来得出每个模块的漏洞结论,因此构建内的依赖项读取的状态为 `Clean`/`Affected`,绝不会仅仅因为你的项目从未进行的构建而显示为无法分析。*单模块*
`inspect ` 或 `vuln-scan --module ` 是基于坐标键的视图:
它将该模块作为独立的主模块进行扫描,这是预期的“单独查看”分析,且保持不变。
**逐步驱动 pipeline。** `walk`、`extract` 和 `vuln-scan` 均基于一个 **walk id**。`walk` 会打印该 ID,并且你随时可以解析最近成功的 walk:
```
# Walk 模块及其完整的 transitive closure(输出一个 walk id)
kanonarion walk github.com/spf13/cobra@v1.8.1
# 解析最新成功的 walk id(需要 jq)
WALK_ID=$(kanonarion walk-list --latest-success --json | jq -r '.id')
# 提取该 walk 的所有 facts(interfaces、licences、call graphs、examples)
kanonarion extract "$WALK_ID"
# 扫描该 walk 的 vulnerabilities(添加 --reachability 以按 reachability 进行 triage)
kanonarion vuln-scan "$WALK_ID"
```
## 代理编程工作流
Kanonarion 旨在直接从代理工具调用中被使用。代理指南中的推荐模式:
| 场景 | 命令 |
|--------------------------------------------|---|
| 用户添加或升级依赖项 | `walk ` 然后 `extract` |
| 端到端引导新模块 | `inspect ` (walk + extract + vuln-scan + context) |
| 将有关模块的所有已知信息加载到代理的上下文中 | `context --json` |
| “X 的 API 是什么?” | `interface-show --json` |
| 检查特定的类型或函数 | `interface-show --symbol ` |
| 关于某个符号的一切(签名、文档、示例) | `symbol-context --json` |
| “我该如何使用 X?” | `examples-find ` 然后 `examples-show` |
| “我应该用哪个库来实现 X?” | `symbol-find ` |
| “这个库安全吗?” | `vuln-scan --module --reachability` |
| “我可以将其用于商业用途吗?” | `license ` |
| “我的依赖闭包在许可证上是否兼容?” | `license-compat ` |
| 生成第三方署名 / NOTICE 文件 | `notice --package ./cmd/` |
| “函数 F 调用了什么?” | `callees ''` |
| “什么调用了函数 F?” / 影响分析 | `callers ''` |
| 让 callers/callees 解析我自己项目的符号 | `local ` |
| 依赖升级了 - 改变了什么? | `walk-diff ` |
| “X 有更新的版本吗?” | `latest ` |
| 审计本项目的供应链安全 | `directives` / `godebug` / `vendor` / `fips` |
所有的查询命令都支持 `--json` 以提供机器可读的输出,使其易于在代理工具实现中解析。
## 核心功能
- **离线优先。** 在初始的 walk 和 extract 之后,所有的查询都是本地 SQLite 读取。没有网络调用,没有速率限制,没有不稳定(flaky)的 CI。
- **确定性。** 锁定的版本、通过 checksum 验证的 ZIP 包、排序的 JSON 输出。相同的查询在今天和一年后都会返回相同的结果。
- **无 SaaS,无回传(phone home)。** 一个在你运行它的地方运行的单二进制文件。安装后没有账号、没有遥测、没有供应商介入。
- **具备可达性感知的漏洞扫描。** 集成了 govulncheck 并带有可选的 `--reachability` 过滤。你的代码实际上无法触及的 CVE 会被降级处理,而不会在凌晨 2 点把你叫醒。
- **带有来源的许可证合规性。** 针对每个模块的 SPDX 许可证检测,提供完整的传递摘要,分类为已检测、未分类 或无。
- **接口提取。** 完整的公共 API 表面——类型、函数、方法、常量——以代理可直接消费的结构化 JSON 格式呈现。
- **调用图。** 用于影响分析和可达性查询的模块内调用图。
- **使用示例。** 从模块测试文件中提取的经过验证的代码片段,以便代理能够根据实际有效的模式编写代码。
- **策略门禁。** YAML 格式的 walk 遍历规则——最大深度,是否遵循 replace 指令和间接依赖要求——通过 `policy validate` 进行验证。
- **SBOM 生成。** 从任何 walk 生成与 CycloneDX 兼容的软件物料清单。Go 标准库是第一-class 的组件;`--stdlib-from-gomod` 将其版本锁定到 `go.mod` 指令,以确保发布构建产物的可复现性。
- **可审计的证据链。** 每一次获取、每一次验证、每一次策略决定都记录在只能追加的 `audit.jsonl` 中。提供关于 Kanonarion 何时执行了什么操作的可复现的、带时间戳的证据——对于 CI 调查、合规性报告或理解构建为何失败非常有用。
## 存储布局
```
~/.kanonarion/
mirror.db # SQLite - all metadata (walks, interfaces, vulns, licences, …)
blobs/ # Content-addressed module ZIPs
audit.jsonl # Append-only fetch audit log
```
## 策略文件
在你的项目根目录中放置一个 `.kanonarion/policy.yaml`(Kanonarion 会从 cwd 向上搜索)。策略控制 walk 遍历——最大深度、是否遵循 replace 指令,以及是否遍历间接依赖要求。
```
# 验证单个 policy 文件
kanonarion policy validate .kanonarion/policy.yaml
# 验证目录中的所有 policy 文件
kanonarion policy validate docs/examples/policies
```
示例策略位于 [`docs/examples/policies/`](docs/examples/policies/) 中。
### 可观测性
默认情况下,`kanonarion` 会在 `INFO` 级别发出进度信息。对于大规模模块分析(例如 Envoy),可以通过 `--log-level debug` 启用高频内存遥测以进行故障排除。
## 文档
- [`docs/getting-started.md`](docs/getting-started.md) - 从全新的检出到获取模块级的依赖答案,无需任何先验知识(包含可直接复制粘贴的代理提示词)
- [`docs/cli/reference.md`](docs/cli/reference.md) - 完整的 CLI 参考
- [`docs/cli/vuln.md`](docs/cli/vuln.md) - 漏洞命令
- [`docs/cli/extract.md`](docs/cli/extract.md) - 提取 pipeline
## 环境要求
Kanonarion 是一个单二进制程序,但它会调用少量的外部
工具。请确保这些工具在你的 `PATH` 中:
| 工具 | 何时需要 | 安装方式 |
|---|---|---|
| **Go 1.26+** | 安装 *和* 运行时 - Kanonarion 驱动 `go` 工具链(`go list`、`go mod download`、`go test -c`、`go tool nm`)来解析构建列表并分析二进制文件。 | [go.dev/dl](https://go.dev/dl/) |
| **git** | 运行时 - VCS 交叉验证(`fetch` 阶段会将代理下载的 zip 包与上游源代码仓库进行比对)。可选:如果没有 git,获取操作依然会针对 Go checksum database 进行验证,但会记录一个未验证的 VCS 状态;可以通过传递 `--skip-vcs-verify` 来显式跳过。 | 系统包管理器 |
| **govulncheck** | 运行时 - 被 `vuln-scan` / `inspect` 所需。如果缺少该工具,扫描将快速失败并给出可操作的错误提示。 | `go install golang.org/x/vuln/cmd/govulncheck@latest` |
| **jq** | 可选 - 只有本 README 中的 shell 代码片段使用它从 `--json` 输出中提取 walk id。 | 系统包管理器 |
只有在给定模块集的**第一次**运行时才需要网络访问
(模块下载、checksum database、VCS 交叉验证、漏洞
数据库快照)。之后的每次查询都是在本地存储
`~/.kanonarion` 中执行的,无需网络调用。请注意,以项目为根的命令
(audit、inspect、vuln-scan --gomod)依然会使用缓存的模块和漏洞
数据库在你活跃的工作树上重新进行漏洞扫描。
`audit` 还会在每次运行时从模块代理实时解析每个模块的最新版本
(陈旧度列),因此即使在预热(warm)的存储上,它也总是会发起这些出站调用。
标志 --fresh 会重新下载漏洞数据库快照,而 --force
会强制重新获取模块集。
## 从源码构建
贡献者从代码检出进行构建,而不是使用 `go install`:
```
make build # compile binary to ./kanonarion
make test # run all tests with race detector
make coverage # generate coverage report
make lint # run golangci-lint
```
## 状态
Kanonarion 是基于 Apache-2.0 的开源项目,目前正在积极开发中。如果你的组织正在监管审查下(如 DORA、CRA、NIS2、欧盟 AI 法案、澳大利亚 ISM)针对 Go 代码库使用 AI 编程工具——并且你希望参与塑造发展路线图,请联系我们。
标签:EVTX分析, Go, Ruby工具, SOC Prime, 依赖管理, 开发工具, 日志审计, 本地数据库, 许可证合规