生产 Agent 的密钥和凭据边界:不要让模型直接碰 API Key
生产 Agent 的密钥和凭据边界不要让模型直接碰 API Key很多团队给 Agent 接工具时会先解决“模型怎么调用外部系统”。下一步很容易被忽略这些外部系统的凭据到底在哪里谁能拿到出了事怎么撤回。如果做法是把 API Key、数据库连接串、云账号 token 或 SaaS 访问令牌放进环境变量然后让工具适配器随便取短期 demo 能跑生产风险会很高。生产 AI Agent 系统里模型不应该直接接触密钥。更准确地说模型只能提出“要做什么”凭据的选择、权限、有效期、审计和撤销应该由代码层的工具代理和策略层处理。凭据问题为什么比普通后端更敏感传统后端服务也会用密钥但调用路径通常比较稳定哪个服务调用哪个接口权限范围、调用频率和错误模式都相对可控。Agent 不一样。它的动作来自模型推理、用户输入、检索上下文和工具返回结果的组合。一次看似普通的任务可能经过多轮计划、改写、重试和降级最后触发一个真实写操作。这里有三个典型风险提示词或上下文泄露如果工具说明、错误信息或调试日志里带出密钥模型可能把它写进回答、记录或后续工具参数。权限被工具间接放大Agent 本来只需要查工单却通过某个通用工具拿到了客户、订单、财务或云资源的更大权限。出事后无法快速收口没有 token 版本、租户范围、调用 trace 和撤销机制团队只能轮换一批大权限密钥影响范围很难判断。这不是“模型会不会作恶”的问题而是生产系统应该默认任何自动化链路都可能被误用、注入、重试放大或被错误上下文带偏。推荐架构模型拿 action工具代理拿凭据一个更稳的结构是把模型、策略层、工具代理和凭据系统拆开模型提出动作策略层校验工具代理凭据代理 / Vault业务系统人工审批审计 trace模型输出的是候选动作例如{tool:ticket.update_status,args:{ticketId:T-48291,status:pending_close},evidenceIds:[msg_781,kb_rule_17]}这里不应该出现真实密钥。工具代理根据租户、工具、风险等级、审批状态和证据链去凭据代理里换取一个短期、最小权限、可审计的访问能力。不要把 secret 当作普通配置建议把工具配置分成两层。第一层是可以被模型看到的工具契约工具名称能做什么必需参数风险等级需要哪些证据是否需要人工审批可能失败的原因。第二层是模型永远看不到的执行配置secretRef凭据版本租户范围目标系统 allowlisttoken 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){constpolicytoolPolicies[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 业务系统交付