引言
用 Claude Code 的时候,我突然意识到一件事:它能读我的 .env。
不是恶意的,这是正常的文件系统访问。但这让我开始想一个问题------在 AI Agent 拥有工具调用能力的时代,secrets 的边界是不是已经被打破了?
我花了很长时间试图找到解法,最后推导出了一个让我有点沮丧的结论。这篇文章记录整个思考过程。
一、问题的精确定位
先不要被"AI 读了你的 .env"这个标题吓到,精确化威胁模型很重要。
真实威胁:
bash
Agent 模式下有文件系统访问权限
→ .env 在工作目录内可被读取
→ AI 工具上传代码上下文到服务商服务器
→ .env 内容可能随上下文一起被传走
Cursor 默认对全仓库做 embedding,这个过程是否包含 .env,你无法审计。这不是假设,是默认行为。
被夸大的威胁:
.env 本来就不该进 git------这是基础安全卫生,不是 AI 带来的新问题。本地读取 .env 数据不离本机,威胁相对有限。
所以精确的问题是:Agent 拥有文件系统工具调用能力后,secrets 的边界被打破了。

二、现有方案为什么不够
| 方案 | 问题 |
|---|---|
.gitignore |
只防 git,不防运行时读取 |
1Password CLI op run |
注入环境变量,Agent 仍能读注入后的值 |
| Vault / Doppler | 云端注入,上下文上传问题不变 |
| 权限收紧 | 和 Agent 能力本身冲突 |
根本矛盾:Agent 要能工作就需要环境上下文,但 secrets 不应该是环境上下文的一部分。
三、三条路径

想清楚这个矛盾之后,解法只有三个方向:
css
A. 消灭凭证本身 → 用其他东西替代(支付、身份、证明)
B. 凭证生命周期归零 → 存在但单次/瞬时
C. 凭证无法被提取 → 存在但物理上不可读
A 路径:x402 Payment Protocol
x402 是 Coinbase 推动的 HTTP 402 扩展:
arduino
Client → Server: GET /resource
Server → Client: 402 + payment details
Client → Server: GET /resource + payment proof
Server → Client: 200 OK
核心思想:用支付替代凭证。没有需要保管的长期 API key,每次访问即时支付,payment proof 即授权,天然单次有效。
这是"消灭凭证本身"最彻底的实现。但冷启动问题几乎致命------API 厂商没有动机改造计费体系,开发者侧也强依赖 Base L2 + USDC。
B 路径:SPIFFE + UCAN

SPIFFE(Secure Production Identity Framework For Everyone)本来是给微服务设计的 workload identity 系统。移植到 Agent 场景:
bash
每个 Agent task 获得一个生命周期绑定的身份:
spiffe://domain/agent/{agent-id}/task/{task-id}
SPIRE 颁发短期 X.509 证书(TTL = task 生命周期)
task 结束 → 证书自动过期
没有任何静态 secret
UCAN(User Controlled Authorization Networks)解决 capability 衰减问题:
lua
用户授权 Agent:db:read + db:write
Agent 分配给 SubAgent:db:read(只能缩小)
SubAgent 分配给工具调用:db:read:table/users,maxCalls: 5
两者组合可以构成完整的 AAP(Agent Authorization Protocol) :
yaml
Layer 0: TEE → 硬件信任根
Layer 1: SPIFFE → 身份层(Who are you)
Layer 2: AAP → 能力层(What can you do)
Layer 3: Transport → mTLS / x402
Layer 4: SDK → 框架集成层
技术上最完整,但有个前提:你必须控制 Agent runtime。
C 路径:TEE(可信执行环境)
TEE 是最彻底的 C 路径实现:
javascript
Agent 运行在 Intel TDX / AMD SEV-SNP 等 TEE 里
secrets 只在 TEE 内存存在
即使 root 权限也读不到 TEE 内存
即使 context window 被完整泄露,secrets 也不在里面
服务端通过 Remote Attestation 验证:
硬件真实?固件未篡改?代码度量值匹配?
→ 验证通过,下发 secrets 到 TEE 内
→ secrets 永远不离开 TEE
保护最彻底,但开发硬件门槛高,调试极其困难。
四、把这些放到 Claude Code 场景
这里有一个我一开始忽视的关键差异:
css
自建 Agent(如 z0):你控制 runtime,AAP 可以完整实现
编程助手(Claude Code/Cursor):你不控制 runtime,AAP 无法强制执行
以 MCP Server 为例------我曾经设想提供一个 get_secret 工具替代直接读 .env:
vbnet
server.tool("get_secret", async ({ name, taskContext }) => {
const capability = await aap.evaluate({ requested: name, intent: taskContext })
if (!capability.allowed) return { error: "capability not granted" }
return { value: await vault.getEphemeral(name, ttl: capability.ttl) }
})
但问题是:MCP 工具是加法,不是拦截。
你加了 get_secret,但 read_file(".env") 仍然存在。两个通道同时有效,Claude Code 可以绕过你的 MCP 直接读文件。
所以 AAP 在编程助手场景能做到:
bash
✓ 提供标准的 secrets 请求协议
✓ 审计通过 MCP 通道的访问
✗ 无法阻止直接读 .env
✗ 无法审计绕过 MCP 的访问

五、撞上的那堵墙
推导到最后,我发现了一个更根本的问题。
AAP 要真正闭环,需要的不是协议设计,而是采用方:
css
A 路径(x402):
需要 API 厂商支持 402 响应
需要 Agent 平台支持支付
两边都是大公司,个人无法推动双边采用
B 路径(AAP 替代 API 逻辑):
需要 API 厂商主动把 key 体系换掉
等于让他们否定现有基础设施
动机几乎为零
"无长期凭证"是一个需要供给侧和消费侧同时改变的问题。任何单边方案都只能做到部分保护,无法闭环。
OIDC 的成立不是因为某人设计得好,是因为 Google 和 Microsoft 同时采用了。Agent 时代的凭证标准也会是同样的路径------来自大厂平台内部推行,或监管压力迫使行业标准化。
AWS IAM Roles、Google Workload Identity 已经在各自生态内做到了"无长期凭证"。AI Agent 的版本,大概率也会以同样的方式出现。
六、那这些技术还有价值吗
有,只是场景不同:
SPIFFE / AAP:在你自己控制的 Agent 系统里,这是正确的架构方向
TEE:CI/CD 流水线、云端 Agent 部署,有真实的落地场景
x402:AI × Web3 交叉方向的长期赌注,ERC-8004 已上主网
UCAN:任何需要细粒度 capability 控制的系统
而对于编程助手场景,目前最有效的保护仍然是最朴素的那个:
让 .env 从文件系统彻底消失。 没有文件,就没有读取。
结语
我本来想找到一个漂亮的技术解法。最后发现,这不是一个技术问题,而是一个生态问题。
AI 时代需要新的身份与授权原语。技术路径已经清晰,工程障碍也可以克服。真正的障碍是:谁来推动整个生态同时转向。
这个问题的答案,大概不会来自某个独立开发者。