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, 功能式编程, 命令行封装, 多智能体系统, 恶意软件分析, 数字取证, 日志审计, 确定性协调器, 程序破解, 类型安全, 自主事件响应, 自动化脚本, 证据溯源, 黑客松项目, 黑客马拉松