AtomCode 安全模型分析报告
基于二进制分析、API 行为测试和配置探查 2026-06-22
1. 认证与授权模型
1.1 双层认证体系
Layer 1: OAuth → AtomGit access_token(7 天有效,可 refresh)
Layer 2: OAuth token → CodingPlan 内部 API key(仅 daemon 进程内存持有)关键发现:
- OAuth access_token 用于认证 daemon API 调用(
Authorization: Bearer <token>) - CodingPlan API key 不暴露给任何外部请求,仅 daemon 内部持有
- 直接调用 llm-api 返回
403(即使使用 OAuth access_token)
1.2 API 认证规则
| 端点 | 需要 Bearer token | 说明 |
|---|---|---|
/health | 否 | 公开 |
/auth/* | 否 | 认证前可访问 |
/codingplan/setup | 是 | 需要登录 |
/chat | 是 | 需要登录 |
/sessions | 是 | 需要登录 |
/models | 是 | 需要登录 |
/providers | 是 | 需要登录 |
/config | 是 | 需要登录 |
/skills | 是 | 需要登录 |
/fs/* | 是 | 需要登录 |
/cd | 是 | 需要登录 |
/live/* | 是 | 需要登录 |
1.3 Token 安全性
auth.toml 权限: -rw------- (仅所有者可读)
auth.toml 内容: access_token + refresh_token 明文存储
删除行为: POST /auth/logout → 立即删除 auth.toml
刷新机制: daemon 自动使用 refresh_token 续期2. 敏感/危险工具控制
2.1 环境变量控制
| 变量 | 功能 | 风险等级 |
|---|---|---|
ATOMCODE_DAEMON_ENABLE_DANGEROUS_TOOLS | 启用危险工具 | 🔴 高 |
ATOMCODE_DISABLE_TOOLS | 禁用指定工具 | 🟢 低 |
ATOMCODE_ENABLE_CD | 允许 cd 命令 | 🟢 低 |
2.2 工具分组
来源于二进制中的 ToolGroup 结构:
| 分组 | 包含工具 | 危险等级 |
|---|---|---|
| read | read_file, glob, grep, list_dir, open_file | 🟢 安全 |
| edit | edit_file, search_replace, write_file, parallel_edit | 🟡 中 |
| exec | bash, run_command, run_shell | 🔴 高 |
| network | web_search, web_fetch | 🟢 安全 |
| analysis | trace_*, file_deps, blast_radius, diagnostics, auto_fix, file_history | 🟢 安全 |
| system | cd, use_skill, todo | 🟢 安全 |
2.3 权限审批系统 (/chat/permission)
请求: POST /chat/permission
参数: session_id, decision (allow/deny), tool_name
行为: 当 daemon 需要执行危险操作时,先暂停等待用户确认
SPA 通过此端点进行审批
返回: {"error": "no pending permission for session", "success": false}权限审批流程:
LLM 请求调用 bash
→ daemon 暂停,等待 /chat/permission 响应
→ 用户通过 SPA 发送 allow/deny
→ daemon 继续/中止执行2.4 跳过权限模式
CLI 参数: --dangerously-skip-permissions
环境变量: ATOMCODE_DAEMON_ENABLE_DANGEROUS_TOOLS=1完全跳过所有权限提示(生产环境不推荐)。
3. 钩子系统 (Hooks)
3.1 事件类型
pre_tool_use → 工具调用前触发
post_tool_use → 工具调用后触发
session_start → 会话开始
session_end → 会话结束3.2 配置结构
json
{
"hooks": {
"hook-name": {
"event": "pre_tool_use",
"command": "safety-check.sh",
"timeout_ms": 5000
}
}
}3.3 钩子返回
PreHookResult:
- Allow (继续执行)
- Block (阻止执行,带原因)
- Modify (修改请求)4. Telemetry 隐私
4.1 禁用方式
bash
# 方法 1: 环境变量
ATOMCODE_TELEMETRY=0 atomcode daemon
# 方法 2: CLI 命令
atomcode telemetry disable4.2 上报内容
遥测收集的数据字段:
device_id, launch_id, account_id, session_id, turn_id
app_version, locale, provider_host, repo_origin
has_git, schema_version不收集: 代码内容、文件内容、对话内容(事件中不包含 message text)
4.3 上报端点
POST https://acs.atomgit.com/api/v1/events5. 文件系统安全
5.1 敏感文件保护
二进制中检测到敏感文件覆盖防护:
"Critical system file overwrite" —— 阻止覆盖关键系统文件
"Editing sensitive system" —— 编辑敏感系统文件警告5.2 文件路径限制
工作目录绑定: 工具调用必须使用绝对路径
cd 命令: 可通过 ATOMCODE_ENABLE_CD 控制6. 网络与 TLS
NODE_TLS_REJECT_UNAUTHORIZED=0 (当前环境)
→ 跳过 TLS 证书验证
→ 仅在内部测试环境,生产环境不应使用通过 ProviderConfig 中的 skip_tls_verify 字段控制每个 provider 的 TLS 验证。
7. 会话隔离
每个 session 独立:
- 消息历史
- 工作目录
- 工具调用状态 (permission 审批)
session 之间不共享状态
停止的 session 可以通过 session_id 恢复8. 总体安全评分
| 维度 | 评分 | 说明 |
|---|---|---|
| 传输加密 | ✅ TLS 可用 | skip_tls_verify 可配置 |
| 认证 | ✅ OAuth 2.0 | 不存储密码,7 天 token |
| 授权 | ✅ 双层 | OAuth + CodingPlan |
| 权限控制 | ⚠️ 可选 | 默认需要审批,可跳过 |
| 数据加密 | ❌ 明文 | auth.toml 明文存储 token |
| 审计日志 | ⚠️ 部分 | datalog 记录 LLM 调用,但无系统审计 |
| 输入验证 | ✅ | 结构化请求验证 |
| 文件保护 | ✅ | 关键系统文件保护 |
逆向命令索引
bash
# 提取安全相关字符串
strings atomcode.bin.bak | grep -iE "permission|dangerously|denied_by|blocked_by|PermissionError" | sort -u
# 输出: PermissionDecisionRequest denied_by_user blocked_by_hook CallingToolWaitingApproval
# 提取权限错误枚举
strings atomcode.bin.bak | grep -iE "PermissionError" | sort -u
# 提取绕过机制
strings atomcode.bin.bak | grep -iE "dangerously_skip_permissions" | sort -u
# 输出: dangerously_skip_permissions
# 提取文件保护路径
strings atomcode.bin.bak | grep -iE "\.gitnore|\.bashrc|\.ssh|credentials" | sort -u | head -109. 安全建议
- auth.toml 权限 —
-rw-------合理,但内容为明文。考虑加密存储 token - 危险工具默认关闭 —
ATOMCODE_DAEMON_ENABLE_DANGEROUS_TOOLS不应在生产环境设置 - Telemetry 建议禁用 — 防止环境相关信息通过
acs.atomgit.com泄漏 - TLS 验证不应跳过 — 生产环境确保
NODE_TLS_REJECT_UNAUTHORIZED不设 0 - 定期重新登录 — token 7 天过期,daemon 自动 refresh,但 refresh_token 也存储在同一文件