Repository navigation
finding(core): ObjectLogger 的脱敏表按子串匹配,一个叫 keys 的普通字段会被整块换成 ***REDACTED*** #5573
Copy link
Copy link
Closed
Labels
Description
Activity
分诊(域改标 + 发现分诊轮判级):
- 域:摘
domain:core换domain:engine-core——packages/core按 docs(pm-dispatch): 协调模型改版 —— 分诊/执行纵向拆分 + 一人一车道双射 + 登记表正文即真相 + 座位 Routine 化 (#5472) #5522 域表归 engine-core;domain:core不是任何车道的标签(座位表无此行、无消费方),建议删除该 label 防再吸附(单一生产者纪律:domain:*只由分诊座位产出)。 - 判级:持有(留
finding)。理由:全仓现无 in-tree 调用命中(bug(service-automation): flow 绑定失败的告警把 Zod issue 数组塞进单行日志,读者只拿到一个孤零零的[#5048 的临界点已在 PR fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572 里绕开并钉 pin),今日无用户撞上;而 A/B/C/D 动的是安全相关的脱敏默认语义,属维护者拍板面,不由顺手 finding 决定 —— 正文自己的判断正确。重启条件:出现第一个 in-tree / host 侧命中,或维护者集中裁决脱敏语义时随批晋级为needs-user-decision(正文对 A 词边界的论证届时直接可用)。
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- 域:摘
维护者裁决(2026-08-06,经 services 车道 PM 转达):批准 A 案(词边界匹配)
redactSensitive由子串includes改为 camelCase/snake_case 分词后的词边界匹配:key匹配apiKey/api_key,不匹配keys/monkey/keyword。硬性验收条件(裁决的一部分):
- 落地 PR 必须带真秘密拼法矩阵守卫测试 ——
apiKey/api_key/accessToken/refresh_token/secretKey/privateKey/clientSecret等全数仍被脱敏(词边界不得漏真秘密); - 把
keys/keyword/tokens/monkey钉为不脱敏(本单的症状面); packages/spec/src/system/logging.zod.ts:71的 schema 默认表若需同步,按契约面申报。
摘
finding换pm:queue,domain:engine-core座位执行(PR #5572 的 pin 测试「原样转发会被脱敏」届时按条改判)。
Generated by Claude Code
- 落地 PR 必须带真秘密拼法矩阵守卫测试 ——
认领(PM 会话 session_01V7WetGmnfoXNn8cLieKKmx,
domain:engine-core车道):pm:queue→pm:dispatched,即将派发 os-dev。- 分支:
claude/issue-5573-redact-word-boundary - worktree:
../objectstack-5573 - 文件面:
packages/core/src/logger.ts(redactSensitive)+ 同包测试 + changeset;另按维护者裁决(评论 5199145168)允许触碰 PR fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572 落的那个「原样转发会被脱敏」pin 测试所在文件(仅改判该 pin 的断言,以裁决为据,无论其在哪个包)。 - 修法照维护者批复的 A 案:子串
includes改为 camelCase/snake_case 分词后的词边界匹配。硬性验收(裁决原文):真秘密拼法矩阵(apiKey/api_key/accessToken/refresh_token/secretKey/privateKey/clientSecret等)全数仍脱敏;keys/keyword/tokens/monkey钉为不脱敏;默认表本身不动。若实现中发现packages/spec/src/system/logging.zod.ts需同步,停下申报,不自行改 spec。
竞态复查与派发随后。
Generated by Claude Code
- 分支:
- added a commit that references this issue
on Aug 6, 2026 PM 评审(会话 session_01V7WetGmnfoXNn8cLieKKmx):PR #5786 ACCEPT,附一条小指令,完成后待 CI 绿放行。
已读全量 diff。要点:
- A 案实现合格且硬性验收全数满足:42 条真秘密矩阵(camelCase/snake/SCREAMING/kebab/连写/复合复数)仍脱敏;14 条症状面(含裁决点名的
keys/keyword/tokens/monkey)不再脱敏;默认表与 spec schema 默认值未动。 - 两个边角的取舍我认可:连写救援用显式限定词表(31 词、只认后缀)而非「以 key 结尾」——正确识别了任何区分
apikey/monkey的规则都必须编码词法知识,且方向比 B 案保守(漏一个限定词只回到词边界基线);复数按「复合命中、裸词放行」,裸passwords/secrets的推论后果与tokenCount词义残留都钉成测试并点名属维护者面,不越权收窄。 - 额外价值:证实了一个活的 in-tree 命中(
dispatcher-plugin.ts的keyedBy当年改名躲子串仍被吃),本 PR 后该限流日志首次真正可读——issue 的「无 in-tree 命中」前提被推翻,修复的实际收益上调。 - pin 改判符合裁决授权且翻到正面断言(
visibleIf逐字出现 +issues结构相等),比「没产出所以过了」强;模块 docblock 第二条理由(有界性)正确保留。 - 反向验证 17 红全落症状面、42 绿矩阵不动,方向先判后跑;「多词 pattern 转红」如实标注为净增覆盖。
小指令(裁决你的请示项):
thrown-cause-diagnostics.ts模块 docblock 第一条 bullet(仍描述子串脱敏旧机制)就地订正——一句话改动、纯注释,文件面扩展由本裁决背书;追加一次提交即可,PR 正文的⚠️ 段落改为「已按 PM 裁决订正」。
Generated by Claude Code
- A 案实现合格且硬性验收全数满足:42 条真秘密矩阵(camelCase/snake/SCREAMING/kebab/连写/复合复数)仍脱敏;14 条症状面(含裁决点名的
- added a commit that references this issue
on Aug 6, 2026
在做 #5048(PR #5572)时实测发现,顺手记录。
现象
packages/core/src/logger.ts的redactSensitive递归遍历 meta,判定条件是子串包含:默认脱敏表(
logger.ts:97,与packages/spec/src/system/logging.zod.ts:71的 schema 默认值一致)是['password', 'token', 'secret', 'key']。于是任何名字含这些子串的字段都会被整块替换,不问值是什么:keys(含key)keyword/keywords、keyboard、monkeytokenizer、tokens(计数!)secretary实测(
format: 'json',值是一个普通的字符串数组):keys里根本没有秘密,但读者拿到的是***REDACTED***—— 而且这个字样会让读者以为确实有一个秘密被挡住了,比字段缺失更误导。为什么是 finding 而不是 bug
全仓 grep 过,目前没有任何 in-tree 的
logger.*调用在 meta 里放这类字段名(#5048 差点成为第一个 —— 那条路已经在 PR #5572 里绕开了:字段改名叫unrecognized,并写了 pin 测试固定「原样转发会被脱敏」这个事实)。所以今天没有用户会撞上,归观察类。但
ObjectLogger是公开导出的,redact也是LoggerConfig的公开配置项,host 侧插件自己写logger.info(..., { keys: [...] })就会撞上,而且撞上时是静默的 —— 没有任何提示说脱敏器动过手。取舍(不预设结论)
子串匹配不是笔误,它是为了一网打尽
apiKey/secretKey/privateKey/accessToken这些真实拼法 —— 换成精确匹配会漏掉它们,那更危险。所以这不是「改成 equals 就好」,而是需要维护者定一个方向,几个选项:key匹配apiKey/api_key(camelCase / snake_case 分词后是独立词),但不匹配keys/monkey。能同时保住覆盖面和精度,实现是分词而不是includes。keys、keyword、…)。便宜,但例外表永远追不齐,是治症状。keys: [...],但apiKeys: ['sk-…']就漏了 —— 方向不对。倾向 A(词边界),因为它在「不漏真秘密」和「不吃普通字段」之间不用二选一;但这动的是脱敏语义,属于安全相关默认值,不该由一个顺手的 finding 决定 —— 留给维护者。
影响面
packages/core/src/logger.ts:159-171(redactSensitive)、默认表在:97和packages/spec/src/system/logging.zod.ts:71。[#5048 / PR fix(service-automation): flow 绑定失败的告警改用结构化 meta,不再把 Zod issue 数组塞进单行日志 (#5048) #5572(实测来源,并在那里以改字段名的方式绕开)。Generated by Claude Code