学习笔记 · Obsidian
OAuth Auth Service v2
Auth Service 把 Provider 配置、授权流程、token Vault、审计事件和 Agent 身份解析拆成不同资源。正确实现要保持这几个边界,不能把“Provider 已配置”“用户已有 token”“当前 token 仍可用”混为同一状态。
Provider 管理
| 能力 | 方法与路径 | 关键点 |
|---|---|---|
| 列组织 Provider | GET /v2/auth/providers | 根文档与 list-oauth-providers 是同一操作的两个文档入口 |
| 读取 Provider | GET /v2/auth/providers/{provider_id} | 返回组织级 Provider 配置 |
| 创建 | POST /v2/auth/providers | 手工配置 OAuth Provider |
| 更新 | PATCH /v2/auth/providers/{provider_id} | 全字段可选,做局部更新 |
| 删除 | DELETE /v2/auth/providers/{provider_id} | 删除 Provider 配置,不应被误解为 Provider 侧全局撤权 |
| 平台 Provider | GET /v2/auth/platform-providers、GET /v2/auth/platform-providers/{provider_id} | 与组织自定义 Provider 分离 |
| MCP 自动发现 | POST /v2/auth/providers/mcp-discover | 用 MCP Server 元数据发现 OAuth 配置 |
手工创建 OAuthProviderCreateRequest 必填 provider_id、name、client_id、auth_url、token_url。可选:client_secret、PKCE、code_challenge_method(默认 S256)、Provider 类型、token endpoint 认证方式、额外授权参数与回调 URI 配置。
token_endpoint_auth_method支持none、client_secret_basic、client_secret_post,默认是client_secret_post。- 文档列出的特殊 Provider 类型包括 Microsoft、Salesforce、Slack、X;未设置时为通用 OAuth。
- MCP 自动发现请求必填
provider_id、name、mcp_server_url,可附允许的 redirect URI。 - Provider 响应含
client_id、授权/换 token URL、PKCE 配置、Provider 类型、MCP Server URL、允许及默认 redirect URI、创建/更新时间;密钥材料不应在前端持久化。
取得 token 或启动授权
POST /v2/auth/authenticate 的最小请求是 provider + scopes。它还可接受用户或 Agent 身份、force_new、指定 token_id、redirect_uri、是否默认 token,以及仅检查的 check_only。同一接口可能直接复用有效 token,也可能启动授权流程。
响应的 status 是状态机,而不是布尔值:
completed:已有可用凭据,响应可能带 token;pending:授权正在进行;connection_required:需要用户访问返回的 URL 建立连接;token_expired:已有记录但凭据过期。
响应还可能包含 url、auth_id、user_id、metadata。调用方必须按状态分支,不能假设 HTTP 200 就已经得到可用 token。
GET /v2/auth/wait/{auth_id}?timeout=30 用于等待完成,返回 completed、pending、timeout 或 not_found;长轮询应设置客户端超时、取消机制和总时限,不能无限占用线程。
Callback 与 setup 流程
GET /v2/auth/callback/{provider_id}接受code、state,也接受 Provider 返回的error与error_description。POST /v2/auth/callback/{provider_id}用OAuthFinalizeRequest {code, state}完成前端桥接。GET /v2/auth/setup/{provider_id}用于 Provider 安装/setup callback,还可携带setup_action、installation_id及错误参数。
state 必须一次性校验并绑定用户会话、Provider 和 redirect URI;code 只能单次兑换。回调错误可记录类型与关联 ID,但不得记录 code、state 原值或 token。
Token Vault 操作
| 能力 | 方法与路径 | 返回/约束 |
|---|---|---|
| 查询单 Provider 是否存在 | GET /v2/auth/tokens/exists?provider_id=... | has_token |
| 批量查询 | POST /v2/auth/tokens/exists/batch | Provider ID 列表到存在状态的映射 |
| 查询 Slack 工作区 | GET /v2/auth/tokens/workspace/slack/exists | 工作区级存在状态 |
| 导入外部 token | POST /v2/auth/tokens/import | 只返回新 token_id,不回显秘密 |
| 列用户 token 摘要 | GET /v2/auth/tokens?provider_id=... | 可按 Provider 过滤 |
| 更新标签/默认项 | PATCH /v2/auth/tokens/{token_id}/metadata | 更新 provider_account_label、is_default |
| 列审计事件 | GET /v2/auth/token-events?provider_id=...&limit=50 | Provider、Agent、事件类型、原因、来源、scope、时间等 |
| 删除 Provider 下用户 token | DELETE /v2/auth/tokens?provider_id=... | 批量删除当前用户相应凭据 |
| 删除单 token | DELETE /v2/auth/tokens/{token_id} | 204 |
| 撤销工作区 Slack token | DELETE /v2/auth/tokens/workspace/slack | 工作区级批量撤销 |
导入请求必填 provider_id 与 access_token,可带 refresh token、到期秒数、scopes、metadata 与默认标记。公开的 OAuthTokenSummary 只包含 ID、Provider、账户标签、scopes、过期/默认状态和时间戳,不包含秘密;这是前端应使用的模型。
安全与可靠性结论
- scopes 使用集合包含关系判断,新增 scope 时必须重新授权,不能假设旧 token 自动扩权。
- redirect URI 采用精确 allowlist;不要允许开放重定向或仅比较域名前缀。
- Provider client secret、access/refresh token 全部进入密钥存储;日志和 Trace 做字段级脱敏。
- token 删除、默认项切换和 Provider 更新要写审计事件;批量撤销应具备确认、幂等与失败重试报告。
has_token=true只表示记录存在,不证明 token 未过期、scope 足够或 Provider 尚未撤权;真正调用前仍要走 authenticate/刷新与错误处理。