Component
sight
Bug Description
agentsight dashboard 新增的"设置"页(SettingsPage.tsx,UI 文案 "管理 Dashboard 的全局配置。")允许用户为优化分析功能配置 LLM provider / API Key / Base URL / Model。后端把 api_key 以明文 JSON 写入 /var/log/sysak/.agentsight/optimization_config.json,只通过 chmod 0o600 限制 owner-only 读/写,没有任何加密保护。
文件权限 0o600 只能阻挡非 root 用户的直接 cat,但在以下场景里都失效:
root 用户本机任何进程都可以读到明文 key(agentsight 自己就是 root 跑的,所有 root 进程共享 read 权限)
系统备份 / 日志采集 / 配置管理工具(Ansible / Puppet / scp / rsync)在打包 /var/log/sysak/ 时把明文 key 一并带走,落盘到备份中心 / jump host / 镜像仓库
root 权限被入侵后(apt/cron/服务漏洞),cat /var/log/sysak/.agentsight/optimization_config.json 一行就能拿到 LLM API Key,无声无息
文件被误 chmod / cp / tar 后丢失权限保护,明文 key 进入共享介质
ECS 快照 / 镜像制作时把含明文 key 的文件打进镜像,分发给其他用户
跟 #1658 (cosh-ng ~/.copilot-shell/config.toml 明文存储 api_key / access_key / security_token)是同类问题但不同组件 —— #1658 修了 cosh-ng 的明文存储,但 agentsight dashboard 这个新加的"设置"页又把同样的问题引入了一份,没有走统一 secret store。
转正阻断场景:agentsight 作为 eBPF 观测工具默认以 root 跑、装在测试机 / 镜像里,用户在 dashboard 配了真实可计费的 LLM API Key(DashScope / OpenAI / DeepSeek 等),key 以明文落盘到 /var/log/sysak/.agentsight/optimization_config.json。一旦该机器被共享 / 被入侵 / 被备份外带,API Key 就泄漏,产生计费损失。
Steps to Reproduce
ssh root@< ECS-IP> # 授权测试机,读者自行替换
# 1. 已装 agentsight(RPM 0.9.0+)
rpm -q agentsight
# 2. 启动 agentsight serve(默认监听 0.0.0.0:7396)
systemctl start agentsight
# 或:agentsight serve &
# 3. 在浏览器打开 dashboard http://<ECS-IP>:7396/
# 进入"设置"页(路径 /settings 或侧栏 ⚙️ 设置)
# 在 "LLM 配置" 表单里:
# 云服务商 选 阿里云 DashScope
# API Key 输入 sk-<真实 key>
# 模型 选 qwen3-max 或自定义
# 点 "保存配置"
# 页面提示 "✓ 配置已保存并生效"
# 4. 在 ECS 上 cat 配置文件,直接看到明文 key:
cat /var/log/sysak/.agentsight/optimization_config.json
# 期望:api_key 字段是加密的密文 / 在 keyring 里 / 不出现在文件中
# 实际:api_key 字段就是用户输入的明文 sk-<真实 key>
# 5. 验证文件权限(确实是 0o600 owner-only,但这只挡非 root 用户):
stat -c ' %a %U:%G %n' /var/log/sysak/.agentsight/optimization_config.json
# 输出:600 root:root /var/log/sysak/.agentsight/optimization_config.json
# 6. 模拟 root 进程读 key(本机 root 任何进程都能读):
head -c 100 /var/log/sysak/.agentsight/optimization_config.json
Actual Behavior
实测(2026-07-28 授权测试机,已 redact 真实 API Key / ECS IP):
[root@<INTERNAL-HOST> ~]# rpm -q agentsight
agentsight-0.9.0-1.alnx4.x86_64
[root@<INTERNAL-HOST> ~]# systemctl status agentsight | head -3
● agentsight.service - AgentSight - eBPF-based AI Agent Observability Tool
Loaded: loaded (/usr/lib/systemd/system/agentsight.service; enabled; preset: disabled)
Active: active (running) since Tue 2026-07-28 14:21:30 CST; 9min ago
[root@<INTERNAL-HOST> ~]# ss -tlnp | grep 7396
LISTEN 0 1024 0.0.0.0:7396 0.0.0.0:* users:(("agentsight",pid=15990,fd=21))
[root@<INTERNAL-HOST> ~]# ls -la /var/log/sysak/.agentsight/optimization_config.json
-rw------- 1 root root 155 Jul 28 14:24 /var/log/sysak/.agentsight/optimization_config.json
[root@<INTERNAL-HOST> ~]# cat /var/log/sysak/.agentsight/optimization_config.json
{
"api_key": "<REDACTED-API-KEY>",
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"model": "qwen3-max"
}
[root@<INTERNAL-HOST> ~]# stat -c '%a %U:%G %n' /var/log/sysak/.agentsight/optimization_config.json
600 root:root /var/log/sysak/.agentsight/optimization_config.json
文件权限 -rw-------(0o600)正确生效,但 cat 直接出明文。base_url 和 model 是非敏感配置项,明文存储无问题;问题在 api_key 字段明文。
Expected Behavior
API Key 应该满足下列任一保护方式,不能直接以明文 JSON 字段落盘:
OS keyring 存储 (Linux 上用 keyutils / Secret Service / kernel keyring,key 文件只存 keyring handle,不存明文)
可逆加密 + 密钥派生自机器绑定信息 (machine ID + TPM / KMS / 至少 AES-GCM with key from /etc/machine-id + per-install salt)
统一 secret store (anolisa 全家桶共享一份加密的 secret store,不在各组件各自维护明文 config)
最低限度:对称加密 + key 文件单独 0o400 (比当前 0o600 多一层,但仍是软件层加密,key 在磁盘上)
按 #1658 的修复方向(cosh-ng config.toml 明文 → 加密),agentsight dashboard 这个新加的"设置"页应该走同样的加密路径,而不是又造一份明文存储。
POST /api/optimize/config 返回值里的 api_key 字段已经做了脱敏 (首 6 + •••• + 末 4 字符,见 optimize.rs:85-97 masked_api_key),GET 同样返回脱敏值。这说明设计者已经意识到 API Key 是敏感字段,但只做了传输层脱敏,没做存储层加密 —— 这两个层的处理不对等。
Root Cause
已确认根因 (代码层面已静态定位):
src/agentsight/src/server/optimize.rs:48-59 的 save() 函数只 chmod 0o600,不加密 :
fn save ( & self , path : & Path ) -> std:: io:: Result < ( ) > {
let json =
serde_json:: to_string_pretty ( self ) . map_err ( |e| std:: io:: Error :: other ( e. to_string ( ) ) ) ?;
std:: fs:: write ( path, json) ?;
// Config contains an API key — restrict to owner.
#[ cfg( unix) ]
{
use std:: os:: unix:: fs:: PermissionsExt ;
let _ = std:: fs:: set_permissions ( path, std:: fs:: Permissions :: from_mode ( 0o600 ) ) ;
}
Ok ( ( ) )
}
serde_json::to_string_pretty(self) 直接把 OptLlmConfig.api_key: Option<String> 序列化为明文 JSON,写入磁盘,然后 chmod 0o600 —— 这是对文件权限 的保护,不是对内容 的加密。
src/agentsight/src/server/optimize.rs:30-38 OptLlmConfig struct 里 api_key 是 Option<String> ,存储的是明文,没有任何 marked-for-encryption 的标记 / 包装类型。serde 直接序列化 String 字段就是明文。
缺少 secret store 抽象 :agentsight 的 server/auth.rs 里有 DashboardAuth 写 .dashboard_token 文件,也是明文存储(但 dashboard_token 是服务自己生成的随机 token,泄漏后影响范围限于 dashboard 访问,跟 API Key 的计费损失不可类比)。agentsight 没有"敏感凭据统一加密存储"的模块,每个新加的 secret 字段都各自走"明文 + chmod 0o600"的捷径。
Suggested Fix
按优先级:
方向 A(推荐,根治)—— 用 OS keyring 存储 API Key
修改 OptLlmConfig::save() 和 OptLlmConfig::load():
把 api_key 字段从 config 文件里移除,改存到 Linux kernel keyring(keyutils)或 Secret Service(D-Bus)
config 文件里只保留 base_url / model 等非敏感字段
keyring key 用 agentsight.optimize.<base_url> 或类似 namespace 派生
跨用户 / 跨容器场景 keyring 不可用时,fallback 到方向 B
Linux keyring 是最干净的方案:key 永远不出现在磁盘上,只有持有 keyring perm 的进程能 read。Linux 内核自带 keyutils,无需额外依赖。
方向 B(配套,fallback)—— 可逆加密 + 密钥派生自 machine-id
如果 keyring 不可用(如容器 / 无 loginuid 场景),用 AES-GCM 加密 api_key,密钥派生自 /etc/machine-id + per-install salt(首次随机生成存到 /var/log/sysak/.agentsight/.secret_salt 0o400):
加密后 api_key 字段值是 enc:<base64-ciphertext>,不再是明文
即使文件被 cp 出去,没有 machine-id 也解密不了
machine-id 是机器绑定的,跨机器迁移时 key 自动失效(用户需要重新配,符合预期)
这是 #1658 的同类修复方向(cosh-ng config.toml 加密),agentsight dashboard 应该走同样路径,甚至共享同一份加密实现。
方向 C(长期)—— 统一 anolisa 全家桶 secret store
anolisa 的多个组件(cosh-ng / agentsight / 未来其他)都有"用户配 API Key"的需求,各自走"明文 + chmod 0o600"的捷径,会反复踩同一个坑。长期应该有一个统一的 secret store 模块:
统一加密 / 解密接口
统一存储位置(如 /etc/anolisa/secrets/ 或 ~/.local/share/anolisa/secrets/)
统一 keyring fallback 策略
各组件的 config 文件里只存非敏感字段,敏感字段走 secret store
这条最难但最干净,可以分阶段推进(先抽 agentsight 的 secret store 模块,再推广到 cosh-ng / 其他)。
方向 D(防御性,短期)—— 文档警告 + 配置项开关
短期补救:在 dashboard 设置页 + README + agentsight.json 配置文档里明确警告 "API Key 以明文存储于 /var/log/sysak/.agentsight/optimization_config.json,请确保该文件不被共享 / 备份 / 入侵",并加配置项 optimization.api_key_storage = "plaintext" | "keyring" | "encrypted" 让用户能选存储方式(默认 plaintext 保持兼容,推荐 keyring)。
Environment
OS: Alibaba Cloud Linux 4.0.3 (Agentic Edition), kernel 6.6.102-6.2.alnx4.x86_64
Component version: agentsight 0.9.0
Package/RPM: agentsight-0.9.0-1.alnx4.x86_64
文件路径: /var/log/sysak/.agentsight/optimization_config.json(默认 storage_base_path = /var/log/sysak/.agentsight,见 src/agentsight/src/config.rs:1355-1356)
文件权限: -rw-------(0o600,owner-only read/write)
Additional Context
复现稳定性: 用户授权用静态代码 review + ECS 实测验证提交 issue,未跑新一轮 3 次稳定复现(本 bug 是存储设计问题,不是运行时 flaky)。证据来自 2026-07-28 授权测试机的 agentsight 0.9.0 实测:文件权限 -rw------- + cat 直接出明文 api_key
影响面: 任何在 agentsight dashboard 设置页配过 LLM API Key 的用户都受影响。agentsight 是 eBPF 观测工具默认 root 跑,装在测试机 / 镜像里,用户配置真实可计费的 LLM API Key(DashScope / OpenAI / DeepSeek / 智谱 / Moonshot)后,明文 key 落盘到 /var/log/sysak/.agentsight/optimization_config.json。一旦该机器被共享 / 被备份外带 / 被入侵,key 就泄漏,产生计费损失
相关 issue: [cosh-ng] bug: ~/.copilot-shell/config.toml 把 api_key / access_key / security_token 等敏感凭据明文存储,原 settings.json 是密文(安全回归) #1658 (CLOSED,[cosh-ng] bug: ~/.copilot-shell/config.toml 把 api_key / access_key / security_token 等敏感凭据明文存储,原 settings.json 是密文(安全回归))—— 同类问题但不同组件(cosh-ng vs sight),[cosh-ng] bug: ~/.copilot-shell/config.toml 把 api_key / access_key / security_token 等敏感凭据明文存储,原 settings.json 是密文(安全回归) #1658 修了 cosh-ng 的明文存储,但 agentsight dashboard 这个新加的"设置"页又把同样的问题引入了一份,没有走统一 secret store。本 issue 建议复用 [cosh-ng] bug: ~/.copilot-shell/config.toml 把 api_key / access_key / security_token 等敏感凭据明文存储,原 settings.json 是密文(安全回归) #1658 的加密实现,或在方向 C 里统一抽 secret store 模块
相关 issue: [cosh-ng] bug: WriteFileTool 静默写入字面 '<redacted>' 占位符且报 success — 用户 prompt 中 secret 经 redaction 替换后 LLM 无法还原真值,'LLM 写 secret 到文件'的 skill 工作流必然失败 #1716 (CLOSED COMPLETED,[cosh-ng] bug: WriteFileTool 静默写入字面 '<redacted>' 占位符且报 success)—— 反映 cosh-ng 在 user→LLM 边界做了 redaction 但在持久化边界没做加密,是同一类"传输层脱敏 vs 存储层明文"不对等问题的另一面。本 issue 是 agentsight 自己的"传输层脱敏(POST 返回 masked api_key)+ 存储层明文"不对等
用户提供的真实 ECS IP / hostname 已在 issue 正文中替换为 <ECS-IP> / <INTERNAL-HOST> 占位符;真实 API Key 替换为 <REDACTED-API-KEY>;无其他敏感凭据出现在正文中
Component
sight
Bug Description
agentsight dashboard 新增的"设置"页(
SettingsPage.tsx,UI 文案 "管理 Dashboard 的全局配置。")允许用户为优化分析功能配置 LLM provider / API Key / Base URL / Model。后端把 api_key 以明文 JSON 写入/var/log/sysak/.agentsight/optimization_config.json,只通过chmod 0o600限制 owner-only 读/写,没有任何加密保护。文件权限 0o600 只能阻挡非 root 用户的直接
cat,但在以下场景里都失效:/var/log/sysak/时把明文 key 一并带走,落盘到备份中心 / jump host / 镜像仓库cat /var/log/sysak/.agentsight/optimization_config.json一行就能拿到 LLM API Key,无声无息chmod/cp/tar后丢失权限保护,明文 key 进入共享介质跟 #1658(cosh-ng
~/.copilot-shell/config.toml明文存储 api_key / access_key / security_token)是同类问题但不同组件 —— #1658 修了 cosh-ng 的明文存储,但 agentsight dashboard 这个新加的"设置"页又把同样的问题引入了一份,没有走统一 secret store。转正阻断场景:agentsight 作为 eBPF 观测工具默认以 root 跑、装在测试机 / 镜像里,用户在 dashboard 配了真实可计费的 LLM API Key(DashScope / OpenAI / DeepSeek 等),key 以明文落盘到
/var/log/sysak/.agentsight/optimization_config.json。一旦该机器被共享 / 被入侵 / 被备份外带,API Key 就泄漏,产生计费损失。Steps to Reproduce
Actual Behavior
实测(2026-07-28 授权测试机,已 redact 真实 API Key / ECS IP):
文件权限
-rw-------(0o600)正确生效,但cat直接出明文。base_url 和 model 是非敏感配置项,明文存储无问题;问题在 api_key 字段明文。Expected Behavior
API Key 应该满足下列任一保护方式,不能直接以明文 JSON 字段落盘:
按 #1658 的修复方向(cosh-ng config.toml 明文 → 加密),agentsight dashboard 这个新加的"设置"页应该走同样的加密路径,而不是又造一份明文存储。
POST
/api/optimize/config返回值里的api_key字段已经做了脱敏(首 6 + •••• + 末 4 字符,见optimize.rs:85-97masked_api_key),GET 同样返回脱敏值。这说明设计者已经意识到 API Key 是敏感字段,但只做了传输层脱敏,没做存储层加密 —— 这两个层的处理不对等。Root Cause
已确认根因(代码层面已静态定位):
src/agentsight/src/server/optimize.rs:48-59的save()函数只chmod 0o600,不加密:serde_json::to_string_pretty(self)直接把OptLlmConfig.api_key: Option<String>序列化为明文 JSON,写入磁盘,然后chmod 0o600—— 这是对文件权限的保护,不是对内容的加密。src/agentsight/src/server/optimize.rs:30-38OptLlmConfigstruct 里api_key是Option<String>,存储的是明文,没有任何 marked-for-encryption 的标记 / 包装类型。serde 直接序列化 String 字段就是明文。缺少 secret store 抽象:agentsight 的
server/auth.rs里有DashboardAuth写.dashboard_token文件,也是明文存储(但 dashboard_token 是服务自己生成的随机 token,泄漏后影响范围限于 dashboard 访问,跟 API Key 的计费损失不可类比)。agentsight 没有"敏感凭据统一加密存储"的模块,每个新加的 secret 字段都各自走"明文 + chmod 0o600"的捷径。Suggested Fix
按优先级:
方向 A(推荐,根治)—— 用 OS keyring 存储 API Key
修改
OptLlmConfig::save()和OptLlmConfig::load():api_key字段从 config 文件里移除,改存到 Linux kernel keyring(keyutils)或 Secret Service(D-Bus)base_url/model等非敏感字段agentsight.optimize.<base_url>或类似 namespace 派生Linux keyring 是最干净的方案:key 永远不出现在磁盘上,只有持有 keyring perm 的进程能 read。Linux 内核自带 keyutils,无需额外依赖。
方向 B(配套,fallback)—— 可逆加密 + 密钥派生自 machine-id
如果 keyring 不可用(如容器 / 无 loginuid 场景),用 AES-GCM 加密 api_key,密钥派生自
/etc/machine-id+ per-install salt(首次随机生成存到/var/log/sysak/.agentsight/.secret_salt0o400):enc:<base64-ciphertext>,不再是明文这是 #1658 的同类修复方向(cosh-ng config.toml 加密),agentsight dashboard 应该走同样路径,甚至共享同一份加密实现。
方向 C(长期)—— 统一 anolisa 全家桶 secret store
anolisa 的多个组件(cosh-ng / agentsight / 未来其他)都有"用户配 API Key"的需求,各自走"明文 + chmod 0o600"的捷径,会反复踩同一个坑。长期应该有一个统一的 secret store 模块:
/etc/anolisa/secrets/或~/.local/share/anolisa/secrets/)这条最难但最干净,可以分阶段推进(先抽 agentsight 的 secret store 模块,再推广到 cosh-ng / 其他)。
方向 D(防御性,短期)—— 文档警告 + 配置项开关
短期补救:在 dashboard 设置页 + README +
agentsight.json配置文档里明确警告 "API Key 以明文存储于/var/log/sysak/.agentsight/optimization_config.json,请确保该文件不被共享 / 备份 / 入侵",并加配置项optimization.api_key_storage = "plaintext" | "keyring" | "encrypted"让用户能选存储方式(默认 plaintext 保持兼容,推荐 keyring)。Environment
/var/log/sysak/.agentsight/optimization_config.json(默认storage_base_path=/var/log/sysak/.agentsight,见src/agentsight/src/config.rs:1355-1356)-rw-------(0o600,owner-only read/write)Additional Context
-rw-------+cat直接出明文 api_key/var/log/sysak/.agentsight/optimization_config.json。一旦该机器被共享 / 被备份外带 / 被入侵,key 就泄漏,产生计费损失[cosh-ng] bug: ~/.copilot-shell/config.toml 把 api_key / access_key / security_token 等敏感凭据明文存储,原 settings.json 是密文(安全回归))—— 同类问题但不同组件(cosh-ng vs sight),[cosh-ng] bug: ~/.copilot-shell/config.toml 把 api_key / access_key / security_token 等敏感凭据明文存储,原 settings.json 是密文(安全回归) #1658 修了 cosh-ng 的明文存储,但 agentsight dashboard 这个新加的"设置"页又把同样的问题引入了一份,没有走统一 secret store。本 issue 建议复用 [cosh-ng] bug: ~/.copilot-shell/config.toml 把 api_key / access_key / security_token 等敏感凭据明文存储,原 settings.json 是密文(安全回归) #1658 的加密实现,或在方向 C 里统一抽 secret store 模块[cosh-ng] bug: WriteFileTool 静默写入字面 '<redacted>' 占位符且报 success)—— 反映 cosh-ng 在 user→LLM 边界做了 redaction 但在持久化边界没做加密,是同一类"传输层脱敏 vs 存储层明文"不对等问题的另一面。本 issue 是 agentsight 自己的"传输层脱敏(POST 返回 masked api_key)+ 存储层明文"不对等<ECS-IP>/<INTERNAL-HOST>占位符;真实 API Key 替换为<REDACTED-API-KEY>;无其他敏感凭据出现在正文中