追踪与审计
工作区发出的每一个请求——代理对 LLM 提供商的调用、软件包下载、kubectl 和 aws 流量、普通的网页抓取——都会经过 Bromure Agentic Coding 宿主机侧的 MITM 代理服务器。由于代理服务器已经位于该传输边界上,它可以记录经过它的一切:代理联系了哪些主机、发送了什么、返回了什么、是否有凭据被替换或泄露,以及——对于 AI 流量——模型驱动的完整对话、工具调用和 shell 命令。
该记录就是工作区的会话追踪。它的存在只有一个原因:让你能够在事后回答"代理究竟做了什么?"——细化到单个提示、单个 rm -rf、单个出站请求。所有内容都记录在你的 Mac 上,静态加密,并且(对个人用户而言)永不离开它。
本章涵盖整个系统:追踪捕获什么、如何存储和老化淘汰、追踪检查器窗口、bromure-cli trace 命令行、如何将数据取回,以及本地审计与注册的 Mac 流式传输给组织的遥测数据之间的隐私边界。该窗格逐字段的设置参考位于追踪设置。
追踪记录什么
追踪按工作区进行,由编辑工作区窗口的追踪窗格中的会话追踪选择器控制。它有四个级别,每个级别都是前一个级别的超集:
| 级别 | 记录内容 |
|---|---|
| 关闭 | 不记录任何内容。 |
| 仅活动 | 每个请求一条元数据记录——不含正文。 |
| AI 请求详情(默认) | 每个请求的元数据,加上已知 LLM 主机的完整请求和响应正文。 |
| 全部 | 每个请求的元数据,加上每个主机的正文。 |
新工作区默认为 AI 请求详情,因此代理对话开箱即可审计,而无需将无关流量(软件包下载、遥测 ping)的正文存储到磁盘上。
注意: 在配置文件格式中,追踪级别枚举默认为关闭,因此存储的 JSON 早于此设置的工作区会解码为关闭。AI 请求详情默认值仅适用于从当前模板创建的工作区。当审计很重要时,请刻意选择级别。
元数据记录
在仅活动及以上级别,代理服务器为每个请求写入一条追踪记录。每条记录——无论级别如何——都携带以下元数据:
- 时间戳、主机、端口、HTTP 方法和路径。
- 状态码和延迟,从打开隧道的
CONNECT到响应之间测量。 - 请求字节数(在任何凭据替换之前测量)和响应字节数。
- 令牌替换报告——代理服务器在出站时替换了哪些凭据(参见凭据替换与泄露)。
- 凭据泄露警告——出站请求中 Bromure 未铸造的 bearer 式令牌。
- 在本地或混合模型路由下,哪个后端处理了本轮(参见本地模型)。
这足以重建代理在何时与谁交谈的完整图景,而无需在磁盘上保留一个字节的提示或响应文本。当你想要审计追踪线索——联系过的域名、凭据处理、延迟——但不想要内容时,仅活动就是要选择的级别。
捕获的正文与解析的对话
在 AI 请求详情级别,代理服务器还会为已知的 LLM 主机存储完整的请求和响应正文:Anthropic、OpenAI / ChatGPT、Google、Cohere、Mistral、Perplexity、x.ai / Grok、Groq、Replicate 和 HuggingFace,以及当工作区路由到本地模型时的本地推理主机。在全部级别,会为每个主机保留正文。
捕获的 AI 正文不只是被存储——它还会被解析。追踪检查器将其渲染为对话视图:系统提示、每个用户轮次、助手的回复,以及模型输出的结构化块。这些块正是让编码代理追踪变得有用的原因:
- 工具调用——模型产生的每个
tool_use块,及其输入。 - Shell 命令——
Bash/Shell工具调用,即代理在 VM 中运行的命令。 - 文件读取与写入——
Read/View和Write/Edit/MultiEdit工具调用,及它们触及的路径。
因此单条 AI 请求记录就能回答"模型本轮决定做什么"——读取此文件、运行那条命令、调用此 API——从原始 API 正文中解析出来。同样的结构也正是实时事件抽取在注册的 Mac 上转化为审计事件的内容。
凭据替换与泄露
每个请求都会记录两个凭据处理事实,并被突出显示,因为它们是安全审查中最要紧的:
- 令牌替换。 当代理服务器在传输中将 VM 持有的诱饵凭据替换为真实凭据时,记录会注明这一点——以假值和真值的首/末字符预览形式(
sk-a…f9q3),绝不包含机密字节。这是正常、健康的情况:它确认了替换系统正在履行其职责。 - 泄露。 当出站请求携带 Bromure 未铸造的 bearer 式令牌时——即直接粘贴到 VM 中、绕过替换系统的真实机密——记录会将其标记为潜在泄露,同样仅以预览形式,并标注可疑类别:
knownPrefix(Bromure 未签发的已识别机密前缀)或opaqueToken(一个长的不透明认证值)。泄露标记是调查的提示;诱饵凭据和入侵检测的完整机制见凭据。
静态加密与保留
追踪位于 ~/Library/Application Support/BromureAC/traces/ 下,按天组织:
- 元数据以每个请求一行 JSON 的形式追加到
traces/YYYY-MM-DD/<sessionID>.jsonl。 - 捕获的正文存储在其旁边,为
traces/YYYY-MM-DD/<sessionID>/<recordID>.req.enc和.res.enc——使用 SecretsVault 主密钥进行 AES-GCM 密封,即加密你工作区机密的同一个 Keychain 持有密钥。文件权限为0600。
在写入任何内容之前,记录会被净化:
- 敏感头部会被涂抹。
Authorization、Proxy-Authorization、Cookie、Set-Cookie、x-amz-security-token、api-key,以及任何以-api-key结尾的头部都会被重写为<redacted>。 - 机密仅以预览形式存储。 令牌替换和疑似泄露只保留首/末字符预览——真实机密字节永远不会进入追踪记录,无论加密与否。
保留是自动的,且以延迟方式运行(每 200 次追加执行一次清理):
| 上限 | 超出时的行为 |
|---|---|
| 每会话 100 MB 正文 | 该会话最旧的 .enc 正文文件会被逐出。元数据行保留——你保留审计追踪线索,只丢失最旧的捕获文本。 |
整个 traces/ 目录 5 GB | 首先删除最旧的日期目录。 |
另外,应用为实时视图在内存环形缓冲区中保留最后 5,000 条记录;更旧的记录在上述上限范围内保留在磁盘上。
警告: 在 AI 请求详情和全部级别,AI 交互的完整提示和响应文本都在磁盘上——虽已加密,但确实存在。由于正文使用 SecretsVault 主密钥密封,轮换该密钥会使先前捕获的正文无法解密;此时追踪检查器会在正文应出现的位置显示
(not captured / decryption failed)。
追踪检查器窗口
追踪检查器是所有工作区中每一次已记录交互的实时、可筛选查看器。它读取与 CLI 相同的记录,并在新请求流入时实时更新。
打开窗口
从窗口 → 追踪检查器…(⇧⌘I)打开。它也可以从会话窗口的工具栏中预筛选到某个工作区的形式打开,因此你可以从正在运行的代理直接跳转到它自己的流量。打开时,内存环形缓冲区会从磁盘预热——仅读取今天和昨天的日期目录,因此冷启动很快。更旧的记录保留在磁盘上,当它们进入范围时按下重新加载按钮即可显示,或通过 CLI 读取它们。
请求列表
左侧窗格是一个最新在前的记录列表。每一行从左到右显示:
- 一个按响应类别着色的状态点:2xx 为绿色,3xx 为蓝色,4xx 为橙色,5xx 为红色,其他为灰色。
- 方法和主机(路径显示在下方,中间截断)。
- 徽章(在适用时):未替换凭据(潜在泄露)为橙色警告三角,令牌替换为蓝色替换箭头,以及为此记录捕获了正文时显示文档图标。
- 右侧的状态码和延迟。
页脚显示 N records (last M in memory) 并带有一个从磁盘重新加载按钮(循环箭头图标)。列表支持完整的键盘导航——↑ / ↓ 单步移动,PgUp / PgDn 跳转十条,Home / End 到达两端——新选中的行会滚动到视图中。
筛选
列表上方有一个筛选栏:
| 控件 | 效果 |
|---|---|
| 工作区选择器 | 缩窄到一个工作区,或所有工作区。 |
| 仅泄露 | 仅显示带有未替换凭据警告的记录。 |
| 仅对话 | 仅显示代理服务器解析为 AI 聊天交互的记录。 |
| 主机筛选 | 针对主机的子字符串匹配。 |
注意: 仅对话依赖于记录写入时设置的标志。在该标志存在之前捕获的记录被算作非对话,并被此筛选器隐藏,直到重新记录为止。
详情窗格
选择一行会填充右侧窗格。其标题显示方法、完整 URL、状态,以及一行元数据单元格——工作区、延迟、请求和响应大小,以及时间——加上一个对话 / 原始分段切换。
- 对话渲染解析后的 AI 聊天:系统提示、轮次、工具调用和结果,格式化以便阅读。仅当捕获了正文且交互被解析为 AI 对话时才可用;否则切换会自行回退到原始。
- 原始在各个分节中显示记录的构建块:未替换的凭据(潜在泄露)、令牌替换(每个为
fake → real预览)、请求正文和响应正文。当你选择记录时,正文会按需解密。
每个正文分节都有一个复制按钮,可将完整正文放到剪贴板上——包括超出屏幕截断的全部文本,以及二进制正文的十六进制字符串。当未存储正文,或主密钥不再能解密它时,该分节显示 (not captured / decryption failed)。
未选择任何内容时,窗格显示一个占位符:选择一个请求——在左侧选择一行以检查头部、替换和(如果已捕获)正文。
WebSocket 会话
通过代理服务器进行的长期存活的 WebSocket 升级——OpenAI Realtime、Codex 的 responses_websockets 等——被追踪为每个 WS 会话一条记录,而不是作为不透明的二进制丢失。当工作区的追踪级别为该主机捕获正文时,两个方向都会进行帧解析(RFC 6455):去除掩码,重组连续帧,并对 permessage-deflate 载荷(RFC 7692)进行解压,因此文本帧是可读的,而不是压缩后的乱码。
关闭时,代理服务器在上游握手响应之后追加一份按时间顺序排列的转录文本,并将其存储为记录的响应正文,因此追踪检查器通过普通正文路径渲染它——当它被解析为 AI 交互时也包括对话视图。一条转录条目看起来像:
--- WebSocket session transcript ---
>>> [2026-07-13T15:30:05Z] TEXT 1234B
<<< [2026-07-13T15:30:06Z] TEXT 5678B (truncated, total 40000 bytes)
限制使得聊天频繁的会话保持有界:每条消息保留 1 MB,每会话 4,096 条消息,最大 64 MB 帧,以及最大 32 MB 解压后消息;超出上限的任何内容都被标记为 (truncated, total N bytes)。解析失败只会降级转录文本——实时隧道泵送原始字节,永远不会因追踪而停滞或损坏。
追踪 CLI
bromure-cli trace 命令组在终端中为你提供相同的追踪数据。它是一个瘦客户端:它通过本地控制套接字与运行中的应用通信,因此 GUI 应用必须正在运行(富客户端通过 SSH 隧道传输相同的协议以到达远程实例)。
| 命令 | 作用 |
|---|---|
bromure-cli trace ls [workspace] [--limit N] | 列出近期请求,最新在前(默认 50 行)。列:TIME、HOST、METHOD、STATUS、REQ、RESP、LAT 和 FLAGS(swap×N、LEAK×N、conv)。 |
bromure-cli trace summary [workspace] | 聚合视图:请求和主机计数、上/下行字节数、状态类别直方图、替换/泄露/对话计数,以及排名前 10 的主机。 |
bromure-cli trace hostnames [workspace] | 联系过的每个不同主机,及请求计数。 |
bromure-cli trace leaks [workspace] | 仅列出带有潜在凭据泄露的请求——头部、值预览和可疑类别。干净时打印 No leaks detected. ✓。 |
bromure-cli trace clear [-f] | 在 y/N 确认后(使用 -f 跳过)清除所有追踪历史——内存环形缓冲区和磁盘上的文件。报告清除了多少条记录。 |
可选的 workspace 参数按 id 或名称筛选。如果该工作区的追踪已关闭(或尚未记录任何内容),trace ls 会打印 No trace records. (Tracing is per-workspace — enable it in the workspace's settings.);如果应用未运行,每个子命令都打印 No bromure-cli agent running.。完整的 CLI 记录在自动化与 CLI中。
导出追踪
没有单独的"导出"按钮——追踪数据通过保持加密边界完整的路径离开检查器:
- 从追踪检查器。 在原始模式下,请求正文或响应正文上的复制按钮会将完整的已解密正文复制到剪贴板,超出屏幕截断的部分也包括在内。标题中的 URL 是可选择的文本。这是将单次交互——完整的提示/响应对——取出以用于报告或提交缺陷的方式。
- 从 CLI。 将任何
trace子命令重定向到文件,例如bromure-cli trace summary my-workspace > audit.txt或bromure-cli trace ls my-workspace --limit 500 > requests.txt。这是一次性捕获许多请求的元数据线索的方式。 - 从磁盘。
traces/YYYY-MM-DD/下的元数据 JSONL 是纯文本(机密已涂抹为预览),可以直接读取。.enc正文文件使用 SecretsVault 主密钥进行 AES-GCM 密封,只能在应用内解密——请从检查器复制它们,而不要从磁盘取出。
什么永不离开你的 Mac
对于个人的、非托管的安装,追踪完全是本地的:
- 追踪写入到你 Mac 的 Application Support 目录,并使用你登录 Keychain 中持有的密钥加密。
- 没有任何追踪记录、正文或摘要会被上传到任何地方。代理服务器没有为个人用户接入分析端点。
- 同样馈送安全日志的提示注入分类器在设备上运行;参见提示注入检测与护栏。你的流量的任何信息都不会发送到云服务进行扫描。
上述涂抹和预览规则意味着即使是静态数据也永远不包含可用的机密。追踪是一份私密的审计日志,而不是"回传"。
私密模式与企业遥测
追踪衍生数据离开机器的唯一情况是使用 bromure.io 工作区注册的 Mac。注册将本地审计日志变成组织可见的日志——并为你提供一个开关,将单个工作区重新退出。管理员看到什么、以及注册如何运作,在企业版中有所涵盖;本节从追踪的角度描述该边界。
事件流
在注册的 Mac 上,会话会向组织的管理员工作区流式传输结构化的云事件,从追踪捕获的同一 AI 流量中提取:
llm.request——每次交互:提供商、主机、路径、状态、延迟、模型、输入/输出令牌计数,以及两个 Anthropic 缓存计数器(cache_creation_input_tokens、cache_read_input_tokens,即便从 SSE 流中也会解析;OpenAI 的cached_tokens也受支持)。tool.use——每次工具调用,输入摘要上限为 240 个字符。file.read/file.write——提取的路径和工具名称。command.run——shell 命令,上限为 500 个字符。credential.token_swap——每次传输中替换一次,仅预览。prompt_injection.detection——当检测器触发时转发,携带整个被标记的片段(上限 20 KB),不同于本地安全日志的 160 字符预览。
只会遍历最新的助手轮次,因此重新发送的历史绝不会被重复计算,且原始提示永不发出——遥测回答的是"AI 做了什么",而不是"用户问了什么"。
实时事件抽取
对于长期存活的 WebSocket 会话,如果等到套接字关闭才提取事件,会让管理员在整个会话期间失明。取而代之的是,一个实时事件抽取监视服务器帧,并在每个 response.completed 时发出相同的 llm.request / tool.use / file.read / file.write / command.run 事件,因此正在运行的 Realtime 会话会边进行边报告(此时会跳过关闭时提取以避免重复计算)。仅当工作区的追踪级别已为该主机捕获正文时,抽取才会附加——它搭载在与本章其他所有内容相同的正文捕获路径上,且没有自己的本地 UI。
私密模式
私密模式是追踪窗格上的一个按工作区开关,仅在注册的 Mac 上显示。启用后,该工作区停止向 bromure.io 工作区流式传输会话元数据和上述事件——无论是标题栏指示器还是管理员的会话列表都看不到来自它的任何内容。本地追踪和追踪检查器不受影响:你仍会在自己的机器上获得完整的加密追踪。
它的存在正是针对本地审计与组织遥测应当分道扬镳的情况——例如,你使用个人 API 密钥的工作区,而你不希望该活动出现在组织的仪表板中。在未注册的 Mac 上没有任何东西被流式传输,因此该开关会被完全隐藏。
注意: 私密模式也会抑制
prompt_injection.detection事件,因此在私密工作区上,注入仍会在本地的安全日志中记录(并根据你的检测动作执行),但不会转发给你的组织。开关本身参见追踪设置,注册流式传输什么参见企业版。