Skip to content

Security and Privacy.zh CN

Saco Song edited this page Aug 14, 2026 · 6 revisions

安全与隐私

English · 首页

本页说明当前实现,不构成安全认证。启用远程功能前,请检查 provider 政策,并结合本机桌面的威胁模型作出选择。

数据流摘要

功能 离开本机的数据
local-cli ASR Voice Input 本身不会发起远程 ASR 请求。它会把临时 WAV 路径传给 /usr/bin/voxtype;该独立 backend 的行为取决于自身配置。
Qwen Realtime ASR PCM16 音频 chunk、语言/session control 和 model 选择会发送到配置的 Alibaba WebSocket endpoint。
Qwen Audio3 Streaming PCM16 音频 chunk、streaming control、配置词汇和可选的开始时 session 术语视图会发送到选定的 Audio3 WebSocket endpoint。
Qwen Audio3 Native 完整 WAV、可选 language hint 和配置词汇会发送到选定的 Audio3 Native endpoint。请求上限为 10 MiB。Native 请求不附加开始时 session 术语。
Qwen final pass 完整临时 WAV 会以 base64 data:audio/wav 形式发送到配置的 Alibaba-compatible HTTP endpoint。
Audio3 session 术语视图 开始录音时,Voice Input 会冻结当前聚焦 Kitty Pi/Codex session 中符合条件的术语。脱敏、Jieba 分词、去重、频率排序和截断均在本地完成。Audio3 只会在 run-task 中收到以换行分隔的最终术语,包括换行在内最多 400 字符。
Refinement 术语视图 启用 LLM refinement 时,同一份冻结 snapshot 会独立限制为 96 个术语和 1,500 字符,并随 transcript 发送。停止时的焦点只提供 destination style,以及是否请求 Agent Markdown。
LLM refinement Transcript、可选的 refinement 术语视图,以及 destination style/Agent Markdown 指令会发送到配置的 OpenAI-compatible /chat/completions endpoint。
Quickshell HUD / 输出 只使用本地 runtime state、Unix socket frame、clipboard command 和输入模拟。
Quickshell Settings 通过本地的带版本号 NDJSON 与专用 Rust child 通信。只有用户明确执行 Test LLM 时,程序才会访问配置的 LLM endpoint。

当前源代码不包含 telemetry 或 analytics client。网络流量来自用户配置的远程 ASR 和 LLM adapter。

原始 assistant message、术语频率、session path 和 window/desktop metadata 不会作为术语发送。高置信 ASCII 大小写/分隔符变体会在 Refine 前于本地归一化,并在 model 输出后再次于本地归一化。完整生命周期和限制见 Agent 上下文

Prompt 边界

Refinement prompt 把 model 定义为 transcript editor,而不是 assistant。Prompt 明确要求它只编辑 transcript,并把问题、请求和命令保留为听写文本——绝不回答、执行、讨论或采取行动。Agent Markdown 只改变格式,不改变该边界。

Session 术语会被标记为不可信、仅供词汇参考的数据。它不得被视为指令、事实、声明或权威。这可以降低 prompt injection 风险,但不能让外部 model 或 provider 变得可信。

麦克风持续时间

公开默认配置为:

[audio]
pre_roll_enabled = false

此时 pw-record 会在 dictation session 开始时启动,并在停止或取消时终止。启用 pre-roll 后,常驻 capture service 会在 daemon 整个生命周期内保持麦克风 stream,并在内存中保留较短的环形缓冲区。该功能可以减少开头音节被截断的情况,但会改变隐私边界,也可能让桌面麦克风指示器持续显示活动状态。

当前 session 的完整音频会保存在内存中,直到最终处理完成。本地、final-pass 和 Audio3 Native 识别会在操作系统临时目录中使用临时 WAV;Voice Input 不会有意归档录音。

Runtime state 与 diagnostics

Runtime snapshot 包含实时 transcript 数据,并可能在输出后继续保留原始/refined 文本、refinement 状态、输出目标 metadata、计时和缩短后的 tooltip transcript。默认位置为:

$XDG_RUNTIME_DIR/voice-input/state.json

标准 runtime directory 权限为 0700;state file、临时 state file 和承载私有数据的 runtime socket/file 使用 0600。Runtime 数据通常会随用户会话结束而消失。自定义 state_file 可能在该受保护目录之外创建持久副本;请自行保护其 parent 和文件,或者保留 auto

用于支持报告时,首选 schema 4 diagnostics:

voice-input diagnostics
voice-input diagnostics --format text
voice-input diagnostics --format json

Diagnostics 使用严格 allowlist。它会报告安全的配置选择、粗粒度 runtime/session state、stage 与 failure category、受限 identifier、计数、时长、delay/timestamp 聚合、重连总数、Native-mode decision 和所选结果 latency。它不包含 transcript、endpoint/host 值、model 名称、credential 或 key、术语、provider message、session path、window/app metadata 或 Agent source 内容。Provider error identifier 只能作为简短、已清理的 ASCII token 出现,绝不会包含 provider message。

不要分享 voice-input status 的输出;尤其绝对不要分享 voice-input status --format json --extended。Extended status 包含 transcript 字段。不要附加 state.json、waveform 数据、Pi/Codex JSONL、原始音频或未经检查的 journal。应优先使用 diagnostics,并在发布前仍然检查一次。

配置持久化

Settings QML 不能写入配置。它的 Rust child 独占加载、验证和序列化完整受支持配置的职责。Rust 会把每次加载绑定到一个不透明的精确源 revision;如果文件在加载后发生变化,Rust 会拒绝保存。成功写入时,配置目录权限为 0700,配置文件权限为 0600,并通过临时文件执行原子替换。这可以防止产生不完整文件,并降低并发编辑被意外覆盖的风险,但不能替代备份。

加密 credential

标准 service 声明了两个可选的加密 credential ID:

alibaba-api-key
openrouter-api-key

Settings 会把加密 blob 存储在:

${XDG_CONFIG_HOME:-$HOME/.config}/credstore.encrypted/

建议通过 Settings 输入 key,避免把 key literal 写入 shell history:

voice-input settings

新 key 使用 password input。QML 只会通过专用 child 继承的 stdin 发送该值;Rust 随后通过 stdin 把它传给 systemd-creds encrypt --user --name=<id>。Key 不会进入 TOML、process argument、环境变量、日志或 backend response。Backend response 只提供不包含 secret 的 credential metadata。加密 credential store 目录权限为 0700,每个 blob 的权限为 0600,并采用原子替换。

该界面只提供保留替换 credential,不提供删除功能。输入框留空表示保留。Save 和 Test LLM 提交 request 后会立即清空已经输入的 credential field。QML/JavaScript string 使用托管内存,因此清除引用只能尽力执行,无法保证内存立即归零。Test LLM 可以使用刚输入但不保存的 LLM key,也可以使用加密 credential store 中已有的值。

启动 service 时,systemd 会把选定的 credential 解密到 $CREDENTIALS_DIRECTORY;daemon 从该目录读取。仅使用本地功能时可以不配置 credential。加密 blob 仍然需要妥善保护;systemd credential 的保护能力取决于 host 和用户 credential 机制。

即使 api_base_url 指向其他 OpenAI-compatible provider,credential 名仍然是 openrouter-api-key。该 ID 只是实现名称,不代表程序验证了 provider 身份。

解析优先级

Daemon 启动时按以下顺序解析 key:

  1. systemd $CREDENTIALS_DIRECTORY
  2. VOICE_INPUT_ALIBABA_API_KEYVOICE_INPUT_OPENROUTER_API_KEY
  3. 从旧版配置接受的 legacy TOML 值。

公开示例没有 key 字段,序列化也会有意省略运行时 key。随附的长期运行 service 不应使用 legacy plaintext TOML 或环境变量。环境变量可能通过同一用户的 process inspection、诊断工具或 service config 暴露。

Agent 上下文的防护与限制

Agent 上下文是开始时不可变的术语 snapshot。Voice Input 会验证当前聚焦的 Kitty Pi/Codex process、session identity、canonical path、PID start time 和 file identity,然后最多读取 session 末尾 8 MiB,并选择最新完成的 assistant source。Secret pattern 脱敏和术语提取均在本地执行。

这些检查可以降低意外泄露;启发式脱敏无法识别每个 secret、个人信息、专有术语或新的 injection。处理敏感 session 或使用不可信 provider 时,请保持 agent_context_enabled = false。取消会尽可能阻止后续输出和工作,但不能撤销录音开始后已经在本地读取或已经发送的数据。

Clipboard 与合成输入

所有输出都会通过 clipboard 粘贴。在 Wayland 上,临时 transcript clipboard 和恢复的 clipboard payload 都会标记为 sensitive。Clipboard backup 会跳过敏感 metadata MIME x-kde-passwordManagerHint,并且只捕获一个选定的非敏感-metadata MIME payload。

该保护仅对兼容的 Wayland clipboard manager 有效。X11/XWayland 没有同等的 sensitive-metadata 保证。在 clipboard 被替换期间,其他同一用户的 clipboard client 可以观察 transcript。Owner 变化、不支持的 MIME type 或 helper failure 也可能导致无法完整恢复。

Clipboard backup 使用私有临时文件。成功恢复后会删除,但 crash 或强制终止可能在临时目录中留下敏感 backup 残留。应据此保护临时目录和 crash artifact。

外部 process 与错误

输出 helper 和本地 ASR backend 都使用明确 deadline 和输出大小上限。程序会并行排空 stdout/stderr,而不是先等待其中一个 stream;timeout cleanup 会终止 helper process group。面向用户的 error 会被清理,不包含捕获的 clipboard 内容、transcript、provider stderr 或无上限的 child output。

这些控制可以限制 hang、内存增长和意外内容传播,但不能让不可信 executable 变得安全。请保持配置的 executable path 明确,并分别审计 /usr/bin/voxtype、clipboard tool、compositor tool 和任何自定义 command。

实用安全检查清单

  • 在确实需要前,保持 pre-roll、远程 ASR、final pass、LLM 和 Agent 上下文关闭。
  • 使用加密 systemd credential,并保留目录 0700 / 文件 0600 权限。
  • 保留明确的 /usr/bin/voxtype 路径,并单独检查该 backend。
  • 限制自定义 state path 的权限;不要把 state 持久化到同步目录或公开目录。
  • 假设 clipboard manager、临时 backup file 和同一用户的 process 可以看到 paste payload。
  • 使用可信的 HTTPS/WSS endpoint 和 model;endpoint 字段完全由用户控制。
  • voice-input diagnostics --format json 收集支持信息。绝不分享 status/extended 输出、state file 或未经检查的 journal。

另请参阅:配置参考 · 故障排查

Clone this wiki locally