feat(audit): 每命令结构化审计日志 + 可插拔企业 sink(通用合规能力)#398
Conversation
a4ae3ea to
953d1a8
Compare
…se sink 面向所有部署 dws 的企业的通用合规审计能力:为每次命令调用产出一条 结构化审计记录,把员工经 dws 的操作留痕。遵循开源惯例,把"产生事件" 与"投递事件"分离: - 通道A 本地审计文件 <configDir>/logs/audit.jsonl(源头真相,operator 自有) - 通道B 转发到企业自有 sink(endpoint 由部署企业配,不写死厂商;转发前可脱敏) - 默认全关:不设 DWS_AUDIT_ENABLED 则零产出、热路径零影响 字段尽量不丢:time/trace_id、actor/org(token)、device(opt-in 含 sn_no)、 自然语言 intent(仅 agent 层能注入,标记 provenance 表不可验真)、 module/command/subcommand、子命令介绍与敏感度(catalog)、操作对象(参数)、 数据流向(推断)、outcome。 接入点为 executeInvocation 收口处的 defer,与既有 LogCommandEnd 并列。 新增 internal/audit(schema/sink/forwarder/device/config)+ docs/audit.md, 全部带测试:脱敏分档、本地+转发投递、设备指纹 opt-in 门控(darwin 实采 ioreg 验证)、配置注册、app 层端到端字段填充与 flow 分类。
953d1a8 to
edd30d3
Compare
…sion), defer forgeable env fields 按可信度分层:只记录不可被调用方伪造的字段。 - 新增 client 块:agent_id(identity.json 装机 id)、source、cli_version(编译注入), 以及 actor.user_id / org.corp_id(token 网关验签)——均不可 per-call 伪造。 - host_agent(DINGTALK_AGENT) / channel(DWS_CHANNEL) / agent_code 是调用方自报的 环境变量、可伪造,故先不记录;待网关回带签名 agent 凭证再加(见 docs TODO)。 - schema v2;脱敏:hashed 档哈希 agent_id,minimal 档仅留 cli_version 做运维维度。 - docs/audit.md:字段按可信/暂不上分类,补"日志去向/中心化收集"与 TODO 两节。 真实验证:dws minutes list mine 实跑,client.agent_id/source/cli_version 落盘, org.corp_id 来自真 token;故意注入 DINGTALK_AGENT=fake 不进审计。
…ward target examples/audit-ingest:dws 审计转发的最小参考接收端。 - 本地验证版(纯标准库):校验 Bearer + schema,落 JSONL,已端到端实测 (真 dws minutes 调用 → 转发 → ingest 收下落库)。 - README:阿里云 SLS 生产版(PutLogs 落 Logstore + 索引)、函数计算 FC 部署步骤、 SLS 控制台开通指引、数据边界提醒。 让运维方照此把 DWS_AUDIT_FORWARD_URL 指向自己的端点即可统一收集审计。
examples/audit-ingest 的任务(本地证明转发链路可通)已完成;作为 CLI 仓库里的 常驻代码它是噪音——收数据的服务端不该由 CLI 仓库承载。删除该目录,把真正有价值的 "接收端契约 + 阿里云 SLS/FC 接入步骤"并入 docs/audit.md,知识留下、toy 去掉。
…y-signed identity 新增 client.channel:来自 DWS_CHANNEL,记录"哪个 agent/渠道在调用" (OpenClaw / Qoder…)。定位为半可信——网关按 allowedChannels 白名单校验 membership(乱填渠道会被拒),但未做密码学绑定,已登记渠道间仍可冒充; minimal 脱敏档保留 channel 作为运维维度。 host_agent(DINGTALK_AGENT) / agent_code 仍是无校验纯标签、完全可伪造, 继续不记录。docs/audit.md 补"网关侧支持需求":签发与 token 绑定的签名 agent 凭证 + 调用回带 + 网关验签后回带已验证身份的接口契约草案,让 channel 升为完全可信、解锁 host_agent/agent_code。 真实验证:dws minutes list mine + DWS_CHANNEL=openclaw → client.channel=openclaw 落盘。
dws 操作审计日志:字段说明、接入方式与网关侧支持需求一、审计日志字段(schema v2)字段按可信度分级。可信字段来源于 token 校验、dws 自管状态或 dws 运行时实测,调用方无法在单次调用中伪造。 已记录字段
暂不记录字段: 二、接入方式审计能力默认关闭,通过环境变量按需开启:
接入方(如 OpenClaw、Qoder 等 Agent 宿主)在拉起 dws 进程时设置 三、网关侧支持需求能力目标:使审计记录中的「调用方 Agent / 渠道」身份达到不可伪造,从而支撑安全与合规归因,包括按渠道维度统计调用量与成功率、对指定渠道实施访问控制或封禁、以及在异常时定位真实接入方。 设计依据(为何须由网关侧实现):dws 运行于调用方环境并受其控制,凡 dws 可在本地读取的信息,调用方均可篡改(例如通过 需求项:
接口契约(草案)
网关能力就绪后,dws 侧将把 完整说明详见本 PR 内 |
Open-source repo convention: configmeta descriptions, struct-field comments, test fixtures and docs/audit.md are now English. No behavior change; audit tests still pass (redaction-boundary assertions updated to English sentinels).
…rmat Reframe the client-side audit as a best-effort LOCAL diagnostic/troubleshooting trail, not a mandatory compliance record — a user controls their own machine and can bypass it, so authoritative/mandatory audit belongs on the MCP gateway. Adds a 'Scope and limits' note up top and a gateway pointer in the collection section. Also make the file location explicit (default ~/.dws/logs/audit.jsonl, per-OS table, DWS_CONFIG_DIR override) and document the JSONL format choice with ready jq examples.
The single audit.jsonl grew unbounded. Switch to one file per calendar day (audit-YYYY-MM-DD.jsonl) via a stdlib DateRotatingWriter that rolls at midnight and prunes files older than DWS_AUDIT_MAX_AGE_DAYS (default 30; 0 = keep all). Works for both the short-lived CLI and long-running stdio mode. Docs updated; rotation + pruning covered by tests.
背景
通用企业合规审计能力:为每一次 dws 命令调用产出一条结构化审计记录,
让任何部署 dws 的企业都能把员工经 dws 的操作留痕。非某一客户专属。
设计:产生与投递分离(开源惯例)
<configDir>/logs/audit.jsonl:源头真相,operator 自己拥有、可grep。DWS_AUDIT_FORWARD_URL),不写死厂商默认。富审计数据是企业自己的合规资产,进企业自己的库,厂商不背数据责任。
DWS_AUDIT_ENABLED则零产出,热路径零影响。字段(尽量不丢,除非该层完全拿不到)
time / trace_id、actor·org(登录 token)、device(os 始终;device_id·sn_no 为 PIPL 个人信息,
opt-in 默认关)、自然语言 intent(仅 agent 层能注入,记录里标
provenance=agent表不可验真)、module·command·subcommand、子命令介绍与敏感度(catalog)、操作对象 id·名称(参数)、
数据流向 direction·api·本地路径·peer ids(推断)、outcome·err_class。
脱敏分档(仅作用于转发,本地文件始终全量)
none(企业自有信任域)/hashed(加盐可关联不可还原)/minimal(仅维度,供运维监控)。接入点
runner.go的executeInvocation收口defer,与既有LogCommandEnd并列;单点、低风险。验证
go build ./.../go vet全过。internal/audit:脱敏分档、本地+转发投递、设备指纹 opt-in 门控(darwin 实采 ioreg 验证 IOPlatformUUID/SerialNumber)、配置注册。internal/app:端到端emitAudit字段填充 + flow 分类(含 local-export / read)。DWS_AUDIT_*已注册进 configmeta。复现:
```bash
export DWS_AUDIT_ENABLED=true
export DWS_AUDIT_FORWARD_URL=https://audit.internal.example.com/dws
export DWS_AUDIT_FORWARD_TOKEN=
export DWS_AUDIT_DEVICE_FINGERPRINT=true # 需采集设备指纹时
dws minutes export --minute-id m-77 --output ~/Desktop/q2.md --format json
tail -n1 ~/.dws/logs/audit.jsonl | jq .
```
详见
docs/audit.md。后续(本 PR 未含)