Agent 权限模型设计:用户身份、工具权限、审计日志和密钥隔离

"MCP Security Best Practices 将 token passthrough 标为反模式,并建议使用最小权限 scope、服务端授权和可审计的权限提升流程。"
团队把同一个管理员 token 配给 Agent,想着”反正都是内部系统”。结果用户 A 提交的查询请求,Agent 用管理员身份读到了用户 B 的 CRM 记录——权限失控比没有 Agent 更致命。
这不是假设场景。MCP Security Best Practices 明确把 token passthrough 标为反模式:绕过安全控制、破坏 audit trail、打破信任边界。OWASP AI Agent Security Cheat Sheet 把”工具滥用和权限越界”列为核心风险之一。
问题归结为三个:Agent 代表谁、凭什么调、能访问什么。以下是完整的权限模型工程蓝图:身份映射表、工具权限字段清单、Secret Vault 的核心步骤、审计日志 schema 和脱敏规则、权限决策判断表、排障清单、落地步骤。
身份映射:Agent 代表谁?
Agent 调用工具时,日志和权限系统首先要回答一个问题:谁发起的调用,代表谁操作。这两个实体可能相同,也可能不同。混淆它们会导致权限失控和审计混乱。
身份类型对照表
| 类型 | actor | subject | 适用场景 | 权限边界 |
|---|---|---|---|---|
| user identity | 用户 A | 用户 A | 用户直接交互 | 继承用户权限 |
| service account | system_bot | null | 后台任务、定时作业 | 系统级权限,独立于用户 |
| delegated token | workflow_123 | 用户 A | 用户授权的自动化工作流 | 工作流 scope,受限于用户授权范围 |
| tenant context | agent_456 | tenant_B | 多租户系统 | 租户隔离,不能跨租户访问 |
字段定义:actor 是发起调用的实体(用户、Agent、工作流、系统),日志中记录 actor 的 ID;subject 是被代表的实体(用户或 null),用户本人交互时 actor=subject,系统账号执行后台任务时 subject=null;delegatedBy 是委托来源,标识哪个用户授权了这个工作流;tenantId 是租户标识,用于多租户系统中的数据隔离。
根据 MCP Authorization 规范,MCP servers 必须验证 access token 是签发给自己的 intended audience。Token 的 audience 字段必须指向该 MCP server 的资源标识。Token 不应放在 URI query string,因为 URI 会出现在日志、浏览器历史、代理缓存中。
OWASP Access Control Cheat Sheet 强调 deny by default、least privilege,并在每个请求上执行检查。身份映射是权限检查的第一步:actor/subject/tenantId 决定了后续的权限判断。
工具权限:Agent 能调什么?
工具注册时不只是定义 name、description、input_schema。OpenAI Agents SDK 工具参考中有一组字段用于权限和执行控制。
工具权限决策表
| 权限控制 | 适用场景 | 实现方式 | 风险 |
|---|---|---|---|
| per-tool permission | 每个工具独立授权 | 工具注册时设置 permission_level(read/write/admin) | 权限配置复杂,需要维护权限矩阵 |
| scope minimization | 渐进式最小权限 | 初始 scope 只包含低风险操作,高权限操作通过 scope challenge 增量扩展 | Scope 管理成本高,需要动态调整 |
| whitelist | 工具白名单 | 只允许特定工具组合(如 read_customer + summarize) | 白名单维护成本,可能限制灵活性 |
| approval | 人工审批 | needs_approval=true 的工具在执行前暂停,等待人工审批 | 审批耗时,影响用户体验 |
OpenAI Agents SDK 工具字段包括:is_enabled 用于运行时启用控制,可根据用户角色、tenant、workflow context 动态禁用工具;needs_approval 标记是否需要人工审批,审批通过后仍会执行 tool_input_guardrails;tool_input_guardrails 负责输入校验(PII 检测、参数越界检查);tool_output_guardrails 负责输出校验(内容过滤)。
根据 MCP Security Best Practices,scope minimization 建议渐进式最小权限:初始 scope 只包含低风险的发现/读取操作(如 read:metadata、list:resources);高权限操作通过精确的 scope challenge 增量扩展;避免 wildcard/full-access scopes。
OWASP AI Agent Security Cheat Sheet 建议 per-tool permission scoping:不同 trust level 使用不同 tool sets;敏感操作显式授权;fail closed(权限检查失败时明确拒绝)。
Secret 隔离:Agent 怎么取用密钥?
Agent 不应直接持有长期明文 API key。OWASP Secrets Management Cheat Sheet 建议:集中和标准化 secret 管理;secret 管理系统也要支持 Authentication、Authorization、Accounting 和 lifecycle。
Secret 访问模式对照表
| 模式 | 风险 | 适用场景 | 示例 |
|---|---|---|---|
| 直接持有(明文 .env) | 泄漏风险高,无法追踪,无法撤销 | 不推荐 | 硬编码 API key |
| 环境变量 | 日志泄漏风险,仍无法追踪和撤销 | 单机部署 | process.env.API_KEY |
| secret vault | 集中管理、加密存储、审计追踪、可撤销 | 生产环境 | AWS Secrets Manager、HashiCorp Vault |
| secret reference | Agent 持有 reference,执行时按需取用短期 token | 多租户、高安全场景 | vault.get(secretRef) |
Secret 生命周期包括四个阶段:creation 时生成短期 token而非长期 key;rotation 定期轮换(每 30 天),自动化流程更新 secret 并通知相关系统;revocation 提供紧急撤销机制,发现泄漏时立即禁用 secret;expiration 设置过期时间,过期后自动失效。
MCP Security Best Practices 明确指出 token passthrough 是反模式:把用户 OAuth token 直接传给 Agent 会绕过安全控制、破坏 audit trail、打破信任边界。正确做法是用户授权给 Agent 时生成 delegated token(短期、scope 受限、audience 明确)。
OWASP Secrets Management 的核心原则:centralize、least privilege、automate、auditing。访问 secret 应遵循最小权限;人工维护会增加泄漏和错误风险,rotation/revocation/expiration 是生命周期的一部分。
审计日志:谁在什么时候调了什么?
审计日志要能还原”谁代表谁调用了哪个工具、访问了哪个对象、结果如何”,同时必须脱敏参数和 secret。
Audit Log Schema
| 字段 | 说明 | 脱敏规则 |
|---|---|---|
| traceId | 调用链路 ID(复用 N156 的 trace/runId 概念) | 不脱敏 |
| timestamp | 调用时间(ISO 8601) | 不脱敏 |
| actor | 发起调用的实体 | 不脱敏 |
| subject | 被代表的实体 | 不脱敏 |
| tool | 工具名 | 不脱敏 |
| action | 操作类型(read/write/delete) | 不脱敏 |
| resource | 操作对象 | 脱敏:customer_id → cust_*** |
| outcome | 结果(success/failure/denied) | 不脱敏 |
脱敏规则:不记录 token、secret、password、email、phone、PII。应记录 who/what/when/where/outcome。示例:customer_id=12345 记为 cust_;email=[email protected] 记为 e@***.com;token=Bearer xxx 记为 Bearer ***;password=secret123 不记录。
根据 OWASP Logging Cheat Sheet,安全日志应支持调查、审计和监控,但不能记录密码、session id、access token、敏感个人数据。应记录 who/what/when/where/outcome 等可追溯信息。
NIST SP 800-53 的 audit and accountability 控制族强调:审计日志是权限系统的最后一道防线。权限检查失败时,必须在日志中记录原因(actor 无权限、subject 无 target 权限、scope 不足)。
权限模型决策表:快速判断你的 Agent 应该用什么控制组合
身份映射、工具权限、Secret 隔离、审计日志不是独立控制,而是组合约束。以下是不同场景的控制组合。
| 场景 | identity type | tool permission | secret access | audit log | 典型应用 |
|---|---|---|---|---|---|
| 低风险内部工具 | service account | whitelist(只允许 read 工具) | 环境变量 | actor/tool/outcome | 内部报表生成、定时同步 |
| 多租户 SaaS | delegated token + tenantId | per-tool permission(按租户过滤) | secret vault(租户隔离) | full schema(含 tenantId) | CRM Agent、邮件助手 |
| 金融交易 | user identity + approval | scope minimization + approval | secret reference(短期 token) | full schema + approvalId | 交易审批、资金操作 |
| 敏感数据操作 | delegated token + approval | whitelist + approval + guardrails | secret vault(紧急撤销) | full schema + 脱敏 | 数据导出、客户查询 |
OWASP AI Agent Security Cheat Sheet 建议 separate tool sets(不同 trust level 使用不同工具集合)和 explicit authorization(敏感操作显式授权)。权限模型决策表的核心是组合关系:高风险场景需要多层控制叠加,而不是单一控制。
排障清单:权限问题的常见症状
以下是权限问题的常见症状、可能原因、检查步骤和解决方案。
| 症状 | 可能原因 | 检查步骤 | 解决方案 |
|---|---|---|---|
| Agent 调工具时返回 403 Forbidden | actor 无 tool permission 或 subject 无 target permission | 检查 actor 的 permission_level、subject 的 resource 权限 | 确认身份映射正确,调整权限矩阵 |
| 日志里看到 actor 为空或 subject 混乱 | 身份映射字段未正确传递 | 检查 Agent context 是否包含 actor/subject/tenantId | 确保身份字段在调用链路中正确传递 |
| 工具调用成功但审计日志缺失必要字段 | Audit Log Schema 未完整实现 | 检查日志写入逻辑是否包含所有字段 | 补齐 Schema,添加 traceId/approvalId |
| 用户 A 的请求可以读到用户 B 的数据 | tenantId 或 subject 未隔离,管理员 token 混用 | 检查是否使用 delegated token、tenantId 是否正确 | 改用 delegated token,强制 tenantId 校验 |
| Secret rotation 后 Agent 仍用旧 key | Secret reference 未更新,或 rotation 未生效 | 检查 vault 是否返回新 secret、Agent 是否重新获取 | 确保 rotation 自动更新 reference |
| 审批通过后工具仍调用失败 | Guardrails 失败(参数越界、PII 检测) | 检查 tool_input_guardrails 日志 | 调整参数或 guardrails 规则 |
落地清单:从 0 到 1 搭建 Agent 权限模型
以下是权限模型落地的 5 个核心步骤。
步骤 1:定义身份映射规则
决策点:是否需要多租户隔离(添加 tenantId 字段)?是否有后台任务(定义 service account)?是否有自动化工作流(使用 delegated token)?
代码示例(伪代码):
interface IdentityContext {
actor: string; // 发起调用的实体
subject: string | null; // 被代表的实体
delegatedBy?: string; // 委托来源
tenantId?: string; // 租户标识
}
步骤 2:设计工具权限矩阵
决策点:是否需要审批(设置 needs_approval=true)?是否需要动态过滤(实现 is_enabled 的运行时判断)?是否需要参数校验(实现 tool_input_guardrails)?
代码示例:
interface ToolPermission {
name: string;
permission_level: 'read' | 'write' | 'admin';
required_scope: string[];
needs_approval: boolean;
is_enabled: (context: IdentityContext) => boolean;
}
步骤 3:接入 secret vault
决策点:是否需要短期凭证(使用 secret reference)?是否需要紧急撤销(确保 vault 支持紧急禁用)?
代码示例:
async function getSecret(secretRef: string, context: IdentityContext): Promise<string> {
// 校验身份
await vault.authenticate(context.actor);
// 校验权限
await vault.authorize(context.actor, secretRef);
// 获取短期 token
const token = await vault.getToken(secretRef, expiresIn: '15m');
// 记录审计
await auditLog.record({
actor: context.actor,
action: 'get_secret',
resource: secretRef,
outcome: 'success'
});
return token;
}
步骤 4:实现审计日志
决策点:是否需要脱敏(实现 redaction 规则)?是否需要 traceId(复用 N156 的 trace/runId)?
代码示例:
interface AuditLogEntry {
traceId: string;
timestamp: Date;
actor: string;
subject: string | null;
tool: string;
action: 'read' | 'write' | 'delete';
resource: string; // 脱敏后
outcome: 'success' | 'failure' | 'denied';
}
步骤 5:测试权限边界
决策点:是否测试越权场景(模拟用户 A 访问用户 B 的数据)?是否测试 token 泄漏(模拟 secret 泄漏后的撤销流程)?是否测试审计追踪(通过 traceId 回溯完整链路)?
测试清单:越权测试(actor=user_A,resource=tenant_B → 应返回 403);Token 泄漏测试(vault.revoke(secretRef) → Agent 应无法获取新 token);Audit 追踪测试(通过 traceId 查询完整调用链路 → 应包含 actor/subject/tool/outcome)。
下一步:延伸阅读
Agent 权限模型涉及身份、工具、Secret、审计等多个层面。以下是相关的扩展阅读。
已发布文章:
- Agent Sandbox 指南:Sandbox 解决运行隔离(容器/Docker),本文讲权限和 secret 边界,两者互补。
- 工具调用实战:工具调用基础,本文扩展了工具白名单、per-tool permission、输入校验。
- AI Agent 监控与恢复:监控和告警基础,本文补了 audit 字段、traceId。
设计 Agent 权限模型
为 Agent 生产系统设计用户身份、工具权限、secret 访问和审计日志。
- 1
步骤 1: 列出工具和资源
列出 Agent 会调用的工具、资源、动作和外部系统,先确定哪些操作只是读取,哪些操作会写入、发送、删除或触发财务动作。 - 2
步骤 2: 明确身份上下文
为每次 run 明确 actor、subject、tenant、workflow 和 traceId,避免把用户身份、系统账号和自动化 workflow 混在同一个管理员身份里。 - 3
步骤 3: 区分身份类型
区分 delegated user identity、service account 和 system maintenance job,并为每种身份定义资源边界和审计字段。 - 4
步骤 4: 建立工具权限矩阵
为每个工具定义 action、resource、scope、approval、secret、audit metadata,并在执行前做 server-side authorization。 - 5
步骤 5: 接入 secret vault
把 secret 存到 vault 或凭证服务,只在执行层按需换取短期凭证,支持 rotation、revocation 和 expiration。 - 6
步骤 6: 实现 fail closed
在工具网关执行前检查 actor、subject、resource、action、scope 和 approval;任何检查失败都明确拒绝。 - 7
步骤 7: 写入脱敏审计日志
记录 who、what、when、where、outcome、traceId、approvalId 和脱敏后的资源摘要,并为权限变更、scope elevation、secret access 设置告警。
常见问题
Agent 调工具时到底代表用户、系统账号,还是 workflow 自己?
用户 OAuth 授权过了,为什么还需要 per-tool permission?
一个管理员 token 能不能让 Agent 替所有用户查数据?
Agent 能不能直接读取 .env 或用户 API key?
审批通过后,是否可以长期复用同一个高权限 token?
审计日志要记参数吗?如何避免把 token、邮箱、客户数据写进日志?
11 分钟阅读 · 发布于: 2026年9月17日
AI Agent 工程化专题:架构、工具调用、评估与恢复
如果你是从搜索进入这篇文章,建议顺手补上上一篇或继续下一篇,这样更容易把同一主题读完整。
上一篇
Agent 成本控制:模型路由、工具调用预算、缓存和失败重试怎么设计
把 AI Agent 成本控制拆成可落地的预算对象:模型路由、工具调用限额、prompt caching、Batch/Flex、失败重试、熔断、成本日志和告警字段,避免生产任务无声烧钱。
第 20 / 22 篇
下一篇
Agent 状态机设计:为什么复杂任务不能只靠 Prompt
复杂 Agent 任务不能只靠 prompt 记进度。本文用 state、event、transition、guard、action、checkpoint、retry、compensation、approval pause 和 terminal state,设计可恢复的 Agent 状态机。
第 22 / 22 篇



评论
使用 GitHub 账号登录后即可评论