# 面向法律审查的代理活动导出：构建可验证的证据

**代理活动导出文件**必须让局外人无需相信整理它的人，就能回答四个简单问题：发生了哪些操作、分别在什么时候发生、记录是否被改动过，以及收集后由谁控制这些材料。大多数团队都能回答第一个问题。后面三个问题，往往会让一次普通事件变成一场围绕证据的争论。

不要等到收到传票、发生员工纠纷、安全事件或客户投诉后，才决定要保留什么。到了那时，保留任务可能已经删除日志，人员可能已经打开并重新整理文件，匆忙导出的工程师也可能只导出了看起来相关的记录。这些做法可以理解，但也正是审查包失去可信度的原因。

下面介绍一种实用方法，用于为法律顾问、内部调查、合规审查或外部审查人员准备代理操作记录。它不能替代法律意见，但能为法律顾问提供远胜于一个名称令人安心的电子表格的材料。

## 把证据包当作证据，而不是报告

证据包保存源材料，并说明这些材料如何被处理。报告则从材料中进行选择、解释和论证。你可能两者都需要，但如果不加区分地把它们合在一起，就会带来问题。

报告可以写：「代理在这个时间点尝试对这台主机执行 SSH 命令。」证据包则应让审查人员找到对应的底层操作记录，查看时间的表示方式，检查记录的结果，确认哪个系统生成了它，并验证导出文件是否发生过变化。报告应放在证据包旁边，而不是放进证据包唯一的副本中。

当早期理论被证明错误时，这一区分尤其重要。调查人员往往会随着了解增多而缩小关注范围。如果他们只导出一组手选的「异常」事件，然后丢弃周围的记录，就无法再检验重试、审批、会话变化或操作人员行为是否解释了该事件。上下文不是装饰。它往往决定了某次事件究竟是未经授权的操作，还是一连串普通故障造成的误导性印象。

收集前先确定范围。用一句简短的话写清楚：

- 涉及哪些代理进程或会话标识
- 涉及哪些操作渠道，例如 HTTP 和 SSH
- UTC 起止时间
- 覆盖哪些系统或账户
- 已知的排除项，以及排除每项的原因

之后不要悄悄扩大范围。应新增一次补充收集。例如，第一份证据包覆盖六小时的事件窗口，审查人员后来要求查看前一天的记录，就应创建第二份具有独立清单和哈希值的证据包，并在保管记录中将它与第一份关联。这样可以保留第一项决定的边界。

团队还常犯一个有害的错误：把活动视图误认为完整的源记录。仪表板适合初步分流，但通常会应用筛选、分页、用户偏好和保留期限，这些条件在截图中看不出来。应收集原始记录或最接近原始记录的源导出文件，再从这些材料生成易读的视图。

## 分开证明真实性和完整性

真实性和完整性是两种不同的主张，好的证据包应分别支持它们。

真实性关注某条记录是否来自声称的源，以及收集后是否有人改动过它。哈希、签名、只追加存储和哈希链有助于支持这一主张。完整性关注证据包是否包含了按声明范围应当包含的全部记录。查询结果、源系统计数、保留设置和收集说明有助于支持这一主张。

团队经常夸大文件哈希的作用。SHA-256 哈希可以证明 `activity.jsonl` 当前与此前计算哈希的版本一致，但无法证明文件包含了该期间的每项操作，也无法证明系统时钟正确，更无法证明文件确实来自备忘录中所写的系统。哈希非常适合证明逐字节的连续性，却不是万能的真相印章。

同样，审计链可以发现它所覆盖的序列中存在删除或改动，但无法弥补糟糕的范围定义。如果事件涉及两个代理会话，而你只收集了其中一个，那么第一条会话的链条即使完整，也不能让证据包变得完整。

使用清单，让这些主张可以被检查。清单应标明源、范围、收集人、收集时间、文件目录和验证材料。应使用不依赖特定应用即可读取的纯文本格式。

```text
case_reference: IR-2025-017
package_id: 2025-017-agent-actions-01
collected_at_utc: 2025-03-08T14:27:19Z
collected_by: employee-id-1842
source_system: macOS workstation, asset WS-042
scope_start_utc: 2025-03-07T18:00:00Z
scope_end_utc: 2025-03-08T02:00:00Z
channels: HTTP, SSH
included_files:
  - original/activity-records.jsonl
  - original/session-records.jsonl
  - original/audit-verification.txt
  - derived/action-timeline.csv
exclusions: Browser history and local shell history were outside this collection.
```

`original` 目录应存放收集到的源材料。`derived` 目录可以存放 CSV 时间线、审查备忘录或编辑后的副本。这样可以避免一种常见故障：有人打开 JSON 文件，通过会改变换行符或字符编码的编辑器保存它，随后才发现原始哈希不再匹配。

《联邦证据规则》中的第 901 条规定，要证明证据的真实性，需要提供足以支持「该物品就是主张者所称物品」这一判断的证据。第 902(14) 条专门涉及从电子设备、存储介质或文件复制并认证的电子数据，只要具备资质的人能通过数字识别流程确认其身份。这些规则并不允许技术人员跳过文档记录，反而说明识别过程本身就是证明的一部分。

## 在让源记录变得易读前先冻结它

只收集一次，保存这次收集的结果，然后在副本上进行排序和格式化。直到调查人员第一次需要解释「为什么团队宣布某个文件为证据后它却发生了变化」，你才会发现这并不是吹毛求疵。

先创建一个访问受限的案件目录。记录收集记录的确切系统位置、使用的收集账户，以及收集后源系统是否仍在运行。如果源系统可能继续接收事件，也应写明。运行中的系统不是静态展品，假装它是静态的只会造成混乱的时间线。

然后直接导出源数据。在计算哈希之前，不要用电子表格软件打开文件。电子表格应用经常会重新解释日期、截断长值、改变分隔符，并把标识符当成数字处理。这些行为对工作分析文件或许可以接受，但对保存的副本不可接受。

在 macOS 上，将原始文件放入证据包目录后，从该目录内计算 SHA-256 清单：

```sh
find original -type f -print0 | sort -z | xargs -0 shasum -a 256 > SHA256SUMS.txt
cat SHA256SUMS.txt
```

输出中每个文件占一行，包含 64 位十六进制摘要和文件路径。将命令输出作为证据包的一部分保存，并记录执行命令的人。之后可以用同一清单进行验证：

```sh
shasum -a 256 -c SHA256SUMS.txt
```

验证成功时，每个路径后面都会显示 `OK`。如果某个路径显示 `FAILED`，就不要再把证据包当作未发生变化的包。保留验证失败的副本，记录结果，并查明原因是传输、重命名、换行符转换还是实际改动。不要重新生成哈希文件后若无其事地继续。

文件名应朴素且稳定。必要时加入证据包标识、源类别和 UTC 收集时间。避免使用 `final-final-v3` 或 `suspicious stuff` 之类的名称。审查人员不应需要依靠口头说明，才能分辨原始导出文件和经过筛选的分析工作表。

NIST 特别出版物 800-86《将取证技术融入事件响应》强调，要保存数据并记录收集和处理过程。虽然其中的建议早于代理工具，但这套纪律仍然适用。代理操作速度很快，这更需要完善收集说明，而不是降低标准。

## 记录时间戳及其时钟背景

没有明确定义时钟的时间戳，只是一个不完整的事实。保留原始时间戳值、时区或偏移量、字段名，以及任何已知的排序标识符。

以 UTC 作为证据包的参考时间，并使用 ISO 8601 格式，例如 `2025-03-08T14:27:19Z`。同时保留源系统原样导出的时间戳。如果源系统显示本地时间，应记录其配置的时区，以及系统是否通过批准的服务同步时间。不要仅仅因为团队偏好另一种显示格式，就覆盖源时间戳。

一次代理操作可能产生多个时间。操作记录可能包括代理请求操作的时间、审批出现的时间、人类批准的时间、系统执行的时间，以及远程服务响应的时间。这些时间不能互相替代。

要制作有用的时间线，应按事件标记这些时间，而不是把它们压缩成一个 `timestamp` 列。10:00:01 发起请求、10:00:28 获得审批、10:00:29 执行、10:00:31 远程失败，与「执行发生在审批之前」讲述的是完全不同的故事。事件顺序可能证明或推翻人工控制的主张。

如果有序列标识符，就一并收集。单调递增的审计序列、会话内调用编号或请求标识符，都能在两条记录具有相同时间精度时帮助解决顺序问题。如果记录只有秒级时间戳，就明确说明。不要用导出时间来人为制造毫秒级精度。

时钟不一致应单独记录。如果本地工作站和远程 API 相差几分钟，就保留这一观察结果并标明来源。不要为了让时间线看起来更整齐而「修正」某条记录。审查人员之后可能需要判断系统是否使用了不同的时钟，或某个事件是否跨越了时间边界。

证据包应包含类似下面的简短时间说明：「所有时间线显示均使用 UTC。源值保留在原始文件中。收集期间工作站报告的 UTC 偏移为 +00:00。未进行独立时钟比对。」最后一句可能让人感到不够圆满，但它是诚实的。没有依据的确定性，比明确记录限制造成更大的损害。

## 保存操作及其决策上下文

操作记录需要足够的上下文，才能区分尝试发出的请求、获得授权的执行，以及已经完成的外部影响。这些是不同的事件。

对于 HTTP 活动，应保留操作时间、会话或进程标识、方法、目标主机、路径、删除机密后的相关请求头、请求正文的处理方式、响应状态和结果元数据。仅仅因为令牌、密码或私钥经过操作系统，审查包就不应包含可重复使用的承载令牌、密码或私钥。机密可能在证据处理过程中引发第二起事件。

对于 SSH 活动，应保留目标主机或主机别名、操作系统使用的用户身份、记录中的命令或命令类别、认证结果、退出状态，以及经过有记录的编辑规则处理后的返回输出。如果命令输出可能包含客户数据，应在受限访问下保留原始文件，并创建审查副本，同时说明每处编辑。没有编辑日志的黑色遮挡条，会让审查人员怀疑还有什么内容被删除。

进程身份与操作本身同样重要。应记录发起调用的代理进程、可用时记录其代码签名机构、会话标识和会话生命周期。「是编码代理做的」对法律审查来说过于模糊。即使人们都把不同进程称为同一个代理，它们也可能有不同的来源、审批和权限。

审批记录需要谨慎措辞。审批意味着某人根据系统设计，允许某项明确定义的操作或会话。它不能证明此人阅读了每个细节、理解了每个后果，或根据公司政策拥有相应权限。除非有单独证据支持，否则不要作出这些主张。

Sallyport 在 Sessions 日志中记录代理运行，在 Activity 日志中记录单次调用，两个视图都来自同一条加密的哈希链审计日志。这种设计便于审查，因为会话层面的问题和调用层面的问题，都可以追溯到同一条底层记录序列。

保留原始请求与结果之间的关系。失败的调用可能和成功的调用同样重要。连续失败可能表明代理正在重试被阻止的凭据、改动后的端点，或操作人员正在修正配置。为了缩短时间线而删除失败记录，往往也会删除那次关键成功的解释。

## 在源数据仍可用时验证篡改迹象

在收集过程中执行完整性验证，并将输出与原始记录一起保存。之后再验证仍有价值，但早期结果能将证据包与收集时日志系统的状态联系起来。

哈希链日志通过加密数据将每条记录与之前的材料连接起来。改动、删除或插入记录，通常都会破坏后续的链接关系。这样，审查人员就有一个明确的属性可以检验：该序列是否能按发布时的状态通过验证。但它不能证明记录的操作在伦理上合理，也不能证明所有可能的系统事件都进入了日志。应将这些主张分开。

对于 Sallyport 审计日志，在依赖日志视图前，应对收集到的源数据运行 `sp audit verify`。验证可以离线对密文执行，不需要保险库密钥，因此调查人员无需取得执行外部操作所用的凭据，也能保存完整性结果。

保存完整的终端记录，包括命令、当前目录、账户身份（如果流程会记录）、开始和结束时间，以及退出状态。截图不如文本，因为它难以搜索、复制和独立重跑。如果命令报告失败，也要保留该结果。不要只导出那些看起来验证成功的记录。

验证需要可重复的条件。记录应用版本，以及在相关情况下记录操作系统版本和确切的收集路径。如果验证工具依赖特定的本地安装，也应保留这项依赖的记录。通常不必默认打包每个可执行文件，但审查人员应知道要重现检查需要什么。

一条简单的验证说明可以写成：「收集人员于 2025-03-08T14:31:02Z，对 `original/` 中复制的加密审计日志运行了审计验证命令。命令成功退出。未经编辑的终端记录位于 `original/audit-verification.txt`。」如果命令没有成功退出，就直白说明，并记录它对证据包的影响。完整性证据有用，正因为它可能推翻你偏好的解释。

## 在保管记录中写明人员和交接

保管链是对占有和控制情况按时间顺序作出的记录。它不是有人提出要求后才事后补填的一页签名表。

从收集人员创建证据包时开始记录。每条记录都应写明证据包标识、UTC 日期和时间、转交控制权的人或服务账户、接收人、转交目的、转交方式、存储位置，以及证据包哈希或哈希清单的引用。如果整个收集期间始终由同一个人保管，也应记录这一点。

使用公司之后可以解析的姓名或稳定内部身份。「安全团队」不是保管人，「法务的 Jane」也不够明确。人员会换岗、离职，并且在压力下对事件有不同记忆。

```text
2025-03-08T14:38:11Z
Package: 2025-017-agent-actions-01
Released by: employee-id-1842
Received by: legal-ops-id-77
Purpose: counsel review under incident hold
Method: encrypted internal file transfer
Integrity reference: SHA256SUMS.txt verified before transfer
Storage: matter workspace, restricted folder
```

如果交接使用加密存储或安全文件交换，应记录具体方式，但不要以为加密就证明了保管链。加密能保护传输过程中的机密性，保管记录则说明谁有意转交以及谁接收了证据包。要求接收人确认收件，然后记录之后为顾问、保险公司、监管机构或外部法律顾问制作的每个副本。

访问日志可以支持保管记录，但不能替代它。存储日志可能显示某个账户访问过文件，却未必能说明该账户为何访问、当时账户是否属于预期人员，或一次获批准的交接是否在存储系统之外完成。

不要用普通电子邮件发送唯一的原始文件。邮件会产生无法控制的副本、自动转发风险和保留方面的问题，也会让附件版本变得模糊。如果法律顾问需要副本，应创建有记录的分发副本，交接后验证其哈希，并将原始文件保存在受控位置。

## 编辑过程应可追溯，文件不应可逆恢复

应根据明确的受众和目的进行编辑，但在法律、政策和调查要求时，保留未编辑的原始文件。不要让编辑后的版本成为唯一幸存的证据包。

代理记录可能包含机密、源代码、个人数据、客户数据、内部主机名或运营细节。如果广泛分享，可能产生新的风险。法律审查很少需要可重复使用的 API 凭据或私有 SSH 材料。应将这些内容从审查副本中排除，并说明收集流程如何处理它们。如果源导出文件包含机密，应进一步限制原始文件的访问，而不是把它分发给每位审查人员。

使用编辑日志，为每个被编辑的项目或一致类别各记一行。写明文件、记录标识、字段、原因、执行编辑的人、日期，以及原始文件是否仍能在受限访问下取得。审查人员应能区分被编辑的授权标头和被删除的操作结果。

不要依赖 PDF 或截图上的视觉遮挡。错误的编辑曾多次暴露底层文字，因此绝不能把它当作次要的制作细节。应从受控副本创建新的审查材料，用普通提取工具检查，并确认敏感内容不再出现。随后单独计算编辑后材料的哈希值，但它不能替代原始清单。

筛选后的时间线可能很有用，尤其是案件涉及数千次常规调用时。应将它标为派生证据，并包含筛选逻辑。例如：「包含规定 UTC 时间内对指定客户租户的调用；排除所有其他目标；源记录仍位于 original/activity-records.jsonl。」这句话让法律顾问可以解释该证据的性质，而不会误称它是完整的审计历史。

## 让证据包在六个月后仍可审查

收集证据包的人不一定是之后解释它的人。应为接手案件的人编写收集说明，考虑到事件聊天记录已经消失，原工程师也忘记了细节。

加入一份简短的自述文件，回答实际问题：哪些文件是原始文件，哪些是派生文件，每个导出文件由什么工具生成，如何验证哈希，如何理解时间戳，以及保存的原始文件在哪里、由谁控制访问。除非证据包明确将其标为分析人员陈述，否则应将观点放在单独的事件分析中。

Sallyport 的保险库门控、会话授权和逐次调用审批，都可能生成有助于说明操作周围人工控制情况的记录。应保存案件所需的准确审批证据层级，但不要声称某项产品控制回答了属于政策、权限或意图范畴的法律问题。

在调查迫使你处理这些问题之前，先进行一次演练。让一位没有收集证据包的同事，只使用自述文件、清单、哈希和验证记录来回答：包含了哪些源记录？我能验证它们吗？采用什么时间依据？谁负责保管？如果这位同事仍需向收集人员询问基本问题，证据包就还没有准备好。

最有用的第一步通常很不起眼：现在就创建案件目录模板、纯文本清单、哈希清单命令和保管日志。真正的事件发生时，这四项内容能避免匆忙导出的文件变成无法验证的故事。
