生产 Agent 的密钥和凭据边界:不要让模型直接碰 API Key

很多团队给 Agent 接工具时,会先解决“模型怎么调用外部系统”。下一步很容易被忽略:这些外部系统的凭据到底在哪里,谁能拿到,出了事怎么撤回。

如果做法是把 API Key、数据库连接串、云账号 token 或 SaaS 访问令牌放进环境变量,然后让工具适配器随便取,短期 demo 能跑,生产风险会很高。

生产 AI Agent 系统里,模型不应该直接接触密钥。更准确地说,模型只能提出“要做什么”,凭据的选择、权限、有效期、审计和撤销,应该由代码层的工具代理和策略层处理。

凭据问题为什么比普通后端更敏感

传统后端服务也会用密钥,但调用路径通常比较稳定:哪个服务调用哪个接口,权限范围、调用频率和错误模式都相对可控。

Agent 不一样。它的动作来自模型推理、用户输入、检索上下文和工具返回结果的组合。一次看似普通的任务,可能经过多轮计划、改写、重试和降级,最后触发一个真实写操作。

这里有三个典型风险:

  1. 提示词或上下文泄露
    如果工具说明、错误信息或调试日志里带出密钥,模型可能把它写进回答、记录或后续工具参数。

  2. 权限被工具间接放大
    Agent 本来只需要查工单,却通过某个通用工具拿到了客户、订单、财务或云资源的更大权限。

  3. 出事后无法快速收口
    没有 token 版本、租户范围、调用 trace 和撤销机制,团队只能轮换一批大权限密钥,影响范围很难判断。

这不是“模型会不会作恶”的问题,而是生产系统应该默认任何自动化链路都可能被误用、注入、重试放大或被错误上下文带偏。

推荐架构:模型拿 action,工具代理拿凭据

一个更稳的结构是把模型、策略层、工具代理和凭据系统拆开:

模型提出动作

策略层校验

工具代理

凭据代理 / Vault

业务系统

人工审批

审计 trace

模型输出的是候选动作,例如:

{
  "tool": "ticket.update_status",
  "args": {
    "ticketId": "T-48291",
    "status": "pending_close"
  },
  "evidenceIds": ["msg_781", "kb_rule_17"]
}

这里不应该出现真实密钥。工具代理根据租户、工具、风险等级、审批状态和证据链,去凭据代理里换取一个短期、最小权限、可审计的访问能力。

不要把 secret 当作普通配置

建议把工具配置分成两层。

第一层是可以被模型看到的工具契约:

  • 工具名称;
  • 能做什么;
  • 必需参数;
  • 风险等级;
  • 需要哪些证据;
  • 是否需要人工审批;
  • 可能失败的原因。

第二层是模型永远看不到的执行配置:

  • secretRef;
  • 凭据版本;
  • 租户范围;
  • 目标系统 allowlist;
  • token TTL;
  • 调用限额;
  • 网络出口策略;
  • 审计保留周期。

例如:

type ToolPolicy = {
  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 要按凭据边界处理

只靠“忽略用户要求泄露密钥”的提示词不够。

用户输入、网页内容、知识库文档、邮件和工单备注都可能夹带指令。生产系统应该假设模型会读到恶意文本,因此敏感动作必须由策略层挡住。

一个简单的防线可以这样写:

function canIssueCredential(request: ToolRequest, context: AgentContext) {
  const policy = toolPolicies[request.toolName];

  if (!policy) return deny("unknown_tool");
  if (!context.tenantId) return deny("missing_tenant_scope");
  if (request.args.includesSecretLikeValue) return deny("secret_in_args");
  if (!hasRequiredEvidence(request, policy.visibleToModel.requiredEvidence)) {
    return deny("missing_evidence");
  }
  if (policy.executionOnly.approvalRequired && !context.approvalId) {
    return deny("human_approval_required");
  }

  return allow({
    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 能不能进入客户数据、工单、订单、设备和云资源所在的真实环境。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐