docs(identity): 发布统一认证管理契约

为配对、策略、验证、激活、回滚、禁用和公开运行时接口补充 OpenAPI 注解,并将通用 Identity 类型加入生成范围。生成契约不包含 Exchange Token、Machine Secret 或 Secret 引用。\n\n验证:pnpm openapi;OpenAPI 敏感字段扫描通过
This commit is contained in:
chengcheng 2026-07-17 12:31:11 +08:00
parent a767dc42c0
commit cdfca61304
4 changed files with 1626 additions and 1 deletions

View File

@ -2868,6 +2868,575 @@
}
}
},
"/api/admin/system/identity/configuration": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"description": "返回 Active、Draft、Previous Revision、配对进度和脱敏运行时健康状态。",
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "获取统一认证配置",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httpapi.identityConfigurationView"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"503": {
"description": "Service Unavailable",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/system/identity/disable": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "保留 Superseded Revision 供回滚,清理 BFF Session并继续允许本地管理登录。",
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "禁用统一认证",
"parameters": [
{
"type": "string",
"description": "幂等键",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"type": "string",
"description": "当前 Active Revision ETag",
"name": "If-Match",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/identity.Revision"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"412": {
"description": "Precondition Failed",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"428": {
"description": "Precondition Required",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/system/identity/pairings": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "使用一次性接入码创建 Draft 和异步 Exchange。接入码仅允许出现在请求 Body。",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "启动统一认证配对",
"parameters": [
{
"type": "string",
"description": "幂等键",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"type": "string",
"description": "首次配对固定为 W/\\",
"name": "If-Match",
"in": "header",
"required": true
},
{
"description": "配对参数",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/identity.PairingInput"
}
}
],
"responses": {
"202": {
"description": "Accepted",
"schema": {
"$ref": "#/definitions/identity.PairingExchange"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"428": {
"description": "Precondition Required",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/system/identity/pairings/{pairingID}": {
"get": {
"security": [
{
"BearerAuth": []
}
],
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "查询统一认证配对状态",
"parameters": [
{
"type": "string",
"description": "配对 ID",
"name": "pairingID",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/identity.PairingExchange"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/system/identity/revisions/{revisionID}": {
"patch": {
"security": [
{
"BearerAuth": []
}
],
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "修改统一认证 Draft 策略",
"parameters": [
{
"type": "string",
"description": "Revision ID",
"name": "revisionID",
"in": "path",
"required": true
},
{
"type": "string",
"description": "幂等键",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"type": "string",
"description": "当前 Revision ETag",
"name": "If-Match",
"in": "header",
"required": true
},
{
"description": "Gateway 本地策略",
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/httpapi.identityPolicyPatch"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/identity.Revision"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"412": {
"description": "Precondition Failed",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"428": {
"description": "Precondition Required",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/system/identity/revisions/{revisionID}/activate": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"description": "在完整候选 Runtime 验证成功且本地 Break-glass Manager 可用后原子热切换。",
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "激活统一认证 Revision",
"parameters": [
{
"type": "string",
"description": "Revision ID",
"name": "revisionID",
"in": "path",
"required": true
},
{
"type": "string",
"description": "幂等键",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"type": "string",
"description": "当前 Revision ETag",
"name": "If-Match",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/identity.Revision"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"412": {
"description": "Precondition Failed",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"428": {
"description": "Precondition Required",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/system/identity/revisions/{revisionID}/rollback": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "回滚统一认证 Revision",
"parameters": [
{
"type": "string",
"description": "Revision ID",
"name": "revisionID",
"in": "path",
"required": true
},
{
"type": "string",
"description": "幂等键",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"type": "string",
"description": "当前 Revision ETag",
"name": "If-Match",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/identity.Revision"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"409": {
"description": "Conflict",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"412": {
"description": "Precondition Failed",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"428": {
"description": "Precondition Required",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/system/identity/revisions/{revisionID}/validate": {
"post": {
"security": [
{
"BearerAuth": []
}
],
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "验证统一认证 Revision",
"parameters": [
{
"type": "string",
"description": "Revision ID",
"name": "revisionID",
"in": "path",
"required": true
},
{
"type": "string",
"description": "幂等键",
"name": "Idempotency-Key",
"in": "header",
"required": true
},
{
"type": "string",
"description": "当前 Revision ETag",
"name": "If-Match",
"in": "header",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/identity.Revision"
}
},
"401": {
"description": "Unauthorized",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"412": {
"description": "Precondition Failed",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"428": {
"description": "Precondition Required",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
},
"502": {
"description": "Bad Gateway",
"schema": {
"$ref": "#/definitions/httpapi.ErrorEnvelope"
}
}
}
}
},
"/api/admin/tenants": {
"get": {
"security": [
@ -5320,6 +5889,26 @@
}
}
},
"/api/v1/public/identity": {
"get": {
"description": "返回 Web 运行时需要的启用状态和非敏感登录、退出入口,不返回 Client、Secret 或内部标识。",
"produces": [
"application/json"
],
"tags": [
"identity"
],
"summary": "获取公开统一认证状态",
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/httpapi.publicIdentityConfiguration"
}
}
}
}
},
"/api/v1/reranks": {
"post": {
"security": [
@ -10742,6 +11331,104 @@
}
}
},
"httpapi.identityConfigurationView": {
"type": "object",
"properties": {
"active": {
"$ref": "#/definitions/identity.Revision"
},
"draft": {
"$ref": "#/definitions/identity.Revision"
},
"pairing": {
"$ref": "#/definitions/identity.PairingExchange"
},
"previous": {
"$ref": "#/definitions/identity.Revision"
},
"runtime": {
"$ref": "#/definitions/httpapi.identityRuntimeStatus"
}
}
},
"httpapi.identityPolicyPatch": {
"type": "object",
"properties": {
"jitEnabled": {
"type": "boolean"
},
"legacyJwtEnabled": {
"type": "boolean"
},
"localTenantKey": {
"type": "string"
},
"rolePrefix": {
"type": "string"
},
"sessionAbsoluteSeconds": {
"type": "integer"
},
"sessionIdleSeconds": {
"type": "integer"
},
"sessionRefreshSeconds": {
"type": "integer"
}
}
},
"httpapi.identityRuntimeStatus": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"jit": {
"type": "string"
},
"lastAuditId": {
"type": "string"
},
"lastErrorCategory": {
"type": "string"
},
"lastTraceId": {
"type": "string"
},
"login": {
"type": "string"
},
"revisionId": {
"type": "string"
},
"sessionRevocation": {
"type": "string"
},
"tokenIntrospection": {
"type": "string"
}
}
},
"httpapi.publicIdentityConfiguration": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"loginUrl": {
"type": "string"
},
"logoutUrl": {
"type": "string"
},
"oidcLogin": {
"type": "boolean"
},
"status": {
"type": "string"
}
}
},
"httpapi.updatePlatformDynamicPriorityRequest": {
"type": "object",
"properties": {
@ -10805,6 +11492,224 @@
}
}
},
"identity.PairingExchange": {
"type": "object",
"properties": {
"authCenterAuditId": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"expiresAt": {
"type": "string"
},
"id": {
"type": "string"
},
"lastErrorCategory": {
"type": "string"
},
"lastTraceId": {
"type": "string"
},
"remoteExchangeId": {
"type": "string"
},
"remoteVersion": {
"type": "integer"
},
"revisionId": {
"type": "string"
},
"status": {
"$ref": "#/definitions/identity.PairingStatus"
},
"updatedAt": {
"type": "string"
},
"version": {
"type": "integer"
}
}
},
"identity.PairingInput": {
"type": "object",
"properties": {
"authCenterUrl": {
"type": "string"
},
"legacyJwtEnabled": {
"type": "boolean"
},
"localTenantKey": {
"type": "string"
},
"onboardingCode": {
"type": "string"
},
"publicBaseUrl": {
"type": "string"
},
"webBaseUrl": {
"type": "string"
}
}
},
"identity.PairingStatus": {
"type": "string",
"enum": [
"metadata_pending",
"preparing",
"ready",
"credentials_saved",
"completed",
"failed",
"expired"
],
"x-enum-varnames": [
"PairingMetadataPending",
"PairingPreparing",
"PairingReady",
"PairingCredentialsSaved",
"PairingCompleted",
"PairingFailed",
"PairingExpired"
]
},
"identity.Revision": {
"type": "object",
"properties": {
"activatedAt": {
"type": "string"
},
"applicationId": {
"type": "string"
},
"audience": {
"type": "string"
},
"authCenterUrl": {
"type": "string"
},
"browserClientId": {
"type": "string"
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
},
"createdAt": {
"type": "string"
},
"id": {
"type": "string"
},
"issuer": {
"type": "string"
},
"jitEnabled": {
"type": "boolean"
},
"lastAuditId": {
"type": "string"
},
"lastErrorCategory": {
"type": "string"
},
"lastTraceId": {
"type": "string"
},
"legacyJwtEnabled": {
"type": "boolean"
},
"localTenantKey": {
"type": "string"
},
"machineClientId": {
"type": "string"
},
"publicBaseUrl": {
"type": "string"
},
"rolePrefix": {
"type": "string"
},
"schemaVersion": {
"type": "integer"
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"securityEventAudience": {
"type": "string"
},
"securityEventConfigurationUrl": {
"type": "string"
},
"securityEventIssuer": {
"type": "string"
},
"sessionAbsoluteSeconds": {
"type": "integer"
},
"sessionIdleSeconds": {
"type": "integer"
},
"sessionRefreshSeconds": {
"type": "integer"
},
"sessionRevocation": {
"type": "boolean"
},
"state": {
"$ref": "#/definitions/identity.RevisionState"
},
"supersededAt": {
"type": "string"
},
"tenantId": {
"type": "string"
},
"tokenIntrospection": {
"type": "boolean"
},
"updatedAt": {
"type": "string"
},
"validatedAt": {
"type": "string"
},
"version": {
"type": "integer"
},
"webBaseUrl": {
"type": "string"
}
}
},
"identity.RevisionState": {
"type": "string",
"enum": [
"draft",
"validated",
"active",
"superseded",
"failed"
],
"x-enum-varnames": [
"RevisionDraft",
"RevisionValidated",
"RevisionActive",
"RevisionSuperseded",
"RevisionFailed"
]
},
"store.APIKey": {
"type": "object",
"properties": {

View File

@ -823,6 +823,70 @@ definitions:
billing:
$ref: '#/definitions/httpapi.desktopBillingConfigResponse'
type: object
httpapi.identityConfigurationView:
properties:
active:
$ref: '#/definitions/identity.Revision'
draft:
$ref: '#/definitions/identity.Revision'
pairing:
$ref: '#/definitions/identity.PairingExchange'
previous:
$ref: '#/definitions/identity.Revision'
runtime:
$ref: '#/definitions/httpapi.identityRuntimeStatus'
type: object
httpapi.identityPolicyPatch:
properties:
jitEnabled:
type: boolean
legacyJwtEnabled:
type: boolean
localTenantKey:
type: string
rolePrefix:
type: string
sessionAbsoluteSeconds:
type: integer
sessionIdleSeconds:
type: integer
sessionRefreshSeconds:
type: integer
type: object
httpapi.identityRuntimeStatus:
properties:
enabled:
type: boolean
jit:
type: string
lastAuditId:
type: string
lastErrorCategory:
type: string
lastTraceId:
type: string
login:
type: string
revisionId:
type: string
sessionRevocation:
type: string
tokenIntrospection:
type: string
type: object
httpapi.publicIdentityConfiguration:
properties:
enabled:
type: boolean
loginUrl:
type: string
logoutUrl:
type: string
oidcLogin:
type: boolean
status:
type: string
type: object
httpapi.updatePlatformDynamicPriorityRequest:
properties:
dynamicPriority:
@ -868,6 +932,157 @@ definitions:
example: manual recharge
type: string
type: object
identity.PairingExchange:
properties:
authCenterAuditId:
type: string
createdAt:
type: string
expiresAt:
type: string
id:
type: string
lastErrorCategory:
type: string
lastTraceId:
type: string
remoteExchangeId:
type: string
remoteVersion:
type: integer
revisionId:
type: string
status:
$ref: '#/definitions/identity.PairingStatus'
updatedAt:
type: string
version:
type: integer
type: object
identity.PairingInput:
properties:
authCenterUrl:
type: string
legacyJwtEnabled:
type: boolean
localTenantKey:
type: string
onboardingCode:
type: string
publicBaseUrl:
type: string
webBaseUrl:
type: string
type: object
identity.PairingStatus:
enum:
- metadata_pending
- preparing
- ready
- credentials_saved
- completed
- failed
- expired
type: string
x-enum-varnames:
- PairingMetadataPending
- PairingPreparing
- PairingReady
- PairingCredentialsSaved
- PairingCompleted
- PairingFailed
- PairingExpired
identity.Revision:
properties:
activatedAt:
type: string
applicationId:
type: string
audience:
type: string
authCenterUrl:
type: string
browserClientId:
type: string
capabilities:
items:
type: string
type: array
createdAt:
type: string
id:
type: string
issuer:
type: string
jitEnabled:
type: boolean
lastAuditId:
type: string
lastErrorCategory:
type: string
lastTraceId:
type: string
legacyJwtEnabled:
type: boolean
localTenantKey:
type: string
machineClientId:
type: string
publicBaseUrl:
type: string
rolePrefix:
type: string
schemaVersion:
type: integer
scopes:
items:
type: string
type: array
securityEventAudience:
type: string
securityEventConfigurationUrl:
type: string
securityEventIssuer:
type: string
sessionAbsoluteSeconds:
type: integer
sessionIdleSeconds:
type: integer
sessionRefreshSeconds:
type: integer
sessionRevocation:
type: boolean
state:
$ref: '#/definitions/identity.RevisionState'
supersededAt:
type: string
tenantId:
type: string
tokenIntrospection:
type: boolean
updatedAt:
type: string
validatedAt:
type: string
version:
type: integer
webBaseUrl:
type: string
type: object
identity.RevisionState:
enum:
- draft
- validated
- active
- superseded
- failed
type: string
x-enum-varnames:
- RevisionDraft
- RevisionValidated
- RevisionActive
- RevisionSuperseded
- RevisionFailed
store.APIKey:
properties:
createdAt:
@ -4372,6 +4587,374 @@ paths:
summary: 更新文件存储设置
tags:
- system
/api/admin/system/identity/configuration:
get:
description: 返回 Active、Draft、Previous Revision、配对进度和脱敏运行时健康状态。
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/httpapi.identityConfigurationView'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"503":
description: Service Unavailable
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 获取统一认证配置
tags:
- identity
/api/admin/system/identity/disable:
post:
description: 保留 Superseded Revision 供回滚,清理 BFF Session并继续允许本地管理登录。
parameters:
- description: 幂等键
in: header
name: Idempotency-Key
required: true
type: string
- description: 当前 Active Revision ETag
in: header
name: If-Match
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/identity.Revision'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"409":
description: Conflict
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"412":
description: Precondition Failed
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"428":
description: Precondition Required
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 禁用统一认证
tags:
- identity
/api/admin/system/identity/pairings:
post:
consumes:
- application/json
description: 使用一次性接入码创建 Draft 和异步 Exchange。接入码仅允许出现在请求 Body。
parameters:
- description: 幂等键
in: header
name: Idempotency-Key
required: true
type: string
- description: 首次配对固定为 W/\
in: header
name: If-Match
required: true
type: string
- description: 配对参数
in: body
name: body
required: true
schema:
$ref: '#/definitions/identity.PairingInput'
produces:
- application/json
responses:
"202":
description: Accepted
schema:
$ref: '#/definitions/identity.PairingExchange'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"409":
description: Conflict
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"428":
description: Precondition Required
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 启动统一认证配对
tags:
- identity
/api/admin/system/identity/pairings/{pairingID}:
get:
parameters:
- description: 配对 ID
in: path
name: pairingID
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/identity.PairingExchange'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"404":
description: Not Found
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 查询统一认证配对状态
tags:
- identity
/api/admin/system/identity/revisions/{revisionID}:
patch:
consumes:
- application/json
parameters:
- description: Revision ID
in: path
name: revisionID
required: true
type: string
- description: 幂等键
in: header
name: Idempotency-Key
required: true
type: string
- description: 当前 Revision ETag
in: header
name: If-Match
required: true
type: string
- description: Gateway 本地策略
in: body
name: body
required: true
schema:
$ref: '#/definitions/httpapi.identityPolicyPatch'
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/identity.Revision'
"400":
description: Bad Request
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"412":
description: Precondition Failed
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"428":
description: Precondition Required
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 修改统一认证 Draft 策略
tags:
- identity
/api/admin/system/identity/revisions/{revisionID}/activate:
post:
description: 在完整候选 Runtime 验证成功且本地 Break-glass Manager 可用后原子热切换。
parameters:
- description: Revision ID
in: path
name: revisionID
required: true
type: string
- description: 幂等键
in: header
name: Idempotency-Key
required: true
type: string
- description: 当前 Revision ETag
in: header
name: If-Match
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/identity.Revision'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"409":
description: Conflict
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"412":
description: Precondition Failed
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"428":
description: Precondition Required
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 激活统一认证 Revision
tags:
- identity
/api/admin/system/identity/revisions/{revisionID}/rollback:
post:
parameters:
- description: Revision ID
in: path
name: revisionID
required: true
type: string
- description: 幂等键
in: header
name: Idempotency-Key
required: true
type: string
- description: 当前 Revision ETag
in: header
name: If-Match
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/identity.Revision'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"409":
description: Conflict
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"412":
description: Precondition Failed
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"428":
description: Precondition Required
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 回滚统一认证 Revision
tags:
- identity
/api/admin/system/identity/revisions/{revisionID}/validate:
post:
parameters:
- description: Revision ID
in: path
name: revisionID
required: true
type: string
- description: 幂等键
in: header
name: Idempotency-Key
required: true
type: string
- description: 当前 Revision ETag
in: header
name: If-Match
required: true
type: string
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/identity.Revision'
"401":
description: Unauthorized
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"403":
description: Forbidden
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"412":
description: Precondition Failed
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"428":
description: Precondition Required
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
"502":
description: Bad Gateway
schema:
$ref: '#/definitions/httpapi.ErrorEnvelope'
security:
- BearerAuth: []
summary: 验证统一认证 Revision
tags:
- identity
/api/admin/tenants:
get:
description: 管理端返回网关租户列表。
@ -5951,6 +6534,19 @@ paths:
summary: 获取公开客户端自定义设置
tags:
- system
/api/v1/public/identity:
get:
description: 返回 Web 运行时需要的启用状态和非敏感登录、退出入口,不返回 Client、Secret 或内部标识。
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/httpapi.publicIdentityConfiguration'
summary: 获取公开统一认证状态
tags:
- identity
/api/v1/reranks:
post:
consumes:

View File

@ -74,6 +74,13 @@ func (operation *identityWriteOperation) close() {
}
}
// getPublicIdentityConfiguration godoc
// @Summary 获取公开统一认证状态
// @Description 返回 Web 运行时需要的启用状态和非敏感登录、退出入口,不返回 Client、Secret 或内部标识。
// @Tags identity
// @Produce json
// @Success 200 {object} publicIdentityConfiguration
// @Router /api/v1/public/identity [get]
func (s *Server) getPublicIdentityConfiguration(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Cache-Control", "no-store")
runtime := s.currentIdentityRuntime()
@ -90,6 +97,17 @@ func (s *Server) getPublicIdentityConfiguration(w http.ResponseWriter, _ *http.R
writeJSON(w, http.StatusOK, view)
}
// getIdentityConfiguration godoc
// @Summary 获取统一认证配置
// @Description 返回 Active、Draft、Previous Revision、配对进度和脱敏运行时健康状态。
// @Tags identity
// @Produce json
// @Security BearerAuth
// @Success 200 {object} identityConfigurationView
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 503 {object} ErrorEnvelope
// @Router /api/admin/system/identity/configuration [get]
func (s *Server) getIdentityConfiguration(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-store")
view := identityConfigurationView{Runtime: s.identityRuntimeStatus(r)}
@ -117,6 +135,23 @@ func (s *Server) getIdentityConfiguration(w http.ResponseWriter, r *http.Request
writeJSON(w, http.StatusOK, view)
}
// startIdentityPairing godoc
// @Summary 启动统一认证配对
// @Description 使用一次性接入码创建 Draft 和异步 Exchange。接入码仅允许出现在请求 Body。
// @Tags identity
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param Idempotency-Key header string true "幂等键"
// @Param If-Match header string true "首次配对固定为 W/\"0\""
// @Param body body identity.PairingInput true "配对参数"
// @Success 202 {object} identity.PairingExchange
// @Failure 400 {object} ErrorEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 409 {object} ErrorEnvelope
// @Failure 428 {object} ErrorEnvelope
// @Router /api/admin/system/identity/pairings [post]
func (s *Server) startIdentityPairing(w http.ResponseWriter, r *http.Request) {
var input identity.PairingInput
if !decodeIdentityRequest(w, r, &input) {
@ -139,6 +174,17 @@ func (s *Server) startIdentityPairing(w http.ResponseWriter, r *http.Request) {
s.startIdentityPairingWorker(pairing.ID)
}
// getIdentityPairing godoc
// @Summary 查询统一认证配对状态
// @Tags identity
// @Produce json
// @Security BearerAuth
// @Param pairingID path string true "配对 ID"
// @Success 200 {object} identity.PairingExchange
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 404 {object} ErrorEnvelope
// @Router /api/admin/system/identity/pairings/{pairingID} [get]
func (s *Server) getIdentityPairing(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "no-store")
pairing, err := s.store.IdentityPairingExchange(r.Context(), r.PathValue("pairingID"))
@ -150,6 +196,23 @@ func (s *Server) getIdentityPairing(w http.ResponseWriter, r *http.Request) {
writeJSON(w, http.StatusOK, pairing)
}
// updateIdentityDraftPolicy godoc
// @Summary 修改统一认证 Draft 策略
// @Tags identity
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param revisionID path string true "Revision ID"
// @Param Idempotency-Key header string true "幂等键"
// @Param If-Match header string true "当前 Revision ETag"
// @Param body body identityPolicyPatch true "Gateway 本地策略"
// @Success 200 {object} identity.Revision
// @Failure 400 {object} ErrorEnvelope
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 412 {object} ErrorEnvelope
// @Failure 428 {object} ErrorEnvelope
// @Router /api/admin/system/identity/revisions/{revisionID} [patch]
func (s *Server) updateIdentityDraftPolicy(w http.ResponseWriter, r *http.Request) {
var patch identityPolicyPatch
if !decodeIdentityRequest(w, r, &patch) {
@ -185,24 +248,85 @@ func (s *Server) updateIdentityDraftPolicy(w http.ResponseWriter, r *http.Reques
s.completeIdentityWrite(w, r, operation, http.StatusOK, updated, updated.Version, auditID)
}
// validateIdentityRevision godoc
// @Summary 验证统一认证 Revision
// @Tags identity
// @Produce json
// @Security BearerAuth
// @Param revisionID path string true "Revision ID"
// @Param Idempotency-Key header string true "幂等键"
// @Param If-Match header string true "当前 Revision ETag"
// @Success 200 {object} identity.Revision
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 412 {object} ErrorEnvelope
// @Failure 428 {object} ErrorEnvelope
// @Failure 502 {object} ErrorEnvelope
// @Router /api/admin/system/identity/revisions/{revisionID}/validate [post]
func (s *Server) validateIdentityRevision(w http.ResponseWriter, r *http.Request) {
s.runIdentityRevisionAction(w, r, "revision.validate", func(expected int64, traceID, auditID string) (identity.Revision, error) {
return s.identityRuntime.Validate(r.Context(), r.PathValue("revisionID"), expected, traceID, auditID)
})
}
// activateIdentityRevision godoc
// @Summary 激活统一认证 Revision
// @Description 在完整候选 Runtime 验证成功且本地 Break-glass Manager 可用后原子热切换。
// @Tags identity
// @Produce json
// @Security BearerAuth
// @Param revisionID path string true "Revision ID"
// @Param Idempotency-Key header string true "幂等键"
// @Param If-Match header string true "当前 Revision ETag"
// @Success 200 {object} identity.Revision
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 409 {object} ErrorEnvelope
// @Failure 412 {object} ErrorEnvelope
// @Failure 428 {object} ErrorEnvelope
// @Router /api/admin/system/identity/revisions/{revisionID}/activate [post]
func (s *Server) activateIdentityRevision(w http.ResponseWriter, r *http.Request) {
s.runIdentityRevisionAction(w, r, "revision.activate", func(expected int64, traceID, auditID string) (identity.Revision, error) {
return s.identityRuntime.Activate(r.Context(), r.PathValue("revisionID"), expected, traceID, auditID)
})
}
// rollbackIdentityRevision godoc
// @Summary 回滚统一认证 Revision
// @Tags identity
// @Produce json
// @Security BearerAuth
// @Param revisionID path string true "Revision ID"
// @Param Idempotency-Key header string true "幂等键"
// @Param If-Match header string true "当前 Revision ETag"
// @Success 200 {object} identity.Revision
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 409 {object} ErrorEnvelope
// @Failure 412 {object} ErrorEnvelope
// @Failure 428 {object} ErrorEnvelope
// @Router /api/admin/system/identity/revisions/{revisionID}/rollback [post]
func (s *Server) rollbackIdentityRevision(w http.ResponseWriter, r *http.Request) {
s.runIdentityRevisionAction(w, r, "revision.rollback", func(expected int64, traceID, auditID string) (identity.Revision, error) {
return s.identityRuntime.Rollback(r.Context(), r.PathValue("revisionID"), expected, traceID, auditID)
})
}
// disableIdentityConfiguration godoc
// @Summary 禁用统一认证
// @Description 保留 Superseded Revision 供回滚,清理 BFF Session并继续允许本地管理登录。
// @Tags identity
// @Produce json
// @Security BearerAuth
// @Param Idempotency-Key header string true "幂等键"
// @Param If-Match header string true "当前 Active Revision ETag"
// @Success 200 {object} identity.Revision
// @Failure 401 {object} ErrorEnvelope
// @Failure 403 {object} ErrorEnvelope
// @Failure 409 {object} ErrorEnvelope
// @Failure 412 {object} ErrorEnvelope
// @Failure 428 {object} ErrorEnvelope
// @Router /api/admin/system/identity/disable [post]
func (s *Server) disableIdentityConfiguration(w http.ResponseWriter, r *http.Request) {
expectedVersion, ok := requiredIdentityVersion(w, r)
if !ok {

View File

@ -24,7 +24,7 @@
"outputs": ["{projectRoot}/docs/swagger.json", "{projectRoot}/docs/swagger.yaml"],
"options": {
"cwd": "apps/api",
"command": "go run github.com/swaggo/swag/cmd/swag@v1.16.4 init --parseInternal -d ./cmd/gateway,./internal/httpapi,./internal/store,./internal/auth -g main.go -o docs --outputTypes json,yaml"
"command": "go run github.com/swaggo/swag/cmd/swag@v1.16.4 init --parseInternal -d ./cmd/gateway,./internal/httpapi,./internal/store,./internal/auth,./internal/identity -g main.go -o docs --outputTypes json,yaml"
}
},
"test": {