凭证保护
代码托管平台令牌、提供方 API 密钥和已保存的登录信息如何被挡在 Agent 会话之外。
Daemon 会尽量不让真实凭证进入 Agent 会话。会话拿到的只是占位符,只有当请求发往该凭证所对应的目标时,Daemon 的凭证代理才会把它换成真实凭证。Agent 从环境变量或文件里读到的内容,拿到别处毫无用处。
代码托管平台凭证
GitHub、GitLab 和 Gitea 的访问在所有执行环境中都这样处理:主机、srt、microsandbox、Kubernetes 池中的 Pod,以及 Daemon 组放到其他成员机器上运行的会话。无需任何开启操作。
git、gh和glab照常使用。代理会附上一个短期令牌,范围限定为请求所指的仓库,以及 Agent 在该仓库上的访问级别。- 会话的环境变量、Git 配置和文件里都没有可用的令牌。
- Agent 自己配置的令牌,例如它自己的
GH_TOKEN或GITLAB_TOKEN密钥,会原样透传。 - 原来的
gh-token、glab-token辅助命令以及gh、glab包装器都已移除。脚本请直接调用git、gh或glab。
代理会拒绝的请求
| 请求 | 结果 |
|---|---|
| GitHub GraphQL 变更(mutation) | 拒绝:GraphQL 只读。错误信息会指明负责这类写操作的代码托管平台工具(Pull Request、Issue、评论、评审),Agent 会改用该工具重试。 |
| GitLab 或 Gitea 的 API 写操作 | 拒绝,并指明负责该写操作的工具。API 读操作不受影响。 |
向只有读权限的仓库执行 git push | 拒绝,并提示 Agent 没有写权限。如需允许,请授予读写权限。 |
| 不指向具体仓库的 REST 写操作 | 拒绝。针对某个仓库的 GitHub REST 写操作(例如 gh api)按 Agent 的访问级别放行。 |
创建或修改 GitHub Projects 条目和 Discussions 只能通过 GraphQL 写操作完成,因此 Agent 目前无法执行;读取它们不受影响。
连不上代理的会话(例如所用 Kubernetes Runtime 镜像比 Daemon 旧)启动时不带任何代码托管平台凭证,Daemon 会在日志中记下原因。
提供方 API 密钥
模型提供方的 API 密钥也走同一个代理。Runtime 手里只有占位符,真正到达提供方的请求才带着真实密钥。
| 密钥 | 适用的会话 |
|---|---|
| 组织的基础设施 → Provider keys,用于模型登录设为 Provider key 的 Agent | 主机、srt 和 microsandbox,包括 Daemon 组放到其他成员上运行的主机会话 |
| Daemon 所在机器上的 API 密钥,适用于下表中标为代理的 Runtime | srt 和 microsandbox |
Kubernetes 安装实例的密钥:daemonPool.modelCredentials、modelEgress.clients.<client>.apiKey,以及在 daemonPool.runtimeEnvironment 中映射的 ANTHROPIC_API_KEY、OPENAI_API_KEY、DEEPSEEK_API_KEY 或 COPILOT_PROVIDER_API_KEY | 池中的 Pod(详情) |
组织密钥配置的额外请求头由代理添加,不会进入会话。密钥的端点变更后,请开启新会话来使用它。
以下情况仍会把密钥原样交给会话:
- 端点是明文
http://的密钥,因为占位符只在 HTTPS 上交换; - Daemon 无法为该 Runtime 对应到唯一 HTTPS 端点的密钥,例如发往自定义端口的密钥(Daemon 会记录一次日志);
- 密钥服务器为单个会话签发的短期密钥;
- 订阅和 OAuth 登录,见下文;
- 主机会话中 Daemon 机器自己的密钥,因为主机会话本来就能读取这台机器上的文件。
信任与网络
代理会终结发往代码托管平台和提供方的 TLS,因此会话需要信任 Daemon 创建的证书颁发机构。Daemon 会把标准的信任变量(SSL_CERT_FILE、NODE_EXTRA_CA_CERTS、GIT_SSL_CAINFO、REQUESTS_CA_BUNDLE)指向一个证书包,其中包含系统根证书、这个颁发机构,以及运维人员或会话自身变量原本就指定的颁发机构。会话通过 HTTPS_PROXY 连到代理;忽略该变量或固定使用自带证书的客户端,只会带着占位符直连代码托管平台或提供方,并被拒绝。
运维人员需要注意:
- 出站访问。 上游请求由 Daemon 发出,因此 Daemon 需要能通过 HTTPS 访问其 Agent 用到的每个代码托管平台和提供方端点。在 Kubernetes 上,这指的是 Daemon 池,而不是 Agent Pod。
- 私有颁发机构。 代理用 Daemon 的信任根以及为 Daemon 设置的颁发机构校验上游。
- 出站代理。 如果 Daemon 自己通过
HTTPS_PROXY访问互联网,凭证代理发往上游的请求也会经过它,并遵循NO_PROXY。
按 Runtime 划分的保护
本页其余部分介绍自托管 Linux Daemon 上已保存的登录信息。保护程度取决于 Runtime 和登录方式,在 srt 和 microsandbox 中相同。
| Runtime | OAuth | API 密钥 |
|---|---|---|
| Claude Code | 工具规则 | 代理 |
| Codex | 工具规则 | 代理 |
| DeepSeek Harness | 不适用 | 代理 |
| OpenCode | 无防护 | 代理 |
| pi | 无防护 | 代理 |
| Grok Build | 无防护 | 代理 |
| Qwen Code | 无防护 | 代理 |
| Oh My Pi | 无防护 | 代理 |
| Amp | 不适用 | 代理 |
| Kimi Code | 无防护 | 代理 |
| Cline | 无防护 | 代理 |
| Devin | 无防护 | 不适用 |
| Antigravity ACP | 无防护 | 代理 |
| GitHub Copilot | 无防护 | 代理 |
| Qoder CLI | 无防护 | 无防护 |
| Qoder CN CLI | 无防护 | 无防护 |
- 工具规则:Runtime 阻止其工具读取或修改受保护的凭证文件。
- 代理:真实的 API 密钥留在主机上(支持的来源见下文)。
- 无防护:工具可以在沙箱内读取该凭证。
- 不适用:该集成不涉及这种登录方式。
Claude Code 和 Codex 在使用 API 代理时同样保留其工具规则。
OAuth 与工具规则
OAuth 凭证会被挂载或复制到会话中。登录和令牌刷新由 Runtime 处理。
Claude Code 和 Codex 在 SRT 和 microsandbox 中使用相同的工具规则。Claude Code 限制 Bash 及其文件工具(包括 Read 和 Edit)。Codex 使用权限配置文件限制工具对凭证路径的访问。Runtime 本身仍然可以读取自己的凭证来完成认证。
这些规则适用于 Runtime 内置的工具。它们不覆盖任意辅助进程或 MCP 服务器。其他 Runtime 获得 OAuth 凭证时没有额外的防护。
API 密钥代理
对于受支持的登录方式,Daemon 提供给会话的是占位符而不是真实的 API 密钥。主机代理只会在发往提供方已批准的 HTTPS 端点的请求头中,把该占位符替换为真实密钥。
在 srt 和 microsandbox 中,这都适用于下表中所有 Runtime 已保存的密钥,以及在 Daemon 环境变量或 Runtime 定义中设置的密钥:Claude Code 的 ANTHROPIC_API_KEY、Codex 的 OPENAI_API_KEY、DeepSeek Harness 的 DEEPSEEK_API_KEY,以及 GitHub Copilot 和 Antigravity ACP 的密钥。在 srt 中,还适用于 OpenCode 的这些变量。
沙箱中导入的凭证文件包含的是占位符。对于 Oh My Pi,Daemon 会在写入任何 API 密钥记录之前先创建一个带占位符的私有 SQLite 数据库。主机上的登录文件保持不变。
代理使用主机上的提供方设置。在沙箱内编辑设置无法为密钥授权其他目标地址。获得授权的提供方会收到真实密钥(其响应不会被脱敏)。
支持的已保存密钥
| Runtime | 密钥来源 |
|---|---|
| Claude Code | 当前生效的全局配置中的 primaryApiKey |
| Codex | CODEX_HOME/auth.json 中的 OPENAI_API_KEY |
| DeepSeek Harness | .dsh/.credentials.yaml 或 .dsh/.env 中的标准 DEEPSEEK_API_KEY 条目 |
| OpenCode | auth.json 中的 API 记录(type: api) |
| pi | auth.json 中的 API 记录,或 models.json 中的提供方密钥 |
| Grok Build | config.toml 中的按模型密钥(model.<id>.api_key) |
| Qwen Code | settings.json 中的模型提供方密钥(包括旧版的 security.auth.apiKey) |
| Oh My Pi | agent.db 中的 API 密钥记录 |
| Amp | secrets.json 中的原生 CLI 条目(apiKey@<service URL>) |
| Kimi Code | .kimi-code/config.toml 中的提供方密钥(providers.<name>.api_key) |
| Cline | providers.json 中各提供方的 API 密钥(apiKey 或 auth.apiKey) |
| GitHub Copilot | COPILOT_PROVIDER_API_KEY,发往 COPILOT_PROVIDER_BASE_URL |
| Antigravity ACP | GEMINI_API_KEY(gemini-api-key 登录方式) |
提供方限制
DeepSeek 使用 https://api.deepseek.com。Grok、Qwen 和 Kimi Code 需要在主机配置中显式指定 HTTPS 端点(Kimi Code 为提供方的 base_url)。Claude Code、Codex、OpenCode 和 pi 使用受支持的主机提供方设置或内置默认值。Oh My Pi 使用内置的提供方默认值。
pi、Oh My Pi 和 Cline 支持 Anthropic、OpenAI、DeepSeek、Google、xAI、OpenRouter、Groq 和 Mistral 的默认端点。Cline 的其他提供方需要在提供方条目中设置 HTTPS baseUrl。自定义的 Codex 提供方必须设置 requires_openai_auth = true。
GitHub Copilot 需要 HTTPS 的 COPILOT_PROVIDER_BASE_URL。Antigravity ACP 使用 Gemini API;如果 GOOGLE_GEMINI_BASE_URL 设为 HTTPS 端点,则使用该端点。
如果识别出的 API 密钥没有受支持的路由,它会保持隐藏,对应的提供方不可用。OpenCode 中配置的其他提供方仍可正常工作。DeepSeek 会在启动时拒绝自定义端点。
保护范围覆盖上述已保存的来源。它不会自动覆盖密钥环、基于命令获取的密钥、任意请求头、自定义插件,或在沙箱内新执行的登录。Amp 单独的 amp-acp/credentials.json 登录不在此保护范围内。仅存储在自定义模型文件中的 Oh My Pi 密钥同样不在范围内。Cline 的 AWS 凭证和自定义请求头保持原样,从环境变量读取密钥(api_key_env)的 Kimi Code 提供方也一样。
Qoder CLI 和 Qoder CN CLI 的密钥不受保护:个人访问令牌是在请求体中换取的,服务账号密钥必须保持占位符无法满足的格式。Devin 通过浏览器登录,没有单独的 API 密钥登录方式。
受支持的端点使用 HTTPS,不带自定义端口或 URL 内嵌凭证。受保护的会话会拒绝自定义的 TLS 信任覆盖和相互冲突的凭证挂载。
现有会话与密钥变更
受保护的虚拟机在停止后恢复时会重新加载已更改的主机密钥。正在运行的虚拟机继续使用当前密钥。更改登录账号、提供方记录或凭证布局可能会重建虚拟机(见哪些内容会保留)。