Replies: 1 comment 1 reply
|
@jkt-check 你的两个堵点我在 R1 —— 工具参数执行前改写: 确认无 seam
一个值得注意的语义细节: 参数早在 R2 —— 助手文本展示前改写: 确认无 seam
关联点: 同源第 3 个 gap 可一并考虑R1 堵点其实还附带一个出站打码缺口: 模型合理回显进工具参数里的密钥会未打码落入持久化日志。你说的"同一个 seam 可以解决"成立。若维护者要为 R1 开 seam, 建议同时把"打码 logged copy"(执行复制用还原值, 落盘复制用令牌/打码值)纳入——这比只做执行前还原更完整。 与此相关, 我维护的 补充一个我源级看到的边界: 总之: R1/R2 的缺失是真实的、源级可证的。你的提案把 vault/tokenization 留给插件、只索要两个 rewrite seam, 边界清晰, 是健康的插件面扩展。我支持。 |
Uh oh!
There was an error while loading. Please reload this page.
English
Title: Plugin seams for reversible secret tokenization — tool-argument rewriting and assistant-text restore
Who
We maintain
dsh-secret-scrub, a dsh plugin that rewrites text on its way to the session log and the model: secret-shaped fragments (API keys, tokens, private key blocks, PII) are replaced irreversibly with[REDACTED:<category>]placeholders. It works entirely through the published plugin events (agent/pre-step,tools/post-execute,tools/ptc-dispatch-log).The use case
Users want the model to complete tasks that involve their secrets — write a config file containing the real API key, construct an authenticated
curlcommand, fill in a.env— without the real values ever reaching the model or the durable session log.The standard pattern for this is vault tokenization:
sk-ant-api03-…becomes a different, well-formedsk-ant-api03-…), recording the token → real-value mapping in a local, in-memory, session-scoped vault that never leaves the machine.write_file(content="…token…")writes the real value to disk;What works today
Outbound rewriting is well covered by the existing waterfalls:
agent/pre-step(admitted user messages),tools/post-execute(accepted tool results), andtools/ptc-dispatch-log(the durable copy ofrun_codesub-dispatches). Our plugin already does the tokenization half on these seams.What is missing — two blockers
Neither restore point is reachable from a plugin today:
Tool-call arguments cannot be rewritten before execution.
PreToolDecisionisallow | deny | askonly, and the type documentation states the exclusion explicitly: "Input rewriting is excluded because arguments are already logged and presented." The around-dispatchtools/executewaterfall "may change onlyexec.signal, while call identity remains immutable." So awrite_filecall carrying a token executes with the token verbatim.Assistant text cannot be rewritten before display.
Session events are append-only and deep-frozen;
session/eventis emit-only, and theagent/requestwaterfall "cannot mutate messages." There is no seam on the presentation path between the model's emitted text and what the user sees.A related outbound gap shares blocker 1: tool-call arguments also cannot be scrubbed today — a secret the model legitimately echoes into a tool call lands in the durable log unredacted. The same seam would let plugins redact the logged copy.
Requests
PreToolDecisionvariant such as{ kind: 'allow', args }, or a dedicated waterfall positioned after the original call is logged/presented and before the body dispatches. This placement has a clean security story: the durable log and the presented call keep the tokenized arguments, while the tool body receives the restored values. Call identity, signal re-fusion, scope filtering, and listener-failure containment can all be preserved unchanged.Non-goals
We are not asking dsh to implement the vault, the tokenization, or any secret handling — only the two rewrite seams. The plugin owns the mapping and its security invariants (memory-only, session-scoped, never logged).
We are happy to prototype either seam and share the branch.
中文
标题: 可逆密钥令牌化所需的插件接缝 —— 工具参数改写与助手文本还原
我们是谁
我们维护着 dsh 插件
dsh-secret-scrub:它在文本进入会话日志和模型请求之前做不可逆打码,把密钥形态的片段(API key、token、私钥块、PII)替换为[REDACTED:<category>]占位符。插件完全基于已发布的插件事件(agent/pre-step、tools/post-execute、tools/ptc-dispatch-log)实现。使用场景
用户希望模型完成涉及真实密钥的任务——把真实 API key 写进配置文件、构造带凭证的
curl命令、填写.env——但真实值永远不进入模型上下文和持久化会话日志。标准做法是令牌化(vault tokenization):
sk-ant-api03-…换成另一个合法形态的sk-ant-api03-…),令牌 → 真实值的映射记录在本机内存中的会话级 vault 里,永不出机。write_file(content="…令牌…")落盘的是真实值;目前已可行的部分
出站改写已被现有 waterfall 良好覆盖:
agent/pre-step(准入的用户消息)、tools/post-execute(被接受的工具结果)、tools/ptc-dispatch-log(run_code子调度的持久化副本)。我们的插件已经在这些接缝上完成了令牌化的一半。缺失的部分 —— 两个堵点
两个还原点目前都无法从插件触达:
工具调用参数无法在执行前改写。
PreToolDecision只有allow | deny | ask,类型注释明确写着排除原因:"Input rewriting is excluded because arguments are already logged and presented." 环绕执行的tools/executewaterfall 也声明 "may change onlyexec.signal, while call identity remains immutable"。携带令牌的write_file调用会原样带着令牌执行。助手文本无法在展示前改写。
会话事件是 append-only 且深冻结的;
session/event是只读观察(emit 模式);agent/requestwaterfall "cannot mutate messages"。模型输出文本与用户可见内容之间的展示链路上没有任何接缝。一个相关的出站缺口与堵点 1 同源:工具调用参数目前也无法被打码——模型合理回显进工具参数里的密钥会未打码地落入持久化日志。同一个接缝可以解决这个问题。
请求
PreToolDecision增加{ kind: 'allow', args }变体,或提供一个专用 waterfall,位置在原始调用被记录/展示之后、工具体执行之前。这个位置的安全语义很干净:持久化日志和展示层保留令牌化参数,工具体拿到还原后的真实值。调用身份不可变、signal 重融合、scope 过滤、监听器失败隔离等现有保证都可以原样保留。非目标
我们不要求 dsh 实现 vault、令牌化或任何密钥处理逻辑——只需要这两个改写接缝。映射表及其安全不变量(仅内存、会话级、永不落日志)由插件自己负责。
我们乐意就任一接缝提供原型实现。
All reactions