LLM API密钥如何永远不进沙箱:nono代理凭据注入完整教程
【免费下载链接】nonoagent runtime security - zero trust, zero setup, zero latency.项目地址: https://gitcode.com/gh_mirrors/non/nono
运行 Claude Code、Codex 等 AI 智能体时,大多数人习惯把OPENAI_API_KEY直接塞进环境变量——这意味着 LLM API 密钥长期躺在 agent 进程的环境里,随时可能被 prompt 注入偷走。nono是一款零信任 AI agent 沙箱(无容器、无守护进程、零延迟),它的代理凭据注入功能让真实密钥永远不进入沙箱:本地反向代理在转发请求时替你签名,即使 agent 被攻破也读不到密钥。本文带你 3 步完成配置。
为什么不要把 LLM API 密钥放进沙箱
把密钥写成环境变量"只是"解决了硬编码问题,并没有解决暴露问题:
- 密钥出现在进程环境(如
/proc/<pid>/environ)和内存里,沙箱内任何代码都能读; - agent 的每一次工具输出都是不可信输入——一条恶意的 prompt 注入就可能诱导 agent 读取并外发自己的环境变量;
- 沙箱的网络白名单往往必须放行 LLM API,密钥一旦泄露就有一条现成的外发通道。
nono 的思路是把"执行体"与"秘密"彻底切开:agent 运行在内核沙箱边界之下,而密钥始终留在边界之上的宿主侧。
nono 代理凭据注入的工作原理
启用--credential后,nono 在宿主机上启动一个不受沙箱约束的本地反向代理,流程只有四步:
- agent 把请求发往
localhost:<端口>/<服务>/...; - 代理剥离服务前缀,验证本次会话的"幻影令牌";
- 从系统钥匙串取出真实密钥,注入为 HTTP 头;
- 通过 TLS 转发到上游 API,并把流式响应(SSE 等)原样传回。
Agent 发送: POST http://127.0.0.1:PORT/openai/v1/chat/completions Proxy 发送: POST https://api.openai.com/v1/chat/completions Authorization: Bearer sk-...(从钥匙串注入)关键细节:
- 🔑幻影令牌(Phantom Token):沙箱内的子进程只拿得到一个会话级伪令牌(如
nono_sess_a1b2c3...),真正的密钥只存在于代理一侧。每个会话生成唯一的 256 位会话令牌(经NONO_PROXY_TOKEN传入),防止本机其他进程蹭用注入路由。 - 🔁自动改道:代理会把
OPENAI_BASE_URL、ANTHROPIC_BASE_URL等变量设置为http://127.0.0.1:<端口>/<服务>,主流 LLM SDK 会自动遵循,无需改任何业务代码。 - 🛡️零落盘、零日志:密钥在内存中使用
Zeroizing<String>存储、退出即擦除;审计日志只记录ALLOW REVERSE openai POST /v1/chat/completions -> 200,永远不含密钥值。
三步配置:从存密钥到跑通
第 1 步:把密钥存入系统钥匙串
所有 nono 密钥都统一存放在系统钥匙串(macOS Keychain / Linux Secret Service)下的nono服务中。
macOS:
security add-generic-password -s "nono" -a "openai" -w "sk-..."Linux(需要libsecret-tools):
echo -n "sk-..." | secret-tool store --label="nono: openai" \ service nono username openai target default⚠️ Linux 下属性名必须是
username而非account,且要带上target default,否则 keyring 库找不到条目。
第 2 步:带凭据注入运行 agent
nono run --allow-cwd --network-profile claude-code --credential openai -- my-agent启动时 nono 会列出授予沙箱的完整能力清单,然后进入 agent:
第 3 步:验证密钥没进沙箱
- 子进程环境里只有指向本地代理的
OPENAI_BASE_URL与幻影令牌,没有sk-开头的真实密钥; - nono 审计日志中,每次经代理的调用都会留下
ALLOW REVERSE openai ...记录,方便事后追溯; - 在沙箱内执行
nono why可随时查询某个地址是否被放行。
内置 LLM 服务路由:开箱即用
nono 内置了主流 LLM 与开发平台的凭据路由,直接--credential <服务名>即可,无需任何自定义配置:
| 服务 | 上游地址 | 注入头 | 格式 |
|---|---|---|---|
openai | https://api.openai.com/v1 | Authorization | Bearer {} |
anthropic | https://api.anthropic.com | x-api-key | {} |
gemini/google-ai | https://generativelanguage.googleapis.com | x-goog-api-key | {} |
github | https://api.github.com | Authorization | token {} |
gitlab | https://gitlab.com/api | Authorization | Bearer {} |
这些路由定义在内置的网络策略 crates/nono-cli/data/network-policy.json 中,配套的域名白名单分组(llm_apis、package_registries等)也在同一文件里维护。
进阶:在 profile 中声明自定义凭据
要把配置固化到团队可复用的 profile(组合式 JSON),在network段写custom_credentials即可。支持从钥匙串、1Password(op://)、Bitwarden(bw://)、Apple Passwords(apple-password://)、文件(file://)、宿主环境变量(env://),甚至 CLI 命令捕获(cmd://,例如gh auth token)取密钥:
{ "meta": { "name": "my-agent" }, "network": { "network_profile": "claude-code", "credentials": ["openai"], "custom_credentials": { "telegram": { "upstream": "https://api.telegram.org", "credential_key": "telegram_bot_token", "inject_header": "Authorization", "credential_format": "Bearer {}" } } } }nono run --profile my-agent -- my-agent此外还支持四种注入模式(请求头 / URL 路径 / 查询参数 / Basic Auth),以及面向 Amazon Bedrock 等场景的AWS SigV4 主机侧签名——代理在宿主上解析凭据并逐请求重签名,沙箱内连"能用的 AWS 凭据"都不存在。完整字段说明见 docs/cli/features/credential-injection.mdx。
注意事项与常见坑
- 🐧WSL2:代理注入默认被禁用(网络封禁无法在内核级强制),环境变量注入(
--env-credential)不受影响,可正常工作; - 🍎Go 编写的 CLI(macOS):
gh、terraform等只信任系统证书库,会拒绝代理签发的证书,加--trust-proxy-ca一次性把代理 CA 存入钥匙串即可; - 🧵流式响应:chat completions 的 SSE、MCP Streamable HTTP 均无缓冲直转,打字机体验不受影响;
- 🔀混用模式:同一 profile 里可对非网络类秘密(如数据库口令)用
env_credentials走环境变量注入,对 LLM 密钥用custom_credentials走代理注入,两不耽误。
总结
- 真实 LLM API 密钥只留在宿主侧钥匙串,沙箱内只有幻影令牌——这是代理注入与"塞环境变量"的本质区别;
- 会话令牌 + 域名白名单 + 审计留痕,构成完整的零信任链路;
- 内置 6 条主流服务路由,3 条命令即可完成配置,profile 化后可在团队间共享。
延伸阅读
- 官方文档:docs/cli/features/credential-injection.mdx、docs/cli/features/networking.mdx、docs/cli/internals/security-model.mdx
- 凭据代理源码:crates/nono-proxy/src/credential.rs、crates/nono-proxy/src/token.rs
- 钥匙串读写实现:crates/nono/src/keystore.rs
【免费下载链接】nonoagent runtime security - zero trust, zero setup, zero latency.项目地址: https://gitcode.com/gh_mirrors/non/nono
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考