AI 资产管理中的权限治理 + 常用安全认证方法总结
模型全链路权限管理
核心主题:AI 资产管理中的权限治理
当大模型、知识库、Skill、MCP Server 这些 AI 资产进入企业之后,如何系统性地管理它们的访问权限?
目录
一、整体框架
主要问题:当大模型、知识库、Skill、MCP Server 这些 AI 资产进入企业之后,怎么管理它们的访问权限?
本文从四个层次递进展开:
| 层次 | 核心问题 | 内容概要 |
|---|---|---|
| 第一层:AI 资产管理 | 管什么? | 梳理四类 AI 资产及其各自的权限关注点 |
| 第二层:权限管理 | 谁调谁? | 拆解三条权限链路的校验机制与安全设计 |
| 第三层:身份分类 | 谁是调用方? | 区分人类身份与非人身份,选择对应协议 |
| 第四层:安全认证方式 | 怎么验? | 八种认证方式的原理、优劣及在 AI 场景的组合 |
四层之间的关系:第一层定义"管什么资产",第二层定义"资产之间的权限链路",第三层定义"链路中的调用方是谁",第四层定义"用什么技术手段验证调用方身份"。四层从上到下逐步细化,共同构成完整的权限治理体系
二、第一层:AI 资产管理
企业里的 AI 资产分四类,每类的权限模型不同:
2.1 大模型
谁有权调用哪个模型?是开源模型还是商业 API?调用是否限量(token 配额)?是否允许把敏感数据发给第三方模型?
2.2 知识库
谁有权检索哪个知识库?知识库里的数据有没有分级(公开/内部/机密)?模型检索时是否做了数据脱敏(把敏感内容替换、遮盖、抹除之后再输出给使用者)?
2.3 Skill
谁有权使用哪个 Skill?Skill 内部调用的工具权限是否做了裁剪(权限继承等问题)?
权限继承:指组件内部调用下游服务时,直接使用组件自身服务账号权限执行,而不是使用发起操作的终端用户权限;容易绕过用户权限控制,产生越权漏洞;安全方案是权限透传,下游重新校验原始用户身份。
2.4 MCP Server
谁有权连接哪个 MCP Server?Server 暴露的工具是否做了白名单?Server 的端点是否需要鉴权?
三、第二层:权限管理(三条链路)
在明确了四类 AI 资产之后,需要进一步定义这些资产之间的权限关系。本文将权限关系梳理为三条链路,每条链路解决一类"谁有权调谁"的问题。
3.1 权限链路总览
三条权限链路如下:
-
模型 → 知识库/Skill/MCP 的权限:大模型在运行时需要访问知识库(RAG 检索)、调用 Skill(执行任务)、连接 MCP Server(调用工具)。每一步都需要权限校验——不是模型想调就能调,要有明确的授权策略。
-
Skill → 工具的权限:Skill 内部编排了多个工具调用,每个工具的调用都需要权限校验。前面讨论过的"权限继承问题"就在这里——Skill 不应该继承 Agent 的全部权限,而应该按需分配。
-
用户 → AI 资产的权限:最终用户通过 Agent 访问 AI 资产时,需要校验用户是否有权使用这个模型、检索这个知识库、触发这个 Skill。
下面逐一详细拆解每条链路。
3.2 链路一:模型 → 知识库/Skill/MCP
核心目标:控制模型运行时访问下游资源的权限。
实际场景
用户问了一个问题,模型推理过程中需要:
-
查知识库(RAG 检索):用户问"公司Q3的销售数据",模型需要去知识库检索
-
调 Skill:模型判断需要"生成数据报告",触发对应 Skill
-
调 MCP Server 工具:模型需要"查询订单系统",调用 MCP Server 暴露的工具
这三个动作不是模型自己决定的,是 Host/Agent 在模型输出 tool-use 决策后,代为执行的。所以权限校验的时机是 Host 执行工具调用之前。
权限校验的设计核心:逐层传递用户身份,逐层校验

三个子链路详解
模型 → 知识库:
知识库按敏感等级分级(公开/内部/机密),用户角色对应可访问的等级。RAG 检索时,Host 把用户的权限范围传给知识库服务,知识库只返回用户有权访问的文档片段。不是模型检索到什么就用什么,是知识库根据调用者权限做了过滤后再返回。
测试要点:用低权限用户的 JWT 去触发 RAG 检索,验证返回的数据是否包含高权限文档的内容。如果返回了,就是越权漏洞。
模型 → MCP Server:
Host 连接 MCP Server 时需要鉴权(远程模式)。MCP Server 验证调用方身份后,还要校验该调用方是否有权调用特定工具。一个 MCP Server 可能暴露 10 个工具,但某个 Agent 只被授权调用其中 3 个。
实现方式:MCP Server 维护一份工具白名单,按调用方身份过滤 tools/list 返回的工具清单。低权限的 Agent 调 tools/list 时,只能看到它有权调用的工具,其余的根本不暴露。
测试要点:用低权限 Agent 的凭证调 tools/list,检查返回的工具列表是否包含未授权工具。然后直接调 tools/call 尝试调用未授权工具,验证是否被拒绝(不能只靠 tools/list 隐藏,tools/call 层也要做权限校验)。
模型 → Skill:
Skill 的加载本身需要权限校验——不是所有用户都能触发所有 Skill。Host 在加载 SKILL.md 之前,先检查当前用户/Agent 是否有权使用该 Skill。
认证方式在这条链路中的体现
-
Agent → MCP Server:用 OAuth2 Client Credentials 或 mTLS,Agent 拿一个 service token 证明"我是授权的 Agent"
-
Agent → 知识库:用 JWT 断言,里面带用户身份透传下去,知识库据此做数据级权限过滤
-
Agent → Skill:Skill 加载是 Host 内部行为,但 Skill 内部调工具时走工具的鉴权流程
3.3 链路二:Skill → 工具
核心目标:Skill 内部编排了多个工具调用,Skill 不应该继承 Agent 的全部工具权限,而应该按需分配。
实际场景
一个"生成报告"的 Skill,内部流程是:
-
调 search_web 工具搜索资料
-
调 read_file 工具读取模板
-
调 write_file 工具写出报告
但 Agent 本身还配了 execute_command(执行系统命令)、send_email(发邮件)等高危工具。如果 Skill 继承了 Agent 的全部权限,攻击者通过 Prompt Injection 劫持 Skill 的执行流程后,就能调 execute_command 执行任意命令。
权限模型设计
Skill 级权限裁剪:每个 Skill 在 SKILL.md 中声明自己需要的工具清单,Host 加载 Skill 时只注入这些工具,其余工具对模型不可见:
# SKILL.md 中的权限声明 tools_required: - search_web - read_file - write_file # 没有声明 execute_command, send_email → 模型在这个 Skill 执行期间看不到这两个工具
两层校验:
-
第一层是可见性控制——Skill 执行期间,Host 只把该 Skill 声明的工具注入模型上下文。
-
第二层是调用时校验——即使模型被注入攻击后试图调用未授权工具,Host 在执行 tools/call 之前也要校验"当前 Skill 的权限范围内是否包含这个工具",不包含就拒绝。不能只靠可见性控制,因为模型可能被 Prompt Injection 诱导输出不存在的工具名或构造异常调用。
跨 Skill 调用的权限传递
如果一个 Skill A 内部调用了 Skill B,权限处理:
-
Skill B 的权限范围独立于 Skill A,不能继承 A 的权限
-
Skill B 被加载时,Host 重新按 B 的声明注入工具
-
如果 Skill B 需要用 Skill A 已有的工具,需要在 B 自己的 tools_required 中声明
安全测试要点
-
构造 Prompt Injection 攻击,诱导模型在 Skill 执行期间调用未声明的工具,验证是否被拦截
-
检查 Skill 执行完毕后,工具上下文是否恢复为 Agent 的完整工具集(防止 Skill 的权限范围"泄漏"到后续对话)
-
测试 Skill 嵌套调用时,子 Skill 是否能越权使用父 Skill 的工具
3.4 链路三:用户 → AI 资产
核心目标:最终用户通过前端界面访问 AI 平台时,能使用哪些 AI 资产。
实际场景
用户登录 AI 平台后,能做这些事:
-
跟大模型对话(哪个模型?)
-
上传文件到知识库(哪个知识库?)
-
使用 Skill 完成任务(哪个 Skill?)
-
触发 Agent 自动执行任务(Agent 能访问哪些工具?)
权限模型设计
RBAC + ABAC 混合模型:
-
RBAC(基于角色):用户关联角色,角色关联资源权限。比如"普通员工"角色能使用对话模型和公开知识库,"数据分析师"角色能使用代码生成模型和机密数据知识库。
-
ABAC(基于属性):在角色之上加条件判断。比如"普通员工"角色有权使用知识库 A,但条件是"工作时间 + 公司内网 + 数据标签非机密"。这适合更细粒度的权限控制。
权限策略示例:
{
# 基础的身份标识
"user_id": "zhangsan",
"role": "analyst",
# permissions:RBAC 核心 —— 用户可访问的全部 AI 资产白名单
# 对应文档定义的四类 AI 资产 + 底层工具,**只允许列表内资源访问,默认拒绝其余所有**(最小权限原则)
"permissions": {
"models": ["qwen-72b-chat", "qwen-coder"],
"knowledge_bases": ["public-docs", "internal-finance"],
"skills": ["generate-report", "data-analysis"],
"mcp_servers": ["internal-db-query"],
"tools": ["search_web", "read_file", "query_db"]
},
# conditions:ABAC 属性条件 —— 使用资源的附加约束(不满足则权限失效)
"conditions": {
"time_window": "09:00-18:00",
"network": "corporate-vpn",
"max_daily_tokens": 500000
}
}
认证流程

关键设计原则
-
权限最小化:默认拒绝所有,只显式开放需要的权限。不是"默认开放,按需关闭"。
-
Fail-Closed:权限校验失败或服务不可用时,拒绝请求而非放行。比如权限服务宕机了,应该拒绝所有请求而不是临时放行。
-
权限透传:用户的 JWT 一路传递到最底层的工具调用,每一层都验。不能只在入口验一次就信任后续所有调用。
-
动态权限回收:用户权限变更(离职、调岗)后,JWT 应该短期过期或支持主动吊销。不能用永久有效的 token。
安全测试要点
-
水平越权:用 A 用户的 JWT 尝试访问 B 用户的 AI 资产(如 A 的知识库、A 的对话历史)
-
垂直越权:用普通用户 JWT 尝试调用管理员才能使用的模型或 Skill
-
权限绕过:构造异常 JWT(篡改 role 字段、删除 permissions 字段、使用过期 token),验证是否被拒绝
-
权限泄漏:用户 A 的 Agent 在执行任务时,是否会访问到用户 A 无权访问的资源(Agent 继承了用户身份,但如果权限透传不完整,可能在某个环节丢失用户身份,变成用 Agent 自己的权限访问)
-
会话劫持:窃取他人的 JWT 后调用 AI 资产,验证是否有 IP 绑定、设备指纹等二次校验
3.5 三条链路的关系

三条链路是串联的:用户身份从链路三进入,一路透传到链路二的工具调用。任何一环断了(身份信息丢失、权限校验缺失),都可能导致越权。
核心设计原则就一条:每一次跨资源调用,都要验证"调用方是谁"和"调用方有权做这件事吗"。这跟做传统身份安全测试的逻辑完全一致,只不过资源从"API 接口"变成了"模型、知识库、Skill、MCP 工具"。
四、第三层:身份分类
在权限链路中,调用方分为两大类:人类身份(真实的人通过前端界面访问)和非人身份(服务、Agent、MCP Server 之间的互访)。不同身份类型适用不同的认证协议。
4.1 人类身份
真实的人通过前端界面访问 AI 资产。可选协议:
-
OAuth2:授权码流程,用户通过浏览器跳转登录,适合 Web 应用
-
OIDC:在 OAuth2 之上加了身份层,能拿到用户的身份信息(姓名、邮箱、角色)
-
JWT:用户登录后签发 JWT 令牌,后续请求携带 JWT 证明身份
-
平台认证:企业内部 SSO(单点登录),对接公司统一身份平台
4.2 非人身份
服务、Agent、MCP Server 之间的互访。可选协议:
-
JWT:服务间调用时携带 JWT 断言,证明"我是服务 A,我有权调用服务 B"
-
平台认证:内部服务注册中心颁发的服务身份凭证
-
mTLS:双向 TLS 证书认证,双方互相验证证书,适合服务网格架构
-
SPIFFE:云原生环境下的统一身份框架,为每个工作负载分配可验证的身份
五、第四层:安全认证方式
前文梳理了人类身份与非人身份各自可选的协议,下面逐一详解每种认证方式的实现原理、本质缺陷、安全测试要点,以及在 AI 资产管理中的实际用途。
5.0 认证方式总览
人类身份常用:
-
API Key / Static Token:最简单但最不安全。一个固定字符串,谁拿到谁能用,无法区分调用者身份,无法做细粒度权限控制。适合内部低敏感场景,不适合生产环境的高权限操作。
-
Basic Auth(用户名/密码):每次请求携带 Base64 编码的用户名密码。比 API Key 强一点——但只要密码泄露即全盘沦陷,无法做临时授权,无法做细粒度权限。
非人身份常用:
-
AK/SK(云签名 / HMAC 签名):云厂商标准做法。Access Key ID 是公开的标识,Secret Access Key 是私密的密钥。每次请求用 SK 对请求内容做 HMAC 签名,服务端用相同 SK 验签。好处是密钥不传输、签名不可伪造、请求内容防篡改。AWS、百度云、阿里云都用这套。
-
OAuth2 Client Credentials:专门为服务间通信设计的 OAuth2 流程。服务 A 用自己的 client_id 和 client_secret 向授权服务器换 access_token,然后拿 token 调服务 B。好处是 token 有过期时间(不像 API Key 永久有效),授权服务器可以做细粒度权限控制。
-
JWT 断言 / Service Assertion:服务自己签发或由信任方签发的 JWT,里面包含服务身份、权限范围、过期时间。接收方验签后信任 JWT 中的声明。好处是去中心化——不需要每次都去授权服务器验证,本地验签即可。
-
mTLS 证书:双向 TLS。不仅客户端验证服务端证书(普通 HTTPS 做的),服务端也验证客户端证书。只有持有合法证书的客户端才能建立连接。适合高安全要求的服务间通信,Kubernetes、Service Mesh 中广泛使用。
-
SPIFFE:CNCF 的云原生身份框架。为每个工作负载(Pod、容器、进程)分配一个 SPIFFE ID(如 spiffe://example.com/ns/default/sa/my-service),通过 SPIRE 服务器签发短期 SVID(SPIFFE Verifiable Identity Document)。SVID 可以是 JWT 或 X.509 证书。核心价值:在动态的云原生环境中,工作负载没有固定 IP,SPIFFE 提供了不依赖网络位置的身份验证。
以下按复杂度从低到高逐一详解。
5.1 API Key / Static Token
实现原理:最简单粗暴。平台给每个调用方分配一个固定字符串,调用方每次请求在 Header 里带上:
Authorization: Bearer sk-xxxxxxxxxxxxxxxx
服务端收到请求后,拿这个 Key 去数据库查"这个 Key 是谁的、有什么权限",查到就放行。
本质缺陷:
-
Key 是明文传输的(即使走 HTTPS,服务端日志、网关日志都可能记录)
-
永不过期(除非手动轮换),泄露后无法自动失效
-
无法做细粒度权限(一个 Key 通常对应一组固定权限,无法动态调整)
-
无法区分调用者(谁拿到了 Key 谁就是"主人")
安全测试要点:检查 API Key 是否出现在前端代码、日志、错误信息中;是否支持吊销;是否有使用期限。
5.2 Basic Auth(用户名/密码)
实现原理:用户名和密码用冒号拼接后做 Base64 编码,放在 HTTP Header 中:
import base64
credentials = base64.b64encode(b"admin:Admin@123").decode()
# credentials = "YWRtaW46QWRtaW5AMTIz"
# 请求时
headers = {"Authorization": f"Basic {credentials}"}
服务端解码后拿到用户名密码,查数据库验证。
本质缺陷:
-
Base64 不是加密,是编码,任何人都能解码
-
每次请求都传密码,泄露风险高
-
密码改了所有调用方都要改
-
无法做临时授权
在 AI 资产管理中基本不用,除非对接遗留系统。
5.3 OAuth2
5.3.1 简述 OAuth2.0
简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
举个实例来说明:
有一个"云冲印"的网站(客户端),可以将用户(资源拥有者)储存在Google(HTTP服务提供商)的照片,冲印出来。用户为了使用该服务,必须让"云冲印"读取自己储存在Google上的照片。
所以"云冲印"需要得到用户的授权,Google才会同意"云冲印"读取这些照片。传统方法就是,用户将自己的Google用户名和密码,告诉"云冲印",后者就可以读取用户的照片了。这样的做法有以下几个严重的缺点:
(1)"云冲印"为了后续服务会保存用户的账户密码,这样非常不安全
(2)"云冲印"直接获取全部权限,用户无法限制"云冲印"获得的授权范围和时间,且只有修改密码才能收回权限。
(3)第三方软件一旦被破解,会导致用户账户密码泄漏,后果严重。
OAuth的作用就是让"客户端"安全可控地获取"用户"的授权,从而可以和"服务商提供商"进行互动。
5.3.2 OAuth 的授权认证流程
认证思路
OAuth 在"客户端"与"服务提供商"之间,设置了一个授权层(authorization layer)。"客户端"不能直接登录"服务提供商",只能登录授权层,以此将用户与客户端区分开来。"客户端"登录授权层所用的令牌(token),与用户的密码不同。用户可以在登录的时候,指定授权层令牌的权限范围和有效期。
"客户端"登录授权层以后,"服务提供商"根据令牌的权限范围和有效期,向"客户端"开放用户储存的资料。
认证流程

1)用户访问第三方应用程序(简称:客户端)以后,客户端要求用户给予授权。
2)用户同意给予客户端授权。
3)客户端使用第 2 步获得的授权,向认证服务器申请令牌。
4)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
5)客户端使用令牌,向资源服务器申请获取资源。
6)资源服务器确认令牌无误,同意向客户端开放资源。
上述中的第 2 步是关键,即用户怎样才能给于客户端授权。有了这个授权以后,客户端就可以获取令牌,进而凭令牌获取资源。
5.3.3 四种授权类型
参考:OAuth2.0入门(一)—— 基本概念详解和图文并茂讲解四种授权类型
为了获得访问令牌(Token),客户端需要先从资源所有者(用户)那里获得授权。授权是以授权许可(Grant Type)的形式来表示的。OAuth定义了四种授权类型:
1. 授权码模式(Authorization Code Grant)

当用户访问资源时,比如在网易云音乐中使用第三方登录功能,例如QQ登录,那么这里的资源就是用户的QQ昵称和头像等信息。此时第三方应用(网易云音乐)将发送请求到授权服务器(QQ)去获取授权,此时授权服务器(QQ)将返回一个界面给用户,用户需要登录到QQ,并同意授权网易云音乐获得某些信息(资源)。当用户同意授权后,授权服务器将返回一个授权码(Authorization Code)给第三方应用,此时第三方应用在通过client_id、client_secret(这是需要第三方应用在授权服务器去申请的)和授权码去获得Access Token和Refresh Token,此时授权码将失效。然后就是第三方应用通过Access Token去资源服务器请求资源了,资源服务器校验Access Token成功后将返回资源给第三方应用。
2. 隐式授权(Implicit Grant)
隐式授权又称简化授权模式,它和授权码模式类似,只不过少了获取授权码的步骤,是直接获取令牌token的,且没有Refresh Token,适用于公开的浏览器单页应用。因为令牌直接从授权服务器返回,所以没有安全保证,令牌容易因为被拦截窃听而泄露。
3. 密码模式(Resource Owner Password Credentials Grant)

首先资源所有者(用户)提供自己的用户名和密码给客户端(Client),然后客户端(Client)携带从用户那里获取的凭证去授权服务器请求Token,授权服务器对客户端进行身份认证,并校验资源所有者的凭证,如果都校验通过,则发放Token。
适用范围:只适用于应用是受信任的场景。一个典型的例子是同一个企业内部的不同产品要使用本企业的 Oauth2.0 体系。在这种情况下,由于是同个企业,不需要向用户展示"xxx将获取以下权限"等字样并询问用户的授权意向,而只需进行用户的身份认证即可。这个时候,只需要用户输入凭证并直接传递给鉴权服务器进行授权即可。
4. 客户端授权模式(Client Credentials Grant)

客户端(Client)通过Client_id和Client_secret去授权服务器请求Token,授权服务器认证Client_id和Client_secret是否正确,若正确则发放Token给客户端(Client)。最后客户端通过AccessToken请求资源。
适用范围:只适用于应用是受信任的场景。
5.4 JWT(JSON Web Token)
参考文章链接:全网最透彻:JWT Token 到底是什么?原理+结构+流程图
官方定义
JWT = JSON Web Token
一种开放标准(RFC 7519),用于在网络应用中以 JSON 对象的形式安全传递信息。
核心特点:
-
轻量级:数据量小,传输快
-
自包含:Token 本身携带用户信息,服务器不需要存储 Session
-
无状态:服务端不需要保存任何会话信息
-
跨域/跨服务:适合微服务、分布式、前后端分离
一句话总结:JWT 就是一个加密的、自带用户信息的"身份令牌",服务端不用存 Session,直接验签即可认证。
5.4.1 JWT 的结构
JWT 由三段组成,用 . 分隔:
eyJhbGciOiJIUzI1NiJ9. eyJ1c2VyX2lkIjoiemhhbmdzYW4iLCJyb2xlIjoiYW5hbHlzdCIsImV4cCI6MTcyMzQ1NjAwMH0. s8fJH2k...
三段分别对应:Header.Payload.Signature
Header(算法声明)
作用:描述JWT的加密算法,类型
{
"alg": "HS256", // 签名算法:HMAC-SHA256
"typ": "JWT" // 类型固定为 JWT
}
Payload(负载——存放数据)
作用:存放用户信息(如userId, username, 过期时间)
注意:默认是Base64编码,并非加密,不能存密码进去。
{
"user_id": "zhangsan",
"role": "analyst",
"permissions": {
"models": ["qwen-72b-chat"],
"knowledge_bases": ["public-docs", "internal-finance"],
"tools": ["search_web", "query_db"]
},
"iat": 1723452400, // 签发时间
"exp": 1723456000, // 过期时间(1小时后)
"iss": "ai-platform-auth", // 签发方
"sub": "zhangsan" // 主体
}
Signature(签名)
作用:防止Token被篡改
HMAC-SHA256( base64(header) + "." + base64(payload), SECRET_KEY )
只有服务器持有密钥,只要签名正确,说明 Token 未被篡改。
5.4.2 JWT 的认证流程

-
用户登录,发送账号密码
-
服务端验证成功
-
服务端根据用户信息生成 JWT Token
-
服务端把 JWT 返回给前端
-
前端存储 JWT(localStorage / Cookie)
-
前端每次请求在请求头带上 JWT
-
服务端验证签名
-
签名正确 → 合法用户
-
签名错误 → 伪造/篡改,拒绝
-
-
完成鉴权
5.4.3 HS256 vs RS256
上面用的是 HS256(对称加密)——签发和验签用同一个 SECRET_KEY。问题是:任何知道 SECRET_KEY 的服务都能伪造 token。
生产环境通常用 RS256(非对称加密):
# 签发方用私钥签 token = jwt.encode(payload, PRIVATE_KEY, algorithm="RS256") # 验证方用公钥验(公钥可以公开分发,拿到公钥也无法伪造 token) payload = jwt.decode(token, PUBLIC_KEY, algorithms=["RS256"])
在 AI 资产管理中的应用:授权服务器持有私钥签发 JWT,模型网关、知识库服务、MCP Server 各自用公钥验签。不需要每次都去授权服务器验证 token 是否有效,本地验签即可,性能更好。
5.4.4 JWT 断言(Service Assertion)
服务自身自己签发,不经过统一授权服务器,专门用于AI 体系内服务与服务之间的调用认证(Agent ↔ MCP、Agent ↔ 知识库、Skill ↔ 工具)。 核心:Agent 服务用自己的私钥生成一段自证身份的 JWT,调用下游 MCP / 知识库时带上;下游服务提前持有该 Agent 的公钥,本地验签就能确认调用方身份,不需要远程请求授权服务器鉴权,实现服务间点对点互信。
# 载荷:声明本次调用的身份、目标、权限、有效期
{
"sub": "agent-service-a", # subject:调用主体,当前是谁发起请求(Agent A)
"iss": "agent-service-a", # issuer:签发者,自己给自己发凭证
"aud": "mcp-server-db", # audience:受众,这个JWT只能给MCP数据库服务使用
"scope": "tools:call", # 权限范围:仅允许执行工具调用操作
"exp": int(time.time()) + 300 # 过期时间:仅5分钟有效,短期凭证降低泄露风险
}
# 用Agent自身私钥签名
jwt.encode(..., AGENT_PRIVATE_KEY, algorithm="RS256")
MCP Server 收到后用 Agent 的公钥验签,确认"这确实是 Agent A 签发的,它有权调我的工具"。
关键区别:不经过授权服务器,服务间直接互信。前提是双方预先交换了公钥。
-
RS256非对称加密是关键
-
Agent持有私钥:只有它能生成合法断言JWT;
-
MCP服务持有Agent的公钥:仅能验证签名,无法伪造新的JWT; 解决了对称HS256密钥共享带来的伪造风险。
-
-
请求携带方式:放在HTTP标准
Authorization: Bearer请求头,和用户JWT传输格式统一,网关、服务统一解析逻辑。
完整调用流程(Agent A 调用数据库MCP服务)
-
Agent需要查询数据库工具,本地生成一段JWT断言;
-
在请求头附上该断言,发起POST请求到MCP-DB服务;
-
MCP服务拿到JWT后,使用预先同步的
agent-service-a公钥本地验签; -
验签通过后校验载荷约束:
-
校验
aud:确认这个Token是发给自己的,不能拿来调用其他服务; -
校验
exp:判断凭证未过期; -
校验
scope:确认仅允许工具调用,无越权操作;
-
-
全部校验通过,才允许Agent调用内部数据库查询工具;任意一项不满足直接返回403拒绝。
和普通授权服务器JWT的核心区别
| 维度 | 统一授权服务器JWT(用户侧) | JWT服务断言(Service Assertion) |
|---|---|---|
| 签发方 | 独立授权中心服务 | 调用方服务自身(Agent自己签发) |
| 依赖 | 必须依赖授权服务器,鉴权可联动中心黑名单、动态权限回收 | 去中心化,本地公钥验签,不依赖第三方服务 |
| 使用对象 | 人类终端用户 | 非人服务、Agent、Skill、MCP等内部组件 |
| 信任前提 | 所有服务信任授权中心 | 上下游服务提前交换公钥,点对点互信 |
| 权限回收 | 授权中心可主动吊销token、实时修改权限 | 无法实时回收,只能等待exp过期,固有短板 |
在AI全链路权限框架里的业务价值
结合文档三层权限链路,它主要解决链路一、链路二的服务间鉴权问题:
-
链路一:模型→MCP/知识库 Agent调用MCP Server时,用JWT断言证明自身服务身份,MCP基于断言过滤可调用工具白名单;同时断言内部可嵌套透传用户JWT,实现「服务身份+终端用户身份」双重校验。
-
链路二:Skill→底层工具 Skill服务自签断言,限定
scope仅包含自身SKILL.md声明的工具,防止Prompt Injection越权调用高危工具。 -
性能优势 微服务集群大规模调用时,不用每次鉴权都远程请求授权服务器,本地验签,大幅降低授权中心压力。
安全测试要点
-
alg算法篡改漏洞 攻击者截获断言后,把签名算法
RS256改成none(无签名)或HS256,跳过验签伪造载荷。 校验标准:服务端必须强制校验alg字段,只允许预定义的RS256,拒绝none、HS256等非法算法。 -
exp过期校验缺失 若服务不判断过期时间,泄露的过期断言可无限重放调用;标准:拒绝已超过exp时间的所有JWT断言。
-
aud受众校验缺失 攻击者把发给MCP-DB的断言,拿去调用MCP-运维服务;若不校验aud,会发生跨服务越权。标准:仅放行aud与当前服务名称匹配的token。
-
权限无法动态回收(固有缺陷) 断言是服务本地签发,授权中心无管控能力。如果Agent权限被回收、Agent被下线,已签发未过期的断言仍能正常使用,只能等5分钟过期。 优化方案:缩短exp有效期(文档示例仅5分钟)、搭配mTLS/SPIFFE做双重身份兜底。
-
私钥泄露风险 Agent私钥是信任根,一旦泄露,攻击者可伪造任意JWT断言,完全冒充Agent调用所有下游资源。 防护:私钥不能明文存代码/配置文件,使用密钥管理服务KMS、容器密钥挂载。
适用场景与不适用场景
适合使用JWT断言
企业内部AI集群服务间高频调用:Agent ↔ MCP、Agent ↔ 知识库、Skill ↔ 工具,追求低延迟、去中心化鉴权。
不适合使用
-
面向外部第三方调用(无法提前交换公钥,改用OAuth2 Client Credentials);
-
需要实时、立即回收权限的场景(优先使用授权服务器统一签发的JWT,支持黑名单吊销);
-
公网开放接口(优先mTLS、AK/SK签名,安全性更强)。
5.5 AK/SK(云签名 / HMAC 签名)
参考文章链接:公有云API的认证方式:AK/SK 简介_ak,sk-CSDN博客
AK/SK(aksk)鉴权原理简介_ak sk原理-CSDN博客
ak/sk 是一种身份认证方式,常用于系统间接口调用时的身份验证,其中 ak 为 Access Key ID,sk 为 Secret Access Key。客户端和服务端两者会协商保存一份相同的 sk,其中 sk 必须保密。
-
AK:Access Key Id,用于标示用户
-
SK:Secret Access Key,是用户用于加密认证字符串和用来验证认证字符串的密钥,其中 SK 必须保密
通过使用 Access Key Id / Secret Access Key 加密的方法来验证某个请求的发送者身份。
客户端在调用服务端接口的时候,会带上 ak 以及 signature(使用 sk 对内容进行加密后得出的签名)进行请求,在服务端接收到这个请求的时候,首先会根据 ak 去数据库里面去找到对应的 sk,然后使用 sk 对请求内容进行加密得到一个签名,然后对比客户端传过来的签名和服务端计算的出来的签名是否一致,如果一致则代表身份认证通过,反之则不通过。
使用机制
云主机接收到用户的请求后,系统将使用 AK 对应的相同的 SK 和同样的认证机制生成认证字符串,并与用户请求中包含的认证字符串进行比对。如果认证字符串相同,系统认为用户拥有指定的操作权限,并执行相关操作;如果认证字符串不同,系统将忽略该操作并返回错误码。
流程
-
判断用户请求中是否包含 Authorization 认证字符串。如果包含认证字符串,则执行下一步操作。
-
基于 HTTP 请求信息,使用相同的算法,生成 Signature 字符串。
-
使用服务器生成的 Signature 字符串与用户提供的字符串进行比对,如果内容不一致,则认为认证失败,拒绝该请求;如果内容一致,则表示认证成功,系统将按照用户的请求内容进行操作。
原理
客户端:
-
构建 http 请求(包含 access key)
-
使用请求内容和 secret access key 计算的签名(signature)
-
发送请求到服务端
服务端:
-
根据发送的 access key 查找数据库得到对应的 secret-key
-
使用同样的算法将请求内容和 secret-key 一起计算签名(signature),与客户端步骤 2 相同
-
对比用户发送的签名和服务端计算的签名,两者相同则认证通过,否则失败
实现原理
不传输密钥本身,而是用密钥对请求内容做签名,服务端用相同密钥验签:
import hmac
import hashlib
import base64
def sign_request(method, url, headers, body, sk):
# 1. 构造待签名字符串(Canonical Request)
canonical_string = f"{method}\n{url}\n{sorted_headers_string}\n{body_hash}"
# 2. 用 SK 做 HMAC-SHA256 签名
signature = hmac.new(
sk.encode("utf-8"),
canonical_string.encode("utf-8"),
hashlib.sha256
).hexdigest()
# 3. 请求中带 AK 和签名
headers["X-Auth-Key"] = ak
headers["X-Auth-Signature"] = signature
headers["X-Auth-Timestamp"] = str(int(time.time()))
return headers
服务端验证:
def verify_signature(request, sk_store):
ak = request.headers["X-Auth-Key"]
sk = sk_store.get(ak) # 根据 AK 查到对应的 SK
# 用相同算法重新计算签名
expected_signature = compute_signature(request, sk)
# 对比签名(用恒定时间比较防时序攻击)
if not hmac.compare_digest(expected_signature, request.headers["X-Auth-Signature"]):
raise Exception("Invalid signature")
# 验证时间戳防重放
timestamp = int(request.headers["X-Auth-Timestamp"])
if abs(time.time() - timestamp) > 300: # 5分钟窗口
raise Exception("Request expired")
关键安全要素
-
签名覆盖完整请求:方法 + URL + Headers + Body 都要参与签名。常见漏洞是签名未包含 Body,攻击者拿到签名请求后篡改 Body 内容。
-
时间戳防重放:请求中带时间戳,服务端拒绝超过窗口期(如 5 分钟)的请求。否则攻击者截获请求后可以无限重放。
-
nonce 防重放:更严格的做法是每次请求带一个随机 nonce,服务端记录已用过的 nonce(缓存 5 分钟),拒绝重复的 nonce。
-
恒定时间比较:签名对比必须用 hmac.compare_digest 而非 ==。用 == 时,攻击者可以通过测量响应时间逐字节猜解签名(时序攻击)。
在 AI 资产管理中的用途:Agent 调用大模型 API 时用 AK/SK 签名。比 API Key 安全——即使请求被截获,攻击者没有 SK 也无法伪造新请求。
5.6 mTLS(双向 TLS)
参考文章链接:mTLS到底是个啥?服务间双向认证从原理到实战,一篇搞定-腾讯云开发者社区
5.6.1 TLS 基础
在讲 mTLS 之前,我们得先把 TLS 搞明白。日常我们访问 https 网站,浏览器地址栏那个小锁,背后就是 TLS 在工作。
TLS 的核心逻辑其实很简单——单向认证。什么意思呢?就是客户端去验证服务端的身份,但服务端不验证客户端。流程大概是这样:
-
客户端发起连接请求,告诉服务端我支持哪些 TLS 版本
-
服务端把自己的证书(server.crt)发过来
-
客户端验证这个证书是不是可信 CA 签发的,有没有过期,域名对不对
-
验证通过后,客户端生成一个随机数作为预主密钥,用服务端公钥加密发过去
-
服务端用私钥解密拿到这个随机数
-
双方基于这个随机数协商出会话密钥,后续通信就用这个对称密钥加密

5.6.2 mTLS 概述
参考文章链接:https://juejin.cn/post/7551782160920199168
mTLS(Mutual Transport Layer Security,双向传输层安全)是一种基于 TLS 协议的增强型身份认证与加密技术,核心区别于传统单向 TLS(仅客户端验证服务器身份),实现了客户端与服务器的双向身份核验,同时保障数据传输的机密性与完整性。它是零信任架构("永不信任,始终验证")中验证服务或终端身份的核心技术之一。
传统单向 TLS 仅解决"客户端确认服务器身份"的问题(如浏览器访问 HTTPS 网站时验证服务器证书),而 mTLS 在此基础上增加了"服务器确认客户端身份"的环节,二者的认证逻辑对比如下:

5.6.3 握手流程
mTLS 基于 TLS 1.2/1.3 协议扩展实现,其核心差异体现在握手阶段的双向证书验证环节。以下以 TLS 1.2 为例,拆解完整握手流程(共 11 步,关键差异步骤已标注):
-
客户端发起请求(Client Hello):客户端向服务器发送协议版本、支持的加密套件列表、随机数(Client Random)等信息,表明希望建立 TLS 连接。
-
服务器响应(Server Hello):服务器确认协议版本和加密套件,返回随机数(Server Random)、服务器证书(含服务器公钥),并发送"证书请求"(mTLS 关键步骤 1:单向 TLS 无此步骤)。
-
客户端验证服务器身份:
-
客户端提取服务器证书,验证证书的有效性:检查证书是否由可信 CA(证书颁发机构)签发、证书是否在有效期内、证书绑定的域名是否与服务器域名一致、证书是否被吊销。
-
若验证失败,客户端终止连接;若成功,客户端保存服务器公钥。
-
-
客户端提供身份凭证(mTLS 关键步骤 2):
-
客户端向服务器发送自己的证书(含客户端公钥),以及"证书验证消息"——用客户端私钥对"客户端随机数 + 服务器随机数 + 会话密钥预主密钥"的组合进行签名。
-
-
服务器验证客户端身份:
-
服务器提取客户端证书,重复类似的有效性验证(CA 信任链、有效期、身份绑定等)。
-
服务器用客户端公钥解密"证书验证消息",核对其中的随机数与握手初期的随机数是否一致,确认客户端确实持有证书对应的私钥(身份真实)。
-
若验证失败,服务器终止连接;若成功,进入密钥协商阶段。
-
-
密钥协商:客户端与服务器基于各自持有的随机数和预主密钥,通过约定的加密算法生成会话密钥(对称加密密钥,用于后续数据传输)。
-
客户端发送"完成消息":客户端用会话密钥加密"握手结束"标识,发送给服务器。
-
服务器发送"完成消息":服务器用会话密钥加密"握手结束"标识,发送给客户端。
-
握手完成:双方确认会话密钥可用,后续所有通信数据均通过会话密钥进行对称加密(效率高于非对称加密)。
5.6.4 mTLS 依赖的核心技术组件
mTLS 的实现依赖公钥基础设施(PKI)提供身份信任基础,核心组件及作用如下:
1. 数字证书(Digital Certificate)
-
定义:由可信 CA 签发的电子凭证,包含持有者身份信息(如服务名、设备 ID)、持有者公钥、CA 签名、有效期等关键信息。
-
作用:mTLS 中,客户端和服务器通过证书向对方证明"我是我声称的身份",同时提供用于加密和签名的公钥。
2. 证书颁发机构(CA,Certificate Authority)
-
定义:负责签发、管理和吊销数字证书的可信第三方机构(如公网 CA 赛门铁克、企业内部私有 CA)。
-
作用:作为"信任锚点",CA 用自己的私钥对证书进行签名,客户端/服务器通过验证 CA 签名确认证书的合法性(前提是信任该 CA 的根证书)。
3. 公钥与私钥(非对称加密算法)
-
公钥:公开可见,用于加密数据、验证数字签名(如服务器用客户端公钥验证客户端签名)。
-
私钥:持有者私密保存,用于解密数据、生成数字签名(如客户端用私钥对验证消息签名)。
-
核心逻辑:"公钥加密的数据仅对应私钥可解密,私钥签名的数据仅对应公钥可验证",确保身份真实性和数据机密性。
4. 证书吊销列表(CRL,Certificate Revocation List)
-
定义:CA 维护的已签发但因私钥泄露、身份变更等原因失效的证书列表。
-
作用:解决"证书未过期但已不可信"的问题,客户端/服务器在验证证书时需查询 CRL 或通过 OCSP(在线证书状态协议)确认证书状态。
5.6.5 mTLS 的典型应用场景
mTLS 因强身份认证特性,广泛用于需要严格访问控制的场景,以下为核心场景示例:
1. 服务网格(Service Mesh)
-
代表技术:Istio、Linkerd。
-
应用方式:服务网格通过 sidecar 代理(如 Istio 的 Envoy)为服务自动注入 mTLS 能力,无需修改业务代码。例如 Istio 中通过 PeerAuthentication 配置 STRICT 模式,强制服务间通信必须通过 mTLS 认证,防止未授权服务接入网格。
2. API 安全与微服务通信
-
场景:企业内部微服务集群(如订单服务调用支付服务)、第三方 API 接口(如银行开放平台对接商户系统)。
-
价值:避免 API 密钥泄露导致的非法调用,通过证书身份唯一标识调用方,实现"基于身份的访问控制(RBAC)"。
3. IoT(物联网)设备通信
-
场景:工业传感器、智能家居设备与云端平台的通信。
-
价值:物联网设备数量庞大且易被物理劫持,mTLS 可确保云端仅接收可信设备的数据,同时设备仅连接合法云端,防止数据篡改或设备被伪造。
4. 企业内网安全
-
场景:员工终端访问企业内网服务(如 OA 系统、数据库)、跨数据中心的服务通信。
-
价值:替代传统 VPN 的"基于网络边界的信任",实现"基于身份的零信任访问",即使终端处于内网,也需通过 mTLS 验证身份方可访问资源。
安全测试要点:
-
是否真的验证了客户端证书(有些配置错误的服务端虽然要求客户端证书但不验证其合法性)
-
证书是否过期(过期的证书如果还能用,说明验签逻辑有缺陷)
-
是否校验证书的 CN/SAN 字段(证书绑定的身份与服务实际身份是否匹配)
-
私钥是否安全存储(私钥泄露 = 身份被冒充)
-
是否有证书吊销检查(CRL/OCSP,被吊销的证书是否还能用)
5.7 SPIFFE
详解文章链接:零信任安全之——SPIFFE简介 - 知乎
5.7.1 解决什么问题
在 K8s/云原生环境中,工作负载(Pod/容器)是动态的——IP 随时变、实例随时扩缩容。传统的 IP 白名单、mTLS 证书绑定 IP 的方式都不可行。需要一种不依赖网络位置的身份验证机制。
SPIFFE(Secure Production Identity Framework for Everyone)为每个工作负载分配一个统一格式的身份标识:SPIFFE ID。
5.7.2 核心组件
-
SPIRE Server:集群中的信任根。负责签发 SVID(身份凭证),维护已注册工作负载的身份映射。
-
SPIRE Agent:每个节点上运行一个。负责向 Server 证明本节点的工作负载身份,获取 SVID 后下发给工作负载。
-
SVID(SPIFFE Verifiable Identity Document):工作负载持有的身份凭证,可以是 X.509 证书或 JWT。里面包含 SPIFFE ID。
5.7.3 工作流程
1. 工作负载启动 → 向本节点的 SPIRE Agent 请求 SVID 2. Agent 验证工作负载身份(通过 selector:K8s ServiceAccount、Namespace、镜像哈希等) 3. Agent 向 SPIRE Server 请求签发 SVID 4. Server 签发 SVID(X.509 证书或 JWT),包含 SPIFFE ID 5. 工作负载拿到 SVID,后续通信中使用 SVID 证明身份
5.7.4 SPIFFE ID 格式
spiffe://company.com/ns/production/sa/agent-service-a ↑ 信任域 ↑ namespace ↑ service account
这个 ID 不依赖 IP,无论 Pod 调度到哪个节点、IP 怎么变,身份不变。
5.7.5 两个 Agent 互访的流程
Agent A 要调 Agent B: 1. Agent A 用自己的 SVID(X.509 证书)发起 mTLS 连接 2. Agent B 验证 Agent A 的 SVID(通过信任根 CA 验证证书真伪) 3. Agent B 提取 Agent A 的 SPIFFE ID:spiffe://company.com/ns/production/sa/agent-service-a 4. Agent B 查权限策略:agent-service-a 是否有权调我? 5. 有权 → 建立 mTLS 连接,通信
本质:mTLS + 动态身份 + 统一信任框架。底层还是 mTLS,但证书不是静态管理的,而是 SPIRE 自动签发、自动轮换、随工作负载生命周期管理。
5.7.6 在 AI 资产管理中的用途
-
K8s 集群中部署的 Agent Pod 之间互访
-
Agent Pod 调 MCP Server Pod(同集群内)
-
不需要人工管理证书,SPIRE 自动完成签发和轮换
安全测试要点:
-
SPIRE 的 selector 是否严格(如果用 namespace 做 selector,任何同 namespace 的 Pod 都能拿到该身份——应该叠加 ServiceAccount + 镜像哈希等多重 selector)
-
SVID 是否定期轮换(默认 1 小时过期,过期前自动续签)
-
信任域是否隔离(不同集群/环境是否用不同的信任域)
-
工作负载下线后 SVID 是否自动失效
5.8 各认证方式在 AI 资产管理中的实际组合
生产环境不会只用一种,而是分场景组合:
用户 → AI 平台前端 → OAuth2 授权码流程登录,拿到 JWT(带用户身份和权限) → 后续请求带 JWT AI 平台后端 → 大模型 API → AK/SK 签名(调外部商业模型) → 或 mTLS(调内部部署的模型服务) Agent → MCP Server(同集群) → SPIFFE(K8s 环境下自动身份) Agent → MCP Server(跨集群/跨网络) → OAuth2 Client Credentials 换 token → 或 mTLS(高安全场景) Agent → 知识库 → JWT 断言(带用户身份透传,知识库按用户权限过滤数据) Skill → 工具 → JWT 断言(带 Skill 声明的权限范围)
核心原则:人类用 OAuth2/JWT,服务间用 mTLS/SPIFFE,跨网络用 AK/SK 或 Client Credentials,身份信息全链路透传,每一层都验。
更多推荐



所有评论(0)