Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

全平台客户端

AuthKeystone 的 OAuth client 体系:三级可见性(visibility)、门户展示开关(portal_visible)、 自助接入、越级提升申请工作流,以及管理端操作。


1. 三级 visibility(可见性)

每个 OAuth client 有一个 visibility 字段,决定谁能看到、谁能写。三级从低到高:

级别数值谁能看到(list)谁能写(can_write_client)典型场景
user0仅 owner(owner_user_id仅 owner普通用户自助创建的私有 client
org1同组织成员(org_id 匹配)该组织 org_admin(system:oauth:client:edit + org 匹配)团队/企业共享的 client
system2全平台所有人平台 admin官方 / 全局 client

可见性查询(list_visible_clients)的过滤条件:

visibility = 'system'
  OR (visibility = 'org'  AND org_id = ?)
  OR (visibility = 'user' AND owner_user_id = ?)

应用门户(GET /api/user/apps)与 API Key 的应用选择器共用这一数据源,再由调用方按 portal_visible 决定是否展示。

写权限按级绑定(越级不可直接改)

visibility 同时绑定写权限:只能由当前级的 authority 改写。越级提升(user→org→system)不能直接改字段,必须走提升申请工作流(见第 4 节)——防止 owner 私自把 user 级 client 提到 system 级越权。


2. portal_visible(门户展示开关)

portal_visible 是独立于 visibility 的布尔字段,只控制是否在「我的应用」门户展示,不影响权限:

  • true → 出现在 GET /api/user/apps 列表,普通用户可见可点
  • false → 不出现在门户(即使 visibility 允许看到,也不展示)

典型用法:内部工具、后台 client 关掉;面向终端用户的应用打开。管理端可在 OAuth client 列表内联切换。


3. 自助接入(普通用户自己建 client)

普通用户无需 admin 权限即可注册自己的 OAuth client(默认 visibility=user)。 支持两种类型:Web 应用(用户登录接入)与 M2M 服务身份(服务间调用)。

3.1 用户域端点(/api/my/clients,按 owner 过滤)

方法路径说明
GET/api/my/clients列出我(owner)的 client
POST/api/my/clients创建我的 client(固定 visibility=user)
DELETE/api/my/clients/:client_id删除我的 client(校验 owner 归属)

创建响应里 client_secret 明文仅返回一次。匿名访客须先转正(POST /api/auth/upgrade)才能创建。

存量配额(2026-09 起):每用户名下 client 总数受上限约束(管理台「系统设置」的 self_service_client_quota,默认 10,热生效;0 = 关闭自助创建)。GET 列表响应带 {quota, used, remaining} 余量;超限创建返回 400(删除 client 即释放名额)。admin 通道 创建的 client 不绑 owner,不受此限。

通用约束(防越权):

  • visibility 固定为 user,不能自助指定 org/system
  • grant 白名单:authorization_code / refresh_token / client_credentials
  • redirect_uri 必须 http(s)://
  • 存量配额:见上,资源卫生约束(权限越权已由委托模型/白名单独立挡住)

3.2 两种客户端类型(grant_types 决定)

Web 应用M2M 服务身份
grant_typesauthorization_code(+ refresh_token,缺省即此组合)client_credentials
典型场景Web / SPA 应用接入登录服务间调用、定时任务、机器人
redirect_uris必填(授权码回调)免填(无浏览器回调)
scope只能从 openid / profile / email 选——不能塞系统 scope(如 auth:permissionsauth:org),防自助 client 越权拿权限/组织字段自动置空(M2M 无用户上下文,scope 无意义)
权限通道scope 经用户授权(consent)service_permissions 委托(见 3.3)
is_public允许(前端 SPA,强制 PKCE)不允许——M2M 须机密客户端
is_first_party默认 true(第一方免 consent)强制 false(无浏览器/consent 上下文)

混合 grant(authorization_code + client_credentials)按 Web 型处理,不能携带 service_permissions——需要服务身份时单独创建一个纯 M2M client。

3.3 M2M 委托权限模型(service_permissions

user 级 M2M 的 token 权限不是平台分配,而是创建者对自身权限的委托(与 GitHub OAuth Apps「人人可建、权限不超出本人」同款分层):

  • service_permissions 必须是创建者自身权限(claims.permissions)的子集——只能委托自己有的,超出范围创建报 400
  • 换 token:POST /oauth/token(grant_type=client_credentials)→ 机器 token 的 sub/aud = client_id、token_type=clientpermissions = 委托的权限集、TTL 15 分钟、带 jti
  • 委托校验在创建时执行,配置存于 client;自助面暂无编辑端点,调整委托 = 删除重建
  • 非 user 级(org/system,管理端创建)的 M2M 走命名空间白名单(platform: / capability: / agent:),与 user 级委托是两条权限界

3.4 标准 DCR(RFC 7591/7592,机器自助接入)

下游服务也可走标准动态客户端注册,无需人工:

方法路径说明
POST/oauth/register注册 client,返回 registration_access_token
GET/PUT/DELETE/oauth/register/:client_id用 registration_access_token 管自己注册的 client

4. visibility 提升申请工作流

owner(或当前级写权者)想让 client 从 user 升到 org/system不能直接改,要走申请→审批:

申请方(当前级写权者:owner / org_admin)
   │  POST /api/oauth-clients/:client_id/promote   { to_visibility: "org"|"system", note? }
   ▼
待审批(pending)
   │  目标级 authority 审批:
   │    to=system → 平台 admin
   │    to=org    → 该组织 org_admin(system:oauth:client:edit + org 匹配)
   ▼
 POST /api/promotion-requests/:id/decide   { approve: bool, note? }
   │
   ├─ approve → client.visibility 改为目标级(to=org 时归入申请指定组织)
   │            ⚠ 写权随之转交目标级 authority,原 owner 失去直接编辑权
   └─ reject  → 状态记为 rejected,visibility 不变

端点

方法路径权限说明
POST/api/oauth-clients/:client_id/promote当前级写权者发起提升申请(to 须高于 from,且只能 org/system)
GET/api/promotion-requests-申请列表:平台 admin 看全部;org_admin 看 to=org 本组织;其余看自己提的
POST/api/promotion-requests/:id/decide目标级 authority审批(approve/reject)

关键规则

  • to_visibility 必须高于 from_visibility(user < org < system),且只能是 orgsystem
  • to=org 时,目标组织 = 申请人所在组织
  • approve 后写权转交:原 owner 不再能直接编辑该 client——这是有意设计,避免提升后权限与管理权错配

5. 管理端(平台 admin / org_admin)

方法路径权限说明
GET/api/admin/oauth/clientssystem:oauth:client:listclient 列表
POST/api/admin/oauth/clientssystem:oauth:client:create创建(可直接指定 visibility)
PUT/api/admin/oauth/clients/:client_idsystem:oauth:client:edit更新(含 visibility / portal_visible)
DELETE/api/admin/oauth/clients/:client_idsystem:oauth:client:delete删除
POST/api/admin/oauth/clients/:client_id/rotatesystem:oauth:client:edit轮换 client_secret
GET/POST/api/admin/oauth/clients/:client_id/scopessystem:oauth:client:*查看 / 配置 client 的 scope
GET/POST/PUT/DELETE/api/admin/client-scopessystem:oauth:client:*scope 全生命周期 + 用量追踪

平台 admin 可设任意 visibility;org_admin 仅能管本组织 visibility=org 的 client(Phase 2 写权限按级绑定)。