学习笔记 · Obsidian

OAuth Auth Service v2

LangChainLangSmith

Auth Service 把 Provider 配置、授权流程、token Vault、审计事件和 Agent 身份解析拆成不同资源。正确实现要保持这几个边界,不能把“Provider 已配置”“用户已有 token”“当前 token 仍可用”混为同一状态。

Provider 管理

能力方法与路径关键点
列组织 ProviderGET /v2/auth/providers根文档与 list-oauth-providers 是同一操作的两个文档入口
读取 ProviderGET /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 侧全局撤权
平台 ProviderGET /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/batchProvider ID 列表到存在状态的映射
查询 Slack 工作区GET /v2/auth/tokens/workspace/slack/exists工作区级存在状态
导入外部 tokenPOST /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=50Provider、Agent、事件类型、原因、来源、scope、时间等
删除 Provider 下用户 tokenDELETE /v2/auth/tokens?provider_id=...批量删除当前用户相应凭据
删除单 tokenDELETE /v2/auth/tokens/{token_id}204
撤销工作区 Slack tokenDELETE /v2/auth/tokens/workspace/slack工作区级批量撤销

导入请求必填 provider_id 与 access_token,可带 refresh token、到期秒数、scopes、metadata 与默认标记。公开的 OAuthTokenSummary 只包含 ID、Provider、账户标签、scopes、过期/默认状态和时间戳,不包含秘密;这是前端应使用的模型。

安全与可靠性结论

  1. scopes 使用集合包含关系判断,新增 scope 时必须重新授权,不能假设旧 token 自动扩权。
  2. redirect URI 采用精确 allowlist;不要允许开放重定向或仅比较域名前缀。
  3. Provider client secret、access/refresh token 全部进入密钥存储;日志和 Trace 做字段级脱敏。
  4. token 删除、默认项切换和 Provider 更新要写审计事件;批量撤销应具备确认、幂等与失败重试报告。
  5. has_token=true 只表示记录存在,不证明 token 未过期、scope 足够或 Provider 尚未撤权;真正调用前仍要走 authenticate/刷新与错误处理。