生产 Agent 的密钥和凭据边界:不要让模型直接碰 API Key
很多团队给 Agent 接工具时,会先解决“模型怎么调用外部系统”。下一步很容易被忽略:这些外部系统的凭据到底在哪里,谁能拿到,出了事怎么撤回。
如果做法是把 API Key、数据库连接串、云账号 token 或 SaaS 访问令牌放进环境变量,然后让工具适配器随便取,短期 demo 能跑,生产风险会很高。
生产 AI Agent 系统里,模型不应该直接接触密钥。更准确地说,模型只能提出“要做什么”,凭据的选择、权限、有效期、审计和撤销,应该由代码层的工具代理和策略层处理。
凭据问题为什么比普通后端更敏感
传统后端服务也会用密钥,但调用路径通常比较稳定:哪个服务调用哪个接口,权限范围、调用频率和错误模式都相对可控。
Agent 不一样。它的动作来自模型推理、用户输入、检索上下文和工具返回结果的组合。一次看似普通的任务,可能经过多轮计划、改写、重试和降级,最后触发一个真实写操作。
这里有三个典型风险:
提示词或上下文泄露
如果工具说明、错误信息或调试日志里带出密钥,模型可能把它写进回答、记录或后续工具参数。权限被工具间接放大
Agent 本来只需要查工单,却通过某个通用工具拿到了客户、订单、财务或云资源的更大权限。出事后无法快速收口
没有 token 版本、租户范围、调用 trace 和撤销机制,团队只能轮换一批大权限密钥,影响范围很难判断。
这不是“模型会不会作恶”的问题,而是生产系统应该默认任何自动化链路都可能被误用、注入、重试放大或被错误上下文带偏。
推荐架构:模型拿 action,工具代理拿凭据
一个更稳的结构是把模型、策略层、工具代理和凭据系统拆开:
模型输出的是候选动作,例如:
{"tool":"ticket.update_status","args":{"ticketId":"T-48291","status":"pending_close"},"evidenceIds":["msg_781","kb_rule_17"]}这里不应该出现真实密钥。工具代理根据租户、工具、风险等级、审批状态和证据链,去凭据代理里换取一个短期、最小权限、可审计的访问能力。
不要把 secret 当作普通配置
建议把工具配置分成两层。
第一层是可以被模型看到的工具契约:
- 工具名称;
- 能做什么;
- 必需参数;
- 风险等级;
- 需要哪些证据;
- 是否需要人工审批;
- 可能失败的原因。
第二层是模型永远看不到的执行配置:
- secretRef;
- 凭据版本;
- 租户范围;
- 目标系统 allowlist;
- token TTL;
- 调用限额;
- 网络出口策略;
- 审计保留周期。
例如:
typeToolPolicy={name:"ticket.update_status";visibleToModel:{description:string;requiredArgs:string[];requiredEvidence:string[];riskLevel:"internal_write";};executionOnly:{secretRef:"vault://prod/helpdesk/write-status";tenantScope:"current_tenant_only";tokenTtlSeconds:300;maxCallsPerTrace:1;egressAllowlist:["helpdesk.internal"];approvalRequired:true;};};关键点是:模型可以知道“这个工具需要审批”,但不应该知道密钥在哪里、密钥长什么样、可以访问哪些内部地址。
凭据要按动作分级,不要按系统分级
很多事故来自一个过大的“系统级 token”。例如给 Agent 一个 CRM token,然后靠 prompt 约束它只查客户资料。这个边界太软。
更好的做法是按动作拆权限:
| 动作类型 | 凭据策略 | 生产建议 |
|---|---|---|
| 只读查询 | 短期 token + 租户限制 | 可自动执行,但要记录 query 摘要 |
| 草稿生成 | 无外部写权限 | 可以让 Agent 生成建议,不直接提交 |
| 内部写入 | 幂等键 + 审批或灰度 | 先在低风险对象上放权 |
| 对外副作用 | 人工确认 + 延迟撤销窗口 | 默认不让模型直接执行 |
| 云资源 / 数据库管理 | 独立通道 | 不作为普通业务 Agent 工具开放 |
这套分级比“Agent 有没有权限调用 CRM”更有用。生产里真正要问的是:它能不能读、能不能写、能不能对外发送、能不能改配置、能不能批量执行。
trace 里要记录凭据引用,不记录密钥
审计需要能还原调用链,但不能把密钥写进日志。建议 trace 里记录这些字段:
{"trace_id":"tr_20260711_0930","span_name":"credential.issue","tool_name":"ticket.update_status","secret_ref":"vault://prod/helpdesk/write-status","secret_version":"v17","tenant_scope":"tenant_42","token_ttl_seconds":300,"policy_result":"approval_required","approval_id":"appr_8841","issued":true}这里记录的是 secretRef 和版本,不是 secret value。排障时团队能知道当时用了哪类凭据、哪个版本、哪个租户范围、是否经过审批。即使日志泄露,也不会直接泄露真实 token。
Prompt injection 要按凭据边界处理
只靠“忽略用户要求泄露密钥”的提示词不够。
用户输入、网页内容、知识库文档、邮件和工单备注都可能夹带指令。生产系统应该假设模型会读到恶意文本,因此敏感动作必须由策略层挡住。
一个简单的防线可以这样写:
functioncanIssueCredential(request:ToolRequest,context:AgentContext){constpolicy=toolPolicies[request.toolName];if(!policy)returndeny("unknown_tool");if(!context.tenantId)returndeny("missing_tenant_scope");if(request.args.includesSecretLikeValue)returndeny("secret_in_args");if(!hasRequiredEvidence(request,policy.visibleToModel.requiredEvidence)){returndeny("missing_evidence");}if(policy.executionOnly.approvalRequired&&!context.approvalId){returndeny("human_approval_required");}returnallow({secretRef:policy.executionOnly.secretRef,ttl:policy.executionOnly.tokenTtlSeconds,scope:context.tenantId,});}模型可以被说服,策略层不能被说服。它只看结构化上下文、证据、审批和工具策略。
上线前做一次泄露演练
很多团队有单元测试和回归测试,但没有做过凭据泄露演练。建议上线前至少演练四件事:
- 如果日志里误写了 token,能不能在 10 分钟内发现;
- 如果某个工具凭据被撤销,Agent 能不能降级而不是无限重试;
- 如果某个租户凭据出问题,是否只影响这个租户;
- 如果用户通过 prompt injection 要求泄露配置,策略层能不能拦截并记录。
演练结果应该进入 runbook。谁负责撤销、谁负责轮换、哪些下游系统需要清缓存、哪些任务要暂停、哪些客户对象可能受影响,都要提前写清楚。
上线前检查清单
把 Agent 接入真实业务系统前,至少检查这些问题:
- 模型上下文里是否完全没有真实密钥;
- 工具说明和错误信息是否不会回显 secret;
- 每个工具是否有 owner、风险等级和 secretRef;
- 凭据是否按动作和租户分级,而不是一个大 token;
- 高风险工具是否需要人工审批或灰度放权;
- token 是否短期有效、可撤销、可追溯;
- trace 是否记录 secretRef、版本、租户和审批结果;
- 日志、prompt、工具入参是否有 secret 扫描;
- 凭据撤销后系统是否会停止重试或降级;
- 是否做过 prompt injection 和密钥撤销演练。
这些控制不会让 demo 更漂亮,但会决定 Agent 能不能进入客户数据、工单、订单、设备和云资源所在的真实环境。
AgentKick 怎么看这件事
在 生产就绪审查与路线图 里,密钥和凭据边界通常会和权限控制、工具调用、审计日志、失败处理、人工接管一起看。我们不会只问“Agent 有没有接上工具”,而是看模型、策略层、工具代理和凭据系统之间的边界是否清楚。
如果一个 Agent 需要真实业务权限,却没有凭据分级、短期 token、secretRef 审计和撤销演练,它还不适合直接进入生产。生产就绪不是让模型拿到更多权限,而是让每一份权限都有范围、证据、审批、日志和回收路径。
延伸检查
- 需要看整套系统的生产缺口,可以继续做综合上线前检查:AI 系统上线前检查
- 如果问题已经跨到内容、后台、Agent 和运营链路,可以看业务系统交付范围:AI 业务系统交付