> ## Documentation Index
> Fetch the complete documentation index at: https://openclaw.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 审计历史

# 审计历史

Gateway 会在共享的 OpenClaw 状态数据库中保留一个有界的、仅包含元数据的审计账本。它可以回答诸如“哪个代理运行了、何时运行、以及如何结束的”“某次运行执行了哪些工具操作”，以及在启用消息审计时，“一条已接受的入站消息是否到达了分发阶段”以及“ 一条出站消息是否到达了终态交付状态”等操作性问题。

该账本存储标识、顺序、来源、操作、状态以及规范化的结果代码。它绝不会存储提示词、消息正文、工具参数、工具结果、附件、文件名、URL、命令输出或原始错误文本。

Gateway 还会为新接纳的代理运行保留一个相邻的执行身份上下文。该上下文对于其中包含的身份事实具有权威性；但它不会使活动账本变得无损，也不会将审计记录转变为授权证据。

终端操作员审批是一个独立的权威来源。运行检查会直接将其现有的“首个回答获胜”行转换为决策回执；它不会将审批复制到审计账本或通用决策事实表中。

## 运行身份检查

默认情况下不会记录执行身份，包括全新安装和升级。请显式启用，然后重启 Gateway：

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
openclaw config set logging.audit.executionIdentity true
openclaw gateway restart
```

收集要求 `logging.audit.enabled` 和
`logging.audit.executionIdentity` 均为 true。将任一项设置为 `false`
会在重启后停止新上下文；不存在环境变量别名，也不会通过静默迁移启用该功能。保留的上下文在其 30 天到期前仍可检查。

会话工作准入成功后，OpenClaw 会验证并冻结一个有界的身份封装，立即将其提交给现有的审计写入器队列，然后继续运行，而不会等待写入器就绪、SQLite 或持久化。工作线程会初始化架构和 HMAC 密钥状态，对原始引用进行伪名化，构造不可变上下文，验证其规范化字节，并将其持久化。因此，已接受的封装在排队工作完成期间可能会暂时无法供检查。

持久化仍采取尽力而为的方式。队列饱和、工作线程或存储故障以及进程崩溃都可能导致证据丢失；这些情况只会记录一条有界的运行警告，绝不会中止运行。正常的 Gateway 和直接本地 CLI 关闭会在写入器生命周期允许时刷新已接受的工作，但突然终止仍可能丢失排队中的证据。

启用身份收集后，重启恢复只会使用其现有的私有恢复所有者存储安全的执行/上下文/运行 ID 和时间戳。之后发生的模糊重试会引用该令牌，而不是从新进程重新构建身份。当收集功能或审计账本被禁用时，恢复不会创建、存储或传播新的身份令牌。如果原始排队上下文已丢失，则明确保持无法进行精确检查；重试绝不会伪造替代证据。原始身份引用不会存储在恢复令牌中。

每个获准的外层轮次都会获得一个新的不透明 `executionId`；`contextId`
用于标识其不可变证据记录，而现有的 `runId` 仍可能是共享的路由、会话或恢复关联标识。使用 `audit.run.inspect` 或
[`openclaw audit --execution <id> --explain`](/cli/audit) 查询一个精确的执行。使用 `--run <id> --explain` 发现某个运行关联对应的执行。单个保留匹配会直接解析。多个匹配会返回 `ambiguous`，最多包含 50 个候选执行 ID，并要求进行精确选择；OpenClaw 绝不会静默选择第一个或最新的执行。结果会明确说明以下字段的证据状态：

* 信任域、调用方和入口；
* 代理主体、代理定义和运行时实例；
* 所代表的主体和发起方；
* 适用的授权和保证证据；
* 可用时的父级或子级谱系。

基础设施会在权威生产方记录直接本地 CLI 入口和 Gateway 启动系统入口。当其边界无法证明更具体的来源时，通用公共入口仍会明确标记为未知；OpenClaw 绝不会根据会话密钥推断入口或调用方身份。直接本地执行属于 `unattributed`：其中存在 Gateway 单元、本地 CLI 入口、已配置的代理和运行时绑定，但此边界未提供持久化的调用方主体。只有当权威入口提供调用方事实时，运行才会变为
`attribution-only`。这两种状态都不意味着身份影响了允许或拒绝决策。

经过身份验证的 Gateway attach 记录会一次性写入不可变的审计事实。会话创建会单独读取实时规范的持久配置文件 ID，因此在 attach 之后执行的配置文件链接不会使会话所有权失效。普通会话来源只保留该 ID；不会保留配置文件显示标签。显式启用执行身份记录后，其审计上下文还可能在机密信息删减和 128 个字符的限制之后保留准备好的显示标签。已解析的持久配置文件（包括通过已验证的可信代理或 Tailscale 身份建立的配置文件）会提供经过伪名化的人类调用方。配对设备会增加设备保证，但绝不会成为人类。共享令牌、密码、无认证连接和其他无配置文件客户端仍属于未归属状态。如果经过身份验证的用户证据承诺存在持久配置文件，但配置文件解析失败，则调用方为 `unknown`，而不是从标头、设备 ID、连接 ID 或凭据中猜测。

每个现有上下文都会生成一份运行准入回执。其结果为 `not-applicable`，策略和授权引用为空，原因说明未证明进行过任何身份感知的策略或授权评估。这是对准入证据的解释，而不是执行声明。

当同一个 `runId` 在 `operator_approvals` 中存在一行保留的终态记录时，检查器还会读取其所有者本地的 `operator_approval_execution_identities` 绑定。只有精确的上下文、执行和运行元组才会将该审批投影为已执行。回执会列出持久所有者和记录引用、精确的稳定原因代码、首个回答和终态策略引用、允许决策创建的任何授权、使用的精确上下文字段，以及有界的后续步骤。它绝不会包含命令、参数、路径、环境、审查者设备 ID、解析器 ID 或审批展示文本。

审批结果映射到稳定的回执原因：

| Recorded approval result       | Receipt reason code                                                                       |
| ------------------------------ | ----------------------------------------------------------------------------------------- |
| Allow once / allow always      | `operator_approval_allowed_once` / `operator_approval_allowed_always`                     |
| Reviewer denial                | `operator_approval_denied_by_reviewer`                                                    |
| Deadline expiry                | `operator_approval_expired`                                                               |
| Run abort / Gateway restart    | `operator_approval_cancelled_run_aborted` / `operator_approval_cancelled_gateway_restart` |
| No approval delivery route     | `operator_approval_denied_no_route`                                                       |
| Malformed approval verdict     | `operator_approval_denied_malformed_verdict`                                              |
| Fail-closed storage state      | `operator_approval_denied_storage_corrupt`                                                |
| Unreadable or inconsistent row | `operator_approval_record_corrupt`                                                        |
| Missing execution binding      | `operator_approval_execution_link_missing`                                                |
| Malformed execution binding    | `operator_approval_execution_link_malformed`                                              |
| Mismatched execution binding   | `operator_approval_execution_link_mismatch`                                               |

允许、拒绝、过期和取消的行属于 `enforced`，因为记录的人类决策或故障安全的所有者策略改变了操作是否能够继续。无路由拒绝仅在审批所有者将 `no-route` 记录为返回不执行结果之前的获胜终态原因时，才属于 `enforced`。不可读的行属于 `unknown`，绝不会被重建。如果保留的审批指明了某个运行，但其预期的执行上下文缺失，则运行检查会返回覆盖范围为 `unknown` 的 `decision_context_link_missing`，并且不会编造回执上下文。

由于 `runId` 是关联标识而不是执行身份，因此它绝不会替代所有者本地绑定。缺失、格式错误或不匹配的绑定行会投影为没有授权引用且带有明确绑定修复措施的 `unknown`，即使该运行只保留了一个执行上下文也是如此。检查器绝不会根据会话元数据、时间戳或保留的上下文数量推断绑定。

运行检查会返回成功的类型化诊断，而不是编造事实：

* `unknown`：所选运行或执行未知，或者预期上下文损坏或不可读；这也涵盖保留的决策缺少其预期上下文链接的情况；
* `unsupported`：尽力而为的活动记录显示该运行存在，但没有可用上下文，例如功能启用前、功能禁用或上下文写入失败的情况。刚刚超出保留期的上下文也会在有界清理待处理期间使用此状态，并附带明确的过期修复措施；
* `ambiguous`：某个 `runId` 有多个保留的执行；请先选择候选 `executionId`，再检查身份或决策；
* `unattributed`：受支持的运行没有可用的调用方主体；
* `attribution-only`：调用方归属存在，但尚未针对授权进行评估。

该方法要求 `operator.read`。请求是封闭的，并且会恰好选择一个
`executionId` 或 `runId`。决策页面最多包含 100 份收据；
模糊运行发现页面最多包含 50 个候选执行。两者都使用有界游标。

同一 Gateway 操作员域中拥有 `operator.read` 的每个客户端都可能接收此保留的身份类别。这是有意为之：该范围已经涵盖日志和会话读取，收集功能是显式选择加入的，保留的引用受到限制并经过伪名化，可选的显示标签会进行机密信息删减。`operator.read` 不是用于恶意多租户隔离的边界；当操作员不得共享此诊断数据时，请使用独立的 Gateway 信任域。

## 记录类别

在启用审计时（默认），会记录运行和工具事件。
消息生命周期事件为可选启用，默认处于关闭状态。

| 家族       | 操作                                                       | 默认 |
| -------- | -------------------------------------------------------- | -- |
| Agent 运行 | `agent.run.started`, `agent.run.finished`                | 开启 |
| 工具操作     | `tool.action.started`, `tool.action.finished`            | 开启 |
| 消息       | `message.inbound.processed`, `message.outbound.finished` | 关闭 |

每条记录都包含一个稳定的事件 ID、单调递增的账本序列、生命周期时间戳、actor、action、status、`schemaVersion: 1` 和 `redaction: "metadata_only"`。完整字段参考和查询过滤器请参见 [审计记录](/cli/audit)。

## 消息生命周期事件

设置 [`logging.audit.messages`](/gateway/configuration-reference#audit) 以选择要记录的内容，然后重启网关：

* `off`（默认）：不记录消息。
* `direct`：仅记录直接对话中的消息。
* `all`：记录直接对话、群组和频道消息。

两种权威边界会产生消息记录：

* **入站**行会在已接受的消息到达核心分发时写入，
  包括重复和终态处理结果。
* **出站**行会在共享持久投递到达以下终态时写入：已发送、已抑制、失败，或对
  崩溃歧义发送显式标记为 `unknown`。包括队列恢复和死信结果。
  每个原始逻辑回复负载都会得到一条终态行；分块和适配器扇出会汇总到
  `resultCount`。

### 对话类型分类

`direct` 模式是一个隐私边界，因此只有当目的事实能够证明时，消息才会被归类为直接
对话：发送路径声明了目标对话类型，或者投递会话路由名称与正在投递的通道和对等方
完全一致。较弱的信号，例如策略状态或起始对话，可以将消息归类为 `group`（从而将其
排除在 `direct` 收集之外），但永远不能声明为 `direct`。无法证明为直接对话的消息会被
归类为 `unknown`，并且不会在 `direct` 模式下记录。因此，不声明聊天类型的通道在
`direct` 模式下记录的行数可能少于在 `all` 模式下记录的行数。

## 隐私模型

消息行永远不会存储原始平台标识符。账户、会话、
消息和目标标识符，在可进行关联时，仅作为安装本地的带密钥伪
名导出（`hmac-sha256:v1:<keyId>:<digest>`）：

* HMAC 密钥在首次使用时生成，按标识符类型进行域分离，并与账本保存在同一个状态数据库中。
* 伪名在单次安装内保持稳定，因此关于同一会话的行可以关联，而不会泄露平台标识符。
* 这属于**关联，不是匿名化**：任何能够读取状态数据库的人也拥有该密钥，并且可以将候选原始标识符与伪名进行比对。RPC 和 CLI 导出绝不会包含该密钥。
* 如果在保留消息行的情况下密钥材料缺失或损坏，Gateway 会安全失败并丢弃新的消息记录，而不是静默轮换到新密钥；否则会导致关联被拆分。

运行和工具记录会保留 `sessionKey` 和 `sessionId` 以便关联；
规范化的会话键本身也可能包含平台账户或对端 id。
消息记录会有意省略这两者。

执行身份上下文使用相同的安装本地密钥所有者，但采用独立的 HMAC 域。原始运行时、调用方、入口来源、担保和授权引用仅存在于进程内深度冻结的工作器消息中，并且每个授权/担保数组最多包含 16 KiB 和 16 个条目。工作器会在持久化之前将它们替换为带密钥的伪名；它们绝不会被存储、导出、检查或记录日志。已配置的代理 id 以及上下文、执行和运行 id 对操作员仍然可见。

上下文绝不包含提示词或消息文本、命令正文、参数、路径、凭据、环境值或任意插件负载。每个编码后的上下文同样限制为 16 KiB。

即使不包含内容，审计导出仍属于敏感的操作元数据：
时间、频道、结果和稳定的伪名都可能关联活动。
请对导出内容采取与其他操作员记录相同的访问控制和保留措施。

## 覆盖范围和证明限制

该账本采用尽力而为的方式，并且有意设置了边界。请将其视为已记录内容的证据，而不是对实际发生情况的证明：

* **没有某一行并不能证明任何事情。** 预接纳的入站丢弃、绕过共享持久化传递的插件本地或直接发送路径、被丢弃的接纳信封，以及因崩溃而丢失的排队工作，都可能不会留下记录。
* 写入会经过一个有界的后台工作线程；工作线程故障或队列饱和会丢弃记录，并记录一条运行警告。
* 无法确定是否成功的崩溃期间出站发送会被记录为 `unknown`，而不是臆造结果。

该账本用于调试和运维审查。它不是无损的合规归档；如果你需要这样的归档，请使用由 [OpenTelemetry](/gateway/opentelemetry) 或通道级工具提供数据的外部系统。

## 存储、保留与迁移

记录存放在共享状态数据库（`state/openclaw.sqlite`）中，并且
在交付热路径之外写入。查询绝不会返回超过 30
天的记录，账本最多限制为 100,000 行；过期行会在
启动、每小时维护以及后续写入时被清理。即使禁用收集，
保留维护仍会继续运行。

从使用早期仅限 run/tool 账本的 Gateway 升级时，会在启动时自动迁移
schema（或通过 `openclaw doctor --fix`）；现有
行及其账本序列都会被保留。

执行身份上下文也存放在共享状态数据库中。规范行以唯一的执行 ID 和上下文 ID 为键；`runId` 非唯一，
但会建立索引以用于关联。其附加表会在首次使用时延迟创建，不会导致 schema 版本递增。
全新安装和升级后的安装在操作员启用收集之前，都不会填充身份上下文。
首次使用时的 schema 创建、HMAC 密钥访问、规范上下文构建以及所有 SQLite 操作都在审计工作线程中执行，
绝不会发生在代理准入流程中。
上下文保留 30 天，最多限制为 100,000 行。即使尚未执行物理清理，
精确执行检查和运行发现也绝不会返回超过 30 天的上下文、候选项或准入决策。
过期行会在 Gateway 启动、每小时审计维护以及后续上下文写入期间被清理，
每次写入或维护周期最多移除 1,024 行身份上下文记录。禁用收集时，维护仍会继续运行。
较早版本的构建会忽略此表。

终端审批会在其所有者原生的 `operator_approvals` 表中保留 30 天。即使尚未执行物理清理，检查也会应用这一截止时间。附加的 `execution_decision_facts` 表用于未来没有所有者原生持久记录的操作边界。该表会在首次写入通用事实时延迟创建，事实保留 30 天，表最多限制为 250,000 行，并且每次写入或维护周期最多清理 1,024 行。审批路径绝不会写入此表。对于所记录的决策，其中的事实和审批行都是权威的。写入通用表会使用有界审计工作线程，在持久化前仍采取尽力而为的方式；审批所有者的写入不依赖该队列。活动账本在任一来源丢失后都无法重建它们。

每次通用决策事实写入都会重新读取不可变的执行上下文，并要求完整的上下文、执行和运行元组。投影会再次验证同一个元组；不匹配时状态为 `unknown`，不会仅根据上下文或运行关联重新分配。

## 查询

* CLI：[`openclaw audit`](/cli/audit)，支持按代理、会话、运行、类型、状态、方向、频道、时间范围和游标分页进行筛选。

* Gateway RPC：`audit.activity.list`（需要 `operator.read`）返回带版本的 V1 活动事件联合类型；已发布的 `audit.list` RPC 保持不变，以兼容旧版运行/工具客户端。请参阅
  [Gateway 协议](/gateway/protocol#audit-ledger-rpc)。

* 身份 RPC：`audit.run.inspect`（需要 `operator.read`）接受一个 `executionId` 进行精确检查，或接受一个 `runId` 进行有界发现。对于精确匹配，它返回不可变的 V1 上下文以及分页的准入、审批和未来通用决策回执；当某个运行包含多个执行时，则返回带类型的歧义候选页面。

* CLI：[`openclaw audit`](/cli/audit)，支持按代理、会话、运行、类型、状态、方向、频道、时间范围和游标分页进行筛选。

* 网关 RPC：`audit.activity.list`（需要 `operator.read`）返回带版本的 V1 活动事件联合类型；已发布的 `audit.list` RPC 保持不变，以兼容旧版运行/工具客户端。请参阅
  [网关协议](/gateway/protocol#audit-ledger-rpc)。

* 身份 RPC：`audit.run.inspect`（需要 `operator.read`）接受一个 `executionId` 进行精确检查，或接受一个 `runId` 进行有界发现。对于精确匹配，它返回不可变的 V1 上下文和准入回执；当某次运行包含多个执行时，则返回一个带类型的歧义候选页面。

## 相关内容

* [审计记录 CLI](/cli/audit)
* [配置参考](/gateway/configuration-reference#audit)
* [网关协议](/gateway/protocol#audit-ledger-rpc)
* [OpenTelemetry](/gateway/opentelemetry)
