
AI Agent 的可验证委托verifiable delegation与证明attestation系统是当前自动化工作流里最容易被忽视的安全基础设施。Kessa 这类项目的核心目标是把“用户授权 Agent 代替自己执行操作”这件事从一张截图、一段日志变成可验证、可审计、可撤回的密码学凭证。实际使用 AI Agent 时常见问题往往不是模型能力不够而是它一旦拿到了过高权限下游服务无法确认请求来源是否真的可信。调用方只能看到某个 Agent 进程发来请求却无法判断这次操作是否确实来自用户授权也无法判断权限范围是否被绕过。Kessa 就是针对这个信任缺口设计的授权委托与证明层。这篇文章会从概念讲起委托、证明、认证、授权有什么区别再拆解一个可验证委托系统通常需要哪些核心数据结构和签名机制接着给出一个最小可运行示例用 Python 和 Ed25519 签名跑通“签发委托 - 携带证明 - 验证证明”的完整流程最后补充常见问题、排查路径和落地建议。示例代码用于说明设计思路与 Kessa 的具体实现不一定完全一致但核心模型是可通用的。1. 先理解 Agent 场景里的委托与证明到底指什么1.1 认证、授权、委托和证明的边界很多人会把“认证”和“授权”混在一起再加上“委托”和“证明”边界更模糊。先分开看认证Authentication确认“你是谁”。用户登录、Agent 出示 API Key都属于认证。授权Authorization确认“你被允许做什么”。系统根据角色、权限策略决定某个主体能否执行某操作。委托Delegation一个主体把自己的部分权限临时转交给另一个主体代为行使。证明Attestation第三方或被授权方出示一组可验证信息声称某个主体确实具备某些权限或属性。在传统 Web 系统里登录之后由后端 Session 保存用户身份权限在服务端判断。在 AI Agent 场景里Agent 可能是一个独立进程主动调用多个外部 API。这时下游系统不能只看到“请求来自 Agent”还需要看到“Agent 获得了用户对某个资源执行某个操作的委托”并且“这份委托是真实、未被篡改的”。这就是可验证委托和证明系统要解决的核心问题。概念解决的问题典型技术与 AI Agent 的关系认证你是谁OIDC、API Key、mTLSAgent 需要有身份标识授权你被允许做什么RBAC、ABAC、策略引擎服务端判断 Agent 权限委托用户把权限转交给谁OAuth 授权码、签名凭证Agent 代替用户执行操作证明如何证明你有权限JWT、证书链、远程证明下游验证 Agent 请求是否可信1.2 AI Agent 为什么必须引入可验证委托传统 API 调用中用户先登录服务端发一个 Token客户端用它调接口。这种方式的问题是权限始终绑定在“用户身份”上Agent 只是替用户操作权限边界很难被下游感知。假设用户让 Agent 自动处理 DevOps 工单Agent 需要读取仓库、创建评论、偶尔合并 PR。如果直接把用户 Token 交给 AgentAgent 就拥有用户全部权限如果为 Agent 单独创建 Service Account又很难约束它“只能处理某个仓库的某个时间段工单”。可验证委托系统的思路不一样用户对 Agent 签发一张“授权凭证”明确写出允许哪些资源、哪些操作、多长时间有效、最多执行几次。Agent 在调用下游 API 时把这张凭证一并带上。下游服务验证凭证签名和权限范围后再放行。这样即使 Agent 被打断或恶意利用它也只能在这个范围内活动操作可以被追溯。Kessa 这类系统本质上就是把“授权决策”从 Agent 的逻辑里抽出来变成独立的、可验证的凭证层。Agent 不需要知道完整的权限模型它只需要保管自己的身份私钥并在每次请求时出示用户委托给它的凭证。1.3 Kessa 在系统里的定位从项目名称和关键词来看Kessa 定位为“面向 AI Agent 的可验证委托与证明系统”。它通常不负责模型推理也不直接执行业务操作而是处于 Agent 和下游 API 之间的安全边界层。主要职责可以理解为维护用户、Agent 的身份和密钥。签发委托凭证记录用户授权给 Agent 的具体权限。验证凭证把“这个 Agent 是否有权限执行该操作”变成可编程判断。提供撤销和过期机制防止凭证被无限期使用。在实际系统中Kessa 既可以作为独立服务部署也可以作为库嵌入 Agent 运行环境。它的价值不在于把签名变得更复杂而在于让“Agent 请求是否合规”这件事可以被外部系统独立验证。这样审计、安全策略和权限回收才有统一的抓手。2. 核心设计把授权声明变成可验证的密码学凭证2.1 授权声明的数据模型一份可验证委托凭证本质上是一个带签名的 JSON 对象。它需要描述清楚谁授权、给谁、能操作什么、在什么条件下有效、如何防止重放。下面是一个简化的委托声明结构{ version: 1.0, type: resource_access, issuer: did:example:user:alice, subject: did:example:agent:assistant-01, audience: [https://api.github.com], scope: { resources: [repo:acme/backend, repo:acme/frontend], actions: [read, create_issue, comment] }, conditions: { not_before: 2026-01-01T00:00:00Z, expires_at: 2026-01-02T00:00:00Z, max_executions: 5, allowed_times: [ {start: 09:00, end: 18:00, timezone: Asia/Shanghai} ] }, nonce: f47ac10b-58cc-4372-a567-0e02b2c3d479, issued_at: 2026-01-01T00:00:00Z, jti: delegation-8f8f9a1e-3c18-4b37-9ae0-6e2d90c99a01 }关键字段说明如下字段含义备注issuer委托者标识一般是用户 DID、用户 ID 或公钥指纹subject被委托者标识指向某个 Agent 实例audience凭证允许访问的服务防止 Agent 拿着凭证调无关服务scope权限范围资源和操作的组合应尽量收敛conditions生效条件时间、次数、地理位置等nonce随机数防止重放攻击jti凭证唯一 ID便于吊销和审计在实现时这个 JSON 会经过规范化排序再进行签名。不要直接对整个 JSON 字符串做直观拼接签名因为字段顺序变化会导致同样内容验签失败。推荐把 JSON 序列化后的字节流作为签名输入验证和签发使用同一套规范化逻辑。2.2 签名、证书链和信任根单张凭证的签名只能证明“凭证内容没被篡改”还不足以证明“签发者确实拥有相应权限”。如果一个 Agent 自签一张凭证说“用户可以执行任意操作”下游不能相信。因此可验证委托系统通常引入证书链用户用自己的私钥对“Agent 可以执行某些操作”签发一张委托凭证。Agent 在调用更细粒度任务时可以在这张用户凭证下再签发一张子凭证声明“子任务 Agent 只能在父凭证范围内执行一部分操作”。下游验证时从当前凭证开始一直回溯到信任根比如用户公钥或系统根 CA。证书链的好处是权限可以逐级收缩方便分层审计。例如用户给主 Agent 一个较宽范围主 Agent 给每个子任务签发更窄范围的临时凭证即使某个子任务凭证泄露影响范围也可控。如果 Kessa 使用 DID 或公钥体系信任根通常是一个用户公钥。验证方需要预置或动态获取信任根公钥列表。凭证链上的每一跳都必须验证签名、有效期和作用域缺少任何一环都不能通过。2.3 证明验证流程验证方收到 Agent 的请求和附带凭证后通常按以下顺序检查解析凭证检查 JSON 字段是否完整、版本是否支持。验证签名确认当前凭证确实由上一级签发者签名。递归验证父凭证直到信任根。检查时间条件not_before、expires_at是否满足。检查请求的资源和动作是否落在scope内。检查凭证是否已吊销通过吊销列表或查询吊销服务。检查nonce和jti是否已经被使用避免重放。验证过程用伪代码可以表达为def verify_delegation(request, token, trust_roots): claims parse_and_verify_signature(token, trust_roots) if claims is None: return False, signature_invalid if not check_time_conditions(claims[conditions]): return False, time_condition_failed if not check_scope(claims[scope], request.action, request.resource): return False, scope_mismatch if is_revoked(claims[jti]): return False, revoked if is_replayed(claims[nonce]): return False, nonce_replay return True, ok这里的核心原则是验证方不依赖 Agent 的自我声明而是依赖密码学签名和策略判断。任何一步失败都应该拒绝请求并记录完整上下文。2.4 策略配置示例验证逻辑通常会配合策略文件使用。策略文件描述“哪类请求可以被哪类凭证放行”。例如policy: version: 1.0 trust_roots: - did:example:user:alice required_claims: - type - issuer - subject - scope rules: - action: create_issue resources: - repo:acme/* require_scope: actions: [create_issue] enforce_time_window: true max_executions: 5策略文件不是必选项但推荐引入。把权限判断策略化以后新增资源、调整权限范围不需要改代码只需要改配置并重新加载。3. 环境准备与最小实现跑通一次可验证委托3.1 用到的工具和依赖为了快速验证思路可以只用 Python 和cryptography库完成签名、验证。生产环境则需要考虑密钥管理、吊销服务、审计日志和监控下面先用最小环境演示。工具用途Python 3.10编写签发和验证逻辑cryptography 库提供 Ed25519 签名算法openssl生成和管理密钥jq调试时解析 JSON 凭证curl模拟 Agent 调用下游接口安装依赖python3 -m venv .venv source .venv/bin/activate pip install cryptography3.2 生成用户和 Agent 密钥以 Ed25519 为例先生成用户密钥再生成 Agent 密钥。生产环境应该由专用密钥管理系统生成和托管不要直接放在工作目录。# 用户密钥 openssl genpkey -algorithm ED25519 -out user_private.pem openssl pkey -in user_private.pem -pubout -out user_public.pem # Agent 密钥 openssl genpkey -algorithm ED25519 -out agent_private.pem openssl pkey -in agent_private.pem -pubout -out agent_public.pem生成后用户私钥保存在客户端或者密钥服务Agent 私钥保存在 Agent 运行环境。用户公钥和 Agent 公钥都可以公开。3.3 签发一份委托凭证下面代码实现对委托声明进行规范化并签名。签发方使用用户私钥生成一段 Base64URL 编码的凭证。import json import base64 import time import uuid from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives import serialization def b64url_encode(data: bytes) - str: return base64.urlsafe_b64encode(data).rstrip(b).decode(ascii) def b64url_decode(data: str) - bytes: padding * (-len(data) % 4) return base64.urlsafe_b64decode(data padding) def canonical_json(obj: dict) - bytes: return json.dumps(obj, sort_keysTrue, separators(,, :)).encode(utf-8) def sign_delegation(claims: dict, private_key: Ed25519PrivateKey) - str: claims dict(claims) claims.setdefault(jti, str(uuid.uuid4())) claims.setdefault(issued_at, time.strftime(%Y-%m-%dT%H:%M:%SZ, time.gmtime())) payload canonical_json(claims) signature private_key.sign(payload) token { payload: b64url_encode(payload), signature: b64url_encode(signature), alg: EdDSA } return b64url_encode(canonical_json(token))调用示例with open(user_private.pem, rb) as f: private_key serialization.load_pem_private_key(f.read(), passwordNone) claims { type: resource_access, issuer: did:example:user:alice, subject: did:example:agent:assistant-01, audience: [https://api.example.com], scope: { resources: [repo:acme/backend], actions: [read, create_issue] }, conditions: { not_before: 2026-01-01T00:00:00Z, expires_at: 2026-01-02T00:00:00Z, max_executions: 5 }, nonce: f47ac10b-58cc-4372-a567-0e02b2c3d479 } token sign_delegation(claims, private_key) print(token)这里把签名后的完整数据也做成 JSON 再编码一次是为了避免多层编码问题。实际实现可以采用 JWT 风格即header.payload.signature。3.4 验证方校验委托凭证验证方拿到凭证后需要做三件事解析、验签、检查条件。以下是最小验证函数import json from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey from cryptography.exceptions import InvalidSignature def verify_delegation(token: str, trusted_public_keys: list[Ed25519PublicKey]) - dict: try: token_bytes b64url_decode(token) token_data json.loads(token_bytes) payload_bytes b64url_decode(token_data[payload]) signature_bytes b64url_decode(token_data[signature]) claims json.loads(payload_bytes) except Exception: raise ValueError(invalid token encoding) for public_key in trusted_public_keys: try: public_key.verify(signature_bytes, payload_bytes) return claims except InvalidSignature: continue raise ValueError(signature verification failed) with open(user_public.pem, rb) as f: public_key serialization.load_pem_public_key(f.read()) trusted_keys [public_key] claims verify_delegation(token, trusted_keys) print(验证通过权限范围, claims[scope])注意这个最小示例只验证了签名。完整实现还需要检查时间、作用域、吊销状态和 nonce。读者不能把上面的代码直接放到生产环境它只用于演示核心步骤。3.5 在 Agent 的 API 请求里携带证明Agent 在调用下游 API 时可以在请求头中携带委托凭证。下游服务先验证凭证再执行业务逻辑。curl -X POST https://api.example.com/repos/acme/backend/issues \ -H Authorization: Bearer 用户普通访问凭证 \ -H X-Kessa-Delegation: 上一步生成的token \ -H Content-Type: application/json \ -d {title: 修复登录超时问题, body: delegated by agent}下游服务读取X-Kessa-Delegation头调用验证函数。这样做的好处是权限判断不依赖 Agent 进程本身而是依赖携带的密码学凭证。即使 Agent 的本地配置被修改也无法伪造新的授权范围。4. 运行验证从签发到验证的完整闭环4.1 最小验证流程把前面的代码保存为kessa_demo.py然后依次执行以下命令# 1. 生成密钥 openssl genpkey -algorithm ED25519 -out user_private.pem openssl pkey -in user_private.pem -pubout -out user_public.pem # 2. 签发凭证 python kessa_demo.py sign --claims claims.json --private-key user_private.pem token.txt # 3. 验证凭证 python kessa_demo.py verify --token $(cat token.txt) --public-key user_public.pem预期正常输出Delegation valid issuer: did:example:user:alice subject: did:example:agent:assistant-01 scope: {resources: [repo:acme/backend], actions: [read, create_issue]}如果签名无效程序应当抛出signature verification failed下游服务会返回 401 或 403。4.2 调试和日志检查可验证委托系统最容易出问题的地方是“凭证格式不统一”。调试时可以先把凭证解码查看字段内容# 把 token 解码为 JSON 后通过 jq 查看 python - PY import sys, json, base64 token open(token.txt).read().strip() pad * (-len(token) % 4) data json.loads(base64.urlsafe_b64decode(token pad)) print(json.dumps(data, indent2)) PY这样可以快速确认payload和signature是否存在issued_at和expires_at是否符合预期。验证方的日志应至少记录以下内容凭证 IDjti请求路径和请求动作验证结果失败原因时间戳4.3 学习环境与生产环境的差异上面的最小示例能在本地跑通但离生产使用还有不少距离。学习环境和生产环境的差异如下维度学习环境生产环境密钥管理本地文件硬件安全模块、密钥管理服务信任根单个公钥文件动态轮换、多根信任、DID 文档吊销不支持吊销列表或在线吊销状态服务重放防护nonce 固定分布式缓存、服务端一次性 nonce审计日志标准输出持久化到日志系统带 trace ID策略加载代码写死配置中心、策略引擎动态加载监控告警无验证失败率、过期率、吊销率监控在生产环境Kessa 这类系统通常还需要解决密钥分发的完整生命周期Agent 首次启动如何安全获取私钥、Agent 密钥泄露后如何快速吊销、用户撤销授权后已签发的凭证如何快速失效。这些问题都需要在架构设计时提前规划。5. 常见问题与排查路径5.1 签名验证失败提示公钥不匹配或不支持算法现象验证方抛signature verification failed或invalid signature。可能原因验签时加载了错误的公钥例如拿 Agent 公钥去验证用户签发的凭证。签发和验签使用不同的 JSON 规范化方式字段排序不一致。Base64URL 编解码处理错误。凭证被截断或复制时混入换行符。检查方式# 查看公钥指纹确认是不是同一个密钥 openssl pkey -pubin -in user_public.pem -outform DER | openssl dgst -sha256解决建议先固定使用同一套规范化函数不要直接对字典原始字符串签名调试时打印payload_bytes和对方收到后解码的payload_bytes逐字节对比。注意JSON 字段顺序在签名验证中非常关键。{a:1,b:2}和{b:2,a:1}字符串不同签名必然不同。建议使用sort_keysTrue统一序列化。5.2 委托链断裂父凭证找不到或已过期现象下游验证当前 Agent 凭证时成功但递归验证父凭证时失败。可能原因Agent 只上传了最后一张子凭证没有附带完整父凭证链。父凭证已经过期子凭证仍在有效期内但验证方禁止链上任何凭证过期。父凭证的audience与下游 API 不一致。父凭证的权限范围没有覆盖子凭证声明的范围。检查方式打印完整凭证链逐级检查issuer、subject、expires_at和scope。重点确认子凭证的操作是否超集于父凭证。解决建议Agent 在携带凭证时应携带从信任根到当前凭证的完整链。验证方要对每一层级都执行作用域收缩检查下一级权限只能小于或等于上一级权限不能扩大。5.3 权限作用域被放大或时间条件不满足现象Agent 尝试执行某个操作验证方返回scope_mismatch或time_condition_failed。可能原因scope.resources使用了过宽的通配符例如repo:*。scope.actions允许了write而请求只需要comment。系统时钟不一致验证方和签发方时间差太大。not_before和expires_at被设置成固定的绝对时间且没有考虑时区。检查方式# 查看服务器当前时间和 UTC 时间 date -u解决建议权限范围应尽量写具体。通配符要配合策略引擎使用不能直接放在签名凭证里无限制匹配。时间条件建议统一使用 UTC 时间戳并在验证时允许最大时钟偏移量例如 30 秒。生产环境中签发和验证服务之间应使用 NTP 同步。5.4 重放攻击和重复执行现象同一个委托凭证被多次提交Agent 重复执行某操作或凭证被其他进程截获后重复使用。可能原因凭证没有包含nonce或jti。验证方没有做一次性校验。验证方使用本地内存记录 nonce多实例部署时记录不共享。检查方式核对日志中同一jti出现次数检查验证服务的缓存是否支持分布式。解决建议用户凭证可以设计为“允许最多执行 N 次”在数据库中记录已执行次数子任务的临时凭证建议设置为短时有效每次任务使用新的 nonce。验证方维护已使用 nonce 的去过重缓存缓存时间至少覆盖凭证有效期。5.5 排查顺序清单遇到验证失败时按以下顺序排查检查输入请求是否真的携带了凭证Header 名称是否正确。检查路径和命名公钥路径、token 文件路径是否写错。检查密钥验签公钥是否属于凭证的签发者。检查编码Base64URL 是否被换行、空格污染。检查时间系统时间、时钟偏移、权威时间源。检查配置策略文件中的 trust_roots 是否包含签发者。检查日志验证方是否输出具体失败原因。检查版本cryptography 或相关库是否存在已知兼容问题。6. 最佳实践与扩展方向6.1 委托最小化给 Agent 够用的权限而不是全部权限Agent 需要权力但权力必须收敛。每次委托都应该遵循最小权限原则只委托特定仓库、特定 API、特定动作。尽量缩短凭证有效期。设置执行次数上限。不要把用户长期令牌直接交给 Agent应以临时委托凭证替代。对高风险操作合并 PR、删除资源、转账单独配置二次确认策略。例如一个 Agent 只需要读取 Issue 并创建评论就不要给它repo:*和write。权限写大了签名只能证明“Agent 确实有权限”却无法挽救失控后的爆炸半径。6.2 审计、撤销和紧急熔断可验证委托系统必须配合审计能力。每次签发、验证、吊销都要记录足够上下文至少包括时间、签发者、被委托者、凭证 ID、权限范围、验证结果。日志要接入集中式日志平台方便事后追溯。撤销机制同样重要。当用户发现 Agent 异常、密钥泄露或策略变更时需要能快速吊销凭证。常见方案维护吊销列表验证时查询。使用短时凭证让凭证自然过期。引入在线状态服务验证时实时查询凭证是否有效。紧急情况下直接吊销 Agent 的身份密钥不再接受该 Agent 签发的新凭证。在自动化工作流中建议设置“熔断器”某个 Agent 的错误率或验证失败率超过阈值时自动暂停该 Agent 的所有委托凭证。6.3 与现有身份体系集成Kessa 这类系统不需要替代现有身份系统。它可以和 OIDC、OAuth2、LDAP 或 DID 体系配合用户登录仍然走企业身份系统。Kessa 只负责把用户身份转换为“Agent 可携带的委托凭证”。下游服务统一验证凭证而不是为每个服务开发一套权限逻辑。对于容器和微服务场景可以借鉴 SPIFFE/SPIRE 的证书颁发模式为每个 Agent 实例签发短期身份证书。集成时最需要注意的是信任根和密钥分发的统一管理。如果每个团队自己维护一套信任根验证会变得困难。推荐在组织内部建立统一的信任根和策略中心各服务只做验证不做私人化信任判断。6.4 可复用的落地检查清单在把类似系统应用到实际项目前可以对照以下清单[ ] 每个 Agent 是否有唯一身份标识和私钥私钥是否托管在安全环境。[ ] 用户委托凭证是否包含明确的资源范围、动作范围、有效期、执行次数。[ ] 凭证签名是否使用确定性的规范化 JSON。[ ] 验证方是否支持完整凭证链校验而不是只验最后一张。[ ] 是否实现 nonce 去重和重放防护。[ ] 是否支持凭证吊销和紧急熔断。[ ] 验证日志是否包含 jti、时间、请求路径、验证结果。[ ] 是否配置跨服务的信任根和时钟同步。[ ] 是否有监控告警能够发现异常验证失败和权限滥用。[ ] 是否定期轮换用户和 Agent 密钥并处理旧密钥的过渡期。6.5 扩展方向Kessa 这类系统的下一步演进方向通常包括与策略引擎例如 OPA集成让权限判断不再硬编码在验证逻辑里。引入远程证明Remote Attestation不仅验证 Agent 的授权凭证还验证 Agent 运行环境是否可信。结合 TEE让 Agent 的私钥和决策过程运行在受信任执行环境中防止密钥被内存提取。在跨组织场景中将委托凭证写入可公开验证的账本提高审计透明度。支持更丰富的条件约束例如需要多签授权、需要审批流、需要人工确认后才能执行高风险操作。AI Agent 还会越来越复杂权限边界会越来越细可验证委托与证明系统是让自动化从“能跑”走向“敢用”的关键基础设施。实际落地时最重要的一点不是算法有多新而是把授权语义想清楚谁、在哪、做什么、多长时间、最多几次。Kessa 这样的项目把这个问题变成了工程可验证的协议值得每一个做 Agent 自动化的人认真研究。对新手来说最有价值的练习就是先用最小签名示例跑通一次委托和验证再逐步加入证书链、吊销和策略引擎理解每一层为什么存在。