关于 auth-md
auth-md 是用于生成、验证和讲解 auth.md 协议的技能,该协议帮助 Agent 向在线服务注册。它可生成协议文档与 OAuth 元数据,也可检查现有文件和在线端点。
主要功能
- 01生成 auth.md 与 OAuth 元数据
- 02验证协议文件及一致性
- 03检查在线发现元数据和端点
- 04讲解注册与令牌流程
- 05支持应用和提供方视角
- 06涵盖三种注册方式
适用场景
- 01为服务添加 Agent 注册说明
- 02检查现有 auth.md 实现
- 03核查在线协议端点响应
- 04了解注册及令牌交换流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ fabricioctelles/ skills --skill auth-md安装后在 Claude Code 中输入/auth-md确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
UPSTREAM_COMMITreferences/example-auth-md.mdimplementation-guide.mdmetadata-schema.mdprotocol-template.mdvalidation-rules.md详细介绍
auth-md
生成、验证并解释 auth.md 协议——这项开放标准让 AI Agent 能代表用户注册服务,而无需填写注册表单。
协议背景
auth.md 是发布在服务根目录下的 Markdown 文件(通常为 https://service.com/auth.md),用于指导 Agent 如何注册。它既是面向人类的文档,也是供 Agent 发现的运行时资源。
该协议通过在授权服务器元数据中加入 agent_auth 块来扩展 RFC 9728(OAuth 2.0 受保护资源元数据)。注册后会返回 identity_assertion(由服务签名的 JWT),Agent 可将其提交到 /oauth2/token,以换取 access_token。该协议支持三种注册方式:
| 流程 | 机制 | 适用场景 |
|---|---|---|
| identity_assertion | 提供方签发包含 auth_time 的 ID-JAG,以证明用户身份。服务验证 JWKS 后返回 identity_assertion。Agent 将其提交到 /oauth2/token。 | 服务通过 OIDC/SAML 执行即时配置;希望注册过程零摩擦。 |
| service_auth | 提供电子邮件提示和基于浏览器的验证流程。Agent 会收到 user_code 和 verification_uri;用户登录并输入代码。Agent 轮询 /oauth2/token。 | 无法签发 ID-JAG 的平台上的 Agent;无需信任列表即可自助注册。 |
| anonymous | 初始时不提供身份信息。立即返回带有预先声明范围的 identity_assertion。可选择延后认领以升级权限范围。 | Agent 需要立即获得基本访问权限;用户所有权绑定可延后处理。 |
协议端点
| 端点 | 用途 |
|---|---|
/.well-known/oauth-protected-resource | 发现——资源元数据(RFC 9728) |
/.well-known/oauth-authorization-server | 发现——包含 agent_auth 块的 AS 元数据 |
POST /agent/identity | 注册——根据 type 字段分发处理 |
POST /agent/identity/claim | 发起认领(匿名延后认领,或重新发起已过期的 user_code) |
POST /oauth2/token | 令牌交换(JWT 承载授权)及认领轮询(认领授权) |
POST /oauth2/revoke | 凭据层撤销(RFC 7009) |
events_endpoint | 注册层撤销(接收 SET,RFC 8935) |
令牌生命周期
注册不会直接返回 access_token。流程如下:
- 注册 →
identity_assertion(由服务签名的 JWT,有效期内可重复使用) - 交换 → 使用
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer向POST /oauth2/token发出请求 → 获得access_token - 刷新 →
access_token过期时,重新提交同一个identity_assertion - 断言过期 → 从注册步骤重新开始(步骤 3)
认领验证流程(v2 — 基于浏览器)
认领验证流程采用 RFC 8628 风格的设备授权:
- 注册在
claim块中返回user_code和verification_uri - Agent 向用户显示这两项信息
- 用户打开
verification_uri,登录服务并输入 6 位代码 - Agent 使用
grant_type=urn:workos:agent-auth:grant-type:claim和claim_token轮询POST /oauth2/token - 成功后:收到
access_token和新的identity_assertion
操作模式
| 参数 | 默认值 | 描述 |
|---|---|---|
mode | generate | generate = 创建 auth.md 和元数据;validate = 检查现有 auth.md;explain = 解释该协议 |
validation_level | basic | basic = 结构 + 字段 + 一致性检查(离线);full = basic + 实时获取端点 |
flows | all | 要包含的流程:identity_assertion、service_auth、anonymous、all |
role | app | 视角:app = 接受注册的服务;provider = 签发 ID-JAG 的平台 |
工作流:生成
1. 扫描代码库
查找:
- 现有的 API 路由和身份验证模式
- 已定义的作用域/权限
- 框架(Express、Django、Rails、FastAPI、NestJS 等)
- 基础 URL 和身份验证服务 URL 配置
- 现有的身份验证中间件
- 用户模型和用户配置机制
2. 仅询问无法推断的信息
- 要支持哪些流程(identity_assertion、service_auth、anonymous,或组合)
- 匿名模式下使用认领前作用域还是认领后作用域
- 受信任的 Agent 提供方和信任列表策略(如果使用 identity_assertion)
- 服务是否已支持 JIT 配置,还是需要手动引导用户
idJagMaxAuthAgeSeconds值(默认值:3600)- 所需的速率限制策略
3. 生成产物
生成三项产物:
a) auth.md — 遵循协议模板的 Markdown 文件(参见 references/protocol-template.md)。必须包含:
- 面向 Agent 的标题和简介
- 步骤 1 — 发现(两跳:PRM → AS 元数据)
- 步骤 2 — 选择方法(决策树)
- 步骤 3 — 注册(每种受支持的方法各设一个小节)
- 步骤 4 — 认领流程(如果使用 service_auth,或使用带认领功能的匿名模式)
- 步骤 5 — 交换断言(使用 jwt-bearer 授权类型向 POST /oauth2/token 发送请求)
- 步骤 6 — 使用 access_token
- 错误(包含所有适用代码的完整表格)
- 撤销(两层)
b) oauth-protected-resource.json — /.well-known/oauth-protected-resource 的 JSON,包含 resource_name 和 resource_logo_uri
c) oauth-authorization-server.json — /.well-known/oauth-authorization-server 的 JSON,包含:
issuer、token_endpoint、revocation_endpoint、grant_types_supported- 完整的
agent_auth区块,包含identity_endpoint、claim_endpoint、events_endpoint
4. 生成实施指南
包含以下内容的“后续步骤”部分:
- 如何在域名根路径提供
auth.md - 如何在 well-known 路径提供元数据
- 如何为 401 响应添加
WWW-Authenticate标头 - 端点实施指南(除非用户提出要求,否则不生成特定于框架的代码)
- 在
/oauth2/token实施令牌交换 - 认领页面托管(verification_uri → 登录 → 输入代码 → 确认)
- 建议的速率限制配置
- 建议的审计事件
- 安全注意事项(令牌哈希、auth_time 验证、防重放、claim_token 处理)
5. 生成 Agent 提供方指南(如果 role=provider)
当用户是 Agent 提供方(而非应用)时,生成以下内容:
- 如何创建面向特定受众且包含
auth_time的 ID-JAG - 令牌结构(标头 + 包含必需和可选声明的载荷)
- 如何发布 JWKS
- 可选:如何发布 CIMD(客户端 ID 元数据文档)
- 如何实施撤销(向 events_endpoint 发送 POST SET)
- 如何在断言用户身份前向用户征求同意(使用
resource_name+resource_logo_uri)
工作流:验证
1. 加载 auth.md
从本地文件路径或 URL 加载。
2. 执行所请求级别的验证
基础(离线):
- 包含所有必需标题(步骤 1–6、错误、撤销)
- 至少记录一种流程
- 请求/响应格式的围栏代码块中包含有效 JSON
- AS 元数据包含
identity_endpoint、token_endpoint、grant_types_supported - 错误表包含标准错误代码
- 一致性:正文描述的流程与元数据 JSON 中的
identity_types_supported相符 - 没有未替换的占位符
完整(在线):
- 包含所有基础检查,此外还需:
- 从声明的基础 URL 获取
/.well-known/oauth-protected-resource - 确认 AS 元数据中存在
agent_auth区块 - 获取
/.well-known/oauth-authorization-server并检查一致性 - 检查
identity_endpoint、token_endpoint、revocation_endpoint是否有响应(接受 400/401/422,拒绝 404/405) - 确认 API 返回的 401 响应中包含
WWW-Authenticate,且其值包含resource_metadata
3. 报告结果
按类别分组,并对每条规则标注 ✅/❌:
- 结构 — 标题和顺序
- 字段 — JSON 中的必填字段
- 一致性 — 正文与元数据之间的交叉引用
- 格式 — 有效的 JSON、有效的 HTTP、没有占位符
- 端点(仅完整模式)— 可访问性和响应是否正确
包含严重级别:🔴 错误(Agent 将无法工作)、🟡 警告(体验下降)、🟢 信息(建议)。
完整规则集请参阅 references/validation-rules.md。
工作流:解释
当用户希望了解协议,但不需要生成或验证内容时:
- 确定用户想了解什么(概述、特定流程、特定端点、安全性等)
- 结合上述协议背景和参考资料进行说明
- 必要时使用基于文本的时序图
- 适时指向官方文档
用户匹配和即时配置
identity_assertion 流程需要确定注册对应哪个服务用户。建议按以下顺序进行匹配:
- 委托记录匹配 — 如果已有
(iss, sub)的委托记录,则路由到同一用户 - 已验证的邮箱匹配 — 如果存在拥有相同已验证邮箱的用户,但没有
(iss, sub)委托记录,则返回interaction_required(401),并附上声明块,让用户确认关联 - 已验证的电话号码匹配 — 同样处理
- 无匹配项 → JIT — 根据配置策略创建新用户,或拒绝
如果 ID-JAG 没有已验证的邮箱或已验证的电话号码,则应拒绝,因为没有匹配依据。
速率限制
/agent/identity 端点允许匿名注册,因此无需身份验证。实施两级限制:
- 按 IP 限制(先检查)— 防止单一来源耗尽租户的额度。默认值:匿名注册每小时 5 次,identity_assertion 每小时 60 次。
- 按租户限制(后检查)— 跨 IP 的全局上限。默认值:匿名注册每小时 100 次,identity_assertion 每小时 1000 次。
同时对 /oauth2/token 轮询进行速率限制 — 根据声明块中的 interval 强制执行间隔,轮询过快时返回 slow_down。
建议的审计事件
| 事件 | 触发时机 | 数据 |
|---|---|---|
registration.created | POST /agent/identity 成功 | registration_id, registration_type, iss, sub |
registration.interaction_required | 401 interaction_required | registration_id, iss, sub, matched_user_id |
registration.login_required | 401 login_required | iss, sub, auth_time, max_age |
claim.initiated | 调用 /agent/identity/claim | registration_id, email |
claim.completed | 用户提交了正确的 user_code | registration_id, claimed_by_user_id |
claim.expired | user_code 窗口或注册已过期 | registration_id |
token.exchanged | /oauth2/token jwt-bearer 成功 | registration_id, access_token_id |
token.revoked | 调用 /oauth2/revoke | access_token_id |
registration.revoked | 在 events_endpoint 处理 SET | registration_id, iss, sub |
安全注意事项
- auth_time 验证 — ID-JAG 中必须包含
auth_time。服务会根据idJagMaxAuthAgeSeconds进行验证。如果时间过久,则返回login_required(401)——Agent 必须引导用户在提供方重新进行身份验证。 - claim_token 处理 — 仅在注册响应中返回一次。Agent 仅在整个流程期间将其保存在内存中。第 4 步之后不得持久化。
- 令牌哈希 —
claim_token是持有者密钥。服务端仅存储其 SHA-256 哈希值。 - 同意体验 — 在断言身份之前,向用户展示来自 PRM 的
resource_name和resource_logo_uri。这是用户唯一的同意关卡。 - 两层撤销 — 凭证层(可由 Agent 调用,
/oauth2/revoke,撤销一个 access_token)与注册层(由提供方在events_endpoint发送 SET,拆除整个委托:identity_assertion + 派生令牌 + 注册 + claim 句柄——而不只是令牌;参见示例 #21)。 - 重放防护 — 缓存
jti值,TTL 至少为exp - iat+ 时钟偏差(通常为 6 分钟)。 - CIMD 解析 — 如果
client_id是 URL,则将其作为客户端 ID 元数据文档获取,并验证jwks_uri。 - 批量撤销 — 提供面向运营人员的机制,以撤销某个租户所有尚未过期的 identity_assertions。
错误代码参考
| 代码 | 位置 | 含义 |
|---|---|---|
anonymous_not_enabled | /agent/identity | 服务不接受匿名请求 |
service_auth_not_enabled | /agent/identity | service_auth 已禁用 |
issuer_not_enabled | /agent/identity | 提供方不在信任列表中 |
invalid_request | /agent/identity | 请求正文/声明/签名/jti/aud 有问题 |
interaction_required (401) | /agent/identity | ID-JAG 匹配到账号,但没有委托——需要 claim |
login_required (401) | /agent/identity | auth_time 时间过久——需在提供方重新进行身份验证 |
invalid_claim_token | /agent/identity/claim | 令牌错误或已过期 |
claimed_or_in_flight | /agent/identity/claim | 已被领取或端点错误 |
claim_expired | /agent/identity/claim | 注册已过期 |
invalid_grant | /oauth2/token | Assertion 已过期/已撤销 |
invalid_client | /oauth2/token | 无法识别 client_id |
unsupported_grant_type | /oauth2/token | 不是 jwt-bearer 或 claim 授权类型 |
authorization_pending | /oauth2/token (claim) | 用户尚未完成整个流程 |
expired_token | /oauth2/token (claim) | user_code 有效时间窗口已关闭 |
slow_down | /oauth2/token (claim) | 轮询过于频繁 |
rate_limited (429) | 任意 | 暂缓后重试 |
Agent 就绪度扫描器检查
isitagentready.com 扫描器会将 auth.md 作为 authMd 检查项进行验证。通过标准:
/auth.md从网站根目录提供,且 HTTP 状态码为 200- 内容为 Markdown,且 H1 标题中包含“auth.md”
- 可选:验证
/.well-known/oauth-protected-resource处的 OAuth 受保护资源元数据 - 可选:验证
/.well-known/oauth-authorization-server处的授权服务器元数据
最低限度通过检查:
# auth.md
This service accepts AI agent registrations.
## Authentication
Agents can register via POST /agent/identity with a valid ID-JAG.
See below for supported methods.
获得满分(包含全部元数据):
- 提供标题正确的
/auth.md - 发布
/.well-known/oauth-protected-resource,包含resource、resource_name、resource_logo_uri、authorization_servers、scopes_supported、bearer_methods_supported: ["header"] - 发布
/.well-known/oauth-authorization-server,包含issuer、token_endpoint、revocation_endpoint、grant_types_supported,以及包含skill、identity_endpoint、claim_endpoint、events_endpoint和注册方法的agent_auth块
扫描命令:
curl -s -X POST 'https://isitagentready.com/api/scan' \
-H 'Content-Type: application/json' \
-d '{"url":"https://YOUR-DOMAIN/","enabledChecks":["authMd"]}' | jq '.checks.discovery.authMd'
质量检查清单
交付输出前,请确认:
- 生成的
auth.md包含所有必需步骤(1-6)+ 错误 + 撤销 - AS 元数据包含
issuer、token_endpoint、revocation_endpoint、grant_types_supported -
agent_auth块包含identity_endpoint、claim_endpoint、events_endpoint -
identity_types_supported与用户选择的流程一致 -
scopes_supported反映代码库中实际找到的 API 作用域 -
auth.md与元数据 JSON 中的基础 URL 一致 - 错误代码表包含受支持流程的所有标准代码
- 步骤 5 记录了使用 jwt-bearer 授权类型在
/oauth2/token进行的令牌交换 - 撤销部分记录了两个层面(凭据 + 注册)
- 不包含未替换的占位符值(
{{...}}、<your-...>、[YOUR_...]) - 验证报告涵盖请求级别的所有规则
- 记录了速率限制(包括
/oauth2/token轮询) - 包含安全注意事项(auth_time、claim_token、同意体验)
- 如果 role=provider:记录了包含
auth_time的 ID-JAG 结构
参考资料
references/protocol-template.md— 包含所有章节和占位符的完整 auth.md 模板references/validation-rules.md— 完整的验证规则集,包含错误消息和严重级别references/metadata-schema.md— PRM、AS 元数据、ID-JAG 和 identity_assertion 的 JSON 架构references/example-auth-md.md— 完整 auth.md 文件的可用示例(Acme Notes)references/implementation-guide.md— 服务端实现指南,涵盖令牌交换、声明流程、撤销和安全
更新协议知识
此技能附带 auth.md 协议规范(v2,2026 年 6 月)的快照。可能时,请从以下位置获取最新版本:
- 技能主页和文档中心:
https://auth-md.com - 规范:
https://raw.githubusercontent.com/workos/auth.md/refs/heads/main/AUTH.md - 文档概览:
https://workos.com/auth-md/docs - 应用指南:
https://workos.com/auth-md/docs/apps - Agent 提供方指南:
https://workos.com/auth-md/docs/agent-providers - 文件结构:
https://workos.com/auth-md/docs/auth-md
如果获取失败,请以随附的 references/ 为准。