vinodhalaharvi/provenance
GitHub: vinodhalaharvi/provenance
基于类型化 arrow 组合与确定性 Go 协调器的自主 DFIR 多 agent 系统,通过禁止无效命令表达和完整的审计跟踪来解决 AI 辅助取证中的幻觉与证据安全问题。
Stars: 1 | Forks: 0
# Provenance
一个自主的事件响应协调器,其中每项发现都可追溯至生成它的具体 arrow。提交给
[Find Evil!](https://findevil.devpost.com) 黑客马拉松的作品。
基于 [weft](https://github.com/vinodhalaharvi/weft) 实现类型化的 arrow
组合,并使用 SANS SIFT Workstation 作为底层的取证工具集。
## 核心论点
现有的 AI 辅助 DFIR 工具(例如 SIFT 协议及类似工具)为
LLM agent 提供了一个通用的 `execute_shell_cmd` 加上冗长的系统提示,并
寄望于它能保持在正轨上。黑客马拉松的任务简介指出这是
自主性差距的根源:幻觉、证据损坏风险、
无限循环。
Provenance 使用类型化的动作空间和
基于 critic 介导的策略来替代上述攻击面:
- **类型化的 arrows** 封装了每个 SIFT 工具。输入和输出是 Go
结构体,而不是原始的 shell 文本。agent 无法构造无效的命令
行,无法扫描案例目录之外的内容,也无法在 Linux 镜像上
运行 Windows 插件——这些错误配置是无法表达的。
- **多 agent 循环** 包含专家提议者(内存 / 磁盘 /
网络)和一个独立的 critic,在任何 arrow 运行之前对提案进行评分。专家在跨迭代时是无状态的;证据包
是唯一的记忆。
- **确定性的协调器** 使用 Go 编写(循环体中没有 LLM)强制执行
终止、审计跟踪的生成以及提案选择。
- **函数式接缝** 适用于每一个行为选择。选择策略、
critic 调用策略、提案收集和终止
条件都是可替换的闭包。
## 快速开始
```
make all # tidy, build, test
make test # ~25 unit tests, no SIFT install required
make test-verbose # show every test by name
make cover # coverage report
make run # run the mcp-server binary
```
测试只需要 Go 和本代码仓库——每个 SIFT
工具的调用都是通过一个虚拟的 `runner.RunFunc` 针对
捕获的固件输出进行单元测试的。生产环境二进制文件(`bin/mcp-server`)
期望在 PATH 上存在真实的 SIFT 工具(`vol`, `yara`, ...),并且
打算部署在 SIFT Workstation 虚拟机内部。
需要 Go 1.23 或更高版本。
## 项目布局
```
provenance/
├── runner/ functional seam for subprocess execution
│ └── runner.go RunFunc, RealRun, NewFake
├── sift/ typed SIFT arrows wrapping forensics tools
│ ├── types.go Process, Timeline, YaraReport, ...
│ ├── pslist.go Volatility 3 pslist (Win/Linux dispatch)
│ ├── yara.go YARA scan with case-root path validation
│ ├── triage.go composed Par(memory, disk) -> synthesis arrow
│ └── fixtures/ captured tool outputs for tests
├── coord/ the multi-agent coordinator
│ ├── types.go EvidenceBag, Proposal, Verdict, enums
│ ├── predicate.go DSL parser + field registry + evaluator
│ ├── seams.go four behavioral seams + defaults
│ └── coordinator.go the loop, exposed as a weft.Arrow
├── mcpadapter/ generic weft.Arrow -> MCP tool wrapper
│ └── register.go one function: RegisterArrow[In, Out]
└── cmd/mcp-server/ production binary serving MCP over stdio
```
## 函数式接缝(一个原则,处处适用)
本仓库中的每个测试/生产边界都是一个函数类型,而不是一个
接口。函数类型无法被反向类型断言为一个具体的
实现——接缝背后没有具体类型,只有一个
闭包。这使得边界是不透明的,并防止了某类
有人穿透接缝以绕过它的 bug。
这些接缝:
| 接缝 | 类型 | 位置 |
|---------------------|-------------------------|-------------------|
| 子进程运行器 | `RunFunc` | `runner/` |
| 跟踪发出 | `TraceTap` | `coord/types.go` |
| 提案收集 | `CollectProposalsFn` | `coord/seams.go` |
| Critic 调用 | `InvokeCriticFn` | `coord/seams.go` |
| 选择策略 | `SelectFn` | `coord/seams.go` |
| 终止检查 | `TerminationCondition` | `coord/seams.go` |
| Arrow 执行 | `ArrowExecutor` | `coord/types.go` |
每一项都附带合理的默认值;每一项都可以在调用 `Run()` 之前,在 `Coordinator` 结构体上逐个字段进行替换。
## 架构护栏
这些是在任何子进程生成或任何 LLM 被调用之前强制执行的只读和完整性属性:
1. **Volatility 插件调度** 是由 profile 驱动的 Go 代码。一个
以 `"Win"` 开头的 `MemoryImage.Profile` 会选择 `windows.pslist`;
其他任何情况都会选择 `linux.pslist`。没有 agent 控制的字符串
能够选择错误的插件。
2. **YARA 目标路径** 在清理和 `filepath.Rel` 规范化之后,必须解析到 `CaseRoot` 内部。`../../etc/passwd` 会在 `exec.Command` 被调用之前被拒绝。`CaseRoot` 必须是绝对路径。
3. **谓词 DSL** 在接收提案时进行解析。格式错误的
谓词和对未知字段的引用会在 critic 或执行器看到它们之前被捕获。
4. **协调器循环是确定性的 Go 代码。** 终止条件、
提案验证、审计跟踪的生成——这些都不通过
LLM 运行,因此它们都不会被提示注入诱导偏离正轨。
## 审计跟踪(名字的由来)
每个 `ExecutionStep` 都会记录提议的专家、运行的
arrow、提供的理由和谓词、该步骤填充的 bag 字段以及时间数据。发现会携带一个 `Evidence`
切片,指明为其支持数据做出贡献的 arrows。运行演示的评委可以通过
发现 -> arrows -> 跟踪条目 -> 原始工具调用来追踪任何“高严重性”的声明。
## 已连接 vs 桩实现
| 层 | 状态 |
|------------------------|----------|
| 类型化 arrows (sift/) | 真实 |
| 子进程接缝 | 真实 |
| MCP 工具暴露 | 真实 |
| 协调器循环 | 真实 |
| 谓词 DSL | 真实 |
| 终止条件 | 真实 |
| **专家 agents** | **桩实现** |
| **Critic agent** | **桩实现** |
| **Arrow 执行器** | **桩实现** |
桩实现是确定性的 Go 代码,覆盖了循环中的每条代码路径。
构建的第二阶段将用 LLM 驱动的专家和 critic 替换它们,
加上一个真正的执行器,将 `ArrowName` 分派给
具体的 `sift.*` arrows。
## 生产路线图
对于本次黑客马拉松,这是纯 Go 代码。关于长期规划:
- **Temporal** 将处理持久执行、支持重试的活动、
作为原生审计跟踪的工作流重放,以及用于人机交互的信号/查询。协调器的 `ArrowExecutor` 接缝是自然的切入点——每个 arrow 执行成为一个 Temporal activity,协调器循环成为工作流主体。
- **习得的协调器策略。** 每次运行产生的 提案/裁决/结果 三元组都是训练数据。未来的版本将用在跟踪语料库上训练的模型替换启发式 critic,以根据 bag 状态预测下一个最佳的 arrow。
- **跨案例校准。** 专家在案例之间传递校准分数——那些预期更符合现实的 agent,其提案在选择阶段会获得更高的权重。
## 许可证
MIT。详见 `LICENSE`。
标签:DAST, EVTX分析, Go语言, PyRIT, SANS SIFT, 功能式编程, 命令行封装, 多智能体系统, 恶意软件分析, 数字取证, 日志审计, 确定性协调器, 程序破解, 类型安全, 自主事件响应, 自动化脚本, 证据溯源, 黑客松项目, 黑客马拉松