openapi: 3.1.0
jsonSchemaDialect: https://spec.openapis.org/oas/3.1/dialect/base
info:
  title: ProudAuth API
  version: 1.0.0
  summary: 'Self-hosted identity provider: protocol, interaction, self-service, tenant and administration APIs.'
  description: >
    Contract for the ProudAuth custom HTTP API (`/api/v1/realms/{realm}/...`) and the protocol endpoints served under
    the path-based issuer (`/realms/{realm}`). Generated from the server code (internal/httpapi) and kept in sync by
    tests/contract.


    Conventions (docs/plan.md section 25):


    * **Errors.** Custom APIs return RFC 9457 problem details (`application/problem+json`, schema `Problem`) with a
    stable `code` and the `request_id`. OAuth/OIDC endpoints return standard OAuth errors (`OAuthError`).

    * **Strict JSON.** Request bodies must be `application/json`, are size-bounded, and are rejected when they contain
    duplicate or unknown members (`additionalProperties: false`).

    * **Authentication.** Bearer tokens only in the `Authorization` header (never query strings). 401 for
    missing/invalid credentials, 403 for authenticated-but-disallowed, 404 where existence is concealed.

    * **Idempotency.** Every authenticated POST accepts `Idempotency-Key` (24 hours, actor/realm/route-bound, matched on
    the exact path and body). Only successful responses are recorded, and responses that carried one-time secrets are
    never replayed.

    * **One-time secrets.** Fields marked `x-secret: true` (client secrets, API keys, personal tokens, setup tokens,
    recovery codes, signing secrets, handoff codes, download tokens, continuation tokens) are returned exactly once.

    * **Concurrency.** Editable resources return a weak `ETag` (`W/"v{version}"`); send it in `If-Match`. Stale versions
    return 412; where `If-Match` is required, omitting it returns 428.

    * **Pagination.** Cursor-paginated lists accept `cursor` and `limit` and return `next_cursor` (empty string on the
    last page).

    * **Correlation.** `X-Request-Id` is accepted (printable ASCII, at most 64 characters) or generated, and echoed on
    every response.

    * **Throttling.** 429 and 503 responses include `Retry-After`.

    * **Trust classes and permissions.** `x-trust-class` records the section 25.2 trust class of each operation;
    `x-permissions` lists the permissions the server checks (any one suffices unless noted). Organization-scoped `org.*`
    permissions are evaluated in the organization named by the path, whose existence is concealed (404) from callers
    without any permission in it.
  license:
    name: See LICENSE
    url: https://proudauth.com/docs/reference/license/
servers:
  - url: '{origin}'
    description: The configured public origin (server.public_origin).
    variables:
      origin:
        default: https://identity.example.com
tags:
  - name: Extensions
    description: Lifecycle workflows, signed plugins and extension contract versions (EXT-013..EXT-018).
  - name: Registry
    description: Container-registry token bridge (ADV-010).
  - name: Passkeys
    description: Passkey attestation trust and WebAuthn Level 3 related origins (PASS-009, PASS-010).
  - name: SAML
    description: SAML 2.0 identity provider (SAML applications) and broker (SAML connections), their metadata and signing keys.
  - name: Authentication flows
    description: 'Versioned authentication-flow definitions: analysis, simulation, publication and rollback (AUT-019).'
  - name: Shared signals
    description: 'Shared Signals Framework transmitter: CAEP and RISC security events by push or poll (AUD-016).'
  - name: Directory
    description: >-
      LDAP/Active Directory federation and synchronization, outbound SCIM provisioning, reconciliation and connector
      evidence (PROV-010..PROV-014, PROV-017, PROV-018, FED-015, USR-022).
  - name: Discovery
    description: 'Public metadata: OpenID configuration, RFC 8414 metadata and JWKS.'
  - name: OAuth
    description: >-
      OAuth 2.0 protocol endpoints (authorize, token, introspect, revoke, device authorization, PAR). Errors use the
      OAuth JSON format, not problem details.
  - name: OIDC
    description: OpenID Connect UserInfo and RP-initiated logout.
  - name: CORS
    description: CORS preflight for registered client origins.
  - name: Interaction
    description: Headless authentication transactions, registration, password reset and account setup.
  - name: Self-service
    description: The calling user's own profile, identifiers, credentials, sessions, consents and tokens (/me).
  - name: Organizations
    description: Tenant (organization) lifecycle, members, roles, join requests, groups and domains.
  - name: Invitations
    description: Organization invitations.
  - name: Users
    description: User administration.
  - name: Projects
    description: Project administration.
  - name: Clients
    description: OAuth client registration and credentials.
  - name: Resources
    description: Protected APIs (resources), scopes and introspectors.
  - name: Authorization
    description: Permissions, roles, role assignments and the policy decision API.
  - name: Machine identities
    description: Service principals, API keys and credential inventory.
  - name: Realm
    description: Realm policy, emergency state and signing keys.
  - name: Audit
    description: Audit evidence queries, integrity and exports.
  - name: Jobs
    description: Asynchronous jobs and protected result downloads.
  - name: Provisioning
    description: Inbound SCIM 2.0 provisioning and connector management (PROV-001..PROV-009, PROV-018).
  - name: Federation
    description: Upstream identity providers (OIDC and social), federated sign-in callbacks and linked identities.
  - name: Support access
    description: Support impersonation requests, grants and handoffs.
  - name: Webhooks
    description: Webhook subscriptions and deliveries (event schemas in api/events).
  - name: Imports and exports
    description: Bulk user import.
  - name: Configuration
    description: Configuration-as-code validation, import and export.
  - name: Notifications
    description: Notification delivery settings, templates and jobs.
  - name: Development
    description: Development-mode only helpers.
  - name: Health
    description: Liveness and readiness probes.
paths:
  /realms/{realm}/.well-known/openid-configuration:
    get:
      operationId: getOpenIDConfiguration
      tags:
        - Discovery
      summary: OpenID Provider metadata
      description: Canonical issuer metadata for the realm. Cacheable for 300 seconds.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Cache-Control:
              schema:
                type: string
              description: public, max-age=300
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenIDConfiguration'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /.well-known/oauth-authorization-server/realms/{realm}:
    get:
      operationId: getOAuthServerMetadata
      tags:
        - Discovery
      summary: OAuth 2.0 authorization server metadata (RFC 8414)
      description: RFC 8414 location for the path-based issuer; same document as the OpenID configuration.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Cache-Control:
              schema:
                type: string
              description: public, max-age=300
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenIDConfiguration'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/jwks:
    get:
      operationId: getJWKS
      tags:
        - Discovery
      summary: Public verification keys
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Cache-Control:
              schema:
                type: string
              description: public, max-age=300
          content:
            application/jwk-set+json:
              schema:
                $ref: '#/components/schemas/JWKSet'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oauth/authorize:
    get:
      operationId: authorizeGet
      tags:
        - OAuth
      summary: Authorization request (query)
      description: >-
        Starts an authorization-code flow (PKCE S256 required). On success redirects (302) to the login UI or back to
        the client with code, state and iss. Errors that cannot be safely redirected are returned as OAuth JSON errors
        with status 400. May set pa_tx and pa_sid cookies.
      security: []
      x-trust-class: public-protocol-initiation
      x-optional-security:
        - sessionCookie
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: response_type
          in: query
          required: false
          schema:
            type: string
            const: code
          description: response_type
        - name: client_id
          in: query
          required: false
          schema:
            type: string
          description: client_id
        - name: redirect_uri
          in: query
          required: false
          schema:
            type: string
            format: uri
          description: redirect_uri
        - name: scope
          in: query
          required: false
          schema:
            type: string
            maxLength: 2048
          description: scope
        - name: state
          in: query
          required: false
          schema:
            type: string
            maxLength: 1024
          description: state
        - name: nonce
          in: query
          required: false
          schema:
            type: string
            maxLength: 512
          description: nonce
        - name: code_challenge
          in: query
          required: false
          schema:
            type: string
          description: code_challenge
        - name: code_challenge_method
          in: query
          required: false
          schema:
            type: string
            const: S256
          description: code_challenge_method
        - name: response_mode
          in: query
          required: false
          schema:
            type: string
            enum:
              - query
              - query.jwt
              - jwt
          description: >-
            query (default), or query.jwt / jwt (the same for the code flow) for a JWT-secured authorization response
            (JARM, ADV-002): the redirect carries one parameter, response, a JWT signed by the realm (iss,
            aud=client_id, exp, code or error, state) and encrypted to the client when it registered
            authorization_encrypted_response_alg. Errors returned to the redirect use the same mode.
        - name: prompt
          in: query
          required: false
          schema:
            type: string
          description: prompt
        - name: max_age
          in: query
          required: false
          schema:
            type: string
          description: max_age
        - name: acr_values
          in: query
          required: false
          schema:
            type: string
          description: acr_values
        - name: login_hint
          in: query
          required: false
          schema:
            type: string
            maxLength: 512
          description: login_hint
        - name: ui_locales
          in: query
          required: false
          schema:
            type: string
          description: ui_locales
        - name: organization
          in: query
          required: false
          schema:
            type: string
            description: Organization hint (ID or slug).
          description: Organization hint (ID or slug).
        - name: resource
          in: query
          required: false
          schema:
            oneOf:
              - type: string
              - type: array
                items:
                  type: string
                maxItems: 5
            description: RFC 8707 resource indicator; may repeat (at most 5).
          description: RFC 8707 resource indicator; may repeat (at most 5).
        - name: request_uri
          in: query
          required: false
          schema:
            type: string
            description: PAR request_uri (urn:ietf:params:oauth:request_uri:...).
          description: PAR request_uri (urn:ietf:params:oauth:request_uri:...).
        - name: request
          in: query
          required: false
          schema:
            type: string
            description: Request objects are not supported (request_parameter_supported=false).
          description: Request objects are not supported (request_parameter_supported=false).
        - name: claims
          in: query
          required: false
          schema:
            type: string
            description: The claims parameter is not supported.
          description: The claims parameter is not supported.
        - name: intent
          in: query
          required: false
          schema:
            type: string
            description: Interaction intent hint, e.g. login or register.
          description: Interaction intent hint, e.g. login or register.
      responses:
        '302':
          description: Found (redirect)
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/OAuthError'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: authorizePost
      tags:
        - OAuth
      summary: Authorization request (form post)
      description: >-
        Starts an authorization-code flow (PKCE S256 required). On success redirects (302) to the login UI or back to
        the client with code, state and iss. Errors that cannot be safely redirected are returned as OAuth JSON errors
        with status 400. May set pa_tx and pa_sid cookies.
      security: []
      x-trust-class: public-protocol-initiation
      x-optional-security:
        - sessionCookie
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                response_type:
                  type: string
                  const: code
                client_id:
                  type: string
                redirect_uri:
                  type: string
                  format: uri
                scope:
                  type: string
                  maxLength: 2048
                state:
                  type: string
                  maxLength: 1024
                nonce:
                  type: string
                  maxLength: 512
                code_challenge:
                  type: string
                code_challenge_method:
                  type: string
                  const: S256
                response_mode:
                  type: string
                  enum:
                    - query
                    - query.jwt
                    - jwt
                prompt:
                  type: string
                max_age:
                  type: string
                acr_values:
                  type: string
                login_hint:
                  type: string
                  maxLength: 512
                ui_locales:
                  type: string
                organization:
                  type: string
                  description: Organization hint (ID or slug).
                resource:
                  oneOf:
                    - type: string
                    - type: array
                      items:
                        type: string
                      maxItems: 5
                  description: RFC 8707 resource indicator; may repeat (at most 5).
                request_uri:
                  type: string
                  description: PAR request_uri (urn:ietf:params:oauth:request_uri:...).
                request:
                  type: string
                  description: Request objects are not supported (request_parameter_supported=false).
                claims:
                  type: string
                  description: The claims parameter is not supported.
                intent:
                  type: string
                  description: Interaction intent hint, e.g. login or register.
              additionalProperties: false
      responses:
        '302':
          description: Found (redirect)
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/OAuthError'
        '404':
          $ref: '#/components/responses/NotFound'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oauth/token:
    post:
      operationId: token
      tags:
        - OAuth
      summary: Token endpoint
      description: >-
        Issues tokens for the enabled grants. Parameters must be form-encoded in the body (query parameters are
        rejected) and must not repeat (except resource). Optional DPoP proof in the DPoP header. When issuance fails for
        a configuration reason (the client registered response encryption but has no key that can receive it: 400
        unauthorized_client; no active signing key: 503 temporarily_unavailable), the issuance is rolled back and the
        code, device code or refresh token is not consumed, so a retry is not treated as replay.
      security:
        - clientSecretBasic: []
        - {}
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: DPoP
          in: header
          required: false
          schema:
            type: string
          description: DPoP proof JWT (RFC 9449).
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                  description: Client identifier (client_secret_post, private_key_jwt or public clients).
                client_secret:
                  type: string
                  format: password
                  description: client_secret_post credential. Prefer client_secret_basic.
                client_assertion_type:
                  type: string
                  const: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
                client_assertion:
                  type: string
                  description: private_key_jwt assertion (audience is the endpoint URL).
                grant_type:
                  type: string
                  enum:
                    - authorization_code
                    - refresh_token
                    - client_credentials
                    - urn:ietf:params:oauth:grant-type:device_code
                    - urn:ietf:params:oauth:grant-type:token-exchange
                    - urn:ietf:params:oauth:grant-type:jwt-bearer
                  description: >-
                    Grants the token endpoint implements; others return unsupported_grant_type. jwt-bearer (RFC 7523) is
                    workload federation (MCH-011, ADV-004): assertion is a workload token from an issuer the client
                    trusts (see /clients/{client}/workload-trusts), and the token issued represents the client's service
                    principal and never outlives the assertion. It is distinct from client authentication with
                    client_assertion. The assertion's jti is spent only when the token is issued (in the issuing
                    transaction), so a request refused for its resource, organization or scope leaves the assertion
                    usable. A refused assertion returns invalid_grant without the reason (the reason is audited as
                    workload.assertion.rejected).
                code:
                  type: string
                  x-secret: true
                redirect_uri:
                  type: string
                code_verifier:
                  type: string
                refresh_token:
                  type: string
                  x-secret: true
                  description: Refresh tokens rotate on use; reuse revokes the family.
                scope:
                  type: string
                resource:
                  oneOf:
                    - type: string
                    - type: array
                      items:
                        type: string
                organization:
                  type: string
                device_code:
                  type: string
                  x-secret: true
                assertion:
                  type: string
                  x-secret: true
                  description: The workload assertion for the jwt-bearer grant.
                subject_token:
                  type: string
                  x-secret: true
                subject_token_type:
                  type: string
                actor_token:
                  type: string
                  x-secret: true
                requested_token_type:
                  type: string
                audience:
                  type: string
              required:
                - grant_type
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        '400':
          $ref: '#/components/responses/OAuthError'
        '401':
          $ref: '#/components/responses/OAuthError'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/OAuthError'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oauth/introspect:
    post:
      operationId: introspect
      tags:
        - OAuth
      summary: Token introspection (RFC 7662)
      description: >-
        Only confidential clients registered as introspectors for the token audience see active results. API keys
        (pa_key_) and personal tokens (pa_pat_) are introspected with the same rules.
      security:
        - clientSecretBasic: []
        - {}
      x-trust-class: resource-server
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                  description: Client identifier (client_secret_post, private_key_jwt or public clients).
                client_secret:
                  type: string
                  format: password
                  description: client_secret_post credential. Prefer client_secret_basic.
                client_assertion_type:
                  type: string
                  const: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
                client_assertion:
                  type: string
                  description: private_key_jwt assertion (audience is the endpoint URL).
                token:
                  type: string
                  x-secret: true
                token_type_hint:
                  type: string
              required:
                - token
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntrospectionResponse'
        '400':
          $ref: '#/components/responses/OAuthError'
        '401':
          $ref: '#/components/responses/OAuthError'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oauth/revoke:
    post:
      operationId: revoke
      tags:
        - OAuth
      summary: Token revocation (RFC 7009)
      description: Returns 200 with an empty body for valid and unknown tokens alike.
      security:
        - clientSecretBasic: []
        - {}
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                  description: Client identifier (client_secret_post, private_key_jwt or public clients).
                client_secret:
                  type: string
                  format: password
                  description: client_secret_post credential. Prefer client_secret_basic.
                client_assertion_type:
                  type: string
                  const: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
                client_assertion:
                  type: string
                  description: private_key_jwt assertion (audience is the endpoint URL).
                token:
                  type: string
                  x-secret: true
                token_type_hint:
                  type: string
                  enum:
                    - access_token
                    - refresh_token
              required:
                - token
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/OAuthError'
        '401':
          $ref: '#/components/responses/OAuthError'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oauth/device_authorization:
    post:
      operationId: deviceAuthorization
      tags:
        - OAuth
      summary: Device authorization request (RFC 8628)
      security:
        - clientSecretBasic: []
        - {}
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                  description: Client identifier (client_secret_post, private_key_jwt or public clients).
                client_secret:
                  type: string
                  format: password
                  description: client_secret_post credential. Prefer client_secret_basic.
                client_assertion_type:
                  type: string
                  const: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
                client_assertion:
                  type: string
                  description: private_key_jwt assertion (audience is the endpoint URL).
                scope:
                  type: string
                resource:
                  oneOf:
                    - type: string
                    - type: array
                      items:
                        type: string
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceAuthorizationResponse'
        '400':
          $ref: '#/components/responses/OAuthError'
        '401':
          $ref: '#/components/responses/OAuthError'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/OAuthError'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oauth/par:
    post:
      operationId: pushAuthorizationRequest
      tags:
        - OAuth
      summary: Pushed authorization request (RFC 9126)
      description: >-
        Requires an authenticated client. request_uri is not allowed in a pushed request; the returned request_uri is
        single-use and expires after 60 seconds.
      security:
        - clientSecretBasic: []
        - {}
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                client_secret:
                  type: string
                  format: password
                  description: client_secret_post credential. Prefer client_secret_basic.
                client_assertion_type:
                  type: string
                  const: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
                client_assertion:
                  type: string
                  description: private_key_jwt assertion (audience is the endpoint URL).
                response_type:
                  type: string
                  const: code
                redirect_uri:
                  type: string
                  format: uri
                scope:
                  type: string
                  maxLength: 2048
                state:
                  type: string
                  maxLength: 1024
                nonce:
                  type: string
                  maxLength: 512
                code_challenge:
                  type: string
                code_challenge_method:
                  type: string
                  const: S256
                response_mode:
                  type: string
                  enum:
                    - query
                    - query.jwt
                    - jwt
                prompt:
                  type: string
                max_age:
                  type: string
                acr_values:
                  type: string
                login_hint:
                  type: string
                  maxLength: 512
                ui_locales:
                  type: string
                organization:
                  type: string
                  description: Organization hint (ID or slug).
                resource:
                  oneOf:
                    - type: string
                    - type: array
                      items:
                        type: string
                      maxItems: 5
                  description: RFC 8707 resource indicator; may repeat (at most 5).
                request:
                  type: string
                  description: Request objects are not supported (request_parameter_supported=false).
                claims:
                  type: string
                  description: The claims parameter is not supported.
                intent:
                  type: string
                  description: Interaction intent hint, e.g. login or register.
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PushedAuthorizationResponse'
        '400':
          $ref: '#/components/responses/OAuthError'
        '401':
          $ref: '#/components/responses/OAuthError'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oidc/userinfo:
    get:
      operationId: userinfoGet
      tags:
        - OIDC
      summary: UserInfo (GET)
      description: >-
        Returns claims permitted by the access token. Missing or invalid tokens return 401 with an empty body and a
        WWW-Authenticate Bearer challenge.
      security:
        - userAccessToken: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserInfo'
            application/jwt:
              schema:
                type: string
              description: >-
                OIDC-013: for a client that registered userinfo_signed_response_alg, a JWT signed with the realm key
                whose claims add iss and aud (the client_id); for one that registered userinfo_encrypted_response_alg, a
                JWE encrypted to its newest suitable registered key (nested, cty JWT, when also signed).
        '400':
          description: >-
            The client registered response encryption but has no registered public key that can receive it (error
            invalid_request).
        '401':
          description: Missing or invalid access token (empty body).
          headers:
            WWW-Authenticate:
              $ref: '#/components/headers/WWW-Authenticate'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: userinfoPost
      tags:
        - OIDC
      summary: UserInfo (POST)
      description: >-
        Returns claims permitted by the access token. Missing or invalid tokens return 401 with an empty body and a
        WWW-Authenticate Bearer challenge.
      security:
        - userAccessToken: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserInfo'
            application/jwt:
              schema:
                type: string
              description: >-
                OIDC-013: for a client that registered userinfo_signed_response_alg, a JWT signed with the realm key
                whose claims add iss and aud (the client_id); for one that registered userinfo_encrypted_response_alg, a
                JWE encrypted to its newest suitable registered key (nested, cty JWT, when also signed).
        '400':
          description: >-
            The client registered response encryption but has no registered public key that can receive it (error
            invalid_request).
        '401':
          description: Missing or invalid access token (empty body).
          headers:
            WWW-Authenticate:
              $ref: '#/components/headers/WWW-Authenticate'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oidc/check-session:
    get:
      operationId: checkSessionIframe
      tags:
        - OIDC
      summary: OpenID Connect Session Management check_session_iframe
      description: >-
        OIDC-014, only when the realm policy sets sessions.check_session_iframe (404 otherwise). An HTML page for
        relying parties to embed: it answers postMessage("client_id session_state") with changed, unchanged or error,
        only to an origin registered for the client, recomputing session_state from the pa_opbs browser-state cookie and
        the message origin. Browsers that block or partition third-party cookies make every check report changed;
        server-side session ends (administrator revocation, timeouts) appear only after the browser next reaches the
        provider, so relying parties should also use back-channel logout or token introspection.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            text/html:
              schema:
                type: string
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/oidc/check-session/origin:
    get:
      operationId: checkSessionOrigin
      tags:
        - OIDC
      summary: Check-session iframe origin check
      description: >-
        OIDC-014, used by the check_session_iframe page: whether origin is one of the client's allowed origins or the
        origin of one of its redirect URIs. 404 when session management is off.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: client_id
          in: query
          required: true
          schema:
            type: string
          description: client_id
        - name: origin
          in: query
          required: true
          schema:
            type: string
          description: The origin of the message the iframe received.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - allowed
                properties:
                  allowed:
                    type: boolean
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/oidc/logout:
    get:
      operationId: logoutGet
      tags:
        - OIDC
      summary: RP-initiated logout (GET)
      description: >-
        A GET without id_token_hint never ends the browser session silently (the client must POST). Redirects (302) to a
        registered post_logout_redirect_uri when valid.
      security: []
      x-trust-class: public-protocol-initiation
      x-optional-security:
        - sessionCookie
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: id_token_hint
          in: query
          required: false
          schema:
            type: string
            x-secret: true
          description: id_token_hint
        - name: client_id
          in: query
          required: false
          schema:
            type: string
          description: client_id
        - name: post_logout_redirect_uri
          in: query
          required: false
          schema:
            type: string
            format: uri
          description: post_logout_redirect_uri
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: state
        - name: upstream_logout
          in: query
          required: false
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
          description: >-
            Extension (FED-013): also send the browser to the federated provider's logout endpoint when the ended
            session came from one.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_ended:
                    type: boolean
                  frontchannel_logout_uris:
                    type: array
                    items:
                      type: string
                    description: >-
                      Front-channel logout (SES-018), only to callers sending Accept: application/json: the
                      front-channel logout URIs of the clients that took part in the ended session, for the caller to
                      load in iframes before continuing to redirect_to. Delivery is not confirmed.
                  redirect_to:
                    type: string
                    description: With frontchannel_logout_uris, the post-logout destination the caller continues to afterwards.
                  upstream_logout:
                    type: object
                    description: >-
                      What happened to a federated provider's session (FED-013): not_federated, not_requested (only the
                      local session ended; the provider's session may remain active), unsupported (the provider has no
                      logout endpoint) or unavailable. A redirect to the provider is a 302 instead. With
                      post_logout_redirect_uri and upstream_logout=true, the status is also appended to the redirect as
                      upstream_logout.
                    properties:
                      provider:
                        type: string
                      status:
                        type: string
                        enum:
                          - not_federated
                          - not_requested
                          - redirect
                          - unsupported
                          - unavailable
                required:
                  - session_ended
            text/html:
              schema:
                type: string
              description: >-
                When clients that took part in the ended session registered front-channel logout URIs (SES-018), a
                browser receives a page that loads them in iframes (its Content-Security-Policy frames only those
                origins and runs no script) and continues to the post-logout redirect after two seconds.
        '302':
          description: >-
            Redirect to the registered post-logout URI, or with upstream_logout=true to the federated provider's logout
            endpoint, which returns to /oidc/logout/upstream-return.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: logoutPost
      tags:
        - OIDC
      summary: RP-initiated logout (POST)
      security: []
      x-trust-class: public-protocol-initiation
      x-optional-security:
        - sessionCookie
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: false
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id_token_hint:
                  type: string
                  x-secret: true
                upstream_logout:
                  type: string
                  enum:
                    - 'true'
                    - 'false'
                  description: 'Extension (FED-013): also send the browser to the federated provider''s logout endpoint.'
                client_id:
                  type: string
                post_logout_redirect_uri:
                  type: string
                  format: uri
                state:
                  type: string
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_ended:
                    type: boolean
                  frontchannel_logout_uris:
                    type: array
                    items:
                      type: string
                    description: >-
                      Front-channel logout (SES-018), only to callers sending Accept: application/json: the
                      front-channel logout URIs of the clients that took part in the ended session, for the caller to
                      load in iframes before continuing to redirect_to. Delivery is not confirmed.
                  redirect_to:
                    type: string
                    description: With frontchannel_logout_uris, the post-logout destination the caller continues to afterwards.
                  upstream_logout:
                    type: object
                    description: >-
                      What happened to a federated provider's session (FED-013): not_federated, not_requested (only the
                      local session ended; the provider's session may remain active), unsupported (the provider has no
                      logout endpoint) or unavailable. A redirect to the provider is a 302 instead. With
                      post_logout_redirect_uri and upstream_logout=true, the status is also appended to the redirect as
                      upstream_logout.
                    properties:
                      provider:
                        type: string
                      status:
                        type: string
                        enum:
                          - not_federated
                          - not_requested
                          - redirect
                          - unsupported
                          - unavailable
                required:
                  - session_ended
            text/html:
              schema:
                type: string
              description: >-
                When clients that took part in the ended session registered front-channel logout URIs (SES-018), a
                browser receives a page that loads them in iframes (its Content-Security-Policy frames only those
                origins and runs no script) and continues to the post-logout redirect after two seconds.
        '302':
          description: >-
            Redirect to the registered post-logout URI, or with upstream_logout=true to the federated provider's logout
            endpoint, which returns to /oidc/logout/upstream-return.
          headers:
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oidc/logout/upstream-return:
    get:
      operationId: logoutUpstreamReturn
      tags:
        - OIDC
      summary: Return from a federated provider's logout
      description: >-
        Where a federated provider sends the browser after its own logout (FED-013); register this URI as a post-logout
        redirect at the provider. The sealed state (valid 15 minutes) names the client's post-logout destination,
        reached with upstream_logout=returned appended: the provider's return does not prove its session ended. Without
        a destination the response is JSON. The state is single-use: a state that is malformed, expired or already used
        is refused with 400 ("invalid state", "expired state", "state already used").
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: state
          in: query
          required: true
          schema:
            type: string
          description: Sealed state issued with the upstream logout redirect.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_ended:
                    type: boolean
                  upstream_logout:
                    type: object
                    properties:
                      status:
                        type: string
                        enum:
                          - returned
        '302':
          description: Redirect to the client's registered post-logout URI.
          headers:
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/:
    options:
      operationId: corsPreflightProtocol
      tags:
        - CORS
      summary: CORS preflight
      description: >-
        Matches every path below this prefix (Go ServeMux subtree pattern). Only origins registered on active clients
        are reflected; credentials are allowed only for /auth/ paths. Always returns 204.
      security: []
      x-trust-class: public-metadata
      x-path-match: prefix
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Access-Control-Allow-Origin:
              schema:
                type: string
            Access-Control-Allow-Methods:
              schema:
                type: string
            Access-Control-Allow-Headers:
              schema:
                type: string
            Access-Control-Max-Age:
              schema:
                type: string
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/:
    options:
      operationId: corsPreflightApi
      tags:
        - CORS
      summary: CORS preflight
      description: >-
        Matches every path below this prefix (Go ServeMux subtree pattern). Only origins registered on active clients
        are reflected; credentials are allowed only for /auth/ paths. Always returns 204.
      security: []
      x-trust-class: public-metadata
      x-path-match: prefix
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Access-Control-Allow-Origin:
              schema:
                type: string
            Access-Control-Allow-Methods:
              schema:
                type: string
            Access-Control-Allow-Headers:
              schema:
                type: string
            Access-Control-Max-Age:
              schema:
                type: string
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions:
    post:
      operationId: startTransaction
      tags:
        - Interaction
      summary: Start a headless authentication transaction
      description: >-
        Validates the client and request like the authorization endpoint and returns continuation authority plus the
        first next actions (AUT-001).
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              description: Authorization request parameters for a headless (API-driven) login surface, or a device user code.
              properties:
                client_id:
                  type: string
                redirect_uri:
                  type: string
                scope:
                  type: string
                state:
                  type: string
                nonce:
                  type: string
                code_challenge:
                  type: string
                code_challenge_method:
                  type: string
                  const: S256
                prompt:
                  type: string
                max_age:
                  type: string
                acr_values:
                  type: string
                login_hint:
                  type: string
                ui_locales:
                  type: string
                organization:
                  type: string
                resource:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                intent:
                  type: string
                  description: e.g. login or register.
                request_uri:
                  type: string
                  description: PAR request_uri.
                device_user_code:
                  type: string
                  description: Starts a device-flow approval transaction instead of an authorization request.
                response_mode:
                  type: string
                  enum:
                    - query
                    - query.jwt
                    - jwt
                  description: >-
                    query (default), or a JWT-secured authorization response (JARM, ADV-002): redirect_to then carries
                    response=<JWT> instead of code, state and iss.
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionStarted'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}:
    get:
      operationId: getTransaction
      tags:
        - Interaction
      summary: Get transaction state
      description: Browser callers (cookie) also receive csrf_token.
      security:
        - transactionToken: []
        - transactionCookie: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '410':
          $ref: '#/components/responses/Gone'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/identify:
    post:
      operationId: identifyStep
      tags:
        - Interaction
      summary: Submit identifier
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). Enumeration-safe.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                identifier:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/password:
    post:
      operationId: passwordStep
      tags:
        - Interaction
      summary: Submit password
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). Rate-limited.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                identifier:
                  type: string
                password:
                  type: string
                  format: password
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/otp/send:
    post:
      operationId: sendOTPStep
      tags:
        - Interaction
      summary: Send a one-time code
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). Purpose/identifier-bound send budget.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                purpose:
                  type: string
                  enum:
                    - verify_email
                    - verify_contact
                    - login
                    - magic_link
                  description: >-
                    login sends an email code or, for a phone identifier with SMS sign-in enabled, an SMS code;
                    magic_link emails a single-use link to the configured login UI.
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/otp/verify:
    post:
      operationId: verifyOTPStep
      tags:
        - Interaction
      summary: Verify a one-time code
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). Attempt-limited atomic consumption.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/totp:
    post:
      operationId: totpStep
      tags:
        - Interaction
      summary: Verify a TOTP code
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/hotp:
    post:
      operationId: hotpStep
      tags:
        - Interaction
      summary: Verify an HOTP code
      description: >-
        Counter-based code (MFA-013), offered only in realms that list hotp in mfa.allowed_factors. A code within
        mfa.hotp.look_ahead counters of the stored counter is accepted once; the counter moves past it atomically.
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/challenge:
    post:
      operationId: answerFlowChallenge
      tags:
        - Interaction
      summary: Answer an authentication flow challenge
      description: >-
        Transaction-bound step for a challenge next action (AUT-012, SEC-014): the realm authentication_flow asked for a
        challenge. Give exactly one of provider_response (the token the configured challenge provider issued to the
        login interface; verified with the provider, 503 when the provider is unavailable) or code (sent with POST
        .../challenge/send to the account verified email, the accessible alternative). A wrong answer is 400
        invalid_proof and counts toward the transaction failure limit. An enrolled second factor (TOTP or passkey) also
        satisfies the challenge.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                provider_response:
                  type: string
                  maxLength: 4096
                code:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/challenge/send:
    post:
      operationId: sendFlowChallengeCode
      tags:
        - Interaction
      summary: Email a challenge code
      description: >-
        Transaction-bound step: sends a one-time code for a pending authentication flow challenge to the account
        verified primary email (SEC-014 accessible alternative), when the realm
        authentication_flow.email_code_alternative is not false. Subject to the send budgets; 409 when no challenge is
        pending or no verified email exists.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/totp/enroll:
    post:
      operationId: enrollTOTPStep
      tags:
        - Interaction
      summary: Begin TOTP enrollment (required action)
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). The request body is ignored. The TOTP seed is returned once in one_time.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/totp/activate:
    post:
      operationId: activateTOTPStep
      tags:
        - Interaction
      summary: Activate TOTP enrollment
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). New recovery codes are returned once in one_time.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/recovery-code:
    post:
      operationId: recoveryCodeStep
      tags:
        - Interaction
      summary: Use a recovery code
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). Produces a recovery-restricted session.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/magic-link:
    post:
      operationId: magicLinkStep
      tags:
        - Interaction
      summary: Complete sign-in with a magic link
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). The link secret (delivered only in the URL fragment of the emailed link) must be
        posted back to the same transaction that requested it with otp/send purpose magic_link; a link from another
        transaction is refused and burned (PWDLESS-002, PWDLESS-003).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                token:
                  type: string
                  description: The pa_lnk_ secret from the link fragment.
                  x-secret: true
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/webauthn/options:
    post:
      operationId: webauthnOptionsStep
      tags:
        - Interaction
      summary: Begin passkey authentication
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). Returns WebAuthn request options in the webauthn member. The body must be an
        empty JSON object (or empty).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties: {}
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/webauthn/verify:
    post:
      operationId: webauthnVerifyStep
      tags:
        - Interaction
      summary: Complete passkey authentication
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). credential is the PublicKeyCredential JSON from the browser or platform API
        (required).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                credential:
                  type: object
                  additionalProperties: true
              required:
                - credential
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/webauthn/registration-options:
    post:
      operationId: webauthnRegistrationOptionsStep
      tags:
        - Interaction
      summary: Begin passkey registration
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). The body must be an empty JSON object (or empty).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties: {}
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/webauthn/register:
    post:
      operationId: webauthnRegisterStep
      tags:
        - Interaction
      summary: Complete passkey registration
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). credential is the attestation PublicKeyCredential JSON (required).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                credential:
                  type: object
                  additionalProperties: true
                name:
                  type: string
              required:
                - credential
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/password/update:
    post:
      operationId: updatePasswordStep
      tags:
        - Interaction
      summary: Set a new password (required action)
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                new_password:
                  type: string
                  format: password
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/terms:
    post:
      operationId: acceptTermsStep
      tags:
        - Interaction
      summary: Accept terms
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                version:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/cancel-deletion:
    post:
      operationId: cancelDeletionStep
      tags:
        - Interaction
      summary: Cancel a scheduled account deletion while signing in
      description: >-
        Transaction-bound step for the cancel_deletion action (USR-012). An account with a pending self-service deletion
        completes authentication as usual (every factor it needs, MFA included); the transaction then offers only
        cancel_deletion, whose options carry deletion_scheduled_at and deletion_requested_at, and issues no session,
        code or token. This step cancels the deletion (the account is active again, audited user.deletion.cancelled with
        via sign_in) and the transaction continues to its normal completion: the state may carry further actions or
        redirect_to (and browser callers receive the pa_sid cookie while pa_tx is cleared). 409 unexpected_step when the
        transaction is not at cancel_deletion (factors still missing, or no deletion pending); 409 conflict when the
        deletion was cancelled or completed meanwhile. The body is an empty JSON object.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/profile:
    post:
      operationId: completeProfileStep
      tags:
        - Interaction
      summary: Complete required profile fields
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                fields:
                  type:
                    - object
                    - 'null'
                  additionalProperties: true
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/organization:
    post:
      operationId: selectOrganizationStep
      tags:
        - Interaction
      summary: Select organization
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                organization_id:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/consent:
    post:
      operationId: consentStep
      tags:
        - Interaction
      summary: Approve or deny consent
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                approve:
                  type: boolean
                scopes:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/remember-me:
    post:
      operationId: rememberMeStep
      tags:
        - Interaction
      summary: Set remember-me preference
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                remember:
                  type: boolean
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/cancel:
    post:
      operationId: cancelTransaction
      tags:
        - Interaction
      summary: Cancel the transaction
      description: >-
        Transaction-bound step. On completion the state carries redirect_to (and browser callers receive the pa_sid
        cookie while pa_tx is cleared). The request body is ignored. Returns the cancelled state with redirect_to when
        an error redirect is possible.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/federation/start:
    post:
      operationId: startFederationStep
      tags:
        - Interaction
      summary: Start federated sign-in with an upstream provider
      description: >-
        Transaction-bound step. The returned state carries external_redirect, the upstream authorization URL the browser
        must visit.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                provider:
                  type: string
                  description: Identity provider alias or ID.
              required:
                - provider
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/auth/transactions/{id}/resume:
    post:
      operationId: resumeTransaction
      tags:
        - Interaction
      summary: Resume a transaction after an out-of-band step
      description: >-
        Re-evaluates the transaction after an upstream callback or SSO reuse and completes it when nothing remains. The
        body must be empty or an empty JSON object.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties: {}
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/federation/{connection}/callback:
    get:
      operationId: federationCallbackGet
      tags:
        - Federation
      summary: Upstream callback (query response mode)
      description: >-
        Upstream authorization response endpoint registered with the identity provider. When the realm has a login UI
        the browser is redirected (303) to it with transaction_id (and federation_error); a pending link confirmation
        code travels in the URL fragment (federation_link_code). Headless realms without a login UI receive the outcome
        as JSON. Returns 404 feature_disabled when federation is not configured.
      security: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_connection'
        - $ref: '#/components/parameters/RequestId'
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: state
        - name: code
          in: query
          required: false
          schema:
            type: string
            x-secret: true
          description: code
        - name: error
          in: query
          required: false
          schema:
            type: string
          description: error
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    title: CallbackOutcome
                    properties:
                      transaction_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - ok
                          - error
                      error:
                        type: string
                    required:
                      - status
                  - type: object
                    title: LinkPendingConfirmation
                    properties:
                      status:
                        type: string
                        const: link_pending_confirmation
                      link_code:
                        type: string
                        x-secret: true
                        description: Single-use code for POST /me/linked-identities/confirm.
                    required:
                      - status
                      - link_code
        '303':
          description: Redirect to the realm login UI.
          headers:
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: federationCallbackPost
      tags:
        - Federation
      summary: Upstream callback (form_post response mode)
      description: >-
        Upstream authorization response endpoint registered with the identity provider. When the realm has a login UI
        the browser is redirected (303) to it with transaction_id (and federation_error); a pending link confirmation
        code travels in the URL fragment (federation_link_code). Headless realms without a login UI receive the outcome
        as JSON. Returns 404 feature_disabled when federation is not configured.
      security: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_connection'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              description: At most 64 KiB.
              properties:
                state:
                  type: string
                code:
                  type: string
                  x-secret: true
                error:
                  type: string
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    title: CallbackOutcome
                    properties:
                      transaction_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - ok
                          - error
                      error:
                        type: string
                    required:
                      - status
                  - type: object
                    title: LinkPendingConfirmation
                    properties:
                      status:
                        type: string
                        const: link_pending_confirmation
                      link_code:
                        type: string
                        x-secret: true
                        description: Single-use code for POST /me/linked-identities/confirm.
                    required:
                      - status
                      - link_code
        '303':
          description: Redirect to the realm login UI.
          headers:
            Location:
              $ref: '#/components/headers/Location'
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/registrations:
    post:
      operationId: register
      tags:
        - Interaction
      summary: Register a new account
      description: >-
        Account creation within a transaction (REG-001). The response is identical whether or not the address already
        belongs to an account. Requires transaction continuation authority.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              additionalProperties: false
              properties:
                display_name:
                  type: string
                email:
                  type: string
                family_name:
                  type: string
                given_name:
                  type: string
                invitation:
                  type: string
                  x-secret: true
                  description: Invitation secret to accept during registration.
                locale:
                  type: string
                organization:
                  oneOf:
                    - $ref: '#/components/schemas/OrganizationInput'
                    - type: 'null'
                password:
                  type: string
                  format: password
                profile:
                  additionalProperties: {}
                  type:
                    - object
                    - 'null'
                terms_version:
                  type: string
                username:
                  type: string
                transaction_id:
                  type: string
                  description: Transaction to continue.
              type: object
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/password-resets:
    post:
      operationId: requestPasswordReset
      tags:
        - Interaction
      summary: Request a password reset
      description: Always returns the same generic response (no account enumeration).
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                identifier:
                  type: string
                locale:
                  type: string
              additionalProperties: false
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasswordResetRequested'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/password-resets/complete:
    post:
      operationId: completePasswordReset
      tags:
        - Interaction
      summary: Complete a password reset
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reset_id:
                  type: string
                code:
                  type: string
                  x-secret: true
                new_password:
                  type: string
                  format: password
              required:
                - reset_id
                - code
                - new_password
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: password_reset
                  mfa_unchanged:
                    type: boolean
                    const: true
                required:
                  - status
                  - mfa_unchanged
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/account-setup:
    post:
      operationId: completeAccountSetup
      tags:
        - Interaction
      summary: Complete administrator-initiated account setup
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                setup_token:
                  type: string
                  x-secret: true
                password:
                  type: string
                  format: password
              required:
                - setup_token
                - password
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: account_ready
                required:
                  - status
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me:
    get:
      operationId: getMe
      tags:
        - Self-service
      summary: Get own profile
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SelfUser'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateMe
      tags:
        - Self-service
      summary: Update own profile
      description: Field-level policy and the realm attribute schema apply.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchOptional'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProfilePatch'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SelfUser'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/identifiers:
    get:
      operationId: listMyIdentifiers
      tags:
        - Self-service
      summary: List own identifiers
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/UserIdentifier'
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: addMyIdentifier
      tags:
        - Self-service
      summary: Add an identifier
      description: Requires recent authentication. The identifier is unverified until proven with a verification challenge.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - email
                    - phone
                    - username
                value:
                  type: string
              required:
                - type
                - value
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  type:
                    type: string
                  value:
                    type: string
                  verified:
                    type: boolean
                    const: false
                  next:
                    type: string
                required:
                  - id
                  - type
                  - value
                  - verified
                  - next
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/identifiers/{id}:
    delete:
      operationId: removeMyIdentifier
      tags:
        - Self-service
      summary: Remove an identifier
      description: Requires recent authentication.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/identifiers/{id}/primary:
    post:
      operationId: makeIdentifierPrimary
      tags:
        - Self-service
      summary: Make an identifier primary
      description: Requires recent authentication.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/verification-challenges:
    post:
      operationId: createVerificationChallenge
      tags:
        - Self-service
      summary: Request identifier verification
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                identifier_id:
                  type: string
              required:
                - identifier_id
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  challenge_id:
                    type: string
                required:
                  - challenge_id
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/verification-challenges/{id}/consume:
    post:
      operationId: consumeVerificationChallenge
      tags:
        - Self-service
      summary: Complete identifier verification
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              required:
                - code
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  verified:
                    type: boolean
                    const: true
                required:
                  - verified
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/password:
    post:
      operationId: changeMyPassword
      tags:
        - Self-service
      summary: Change own password
      description: Requires recent authentication.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                current_password:
                  type: string
                  format: password
                new_password:
                  type: string
                  format: password
              required:
                - current_password
                - new_password
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: password_changed
                required:
                  - status
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/credentials:
    get:
      operationId: listMyCredentials
      tags:
        - Self-service
      summary: List own authenticators (safe metadata)
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SelfCredential'
                  recovery_codes_remaining:
                    type: integer
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/credentials/{id}:
    delete:
      operationId: removeMyCredential
      tags:
        - Self-service
      summary: Remove an authenticator
      description: >-
        Requires recent authentication. The password cannot be removed, and the last factor cannot be removed when MFA
        is mandatory (last_sign_in_method).
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/webauthn:
    get:
      operationId: listMyPasskeys
      tags:
        - Self-service
      summary: List own passkeys
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Passkey'
                  rp_id:
                    type: string
                    description: Effective WebAuthn relying party ID for the realm.
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/webauthn/registration-options:
    post:
      operationId: beginMyPasskeyRegistration
      tags:
        - Self-service
      summary: Begin passkey enrollment
      description: >-
        Requires recent authentication. The body must be empty or an empty JSON object. Returns 404 feature_disabled
        unless passkeys are enabled for sign-in or allowed as an MFA factor.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties: {}
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyRegistrationOptions'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/webauthn/registration-complete:
    post:
      operationId: completeMyPasskeyRegistration
      tags:
        - Self-service
      summary: Finish passkey enrollment
      description: Requires recent authentication. A successful enrollment steps up the current session and notifies the user.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ceremony_id:
                  type: string
                credential:
                  type: object
                  description: Attestation PublicKeyCredential JSON from navigator.credentials.create() or the platform API.
                name:
                  type: string
              required:
                - ceremony_id
                - credential
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Passkey'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/webauthn/{id}:
    patch:
      operationId: renameMyPasskey
      tags:
        - Self-service
      summary: Rename a passkey
      description: Passkeys are removed with DELETE /me/credentials/{id}.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
              required:
                - name
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/linked-identities:
    get:
      operationId: listMyLinkedIdentities
      tags:
        - Federation
      summary: List own linked external identities
      description: Returns an empty list when federation is not configured.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/LinkedIdentity'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: beginMyIdentityLink
      tags:
        - Federation
      summary: Start linking an external identity
      description: >-
        Requires recent authentication. The upstream callback returns a link confirmation code to finish with POST
        /me/linked-identities/confirm.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                provider:
                  type: string
                  description: Identity provider alias or ID.
              required:
                - provider
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  authorization_url:
                    type: string
                    format: uri
                    description: Upstream authorization URL to visit to prove control.
                  expires_in:
                    type: integer
                required:
                  - authorization_url
                  - expires_in
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/linked-identities/confirm:
    post:
      operationId: confirmMyIdentityLink
      tags:
        - Federation
      summary: Confirm a pending identity link
      description: Requires recent authentication.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                  x-secret: true
              required:
                - code
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinkedIdentity'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/linked-identities/{id}:
    delete:
      operationId: unlinkMyIdentity
      tags:
        - Federation
      summary: Unlink an external identity
      description: Requires recent authentication. The last viable sign-in method cannot be removed.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/totp/enroll:
    post:
      operationId: beginMyTOTPEnrollment
      tags:
        - Self-service
      summary: Begin TOTP enrollment
      description: Requires recent authentication. Any request body is ignored.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TOTPEnrollment'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/totp/activate:
    post:
      operationId: activateMyTOTP
      tags:
        - Self-service
      summary: Activate TOTP
      description: >-
        Requires recent authentication. Restores normal privileges for a recovery-restricted session. recovery_codes are
        returned once.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              required:
                - code
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: totp_enrolled
                  recovery_codes:
                    type:
                      - array
                      - 'null'
                    items:
                      type: string
                    x-secret: true
                required:
                  - status
                  - recovery_codes
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/totp:
    delete:
      operationId: removeMyTOTP
      tags:
        - Self-service
      summary: Remove TOTP
      description: Requires recent authentication.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/hotp/enroll:
    post:
      operationId: beginMyHOTPEnrollment
      tags:
        - Self-service
      summary: Begin HOTP enrollment
      description: >-
        Optional counter-based tokens (MFA-013): 409 unless the realm lists hotp in mfa.allowed_factors. Requires recent
        authentication and, when the account already has a second factor the realm allows, a session that proved one
        (MFA-006). A recovery-restricted session may enroll (MFA-010). Any request body is ignored. The secret and
        otpauth://hotp URI (counter 0) are returned once.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HOTPEnrollment'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/hotp/activate:
    post:
      operationId: activateMyHOTP
      tags:
        - Self-service
      summary: Activate HOTP
      description: >-
        Verifies a code within mfa.hotp.look_ahead counters of 0 and activates the token (replacing an active one); the
        counter moves past the code. Requires recent authentication. Restores normal privileges for a
        recovery-restricted session. recovery_codes are returned once, only when the account had none.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
              required:
                - code
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: hotp_enrolled
                  recovery_codes:
                    type:
                      - array
                      - 'null'
                    items:
                      type: string
                    x-secret: true
                required:
                  - status
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/hotp/resync:
    post:
      operationId: resyncMyHOTP
      tags:
        - Self-service
      summary: Resynchronize an HOTP token
      description: >-
        Realigns the stored counter with a token pressed beyond the sign-in look-ahead (MFA-013): code and next_code
        must be two consecutive codes within mfa.hotp.resync_window counters of the stored one; the counter only moves
        forward. A single code that far ahead is never accepted. Requires recent authentication and a session that
        completed MFA (403 mfa_required otherwise); at most 5 attempts per 15 minutes (fails closed). Audited as
        mfa.hotp.resynchronized or mfa.hotp.resync_failed.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                code:
                  type: string
                next_code:
                  type: string
              required:
                - code
                - next_code
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: hotp_resynchronized
                required:
                  - status
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/hotp:
    delete:
      operationId: removeMyHOTP
      tags:
        - Self-service
      summary: Remove HOTP
      description: >-
        Requires recent authentication. Refused (409 last_sign_in_method) when it is the last second factor of an
        account that must use MFA (only factors the realm allows count as remaining; a token the realm no longer allows
        can always be removed); remembered devices are forgotten.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/recovery-codes/regenerate:
    post:
      operationId: regenerateMyRecoveryCodes
      tags:
        - Self-service
      summary: Replace recovery codes
      description: Requires authentication within the last 5 minutes from an MFA session. Any request body is ignored.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  recovery_codes:
                    type:
                      - array
                      - 'null'
                    items:
                      type: string
                    x-secret: true
                    description: New recovery codes; returned once. Previous codes are invalidated.
                required:
                  - recovery_codes
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/sessions:
    get:
      operationId: listMySessions
      tags:
        - Self-service
      summary: List own sessions
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SelfSession'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/sessions/{id}:
    delete:
      operationId: revokeMySession
      tags:
        - Self-service
      summary: Revoke one own session
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/sessions/revoke-all:
    post:
      operationId: revokeAllMySessions
      tags:
        - Self-service
      summary: Revoke all own sessions
      description: Any request body is ignored.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RevokedSessions'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/organizations:
    get:
      operationId: listMyOrganizations
      tags:
        - Self-service
      summary: List own memberships
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MembershipSummary'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/organization-grants:
    post:
      operationId: switchOrganization
      tags:
        - Self-service
      summary: Switch organization context
      description: >-
        Issues a new authorization code for the calling client bound to the current session after checking active
        membership and organization MFA/SSO requirements (TEN-005). offline_access is never included. A client that must
        use pushed authorization requests (security_profile fapi2 or high_assurance, or token_policy.require_par) is
        refused with 403: the code would be issued outside PAR (and, for fapi2, the profile's 60-second code lifetime),
        so it switches with a new pushed authorization request naming the organization (ADV-001).
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                organization_id:
                  type: string
                redirect_uri:
                  type: string
                code_challenge:
                  type: string
                  minLength: 43
                  maxLength: 43
                code_challenge_method:
                  type: string
                  const: S256
                scope:
                  type: string
                resource:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                nonce:
                  type: string
                state:
                  type: string
              required:
                - client_id
                - organization_id
                - redirect_uri
                - code_challenge
                - code_challenge_method
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  redirect_to:
                    type: string
                    format: uri
                    description: Redirect URI carrying a new authorization code bound to the current session.
                required:
                  - redirect_to
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/permissions:
    get:
      operationId: getMyPermissions
      tags:
        - Self-service
      summary: Inspect own effective permissions
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Evaluate in this organization (requires active membership).
        - name: project_id
          in: query
          required: false
          schema:
            type: string
          description: >-
            Evaluate for a resource of this project: the caller's project-scoped role assignments for it count too
            (AZ-002). The project must exist and, with organization_id, belong to that organization (owned, or shared
            through an active project grant); otherwise 422.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EffectivePermissions'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/consents:
    get:
      operationId: listMyConsents
      tags:
        - Self-service
      summary: List own consents
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Consent'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/consents/{id}:
    delete:
      operationId: revokeMyConsent
      tags:
        - Self-service
      summary: Revoke a consent
      description: Also revokes the client's active grants for the user.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/security-events:
    get:
      operationId: listMySecurityEvents
      tags:
        - Self-service
      summary: View own security history
      description: Most recent 100 security, support, account and token events.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SecurityEvent'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/deletion-request:
    post:
      operationId: requestMyDeletion
      tags:
        - Self-service
      summary: Request account deletion
      description: >-
        Requires recent authentication. Last owners must transfer ownership first (last_owner). Any request body is
        ignored. The account becomes pending_deletion, every session and grant (offline ones included) is revoked, and
        the deletion_scheduled notice is queued to the verified primary email in the same transaction. Until
        privacy.deletion_grace_period ends the owner can cancel by signing in: after the usual factors the
        authentication transaction offers only the cancel_deletion action (POST
        /auth/transactions/{id}/cancel-deletion), and no session or token is issued unless the deletion is cancelled
        (USR-012).
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                  deletion_scheduled_at:
                    type:
                      - string
                      - 'null'
                    format: date-time
                required:
                  - state
                  - deletion_scheduled_at
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: cancelMyDeletion
      tags:
        - Self-service
      summary: Cancel account deletion
      description: >-
        Kept for compatibility. A pending-deletion account holds no session (the request revoked them all and none is
        issued while it is pending), so owners cancel while signing in with the cancel_deletion transaction step (POST
        /auth/transactions/{id}/cancel-deletion, USR-012). 409 when no deletion is pending.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/personal-tokens:
    get:
      operationId: listMyPersonalTokens
      tags:
        - Self-service
      summary: List personal access tokens
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MachineCredential'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createMyPersonalToken
      tags:
        - Self-service
      summary: Create a personal access token
      description: Requires recent authentication. Bounded by the caller's own grant ceiling; expiry is mandatory.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MachineCredentialInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                    x-secret: true
                    description: >-
                      Personal access token (pa_pat_ prefix). Returned exactly once; it is never stored in plaintext,
                      never shown again and never replayed from the idempotency store.
                  credential:
                    $ref: '#/components/schemas/MachineCredential'
                  notice:
                    type: string
                required:
                  - token
                  - credential
                  - notice
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/personal-tokens/{id}:
    delete:
      operationId: revokeMyPersonalToken
      tags:
        - Self-service
      summary: Revoke a personal access token
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/impersonation-grants:
    get:
      operationId: listMySupportGrants
      tags:
        - Self-service
      summary: View support access to own account
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/CustomerSupportGrant'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/impersonation-grants/{id}/revoke:
    post:
      operationId: revokeMySupportGrant
      tags:
        - Self-service
      summary: End support access
      description: Any request body is ignored.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/support-access:
    put:
      operationId: setMySupportAccess
      tags:
        - Self-service
      summary: Opt out of (or back into) support access
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                opt_out:
                  type: boolean
              required:
                - opt_out
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  opt_out:
                    type: boolean
                required:
                  - opt_out
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/exports:
    post:
      operationId: requestMyDataExport
      tags:
        - Self-service
      summary: Request a personal data export
      description: >-
        Requires recent authentication. Creates a user.export job; download the protected result through the job
        download endpoints.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobAccepted'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations:
    get:
      operationId: listOrganizations
      tags:
        - Organizations
      summary: List organizations
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - realm.organizations.read (otherwise own memberships)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: q
          in: query
          required: false
          schema:
            type: string
          description: Search text (realm-wide listing only).
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: 'Callers holding realm.organizations.read: paginated realm-wide list.'
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Organization'
                      next_cursor:
                        type: string
                        description: >-
                          Opaque cursor for the next page; an empty string when there are no more results. Cursors are
                          bound to the realm and listing and cannot be replayed elsewhere.
                    required:
                      - items
                      - next_cursor
                  - type: object
                    description: 'Other users: the caller''s own memberships (not paginated).'
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/MembershipSummary'
                    required:
                      - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createOrganization
      tags:
        - Organizations
      summary: Create an organization
      description: >-
        Allowed for holders of realm.organizations.create, or for users when the realm policy allows self-service
        organization creation (the creator becomes owner).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - realm.organizations.create
        - realm policy registration.allow_organization_creation (users)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
        - name: join
          in: query
          required: false
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
          description: With true, a realm administrator creating the organization also becomes its owner.
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}:
    get:
      operationId: getOrganization
      tags:
        - Organizations
      summary: Get an organization
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateOrganization
      tags:
        - Organizations
      summary: Update an organization
      description: >-
        If-Match is required when the body changes policy (428 precondition_required without it, 412 when stale;
        API-010); it is optional for other fields.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.update
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchOptional'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrganizationInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organization'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteOrganization
      tags:
        - Organizations
      summary: Delete an organization (asynchronous)
      description: >-
        Revokes access immediately and starts an organization.delete job that cannot be cancelled. Users need recent
        authentication.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.delete
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    const: deleting
                  job_id:
                    type: string
                required:
                  - state
                  - job_id
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/deletion-preview:
    get:
      operationId: previewOrganizationDeletion
      tags:
        - Organizations
      summary: Preview organization deletion impact
      description: >-
        Counts what deleting the organization (TEN-024) would revoke, disable, erase or keep, without changing anything.
        active_legal_holds counts the holds that keep its evidence: realm-wide holds, holds on the organization and
        holds on any account that is (or was) a member.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.delete
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationDeletionPreview'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/archive:
    post:
      operationId: archiveOrganization
      tags:
        - Organizations
      summary: Archive an organization
      description: >-
        Archiving (TEN-001) revokes the organization's sessions and grants like suspension and keeps its records and
        audit history. Requires realm.organizations.suspend and (for users) an MFA session. Note: the body is decoded
        leniently (decode errors are ignored).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - realm.organizations.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    const: archived
                required:
                  - state
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/suspend:
    post:
      operationId: suspendOrganization
      tags:
        - Organizations
      summary: Suspend an organization
      description: >-
        Requires realm.organizations.suspend and (for users) an MFA session. Note: the body is decoded leniently (decode
        errors are ignored).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - realm.organizations.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    const: suspended
                required:
                  - state
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/reactivate:
    post:
      operationId: reactivateOrganization
      tags:
        - Organizations
      summary: Reactivate an organization
      description: >-
        Requires realm.organizations.suspend and (for users) an MFA session. Note: the body is decoded leniently (decode
        errors are ignored).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - realm.organizations.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    const: active
                required:
                  - state
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/ownership-transfers:
    post:
      operationId: transferOrganizationOwnership
      tags:
        - Organizations
      summary: Transfer ownership
      description: Users need recent authentication.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.ownership.transfer
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                membership_id:
                  type: string
                release_current_owner:
                  type: boolean
              required:
                - membership_id
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: transferred
                required:
                  - status
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/members:
    get:
      operationId: listMembers
      tags:
        - Organizations
      summary: List members
      description: >-
        Email local parts are masked unless the caller holds realm.users.read. Each membership's metadata (USR-009) is
        included only when the caller holds org.members.write in the organization.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.members.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: Filter by membership state; removed and expired members are hidden by default.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Membership'
                  next_cursor:
                    type: string
                    description: >-
                      Opaque cursor for the next page; an empty string when there are no more results. Cursors are bound
                      to the realm and listing and cannot be replayed elsewhere.
                required:
                  - items
                  - next_cursor
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: addMember
      tags:
        - Organizations
      summary: Add a member
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.members.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                user_id:
                  type: string
                role_ids:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
              required:
                - user_id
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Membership'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/members/{membership}:
    get:
      operationId: getMember
      tags:
        - Organizations
      summary: Get a membership
      description: >-
        The membership's metadata (USR-009) is included only when the caller holds org.members.write in the
        organization.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.members.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_membership'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  membership:
                    $ref: '#/components/schemas/Membership'
                  role_assignments:
                    type:
                      - array
                      - 'null'
                    items:
                      $ref: '#/components/schemas/RoleAssignment'
                required:
                  - membership
                  - role_assignments
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateMember
      tags:
        - Organizations
      summary: Suspend or reactivate a membership, or edit its metadata
      description: >-
        Changes state, metadata or both, atomically. metadata is the organization's own data about the membership
        (USR-009), separate from the user's profile, admin_metadata and internal metadata: it is merged (a key set to
        null is removed), must stay within limits.metadata_bytes as JSON (422 on metadata), is returned to callers
        holding org.members.write, never to the member or in tokens, is audited as
        organization.membership.metadata_updated with the key names only, and is erased when the membership ends or the
        account is deleted. The member-management ceiling applies (an administrator cannot act on a member holding
        organization permissions the administrator lacks). 409 for a removed or expired membership; 422 when neither
        field is given.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.members.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_membership'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                state:
                  type: string
                  enum:
                    - active
                    - suspended
                metadata:
                  type:
                    - object
                    - 'null'
                  additionalProperties: true
                  description: Keys to set; a key whose value is null is removed. Omitted or null leaves the metadata unchanged.
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Membership'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: removeMember
      tags:
        - Organizations
      summary: Remove a member (or leave)
      description: Members may remove themselves; otherwise org.members.write is required. The last owner cannot be removed.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.members.write (not needed to remove oneself)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_membership'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/members/{membership}/roles:
    post:
      operationId: assignMemberRole
      tags:
        - Organizations
      summary: Assign an organization role to a member
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_membership'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                role_id:
                  type: string
                expires_at:
                  type:
                    - string
                    - 'null'
                  format: date-time
                approver_id:
                  type: string
                reason:
                  type: string
              required:
                - role_id
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleAssignment'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/members/{membership}/roles/{assignment}:
    delete:
      operationId: unassignMemberRole
      tags:
        - Organizations
      summary: Remove a member role assignment
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_membership'
        - $ref: '#/components/parameters/Path_assignment'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/roles:
    get:
      operationId: listOrganizationRoles
      tags:
        - Organizations
      summary: List organization roles
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Role'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createOrganizationRole
      tags:
        - Organizations
      summary: Create an organization role
      description: boundary_type and organization_id are forced to this organization.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/roles/{role}/permissions:
    post:
      operationId: modifyOrganizationRolePermissions
      tags:
        - Organizations
      summary: Change organization role permissions
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_role'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                add:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                remove:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/invitations:
    get:
      operationId: listInvitations
      tags:
        - Invitations
      summary: List invitations
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.invites.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: Filter by invitation state.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Invitation'
                  next_cursor:
                    type: string
                    description: >-
                      Opaque cursor for the next page; an empty string when there are no more results. Cursors are bound
                      to the realm and listing and cannot be replayed elsewhere.
                required:
                  - items
                  - next_cursor
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createInvitation
      tags:
        - Invitations
      summary: Create an invitation
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.invites.create
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InvitationInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  invitation:
                    $ref: '#/components/schemas/Invitation'
                  invitation_secret:
                    type: string
                    x-secret: true
                    description: >-
                      Shared-link secret (only for purpose shared_link; mailed invitations never return it). Returned
                      exactly once; it is never stored in plaintext, never shown again and never replayed from the
                      idempotency store.
                required:
                  - invitation
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/invitations/{id}/resend:
    post:
      operationId: resendInvitation
      tags:
        - Invitations
      summary: Rotate and resend an invitation
      description: Any request body is ignored.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.invites.create
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: resent
                required:
                  - status
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/invitations/{id}/revoke:
    post:
      operationId: revokeInvitation
      tags:
        - Invitations
      summary: Revoke an invitation
      description: Any request body is ignored.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.invites.revoke
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/invitations/inspect:
    post:
      operationId: inspectInvitation
      tags:
        - Invitations
      summary: Inspect an invitation without consuming it
      description: Invalid, expired and used invitations return the same error.
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                invitation:
                  type: string
                  x-secret: true
              required:
                - invitation
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvitationInspection'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/invitations/accept:
    post:
      operationId: acceptInvitation
      tags:
        - Invitations
      summary: Accept an invitation
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                invitation:
                  type: string
                  x-secret: true
              required:
                - invitation
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvitationAcceptance'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/invitations/decline:
    post:
      operationId: declineInvitation
      tags:
        - Invitations
      summary: Decline an invitation
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                invitation:
                  type: string
                  x-secret: true
              required:
                - invitation
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/join-requests:
    get:
      operationId: listJoinRequests
      tags:
        - Organizations
      summary: List join requests
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.join_requests.review
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: Filter by state.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/JoinRequest'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: requestToJoin
      tags:
        - Organizations
      summary: Request to join an organization
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JoinRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/join-requests/{id}/decision:
    post:
      operationId: decideJoinRequest
      tags:
        - Organizations
      summary: Approve or deny a join request
      description: Reviewers cannot approve their own requests.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.join_requests.review
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                approve:
                  type: boolean
                reason:
                  type: string
              required:
                - approve
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/groups:
    get:
      operationId: listGroups
      tags:
        - Organizations
      summary: List groups
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Group'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createGroup
      tags:
        - Organizations
      summary: Create a group
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/groups/{group}:
    get:
      operationId: getGroup
      tags:
        - Organizations
      summary: Get a group
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateGroup
      tags:
        - Organizations
      summary: Update a group
      description: 'Note: unlike GET, the response does not carry an ETag.'
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchOptional'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteGroup
      tags:
        - Organizations
      summary: Delete a group
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/groups/{group}/members:
    get:
      operationId: listGroupMembers
      tags:
        - Organizations
      summary: List group members
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/GroupMember'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: addGroupMember
      tags:
        - Organizations
      summary: Add a group member
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                membership_id:
                  type: string
              required:
                - membership_id
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/groups/{group}/members/{member}:
    delete:
      operationId: removeGroupMember
      tags:
        - Organizations
      summary: Remove a group member
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/Path_member'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/groups/{group}/roles:
    post:
      operationId: assignGroupRole
      tags:
        - Organizations
      summary: Assign an organization role to a group
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                role_id:
                  type: string
              required:
                - role_id
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleAssignment'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/domains:
    get:
      operationId: listDomains
      tags:
        - Organizations
      summary: List domains
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.domains.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Domain'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: addDomain
      tags:
        - Organizations
      summary: Claim a domain
      description: Returns the DNS TXT challenge to publish.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.domains.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                domain:
                  type: string
              required:
                - domain
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DomainChallenge'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/domains/{id}/verify:
    post:
      operationId: verifyDomain
      tags:
        - Organizations
      summary: Verify domain control
      description: Any request body is ignored.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.domains.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Domain'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/domains/{id}:
    patch:
      operationId: updateOrganizationDomain
      tags:
        - Organizations
      summary: Change domain routing
      description: >-
        With include_subdomains a verified domain also routes sign-ins from its subdomains (TEN-011). Routing is
        deterministic: an exactly matching verified domain always wins, otherwise the most specific parent that opted
        in; verified domains are unique in the realm.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.domains.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                include_subdomains:
                  type: boolean
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: removeDomain
      tags:
        - Organizations
      summary: Remove a domain
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.domains.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/organizations/{org}/audit-events:
    get:
      operationId: listOrganizationAuditEvents
      tags:
        - Audit
      summary: Query organization audit events
      description: >-
        Filters combine with AND. Type prefixes are literal, including underscores, percent and backslash. Keep filters
        while following next_cursor; only limit may change. A cursor from another route, organization or filter set
        returns 400.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.audit.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: id
          in: query
          required: false
          schema:
            type: string
          description: One event by ID (evt_...), for example the audit_event_id of a security.alert.
        - name: actor_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by actor.
        - name: subject_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by subject.
        - name: type
          in: query
          required: false
          schema:
            type: string
          description: Exact event type.
        - name: type_prefix
          in: query
          required: false
          schema:
            type: string
          description: Literal event type prefix; percent, underscore and backslash have no wildcard or escape meaning.
        - name: outcome
          in: query
          required: false
          schema:
            type: string
          description: success, denied or failure.
        - name: client_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by client.
        - name: request_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by request ID.
        - name: impersonation_grant_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by support grant.
        - name: grant_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by authorization grant.
        - name: session_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by session (the event session or the acting session).
        - name: target_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by target object ID.
        - name: category
          in: query
          required: false
          schema:
            type: string
          description: Filter by audit category (security, configuration, operations, emergency, ...).
        - name: network
          in: query
          required: false
          schema:
            type: string
          description: IP address or CIDR prefix; matches events whose stored, truncated network context overlaps it (AUD-011).
        - name: from
          in: query
          required: false
          schema:
            type: string
            format: date-time
          description: RFC 3339 lower bound.
        - name: to
          in: query
          required: false
          schema:
            type: string
            format: date-time
          description: RFC 3339 upper bound.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AuditEvent'
                  next_cursor:
                    type: string
                    description: >-
                      Opaque cursor for the next page; an empty string when there are no more results. Cursors are bound
                      to the realm and listing and cannot be replayed elsewhere.
                required:
                  - items
                  - next_cursor
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users:
    get:
      operationId: listUsers
      tags:
        - Users
      summary: Search users
      description: Requires realm.users.read; holders of only support.users.read receive masked views.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
        - support.users.read (masked view)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: q
          in: query
          required: false
          schema:
            type: string
          description: Search text.
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: Filter by state.
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Only members of this organization.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      oneOf:
                        - $ref: '#/components/schemas/AdminUser'
                        - $ref: '#/components/schemas/MaskedUser'
                  next_cursor:
                    type: string
                    description: >-
                      Opaque cursor for the next page; an empty string when there are no more results. Cursors are bound
                      to the realm and listing and cannot be replayed elsewhere.
                required:
                  - items
                  - next_cursor
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createUser
      tags:
        - Users
      summary: Create a user
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  format: email
                username:
                  type: string
                phone:
                  type: string
                  description: E.164.
                display_name:
                  type: string
                given_name:
                  type: string
                family_name:
                  type: string
                locale:
                  type: string
                admin_metadata:
                  type:
                    - object
                    - 'null'
                  additionalProperties: true
                send_setup_email:
                  type:
                    - boolean
                    - 'null'
                  description: Defaults to true. When false (or no email), a setup token is returned once.
                required_actions:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                    enum:
                      - update_password
                      - verify_email
                      - configure_totp
                      - accept_terms
                      - complete_profile
                      - verify_contact
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  user:
                    $ref: '#/components/schemas/AdminUser'
                  setup_token:
                    type: string
                    x-secret: true
                    description: >-
                      One-time account setup token (72 hours) for delivery through a trusted channel; only when no setup
                      email is sent. Returned exactly once; it is never stored in plaintext, never shown again and never
                      replayed from the idempotency store.
                  notice:
                    type: string
                required:
                  - user
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}:
    get:
      operationId: getUser
      tags:
        - Users
      summary: Get a user
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
        - support.users.read (masked view)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/AdminUser'
                  - $ref: '#/components/schemas/MaskedUser'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateUser
      tags:
        - Users
      summary: Update a user
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchOptional'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminUserPatch'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminUser'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteUser
      tags:
        - Users
      summary: Delete a user immediately
      description: Administrators cannot delete themselves (409).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.delete
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/suspend:
    post:
      operationId: suspendUser
      tags:
        - Users
      summary: Suspend a user account
      description: >-
        Global-account authority (realm.users.suspend), not tenant membership administration. Administrators cannot
        change their own state. Note: the body is decoded leniently (decode errors are ignored).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminUser'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/reactivate:
    post:
      operationId: reactivateUser
      tags:
        - Users
      summary: Reactivate a user account
      description: >-
        Global-account authority (realm.users.suspend), not tenant membership administration. Administrators cannot
        change their own state. Note: the body is decoded leniently (decode errors are ignored).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminUser'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/lock:
    post:
      operationId: lockUser
      tags:
        - Users
      summary: Lock a user account
      description: >-
        Global-account authority (realm.users.suspend), not tenant membership administration. Administrators cannot
        change their own state. Note: the body is decoded leniently (decode errors are ignored).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AdminUser'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/required-actions:
    post:
      operationId: setUserRequiredActions
      tags:
        - Users
      summary: Set required actions
      description: >-
        Replaces the account's required actions (AUT-018). The change applies only if the list is still the one the
        request read (409 conflict otherwise, "the required actions changed concurrently; retry") and, when If-Match
        carries the ETag from GET /users/{user}, only if the account is still at that version (412 otherwise), so a
        client that reads the list, edits it and writes it back cannot overwrite a concurrent change (SEC-008). Each
        action added or removed needs its own permission besides realm.users.required_actions. The response carries the
        account's new ETag.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.required_actions
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                actions:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                    enum:
                      - update_password
                      - verify_email
                      - configure_totp
                      - accept_terms
                      - complete_profile
                      - verify_contact
              required:
                - actions
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/revoke-sessions:
    post:
      operationId: revokeUserSessions
      tags:
        - Users
      summary: Revoke all sessions of a user
      description: Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.sessions.revoke
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RevokedSessions'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/sessions:
    get:
      operationId: listUserSessions
      tags:
        - Users
      summary: List sessions of a user
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Session'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/verification-overrides:
    post:
      operationId: overrideIdentifierVerification
      tags:
        - Users
      summary: Mark an identifier verified (override)
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.verification.override
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                identifier_id:
                  type: string
                reason:
                  type: string
              required:
                - identifier_id
                - reason
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/identifiers:
    post:
      operationId: addUserIdentifier
      tags:
        - Users
      summary: Add an email address to an account (lost contact address)
      description: >-
        Lost contact address recovery (MFA-008): adds an email address the owner can still reach, unverified and not
        primary (USR-004). Verify it with POST /users/{user}/verification-overrides, then make it primary with POST
        /users/{user}/identifiers/{id}/primary. Requires both permissions, an MFA session with recent authentication,
        and a reason; administrators cannot change their own identifiers here. An address another account has verified
        answers 409. Audited as user.identifier.added (reason in metadata); the account's verified primary address
        receives an identifier_changed notice that does not name the new address.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.verification.override
        - realm.users.credentials.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                type:
                  type: string
                  enum:
                    - email
                value:
                  type: string
                  format: email
                reason:
                  type: string
                  minLength: 5
                  maxLength: 500
              required:
                - type
                - value
                - reason
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  type:
                    type: string
                    const: email
                  value:
                    type: string
                  verified:
                    type: boolean
                    const: false
                  is_primary:
                    type: boolean
                    const: false
                  next:
                    type: string
                required:
                  - id
                  - type
                  - value
                  - verified
                  - is_primary
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/identifiers/{id}/primary:
    post:
      operationId: makeUserIdentifierPrimary
      tags:
        - Users
      summary: Make a verified email address the account's primary address
      description: >-
        Lost contact address recovery (MFA-008): the primary email address receives assisted recovery's setup link and
        the owner's notices. Only a verified email address can become primary (422 otherwise; 409 when it already is).
        Requires both permissions, an MFA session with recent authentication, and a reason; administrators cannot change
        their own identifiers here. Audited as user.identifier.primary_changed (reason and previous_identifier_id in
        metadata); the previous verified primary address receives an identifier_changed notice that does not name the
        new address.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.verification.override
        - realm.users.credentials.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
                  minLength: 5
                  maxLength: 500
              required:
                - reason
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/credentials/password/compromised:
    post:
      operationId: markPasswordCompromised
      tags:
        - Users
      summary: Mark the password compromised
      description: 'Note: the body is decoded leniently (decode errors are ignored).'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.credentials.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/recovery-requests:
    post:
      operationId: startAssistedRecovery
      tags:
        - Users
      summary: Start assisted account recovery
      description: >-
        Revokes sessions, optionally resets MFA (requires realm.users.credentials.manage), notifies the user and issues
        a setup link delivered to the primary email address. Operators cannot assist their own recovery. 409 when the
        primary email address is not verified: recovery is never delivered to an unverified address (verify it with POST
        /users/{user}/verification-overrides, or make a verified address primary with POST
        /users/{user}/identifiers/{id}/primary).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - support.recovery.assist
        - realm.users.credentials.manage (required for reset_mfa)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
                  minLength: 10
                evidence_reference:
                  type: string
                reset_mfa:
                  type: boolean
              required:
                - reason
                - evidence_reference
              additionalProperties: false
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: recovery_started
                  setup_token:
                    type: string
                    x-secret: true
                    description: >-
                      Two-hour setup token, only when the user has no email address. Returned exactly once; it is never
                      stored in plaintext, never shown again and never replayed from the idempotency store.
                required:
                  - status
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/identity-providers:
    get:
      operationId: listIdentityProviders
      tags:
        - Federation
      summary: List identity provider connections
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/IdentityProvider'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createIdentityProvider
      tags:
        - Federation
      summary: Create an identity provider connection
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdentityProviderInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityProvider'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/identity-providers/{id}:
    get:
      operationId: getIdentityProvider
      tags:
        - Federation
      summary: Get an identity provider connection
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityProvider'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: replaceIdentityProvider
      tags:
        - Federation
      summary: Replace an identity provider connection
      description: >-
        Replaces the connection's settings (If-Match required: 428 without, 412 when stale), validated as at creation.
        alias may be omitted (kept) but cannot change (422 on alias: it is part of the registered callback URL). issuer,
        and the protocol implied by adapter, cannot change while identities are linked to the connection (409 on issuer
        or adapter; use a reviewed migration). client_secret omitted keeps the stored secret, an empty string removes it
        and a value replaces it; claim_mapping omitted keeps the current mapping, and a changed mapping increases
        mapping_revision. SAML connections are managed at /saml/connections (409 here). Audited as
        federation.provider.updated.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchRequired'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdentityProviderInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityProvider'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteIdentityProvider
      tags:
        - Federation
      summary: Delete an identity provider connection
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/identity-providers/{id}/test:
    post:
      operationId: testIdentityProvider
      tags:
        - Federation
      summary: Test a connection (redacted diagnostics)
      description: Fetches discovery and keys through the egress policy without changing state. Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityProviderDiagnostics'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/linked-identities:
    get:
      operationId: listUserLinkedIdentities
      tags:
        - Federation
      summary: List a user's linked identities
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/LinkedIdentity'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/users/{user}/linked-identities/{id}:
    delete:
      operationId: unlinkUserIdentity
      tags:
        - Federation
      summary: Unlink a user's external identity
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/projects:
    get:
      operationId: listProjects
      tags:
        - Projects
      summary: List projects
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Project'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createProject
      tags:
        - Projects
      summary: Create a project
      description: >-
        Note: the request body is the Project model itself; server-managed members (id, realm_id, version, created_at,
        state) are accepted by the decoder.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Project'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/projects/{project}:
    get:
      operationId: getProject
      tags:
        - Projects
      summary: Get a project
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateProject
      tags:
        - Projects
      summary: Update a project
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchOptional'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                description:
                  type: string
                state:
                  type: string
                  enum:
                    - active
                    - suspended
                    - archived
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients:
    get:
      operationId: listClients
      tags:
        - Clients
      summary: List clients
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Client'
                  next_cursor:
                    type: string
                    description: >-
                      Opaque cursor for the next page; an empty string when there are no more results. Cursors are bound
                      to the realm and listing and cannot be replayed elsewhere.
                required:
                  - items
                  - next_cursor
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createClient
      tags:
        - Clients
      summary: Register a client
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClientInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  client:
                    $ref: '#/components/schemas/Client'
                  client_secret:
                    type: string
                    x-secret: true
                    description: >-
                      Client secret for client_secret_* authentication. Returned exactly once; it is never stored in
                      plaintext, never shown again and never replayed from the idempotency store.
                  notice:
                    type: string
                required:
                  - client
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients/{client}:
    get:
      operationId: getClient
      tags:
        - Clients
      summary: Get a client
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                type: object
                properties:
                  client:
                    $ref: '#/components/schemas/Client'
                  resource_grants:
                    type:
                      - array
                      - 'null'
                    items:
                      $ref: '#/components/schemas/ResourceGrant'
                  credentials:
                    type:
                      - array
                      - 'null'
                    items:
                      $ref: '#/components/schemas/ClientCredential'
                required:
                  - client
                  - resource_grants
                  - credentials
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: replaceClient
      tags:
        - Clients
      summary: Replace a client definition
      description: client_type cannot change.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchRequired'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClientInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Client'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients/{client}/suspend:
    post:
      operationId: suspendClient
      tags:
        - Clients
      summary: Suspend a client
      description: 'Note: the body is decoded leniently (decode errors are ignored).'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    const: suspended
                required:
                  - state
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients/{client}/reactivate:
    post:
      operationId: reactivateClient
      tags:
        - Clients
      summary: Reactivate a client
      description: >-
        Note: the body is decoded leniently (decode errors are ignored). A decommissioned client cannot be reactivated
        (409), and neither can a dynamically registered client whose registration is pending approval (409; approve it
        with POST /client-registrations/{client}/approve).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    const: active
                required:
                  - state
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients/{client}/decommission:
    post:
      operationId: decommissionClient
      tags:
        - Clients
      summary: Decommission a client
      description: 'Note: the body is decoded leniently (decode errors are ignored).'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    const: decommissioned
                required:
                  - state
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients/{client}/credentials:
    post:
      operationId: issueClientCredential
      tags:
        - Clients
      summary: Issue a client secret or add public keys
      description: >-
        Without jwks a new secret is issued and, with retire_others_after_seconds, other secrets are scheduled for
        retirement.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.credentials
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                retire_others_after_seconds:
                  type: integer
                  minimum: 0
                jwks:
                  description: JWK Set to add for private_key_jwt; when present no secret is issued.
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    title: SecretIssued
                    properties:
                      client_secret:
                        type: string
                        x-secret: true
                        description: >-
                          New client secret. Returned exactly once; it is never stored in plaintext, never shown again
                          and never replayed from the idempotency store.
                      credential:
                        $ref: '#/components/schemas/ClientCredential'
                      notice:
                        type: string
                    required:
                      - client_secret
                      - credential
                      - notice
                  - type: object
                    title: KeysAdded
                    properties:
                      status:
                        type: string
                        const: keys_added
                    required:
                      - status
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients/{client}/credentials/{id}:
    delete:
      operationId: revokeClientCredential
      tags:
        - Clients
      summary: Revoke a client credential
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.credentials
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/clients/{client}/resource-grants/{resource}:
    get:
      operationId: getClientResourceGrant
      tags:
        - Clients
      summary: Get a client's grant for a resource
      description: Returns the grant with an entity tag; PUT honors If-Match against it (API-010).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_resource'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Entity tag of the grant's state.
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  client_ref:
                    type: string
                  resource_id:
                    type: string
                  allowed_scopes:
                    type: array
                    items:
                      type: string
                  subject_types:
                    type: array
                    items:
                      type: string
                  exchange_policy:
                    type: object
                    additionalProperties: true
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: setClientResourceGrant
      tags:
        - Clients
      summary: Grant a client access to a resource
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_resource'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                allowed_scopes:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                subject_types:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                    enum:
                      - user
                      - service_principal
                exchange_policy:
                  $ref: '#/components/schemas/ExchangePolicy'
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: removeClientResourceGrant
      tags:
        - Clients
      summary: Remove a client resource grant
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_resource'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/resources:
    get:
      operationId: listResources
      tags:
        - Resources
      summary: List resources (APIs)
      description: Returns up to limits.max_page_size resources.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Resource'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createResource
      tags:
        - Resources
      summary: Register a resource (API)
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResourceInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Resource'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/resources/{resource}:
    get:
      operationId: getResource
      tags:
        - Resources
      summary: Get a resource
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_resource'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Resource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: replaceResource
      tags:
        - Resources
      summary: Replace a resource definition
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_resource'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchRequired'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResourceInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Resource'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/resources/{resource}/scopes:
    post:
      operationId: addResourceScope
      tags:
        - Resources
      summary: Add a scope to a resource
      description: >-
        Returns 201 with an empty body. Clients may request the scope only when their resource grant lists it;
        requesting a scope never grants it (APP-007). A scope declared with is_default is requested on a client's behalf
        when a request names the resource but none of its scopes, and then passes the same checks as a requested scope.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_resource'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ScopeInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/scopes/{scope}:
    delete:
      operationId: deleteScope
      tags:
        - Resources
      summary: Delete a scope
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_scope'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/resources/{resource}/introspectors:
    post:
      operationId: addResourceIntrospector
      tags:
        - Resources
      summary: Authorize a client to introspect tokens for a resource
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_resource'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                client:
                  type: string
                  description: Client reference.
              required:
                - client
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/permissions:
    get:
      operationId: listPermissions
      tags:
        - Authorization
      summary: List permissions
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Permission'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: registerPermission
      tags:
        - Authorization
      summary: Register a permission
      description: >-
        Note: the request body is the Permission model itself (id and built_in are accepted by the decoder). Names in
        realm., org., support. and platform. namespaces are reserved.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Permission'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Permission'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/roles:
    get:
      operationId: listRoles
      tags:
        - Authorization
      summary: List roles
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: boundary_type
          in: query
          required: false
          schema:
            type: string
          description: realm, organization or project.
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Organization roles of this organization.
        - name: project_id
          in: query
          required: false
          schema:
            type: string
          description: Project roles of this project.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Role'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createRole
      tags:
        - Authorization
      summary: Create a role
      description: >-
        Permission and delegation ceilings are enforced by the authorization service (grant_ceiling_exceeded). Composite
        roles (composite_role_ids, immutable after creation) must share the boundary type, and for organization and
        project roles the organization or project; they must not form a cycle, and the new role with every role it
        reaches must not exceed limits.max_role_expansion (422, AZ-011).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.write or org.roles.write by boundary (service-enforced, with delegation ceiling)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/roles/{role}:
    get:
      operationId: getRole
      tags:
        - Authorization
      summary: Get a role
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_role'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteRole
      tags:
        - Authorization
      summary: Delete a role
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.write or org.roles.write by boundary (service-enforced)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_role'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/roles/{role}/permissions:
    post:
      operationId: modifyRolePermissions
      tags:
        - Authorization
      summary: Change role permissions
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.write or org.roles.write by boundary (service-enforced, with delegation ceiling)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_role'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                add:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
                remove:
                  type:
                    - array
                    - 'null'
                  items:
                    type: string
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Role'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/role-assignments:
    get:
      operationId: listRoleAssignments
      tags:
        - Authorization
      summary: List role assignments
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: subject_id
          in: query
          required: false
          schema:
            type: string
          description: Subject filter.
        - name: subject_type
          in: query
          required: false
          schema:
            type: string
          description: Subject type (default user when subject_id is set).
        - name: scope_id
          in: query
          required: false
          schema:
            type: string
          description: Scope filter.
        - name: scope_type
          in: query
          required: false
          schema:
            type: string
          description: Scope type.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/RoleAssignment'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: assignRole
      tags:
        - Authorization
      summary: Assign a role
      description: >-
        scope defaults to the realm; a realm scope must name this realm. Answers 202 pending_approval (a role-assignment
        request another administrator approves) when the role requires approval, or when the subject is an agent service
        principal and the role is privileged (MCH-017): realm-boundary, owner, wildcard or any permission registered as
        privileged, through composition at any depth.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.assign or org.roles.assign by scope (service-enforced, with grant ceiling)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                role_id:
                  type: string
                subject:
                  $ref: '#/components/schemas/AuthzSubject'
                scope:
                  $ref: '#/components/schemas/AuthzScope'
                expires_at:
                  type:
                    - string
                    - 'null'
                  format: date-time
                valid_from:
                  type:
                    - string
                    - 'null'
                  format: date-time
                conditions:
                  $ref: '#/components/schemas/GrantConditions'
                reason:
                  type: string
              required:
                - role_id
                - subject
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleAssignment'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/role-assignments/{assignment}:
    delete:
      operationId: unassignRole
      tags:
        - Authorization
      summary: Remove a role assignment
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.assign or org.roles.assign by scope (service-enforced)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_assignment'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/subjects/{subject}/permissions:
    get:
      operationId: getSubjectPermissions
      tags:
        - Authorization
      summary: Inspect a subject's effective permissions
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_subject'
        - $ref: '#/components/parameters/RequestId'
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Evaluate in this organization.
        - name: project_id
          in: query
          required: false
          schema:
            type: string
          description: >-
            Evaluate for a resource of this project: the subject's project-scoped role assignments for it count too
            (AZ-002). The project must exist and, with organization_id, belong to that organization (owned, or shared
            through an active project grant); otherwise 422.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EffectivePermissions'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/authorization/check:
    post:
      operationId: checkAuthorization
      tags:
        - Authorization
      summary: Evaluate one authorization decision
      description: >-
        Requires realm.authorization.check. Deny by default on malformed input; obligations are mandatory conditions.
        subject_token evaluation requires a service-principal caller registered as introspector for the token audience.
        With resource.project_id the subject's role assignments scoped to that project are evaluated in addition to
        realm and organization ones (AZ-002); an unknown project denies with UNKNOWN_PROJECT, and a project that does
        not belong to the decision's organization (resource.org_id or the token's) with PROJECT_ORGANIZATION_MISMATCH.
      security:
        - adminToken: []
      x-trust-class: resource-server
      x-permissions:
        - realm.authorization.check
        - realm.authorization.simulate (free-form subject)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DecisionRequest'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Decision'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/authorization/check-batch:
    post:
      operationId: checkAuthorizationBatch
      tags:
        - Authorization
      summary: Evaluate a bounded batch of decisions
      security:
        - adminToken: []
      x-trust-class: resource-server
      x-permissions:
        - realm.authorization.check
        - realm.authorization.simulate (free-form subject)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                checks:
                  type: array
                  items:
                    $ref: '#/components/schemas/DecisionRequest'
                  minItems: 1
                  description: 1..limits.max_batch_size checks.
              required:
                - checks
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  decisions:
                    type: array
                    items:
                      $ref: '#/components/schemas/Decision'
                required:
                  - decisions
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/service-principals:
    get:
      operationId: listServicePrincipals
      tags:
        - Machine identities
      summary: List service principals
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.service_principals.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ServicePrincipal'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createServicePrincipal
      tags:
        - Machine identities
      summary: Create a service principal
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.service_principals.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServicePrincipalInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipal'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/service-principals/{id}:
    get:
      operationId: getServicePrincipal
      tags:
        - Machine identities
      summary: Get a service principal
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.service_principals.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipal'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateServicePrincipal
      tags:
        - Machine identities
      summary: Update a service principal
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.service_principals.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchOptional'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServicePrincipalInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipal'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteServicePrincipal
      tags:
        - Machine identities
      summary: Delete a service principal
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.service_principals.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/service-principals/{id}/disable:
    post:
      operationId: disableServicePrincipal
      tags:
        - Machine identities
      summary: Disable a service principal
      description: Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.service_principals.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/service-principals/{id}/enable:
    post:
      operationId: enableServicePrincipal
      tags:
        - Machine identities
      summary: Enable a service principal
      description: Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.service_principals.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/api-keys:
    get:
      operationId: listAPIKeys
      tags:
        - Machine identities
      summary: List API keys and personal tokens
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.api_keys.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: owner_type
          in: query
          required: false
          schema:
            type: string
          description: service_principal or user.
        - name: owner_id
          in: query
          required: false
          schema:
            type: string
          description: Owner identifier.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MachineCredential'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createAPIKey
      tags:
        - Machine identities
      summary: Create an API key for a service principal
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.api_keys.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              additionalProperties: false
              properties:
                audience:
                  type: string
                name:
                  type: string
                organization_id:
                  type: string
                scopes:
                  items:
                    type: string
                  type:
                    - array
                    - 'null'
                ttl_days:
                  type: integer
                  maximum: 365
                  description: Expiry is mandatory; at most 365 days.
                service_principal_id:
                  type: string
              type: object
              required:
                - audience
                - name
                - scopes
                - service_principal_id
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  api_key:
                    type: string
                    x-secret: true
                    description: >-
                      API key (pa_key_ prefix). Returned exactly once; it is never stored in plaintext, never shown
                      again and never replayed from the idempotency store.
                  credential:
                    $ref: '#/components/schemas/MachineCredential'
                  notice:
                    type: string
                required:
                  - api_key
                  - credential
                  - notice
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/api-keys/{id}:
    delete:
      operationId: revokeAPIKey
      tags:
        - Machine identities
      summary: Revoke an API key or personal token
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.api_keys.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/credential-inventory:
    get:
      operationId: getCredentialInventory
      tags:
        - Machine identities
      summary: Credential inventory with hygiene flags
      description: Flags credentials expiring within 14 days or unused for 60 days.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.credentials.inventory
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/CredentialInventoryItem'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/settings:
    get:
      operationId: getRealmSettings
      tags:
        - Realm
      summary: Get realm settings
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RealmSettings'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: replaceRealmPolicy
      tags:
        - Realm
      summary: Replace the realm policy
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchRequired'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                policy:
                  $ref: '#/components/schemas/RealmPolicy'
                reason:
                  type: string
              required:
                - policy
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                type: object
                properties:
                  policy:
                    $ref: '#/components/schemas/RealmPolicy'
                  policy_revision:
                    type: integer
                    format: int64
                  version:
                    type: integer
                    format: int64
                required:
                  - policy
                  - policy_revision
                  - version
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/emergency/realm-state:
    post:
      operationId: setRealmEmergencyState
      tags:
        - Realm
      summary: Suspend or reactivate the realm (emergency)
      security:
        - adminToken: []
      x-trust-class: operator-only
      x-permissions:
        - realm.emergency
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                state:
                  type: string
                  enum:
                    - active
                    - suspended
                reason:
                  type: string
              required:
                - state
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  state:
                    type: string
                    enum:
                      - active
                      - suspended
                required:
                  - state
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/signing-keys:
    get:
      operationId: listSigningKeys
      tags:
        - Realm
      summary: List signing key lifecycle metadata
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.keys.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SigningKeyMetadata'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/signing-key-rotations:
    post:
      operationId: rotateSigningKey
      tags:
        - Realm
      summary: Rotate the realm signing key
      description: Requires realm.keys.rotate and authentication within the last 5 minutes.
      security:
        - adminToken: []
      x-trust-class: operator-only
      x-permissions:
        - realm.keys.rotate
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  type: string
                  enum:
                    - planned
                    - emergency
                  description: Anything other than emergency is treated as planned.
                algorithm:
                  type: string
                  description: Defaults to keys.signing_algorithm.
                reason:
                  type: string
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  kid:
                    type: string
                  mode:
                    type: string
                    enum:
                      - planned
                      - emergency
                required:
                  - kid
                  - mode
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/audit-events:
    get:
      operationId: listAuditEvents
      tags:
        - Audit
      summary: Query audit events
      description: >-
        Filters combine with AND. Type prefixes are literal, including underscores, percent and backslash. Keep filters
        while following next_cursor; only limit may change. A cursor from another route, organization or filter set
        returns 400.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Restrict to one organization.
        - name: id
          in: query
          required: false
          schema:
            type: string
          description: One event by ID (evt_...), for example the audit_event_id of a security.alert.
        - name: actor_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by actor.
        - name: subject_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by subject.
        - name: type
          in: query
          required: false
          schema:
            type: string
          description: Exact event type.
        - name: type_prefix
          in: query
          required: false
          schema:
            type: string
          description: Literal event type prefix; percent, underscore and backslash have no wildcard or escape meaning.
        - name: outcome
          in: query
          required: false
          schema:
            type: string
          description: success, denied or failure.
        - name: client_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by client.
        - name: request_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by request ID.
        - name: impersonation_grant_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by support grant.
        - name: grant_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by authorization grant.
        - name: session_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by session (the event session or the acting session).
        - name: target_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by target object ID.
        - name: category
          in: query
          required: false
          schema:
            type: string
          description: Filter by audit category (security, configuration, operations, emergency, ...).
        - name: network
          in: query
          required: false
          schema:
            type: string
          description: IP address or CIDR prefix; matches events whose stored, truncated network context overlaps it (AUD-011).
        - name: from
          in: query
          required: false
          schema:
            type: string
            format: date-time
          description: RFC 3339 lower bound.
        - name: to
          in: query
          required: false
          schema:
            type: string
            format: date-time
          description: RFC 3339 upper bound.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AuditEvent'
                  next_cursor:
                    type: string
                    description: >-
                      Opaque cursor for the next page; an empty string when there are no more results. Cursors are bound
                      to the realm and listing and cannot be replayed elsewhere.
                required:
                  - items
                  - next_cursor
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/audit-integrity:
    get:
      operationId: verifyAuditIntegrity
      tags:
        - Audit
      summary: Verify the audit hash chain
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditVerificationReport'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/audit-exports:
    post:
      operationId: exportAuditEvents
      tags:
        - Audit
      summary: Export audit evidence (asynchronous)
      description: Users need recent authentication.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.export
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected. The body may
          be empty (treated as {}), but Content-Type: application/json is still required.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                organization_id:
                  type: string
                from:
                  type: string
                  description: RFC 3339 lower bound.
                to:
                  type: string
                  description: RFC 3339 upper bound.
                impersonation_grant_id:
                  type: string
                  description: Export only the evidence of one support grant (IMP-024).
              additionalProperties: false
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobAccepted'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/jobs/{id}:
    get:
      operationId: getJob
      tags:
        - Jobs
      summary: Inspect a job
      description: Visible to the requester or holders of realm.jobs.read; otherwise 404.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - requester
        - realm.jobs.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/jobs/{id}/cancel:
    post:
      operationId: cancelJob
      tags:
        - Jobs
      summary: Cancel a job
      description: Organization deletions cannot be cancelled (409). Any request body is ignored.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - requester
        - realm.jobs.cancel
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/jobs/{id}/downloads:
    post:
      operationId: issueJobDownload
      tags:
        - Jobs
      summary: Issue a download token for a protected job result
      description: Only the requester; users need recent authentication. Any request body is ignored.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - requester
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  download_token:
                    type: string
                    x-secret: true
                    description: >-
                      Single-use download credential valid for 300 seconds. Returned exactly once; it is never stored in
                      plaintext, never shown again and never replayed from the idempotency store.
                  expires_in:
                    type: integer
                    const: 300
                required:
                  - download_token
                  - expires_in
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/job-downloads:
    post:
      operationId: downloadJobResult
      tags:
        - Jobs
      summary: Download a protected job result
      description: >-
        Consumes the download token. The requester must still hold the permission the job needed (for example
        realm.data.export for a realm export) when the token is redeemed; a refusal does not consume the token.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - requester
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                download_token:
                  type: string
                  x-secret: true
              required:
                - download_token
              additionalProperties: false
      responses:
        '200':
          description: >-
            The decrypted job result. Audit and realm data exports are NDJSON (application/x-ndjson, filename
            export.ndjson); other results are one JSON document (application/json, filename export.json).
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
            Content-Disposition:
              schema:
                type: string
              description: attachment; filename="export.json" or filename="export.ndjson"
          content:
            application/json:
              schema: {}
            application/x-ndjson:
              schema:
                type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/impersonation-requests:
    post:
      operationId: requestSupportAccess
      tags:
        - Support access
      summary: Request support access
      description: Human operators only.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImpersonationRequestInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImpersonationRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/impersonation-requests/{id}/approve:
    post:
      operationId: approveSupportAccess
      tags:
        - Support access
      summary: Approve support access
      description: Independent eligible approver (user) required. Any request body is ignored.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/impersonation-requests/{id}/issue:
    post:
      operationId: issueSupportAccess
      tags:
        - Support access
      summary: Issue an approved support grant
      description: Human operators only. Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImpersonationIssued'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/impersonation-grants:
    get:
      operationId: listSupportGrants
      tags:
        - Support access
      summary: List support grants
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - support.impersonation.read (otherwise only the caller's own grants)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: ticket_reference
          in: query
          required: false
          schema:
            type: string
          description: Only grants whose request carried this ticket reference (IMP-023).
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: actor_user_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by operator (forced to the caller without support.impersonation.read).
        - name: target_user_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by target user.
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by organization.
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: Filter by state.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ImpersonationGrant'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/impersonation-grants/{id}/revoke:
    post:
      operationId: revokeSupportGrant
      tags:
        - Support access
      summary: End a support grant
      description: 'Note: the body is decoded leniently (decode errors are ignored).'
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: >-
          Optional JSON body. This handler ignores decoding errors, so malformed or unknown members are silently
          dropped.
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/impersonation-grants/{id}/handoffs:
    post:
      operationId: createSupportHandoff
      tags:
        - Support access
      summary: Create a destination-bound support entry code
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                destination_client_id:
                  type: string
              required:
                - destination_client_id
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  handoff_code:
                    type: string
                    x-secret: true
                    description: >-
                      Single-use handoff code for the destination backend. Returned exactly once; it is never stored in
                      plaintext, never shown again and never replayed from the idempotency store.
                  expires_at:
                    type: string
                    format: date-time
                required:
                  - handoff_code
                  - expires_at
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/impersonation-handoffs/redeem:
    post:
      operationId: redeemSupportHandoff
      tags:
        - Support access
      summary: Redeem a support entry code
      description: >-
        Called by the registered destination backend (confidential client). Public clients are rejected (401). Errors
        use problem details.
      security:
        - clientSecretBasic: []
        - {}
      x-trust-class: resource-server
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                  description: Client identifier (client_secret_post, private_key_jwt or public clients).
                client_secret:
                  type: string
                  format: password
                  description: client_secret_post credential. Prefer client_secret_basic.
                client_assertion_type:
                  type: string
                  const: urn:ietf:params:oauth:client-assertion-type:jwt-bearer
                client_assertion:
                  type: string
                  description: private_key_jwt assertion (audience is the endpoint URL).
                handoff_code:
                  type: string
                  x-secret: true
              required:
                - handoff_code
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImpersonationIssued'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/webhooks:
    get:
      operationId: listWebhooks
      tags:
        - Webhooks
      summary: List webhook subscriptions
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by organization.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WebhookSubscription'
                  event_types:
                    type: array
                    items:
                      type: string
                    description: Subscribable event types.
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createWebhook
      tags:
        - Webhooks
      summary: Create a webhook subscription
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  subscription:
                    $ref: '#/components/schemas/WebhookSubscription'
                  signing_secret:
                    type: string
                    x-secret: true
                    description: >-
                      Webhook signing secret. Returned exactly once; it is never stored in plaintext, never shown again
                      and never replayed from the idempotency store.
                  notice:
                    type: string
                required:
                  - subscription
                  - signing_secret
                  - notice
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/webhooks/{id}:
    get:
      operationId: getWebhook
      tags:
        - Webhooks
      summary: Get a webhook subscription
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSubscription'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateWebhook
      tags:
        - Webhooks
      summary: Update a webhook subscription
      description: >-
        Partial update: absent fields keep their current values. A state-only change (pause, resume, disable) does not
        re-resolve the destination. The organization of a subscription cannot change.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchOptional'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              additionalProperties: false
              properties:
                allow_private_network:
                  type: boolean
                destination_url:
                  type: string
                  format: uri
                  description: HTTPS destination subject to the operator egress policy.
                event_types:
                  items:
                    type: string
                  type:
                    - array
                    - 'null'
                  minItems: 1
                  description: Event types from the catalog in api/events (also returned by GET /webhooks as event_types).
                name:
                  type: string
                event_version:
                  type: integer
                  enum:
                    - 1
                    - 2
                  description: Event schema version (EXT-018).
                payload_form:
                  type: string
                  enum:
                    - minimal
                    - standard
                state:
                  type: string
                  enum:
                    - active
                    - paused
                    - disabled
              type: object
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookSubscription'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteWebhook
      tags:
        - Webhooks
      summary: Delete a webhook subscription
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/webhooks/{id}/rotate-secret:
    post:
      operationId: rotateWebhookSecret
      tags:
        - Webhooks
      summary: Rotate the signing secret
      description: The previous secret remains valid (dual signatures) for 24 hours. Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  signing_secret:
                    type: string
                    x-secret: true
                    description: >-
                      New webhook signing secret. Returned exactly once; it is never stored in plaintext, never shown
                      again and never replayed from the idempotency store.
                  previous_secret_valid_for_seconds:
                    type: integer
                    const: 86400
                required:
                  - signing_secret
                  - previous_secret_valid_for_seconds
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/webhooks/{id}/deliveries:
    get:
      operationId: listWebhookDeliveries
      tags:
        - Webhooks
      summary: Delivery history
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WebhookDelivery'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/webhooks/{id}/deliveries/{delivery}/replay:
    post:
      operationId: replayWebhookDelivery
      tags:
        - Webhooks
      summary: Retry a delivery
      description: Redelivers with the stable original event ID. Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_delivery'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/user-imports:
    post:
      operationId: importUsers
      tags:
        - Imports and exports
      summary: Start a bulk user import (asynchronous)
      description: Creates a user.import job. The Idempotency-Key is also bound to the job.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                format:
                  type: string
                  default: proudauth.user-import.v1
                  description: >-
                    The records format (MIG-002); an unsupported format is refused with 422. GET /user-import-formats
                    lists the formats.
                source_system:
                  type: string
                  minLength: 1
                users:
                  type: array
                  items:
                    type: object
                    additionalProperties: true
                  minItems: 1
                  maxItems: 1000
                  description: User records; see api/schemas/user-import.schema.json.
                dry_run:
                  type: boolean
                trust_email_verification:
                  type: boolean
                verification_reason:
                  type: string
                  minLength: 10
                  description: >-
                    Required with trust_email_verification, which also requires realm.users.verification.override
                    (USR-005).
                allow_owner_roles:
                  type: boolean
                import_totp:
                  type: boolean
                  description: >-
                    Authorizes importing totp_secret seeds (MIG-007). Requires realm.users.credentials.manage and an MFA
                    session; without it, a record carrying totp_secret fails. Seeds are base32 (80 to 512 bits),
                    re-encrypted under this deployment's keys and audited as mfa.totp.imported.
              required:
                - source_system
                - users
              additionalProperties: false
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_id:
                    type: string
                  dry_run:
                    type: boolean
                required:
                  - job_id
                  - dry_run
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/configuration/exports:
    post:
      operationId: exportConfiguration
      tags:
        - Configuration
      summary: Export realm configuration (asynchronous)
      description: Creates a config.export job. Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.configuration.export
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobAccepted'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/configuration/validate:
    post:
      operationId: validateConfiguration
      tags:
        - Configuration
      summary: Validate a configuration document
      description: >-
        No mutation. Requires realm.configuration.import. Returns the plan the import would act on, with status 200 even
        when it lists errors: besides validation errors it reports a policy change without expected_policy_revision and
        every change the caller lacks the authority for through the API (realm.settings.write, realm.clients.write,
        realm.resources.write, realm.roles.write), so a plan never shows as valid what the import would refuse.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.configuration.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: mode
          in: query
          required: false
          schema:
            type: string
            enum:
              - reconcile
          description: >-
            reconcile (SDK-012): existing clients, resources and role permissions that differ from the document are
            planned as updates and applied (never deleted); without it they are reported as drift only.
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConfigDocument'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfigPlan'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/configuration/imports:
    post:
      operationId: importConfiguration
      tags:
        - Configuration
      summary: Reconcile a configuration document
      description: >-
        Creates missing objects; existing objects are reported unchanged, or with ?mode=reconcile existing clients,
        resources and role permissions that differ are updated (never deleted; resource members the document omits keep
        their values); a client whose client_type differs and that would be updated is a plan error (a type never
        changes). Every change needs the authority it needs through the API (realm.settings.write, realm.clients.write,
        realm.resources.write, realm.roles.write): an import without it is refused with 403, and ?dry_run=true reports
        it in the plan (422). A policy change needs expected_policy_revision. Users need recent authentication. The
        import is atomic: every change commits or none does.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.configuration.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: mode
          in: query
          required: false
          schema:
            type: string
            enum:
              - reconcile
          description: >-
            reconcile (SDK-012): existing clients, resources and role permissions that differ from the document are
            planned as updates and applied (never deleted); without it they are reported as drift only.
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
        - name: dry_run
          in: query
          required: false
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
          description: With true, only the plan is returned.
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConfigDocument'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    title: Applied
                    properties:
                      plan:
                        $ref: '#/components/schemas/ConfigPlan'
                      applied:
                        type:
                          - array
                          - 'null'
                        items:
                          type: string
                    required:
                      - plan
                      - applied
                  - $ref: '#/components/schemas/ConfigPlan'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          description: >-
            The plan contains errors; nothing was applied. The body is the ConfigPlan (application/json), not a problem
            document, unless request decoding failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConfigPlan'
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/notification-settings:
    get:
      operationId: getNotificationSettings
      tags:
        - Notifications
      summary: Get delivery settings
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: >-
            An organization's sender settings instead of the realm's; the ETag then covers them (for PATCH with
            organization_id).
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  sender_address:
                    type:
                      - string
                      - 'null'
                  sender_name:
                    type:
                      - string
                      - 'null'
                  reply_to:
                    type:
                      - string
                      - 'null'
                  default_locale:
                    type:
                      - string
                      - 'null'
                  adapter:
                    type: string
                required:
                  - sender_address
                  - sender_name
                  - reply_to
                  - default_locale
                  - adapter
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    patch:
      operationId: updateNotificationSettings
      tags:
        - Notifications
      summary: Update delivery settings
      description: 'Note: despite PATCH, every field is written (omitted fields are cleared; default_locale falls back to en).'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                sender_address:
                  type: string
                sender_name:
                  type: string
                reply_to:
                  type: string
                default_locale:
                  type: string
                organization_id:
                  type: string
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/templates:
    get:
      operationId: listTemplates
      tags:
        - Notifications
      summary: List active templates
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/NotificationTemplate'
                  variables:
                    type: object
                    additionalProperties:
                      type: array
                      items:
                        type: string
                    description: Template event type -> allowed variables.
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: upsertTemplate
      tags:
        - Notifications
      summary: Create or replace a template
      description: Disables the previous active template for the same organization, event type and locale.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                organization_id:
                  type: string
                event_type:
                  type: string
                locale:
                  type: string
                  description: Defaults to en.
                subject:
                  type: string
                body_text:
                  type: string
                body_html:
                  type: string
              required:
                - event_type
                - subject
                - body_text
              additionalProperties: false
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                required:
                  - id
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/templates/{id}:
    delete:
      operationId: disableTemplate
      tags:
        - Notifications
      summary: Disable a template
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/notification-tests:
    post:
      operationId: sendNotificationTest
      tags:
        - Notifications
      summary: Send a test message to the caller's verified email
      description: Any request body is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_id:
                    type: string
                  note:
                    type: string
                required:
                  - job_id
                  - note
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/notification-jobs:
    get:
      operationId: listNotificationJobs
      tags:
        - Notifications
      summary: List notification jobs
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - name: reference_type
          in: query
          required: false
          schema:
            type: string
          description: Filter by reference type.
        - name: reference_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by reference ID.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/NotificationJob'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /health/live:
    get:
      operationId: live
      tags:
        - Health
      summary: Process liveness
      description: >-
        Never touches dependencies. Health probes draw on the reserved administrative request pool, so 503 indicates
        severe overload.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: ok
                required:
                  - status
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /health/ready:
    get:
      operationId: ready
      tags:
        - Health
      summary: Readiness
      description: Checks the database, schema version and signing-key availability. Discloses no configuration details.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    const: ready
                required:
                  - status
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          description: Database unavailable, schema behind, or an active realm has no usable signing key.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - unavailable
                      - degraded
                required:
                  - status
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
  /api/v1/realms/{realm}/policies:
    get:
      operationId: listPolicies
      tags:
        - Authorization
      summary: List authorization policies
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Policy'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createPolicy
      tags:
        - Authorization
      summary: Create a policy with its first staged revision
      description: >-
        Policies are typed, bounded restrictions evaluated after RBAC: they can deny or add obligations but never grant
        (AZ-013, AZ-015). Missing attributes fail closed.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PolicyCreate'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  policy:
                    $ref: '#/components/schemas/Policy'
                  version:
                    $ref: '#/components/schemas/PolicyVersion'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}:
    get:
      operationId: getPolicy
      tags:
        - Authorization
      summary: Get a policy
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Policy'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}/versions:
    get:
      operationId: listPolicyVersions
      tags:
        - Authorization
      summary: List immutable policy revisions
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/PolicyVersion'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: stagePolicyVersion
      tags:
        - Authorization
      summary: Stage a new revision
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                definition:
                  $ref: '#/components/schemas/PolicyDefinition'
                note:
                  type: string
                  maxLength: 500
              required:
                - definition
              additionalProperties: false
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyVersion'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}/versions/{version}:
    get:
      operationId: getPolicyVersion
      tags:
        - Authorization
      summary: Get one revision
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/Path_version'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyVersion'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}/versions/{version}/approve:
    post:
      operationId: approvePolicyVersion
      tags:
        - Authorization
      summary: Approve a staged revision
      description: The author cannot approve their own revision (AZ-018). Requires recent authentication.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/Path_version'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyVersion'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}/versions/{version}/publish:
    post:
      operationId: publishPolicyVersion
      tags:
        - Authorization
      summary: Publish a revision
      description: >-
        Policies with requires_approval publish only independently approved revisions. Other nodes observe the change
        within 5 seconds (AZ-019).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/Path_version'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Policy'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}/rollback:
    post:
      operationId: rollbackPolicy
      tags:
        - Authorization
      summary: Restore a previously published revision
      description: Creates and publishes a new revision with the old content; history is never rewritten (AZ-017).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                to_version:
                  type: integer
                  minimum: 1
              required:
                - to_version
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Policy'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}/state:
    post:
      operationId: setPolicyState
      tags:
        - Authorization
      summary: Enable or disable evaluation
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                state:
                  type: string
                  enum:
                    - active
                    - disabled
              required:
                - state
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/policies/{policy}/diff:
    get:
      operationId: diffPolicyVersions
      tags:
        - Authorization
      summary: Human-readable diff between revisions
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/RequestId'
        - name: from
          in: query
          required: true
          schema:
            type: integer
        - name: to
          in: query
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  from:
                    type: integer
                  to:
                    type: integer
                  diff:
                    type: string
                    description: Line diff of the canonical definitions ("+ " added, "- " removed).
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/authorization/simulate:
    post:
      operationId: simulateAuthorization
      tags:
        - Authorization
      summary: Simulate decisions against a candidate policy revision
      description: >-
        Evaluates each check with the active policies and, when a candidate is given, with the candidate in place of the
        policy active revision. Simulations are not audited as decisions.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.authorization.simulate
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                policy:
                  type: string
                  description: Policy ID or name whose active revision the candidate replaces.
                version:
                  type: integer
                  description: Revision to simulate (when no definition is given).
                definition:
                  $ref: '#/components/schemas/PolicyDefinition'
                checks:
                  type: array
                  maxItems: 100
                  items:
                    $ref: '#/components/schemas/DecisionRequest'
              required:
                - checks
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        current:
                          $ref: '#/components/schemas/Decision'
                        candidate:
                          $ref: '#/components/schemas/Decision'
                        changed:
                          type: boolean
                  changed:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/me/remembered-devices:
    get:
      operationId: listRememberedDevices
      tags:
        - Self-service
      summary: List remembered devices
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/RememberedDevice'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: revokeAllRememberedDevices
      tags:
        - Self-service
      summary: Forget every remembered device
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  revoked:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/remembered-devices/{id}:
    delete:
      operationId: revokeRememberedDevice
      tags:
        - Self-service
      summary: Forget one remembered device
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/auth/transactions/{id}/remember-device:
    post:
      operationId: rememberDeviceStep
      tags:
        - Interaction
      summary: Opt in to remembering this device
      description: >-
        After a genuine second factor completes the transaction, a remembered-device secret is issued: browsers receive
        it as the HttpOnly pa_rd cookie, headless callers in one_time.remembered_device_token, to send later as
        X-Remembered-Device. It skips the MFA prompt only where realm policy allows and never raises assurance
        (AUT-013).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                remember:
                  type: boolean
              required:
                - remember
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/role-assignment-requests:
    get:
      operationId: listRoleAssignmentRequests
      tags:
        - Authorization
      summary: List role assignment approval requests
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AssignmentRequest'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/role-assignment-requests/{id}/approve:
    post:
      operationId: approveRoleAssignmentRequest
      tags:
        - Authorization
      summary: Approve a role assignment request
      description: >-
        The approver is the authenticated caller; requester and subject cannot approve, and the approver must be able to
        grant the role (AZ-018). Requires recent authentication.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - authority to grant the role (checked by the authorization service)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignmentRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/role-assignment-requests/{id}/reject:
    post:
      operationId: rejectRoleAssignmentRequest
      tags:
        - Authorization
      summary: Reject a role assignment request
      description: >-
        The approver is the authenticated caller; requester and subject cannot approve, and the approver must be able to
        grant the role (AZ-018). Requires recent authentication.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - authority to grant the role (checked by the authorization service)
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignmentRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/role-assignment-requests/{id}/approve:
    post:
      operationId: approveRoleAssignmentRequestOrg
      tags:
        - Authorization
      summary: Approve a role assignment request
      description: >-
        The approver is the authenticated caller; requester and subject cannot approve, and the approver must be able to
        grant the role (AZ-018). Requires recent authentication.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignmentRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/role-assignment-requests/{id}/reject:
    post:
      operationId: rejectRoleAssignmentRequestOrg
      tags:
        - Authorization
      summary: Reject a role assignment request
      description: >-
        The approver is the authenticated caller; requester and subject cannot approve, and the approver must be able to
        grant the role (AZ-018). Requires recent authentication.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignmentRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/auth/transactions/{id}/account:
    post:
      operationId: selectAccountStep
      tags:
        - Interaction
      summary: Answer prompt=select_account
      description: Offered as the select_account action when prompt=select_account meets an existing SSO session (OIDC-005).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                continue:
                  type: boolean
                  description: true keeps the signed-in account; false switches to signing in as someone else.
              required:
                - continue
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/auth/transactions/{id}/transient:
    post:
      operationId: transientSessionStep
      tags:
        - Interaction
      summary: Request a transient session
      description: >-
        A transient session lasts at most one hour, uses a browser-session cookie and never yields refresh tokens
        (SES-020).
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                transient:
                  type: boolean
              required:
                - transient
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/session-events:
    get:
      operationId: readSessionEvents
      tags:
        - Events
      summary: Read the session and access change stream
      description: >-
        At-least-once, gap-free stream ordered by commit horizon: events of still-open transactions are withheld, so an
        advancing cursor never skips a later-committing event (SES-019). Types: session.revoked,
        user.suspended/locked/deleted/password_reset/recovery_restricted, security.refresh_reuse_detected,
        security.credential_compromised, organization.membership.removed/suspended, organization.suspended/deleted,
        authorization.role.unassigned, support.impersonation.ended, client.state_changed, signing_key.rotated. History
        is retained 7 days after dispatch; a cursor followed by events that were pruned returns 410 cursor_expired (a
        caught-up cursor on a quiet realm stays valid), and the consumer resynchronizes by reading the retained history
        from its beginning (no cursor).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.session_events.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: cursor
          in: query
          required: false
          schema:
            type: string
          description: Position from a previous next_cursor (empty = beginning of retained history).
        - name: from
          in: query
          required: false
          schema:
            type: string
            enum:
              - now
          description: Return only the current head position, to start following from now.
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 500
        - name: wait
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            maximum: 25
          description: Long-poll seconds when no events are available.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  events:
                    type: array
                    items:
                      type: object
                      properties:
                        event_id:
                          type: string
                        event_type:
                          type: string
                        occurred_at:
                          type: string
                          format: date-time
                        organization_id:
                          type: string
                        data:
                          type: object
                          description: Identifiers and states only.
                        cursor:
                          type: string
                  next_cursor:
                    type: string
                required:
                  - events
                  - next_cursor
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '410':
          $ref: '#/components/responses/Gone'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/hooks:
    get:
      operationId: listHooks
      tags:
        - Extensions
      summary: List pre-action hooks with health
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.hooks.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Hook'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createHook
      tags:
        - Extensions
      summary: Register a pre-action hook
      description: >-
        Pre-action hooks are signed (Webhook-Id/Timestamp/Signature), egress-controlled, time-bounded calls.
        Security-decision hooks always fail closed; only token.claims hooks may use failure_mode skip. Hooks cannot
        grant access, skip authentication or set reserved claims (EXT-009..EXT-012).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.hooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HookInput'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  hook:
                    $ref: '#/components/schemas/Hook'
                  signing_secret:
                    type: string
                    x-secret: true
                    description: Returned once.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/hooks/{id}:
    get:
      operationId: getHook
      tags:
        - Extensions
      summary: Get a hook
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.hooks.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Hook'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: updateHook
      tags:
        - Extensions
      summary: Update a hook
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.hooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchRequired'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/HookInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Hook'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteHook
      tags:
        - Extensions
      summary: Delete a hook
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.hooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/activity:
    get:
      operationId: getAccountActivity
      tags:
        - Self-service
      summary: Account activity summary
      description: >-
        Recent sign-ins, sessions, authenticator activity, security changes and support access for the caller (USR-019).
        Other principals are reported only by type; metadata is allowlisted. Query parameter days (1-365, default 30)
        bounds the window.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: days
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 365
            default: 30
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  since:
                    type: string
                    format: date-time
                  sign_ins:
                    type: array
                    items:
                      $ref: '#/components/schemas/ActivityEvent'
                  sessions:
                    type: array
                    items:
                      type: object
                  authenticators:
                    type: array
                    items:
                      type: object
                  security_changes:
                    type: array
                    items:
                      $ref: '#/components/schemas/ActivityEvent'
                  support_access:
                    type: array
                    items:
                      $ref: '#/components/schemas/ActivityEvent'
                required:
                  - since
                  - sign_ins
                  - sessions
                  - authenticators
                  - security_changes
                  - support_access
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/invitations/batch:
    post:
      operationId: createInvitationBatch
      tags:
        - Invitations
      summary: Create invitations in bulk
      description: >-
        Validates and creates up to 100 invitations independently (INV-011). Each entry has its own result; one failure
        never rolls back the others; delivery is queued per invitation. Shared links are not accepted in batches.
        Retrying with the same Idempotency-Key replays the original results.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.invites.create
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                items:
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    $ref: '#/components/schemas/InvitationInput'
              required:
                - items
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  batch_id:
                    type: string
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/InvitationBatchResult'
                required:
                  - batch_id
                  - results
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/invitations/{id}/reassign:
    post:
      operationId: reassignInvitation
      tags:
        - Invitations
      summary: Reassign a pending invitation to a new target
      description: >-
        Administrator-reviewed reassignment (INV-014): the pending invitation is revoked and superseded by a fresh
        invitation for the new address or account, re-validated against current roles, ceilings and domain policy.
        Requires org.invites.revoke as well and a review reason, which is audited.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.invites.create
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                user_id:
                  type: string
                reason:
                  type: string
                  minLength: 3
                  maxLength: 500
                locale:
                  type: string
              required:
                - reason
              additionalProperties: false
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  invitation:
                    $ref: '#/components/schemas/Invitation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/projects/{project}/grants:
    get:
      operationId: listProjectGrants
      tags:
        - Projects
      summary: List project grants
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProjectGrant'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createProjectGrant
      tags:
        - Projects
      summary: Delegate project roles to an organization
      description: >-
        Lets a non-owning organization invite users to the listed project roles (INV-012). allowed_role_ids is the
        organization ceiling for the project.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                organization_id:
                  type: string
                allowed_role_ids:
                  type: array
                  maxItems: 50
                  items:
                    type: string
                valid_until:
                  type: string
                  format: date-time
              required:
                - organization_id
              additionalProperties: false
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectGrant'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/projects/{project}/grants/{id}/revoke:
    post:
      operationId: revokeProjectGrant
      tags:
        - Projects
      summary: Revoke a project grant
      description: >-
        Revokes the grant and removes project role assignments made through it in the same transaction. Any request body
        is ignored.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/sessions/{id}:
    delete:
      operationId: revokeUserSession
      tags:
        - Users
      summary: Revoke one session of a user
      description: >-
        Revokes a single session (SES-003) with its grants, refresh families and opaque tokens; back-channel logout is
        queued. Audited as session.revoked_by_admin.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.sessions.revoke
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/members/{membership}/permissions:
    get:
      operationId: inspectMemberPermissions
      tags:
        - Organizations
      summary: Inspect a member's effective permissions
      description: >-
        Scoped administrator inspection (AZ-009): the member's effective permissions in this organization with
        provenance. Realm-level grants are reported without role names; policy definitions are never included.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_membership'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EffectivePermissions'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/identity-providers:
    get:
      operationId: listOrganizationIdentityProviders
      tags:
        - Federation
      summary: List the organization's connections
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/IdentityProvider'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createOrganizationIdentityProvider
      tags:
        - Federation
      summary: Create an organization connection
      description: >-
        Organization-scoped federation connections managed by organization administrators (TEN-007). The connection is
        always scoped to the path organization; trusted-email linking is limited to the organization's verified domains;
        trust_upstream_mfa requires a realm administrator. Writes require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdentityProviderInput'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityProvider'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/identity-providers/{id}:
    get:
      operationId: getOrganizationIdentityProvider
      tags:
        - Federation
      summary: Get an organization connection
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityProvider'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: updateOrganizationIdentityProvider
      tags:
        - Federation
      summary: Update an organization connection
      description: >-
        Organization-scoped federation connections managed by organization administrators (TEN-007). The connection is
        always scoped to the path organization; trusted-email linking is limited to the organization's verified domains;
        trust_upstream_mfa requires a realm administrator. Writes require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchRequired'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdentityProviderInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdentityProvider'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteOrganizationIdentityProvider
      tags:
        - Federation
      summary: Delete an organization connection
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/projects/{project}/ownership-transfer:
    post:
      operationId: transferProject
      tags:
        - Projects
      summary: Transfer project ownership
      description: >-
        Changes the accountable owner user and/or owning organization (APP-001) with an audited reason.
        owner_organization_id '-' clears the organization owner. Honors If-Match.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner_user_id:
                  type: string
                owner_organization_id:
                  type: string
                reason:
                  type: string
                  minLength: 3
              required:
                - reason
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Project'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/projects/{project}/applications:
    get:
      operationId: listProjectApplications
      tags:
        - Projects
      summary: List a project's clients, resources and organization grants
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  clients:
                    type: array
                    items:
                      type: object
                  resources:
                    type: array
                    items:
                      type: object
                  organization_grants:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProjectGrant'
                required:
                  - clients
                  - resources
                  - organization_grants
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/impersonation-requests/{id}/deny:
    post:
      operationId: denyImpersonationRequest
      tags:
        - Support
      summary: Deny or withdraw a support-access request
      description: >-
        Allowed for the requesting operator (withdraw) and for whoever may approve under the request policy: the
        customer, a second operator or an organization owner (IMP-022). Unrelated callers receive 404.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/impersonation-requests:
    get:
      operationId: listMyPendingSupportRequests
      tags:
        - Self-service
      summary: Support-access requests awaiting my approval
      description: >-
        Requests whose policy requires the customer's approval (IMP-022), with the stated reason and ticket. The
        operator is not identified.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        organization_id:
                          type: string
                        mode:
                          type: string
                        scopes:
                          type: array
                          items:
                            type: string
                        reason:
                          type: string
                        ticket_reference:
                          type: string
                        created_at:
                          type: string
                          format: date-time
                        expires_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/credential-inventory/revocations:
    post:
      operationId: revokeInventoryCredentials
      tags:
        - Machines
      summary: Revoke credentials in bulk
      description: >-
        Revokes up to 100 API keys, personal tokens (akc_) and client secrets (ccr_) found in the inventory (MCH-016).
        Each is revoked in its own transaction with its own audit record; per-item permissions (realm.api_keys.manage,
        realm.clients.credentials) apply. Results are per item.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.credentials.inventory
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ids:
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    type: string
                reason:
                  type: string
                  minLength: 3
              required:
                - ids
                - reason
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        status:
                          type: string
                          enum:
                            - revoked
                            - failed
                        error:
                          type: string
                  reason:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/notification-preferences:
    get:
      operationId: getNotificationPreferences
      tags:
        - Self-service
      summary: Optional notice preferences
      description: >-
        Only optional notices (currently new_login) can be muted; security and account notices are always delivered
        (MSG-010).
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  preferences:
                    type: object
                    additionalProperties:
                      type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: setNotificationPreferences
      tags:
        - Self-service
      summary: Update optional notice preferences
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                preferences:
                  type: object
                  additionalProperties:
                    type: boolean
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  preferences:
                    type: object
                    additionalProperties:
                      type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/delivery-events:
    post:
      operationId: recordDeliveryEvents
      tags:
        - Notifications
      summary: Provider delivery feedback
      description: >-
        Bounce and complaint callbacks from the email provider (MSG-007). Authenticated with a Standard Webhooks
        signature (Webhook-Id, Webhook-Timestamp, Webhook-Signature) over the raw body using
        delivery.email.events_secret; disabled (404) when no secret is configured. Permanent bounces and complaints
        suppress optional mail to the address; feedback never verifies or changes an identity.
      security: []
      x-trust-class: signed-provider-callback
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                events:
                  type: array
                  minItems: 1
                  maxItems: 500
                  items:
                    type: object
                    properties:
                      type:
                        type: string
                        enum:
                          - delivered
                          - bounce
                          - complaint
                      recipient:
                        type: string
                      provider_message_id:
                        type: string
                      permanent:
                        type: boolean
                    required:
                      - type
              required:
                - events
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  applied:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/notification-settings/check:
    post:
      operationId: checkNotificationDelivery
      tags:
        - Notifications
      summary: Check delivery configuration
      description: >-
        Connects to the configured SMTP server, negotiates TLS and authenticates without sending (MSG-012). Only the
        failing stage is returned; server responses and credentials go to the operator log.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.notifications.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  ok:
                    type: boolean
                  stage:
                    type: string
                    enum:
                      - ok
                      - connect
                      - greeting
                      - starttls
                      - credentials
                      - authentication
                      - not_applicable
                  email_adapter:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/assisted-recoveries/{id}/approve:
    post:
      operationId: approveAssistedRecovery
      tags:
        - Users
      summary: Approve a scheduled assisted recovery
      description: >-
        Independent second-operator approval when the realm sets recovery.require_approval (MFA-009). Neither the
        requesting operator nor the account owner may approve.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - support.recovery.assist or realm.users.credentials.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/assisted-recoveries:
    get:
      operationId: listMyAssistedRecoveries
      tags:
        - Self-service
      summary: Scheduled assisted recoveries of my account
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/assisted-recoveries/{id}/cancel:
    post:
      operationId: cancelMyAssistedRecovery
      tags:
        - Self-service
      summary: Cancel a scheduled assisted recovery
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/registration-approvals:
    get:
      operationId: listRegistrationApprovals
      tags:
        - Users
      summary: List queued self-registrations
      description: >-
        Registrations queued by registration.require_approval (REG-008). Email addresses are masked. Filter with state
        (pending, approved, denied, expired).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.registrations.review
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        user_id:
                          type: string
                        email_hint:
                          type: string
                        state:
                          type: string
                        reviewer_id:
                          type: string
                        reason:
                          type: string
                        expires_at:
                          type: string
                          format: date-time
                        decided_at:
                          type: string
                          format: date-time
                        created_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/registration-approvals/{id}/decision:
    post:
      operationId: decideRegistration
      tags:
        - Users
      summary: Approve or deny a queued registration
      description: >-
        Denial suspends the account. The applicant is notified; undecided reviews expire after 14 days and the account
        stays suspended.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.registrations.review
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                approve:
                  type: boolean
                reason:
                  type: string
              required:
                - approve
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/auth/transactions/{id}/guest:
    post:
      operationId: continueAsGuest
      tags:
        - Authentication
      summary: Continue as a guest
      description: >-
        Creates a low-privilege guest identity when registration.allow_guests is enabled (REG-010). Guests hold no
        organization membership or roles and are refused any context that requires MFA or an organization; assurance is
        urn:proudauth:acr:anonymous. Rate-limited like self-registration. Any request body is ignored.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/upgrade:
    post:
      operationId: upgradeGuest
      tags:
        - Self-service
      summary: Upgrade a guest account
      description: >-
        Sets a password and adds the email address unverified (REG-010). The account stops being a guest when the
        address is verified through POST /verification-challenges; the response is identical for addresses that already
        belong to another account, and verifying such an address fails, so nothing is linked or merged.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                password:
                  type: string
                  x-secret: true
              required:
                - email
                - password
              additionalProperties: false
      responses:
        '202':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  identifier_id:
                    type: string
                  next:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/merges:
    post:
      operationId: proposeAccountMerge
      tags:
        - Users
      summary: Propose merging an account into this one
      description: >-
        USR-011: records a reviewed plan and notifies both owners. Requires an MFA session. The account in the path
        survives.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                source_user_id:
                  type: string
                reason:
                  type: string
                  minLength: 10
              required:
                - source_user_id
                - reason
              additionalProperties: false
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  survivor_id:
                    type: string
                  source_id:
                    type: string
                  reason:
                    type: string
                  plan:
                    type: object
                    description: >-
                      Reviewed effect: identifiers and federation links to move, organizations joined with the member
                      role only, source roles listed for review (never copied), credentials not transferred.
                  survivor_confirmed_at:
                    type: string
                    format: date-time
                  source_confirmed_at:
                    type: string
                    format: date-time
                  state:
                    type: string
                    enum:
                      - pending
                      - completed
                      - cancelled
                      - expired
                  expires_at:
                    type: string
                    format: date-time
                  created_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/account-merges/{id}/execute:
    post:
      operationId: executeAccountMerge
      tags:
        - Users
      summary: Execute a confirmed merge
      description: >-
        Requires both owners' confirmation and an MFA session. Moves identifiers and federation links, joins
        organizations with the member role only, ends all sessions of both accounts, deletes the source as an alias of
        the survivor and publishes user.merged.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  survivor_id:
                    type: string
                  source_id:
                    type: string
                  reason:
                    type: string
                  plan:
                    type: object
                    description: >-
                      Reviewed effect: identifiers and federation links to move, organizations joined with the member
                      role only, source roles listed for review (never copied), credentials not transferred.
                  survivor_confirmed_at:
                    type: string
                    format: date-time
                  source_confirmed_at:
                    type: string
                    format: date-time
                  state:
                    type: string
                    enum:
                      - pending
                      - completed
                      - cancelled
                      - expired
                  expires_at:
                    type: string
                    format: date-time
                  created_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/subject-aliases/{id}:
    get:
      operationId: getSubjectAlias
      tags:
        - Users
      summary: Resolve a merged-away subject
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  alias_id:
                    type: string
                  user_id:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/account-merges:
    get:
      operationId: listMyAccountMerges
      tags:
        - Self-service
      summary: Merges involving my account
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/account-merges/{id}/confirm:
    post:
      operationId: confirmAccountMerge
      tags:
        - Self-service
      summary: Confirm a merge of my account
      description: Requires recent authentication. Each account owner confirms separately.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/auth/transactions/{id}/registration:
    post:
      operationId: registerInTransaction
      tags:
        - Authentication
      summary: Register a new account in this transaction
      description: >-
        Browser form of POST /registrations (REG-001): the transaction cookie is scoped to this transaction's path, so
        login UIs register here with the same Origin and CSRF checks as every other step. The response is identical
        whether or not the address already belongs to an account.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              additionalProperties: false
              properties:
                display_name:
                  type: string
                email:
                  type: string
                family_name:
                  type: string
                given_name:
                  type: string
                invitation:
                  type: string
                  x-secret: true
                  description: Invitation secret to accept during registration.
                locale:
                  type: string
                organization:
                  oneOf:
                    - $ref: '#/components/schemas/OrganizationInput'
                    - type: 'null'
                password:
                  type: string
                  format: password
                profile:
                  additionalProperties: {}
                  type:
                    - object
                    - 'null'
                terms_version:
                  type: string
                username:
                  type: string
              type: object
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/emergency/controls:
    get:
      operationId: getEmergencyControls
      tags:
        - Administration
      summary: List active emergency controls
      description: >-
        Grant classes switched off realm-wide and the clients, identity providers, organizations, service principals,
        hooks and webhooks currently disabled (SEC-020). Each list holds at most 200 IDs.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.emergency
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  realm_state:
                    type: string
                  disabled_grant_types:
                    type: array
                    items:
                      type: string
                  suspended_clients:
                    type: array
                    items:
                      type: string
                  disabled_identity_providers:
                    type: array
                    items:
                      type: string
                  suspended_organizations:
                    type: array
                    items:
                      type: string
                  disabled_service_principals:
                    type: array
                    items:
                      type: string
                  disabled_hooks:
                    type: array
                    items:
                      type: string
                  disabled_webhooks:
                    type: array
                    items:
                      type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: applyEmergencyControl
      tags:
        - Administration
      summary: Disable or re-enable a client, provider, organization, extension or grant class
      description: >-
        One audited emergency surface (SEC-020): the change takes effect at once, is recorded in the emergency audit
        category with the reason, and raises the emergency_action security signal. A disabled grant class is refused at
        the authorization, device authorization and token endpoints (unauthorized_client) and no refresh tokens are
        minted while refresh_token is disabled; the operator CLI client (proudauth-cli) is exempt so the control can
        always be reversed. Disabling a client suspends it and revokes its grants; disabling an organization suspends
        it. Signing keys use emergency rotation instead.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.emergency
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - target_type
                - target_id
                - action
                - reason
              properties:
                target_type:
                  type: string
                  enum:
                    - grant_type
                    - client
                    - identity_provider
                    - organization
                    - service_principal
                    - hook
                    - webhook
                target_id:
                  type: string
                  description: >-
                    The object ID, or for grant_type one of authorization_code, refresh_token, client_credentials,
                    urn:ietf:params:oauth:grant-type:device_code, urn:ietf:params:oauth:grant-type:token-exchange.
                action:
                  type: string
                  enum:
                    - disable
                    - enable
                reason:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  target_type:
                    type: string
                  target_id:
                    type: string
                  state:
                    type: string
                    enum:
                      - disabled
                      - enabled
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/account-merges/{id}/cancel:
    post:
      operationId: cancelAccountMerge
      tags:
        - Users
      summary: Cancel a pending merge
      description: >-
        Withdraws a pending proposal (user.merge.cancelled). Lapsed proposals expire on their own and never block a new
        proposal for the same account.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/account-merges/{id}/decline:
    post:
      operationId: declineAccountMerge
      tags:
        - Self-service
      summary: Decline a merge of my account
      description: >-
        Either account owner can decline a pending merge (user.merge.declined); the administrator may propose again
        later.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/lifecycle/preview:
    get:
      operationId: previewUserLifecycle
      tags:
        - Users
      summary: Preview account lifecycle jobs (dry run)
      description: >-
        What the next lifecycle run would do (USR-015): abandoned unverified registrations and unused guests are
        deleted, dormant accounts are reported or suspended per lifecycle.dormant_action, and scheduled deactivations
        suspend the account. Shows the number due and up to 20 sample account IDs per rule; nothing changes. The worker
        applies at most batch_size accounts per rule per run, re-checking each one.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  dry_run:
                    type: boolean
                  batch_size:
                    type: integer
                  rules:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          enum:
                            - unverified_expired
                            - dormant
                            - guest_expired
                            - scheduled_deactivation
                        action:
                          type: string
                          enum:
                            - delete
                            - report
                            - suspend
                        due:
                          type: integer
                        sample_user_ids:
                          type: array
                          items:
                            type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/scheduled-deactivation:
    put:
      operationId: scheduleUserDeactivation
      tags:
        - Users
      summary: Schedule an account deactivation
      description: >-
        At the given time the lifecycle job suspends the account (reason scheduled_deactivation), ending its sessions.
        Audited as user.deactivation_scheduled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - at
              properties:
                at:
                  type: string
                  format: date-time
                reason:
                  type: string
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  user_id:
                    type: string
                  deactivate_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: cancelUserDeactivation
      tags:
        - Users
      summary: Cancel a scheduled deactivation
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.suspend
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/user-bulk-operations:
    post:
      operationId: createUserBulkOperation
      tags:
        - Users
      summary: Apply one action to many accounts
      description: >-
        Runs as a checkpointed user.bulk job (USR-016): each account is validated and changed in its own transaction,
        protected accounts and the requester are skipped for suspend and lock, and the job result reports only account
        IDs with outcome (applied, valid, skipped, failed) and a stable code. Permissions: realm.users.suspend for
        suspend, reactivate and lock; realm.users.sessions.revoke for revoke_sessions; realm.users.required_actions for
        add_required_action; all re-checked when the job runs. Requires an MFA session. dry_run validates without
        changing anything; Idempotency-Key returns the same job for a retried submission.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - action
                - user_ids
                - reason
              properties:
                action:
                  type: string
                  enum:
                    - suspend
                    - reactivate
                    - lock
                    - revoke_sessions
                    - add_required_action
                user_ids:
                  type: array
                  minItems: 1
                  maxItems: 1000
                  uniqueItems: true
                  items:
                    type: string
                reason:
                  type: string
                  minLength: 5
                  maxLength: 500
                required_action:
                  type: string
                  description: The required action to add (add_required_action only).
                dry_run:
                  type: boolean
      responses:
        '202':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_id:
                    type: string
                  dry_run:
                    type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/external-ids:
    get:
      operationId: listUserExternalIds
      tags:
        - Users
      summary: List an account's external IDs
      description: >-
        Connector-scoped IDs (USR-017), including mappings recorded by user imports. External IDs are unique only within
        their source system.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        source_system:
                          type: string
                        external_id:
                          type: string
                        job_id:
                          type: string
                        created_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/external-ids/{source}:
    put:
      operationId: setUserExternalId
      tags:
        - Users
      summary: Set an account's ID in a source system
      description: >-
        Replaces the previous value in that system; a value mapped to another account in the same system conflicts
        (409). Audited as user.external_id.set.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/Path_source'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - external_id
              properties:
                external_id:
                  type: string
                  minLength: 1
                  maxLength: 256
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  source_system:
                    type: string
                  external_id:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: removeUserExternalId
      tags:
        - Users
      summary: Remove an account's ID in a source system
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/Path_source'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/external-ids/{source}/{id}:
    get:
      operationId: resolveExternalId
      tags:
        - Users
      summary: Resolve an external ID to an account
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_source'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  source_system:
                    type: string
                  external_id:
                    type: string
                  user_id:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/consents:
    get:
      operationId: listUserConsents
      tags:
        - Users
      summary: List a user's consents
      description: >-
        Consent records with client, scopes, resources, terms version, mode (user or preauthorized), grant and
        revocation times (APP-013).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/QueryHistory'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Consent'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/consents/{id}:
    delete:
      operationId: revokeUserConsent
      tags:
        - Users
      summary: Revoke a user's consent
      description: Ends the client's grants for the user; audited as consent.revoked.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/clients/{client}/consent-preauthorizations:
    get:
      operationId: listConsentPreauthorizations
      tags:
        - Clients
      summary: List consent pre-authorizations
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        client:
                          type: string
                        organization_id:
                          type: string
                        scopes:
                          type: array
                          items:
                            type: string
                        terms_version:
                          type: string
                        reason:
                          type: string
                        granted_by_id:
                          type: string
                        granted_at:
                          type: string
                          format: date-time
                        revoked_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createConsentPreauthorization
      tags:
        - Clients
      summary: Pre-authorize a client on behalf of users
      description: >-
        Administrative consent (APP-013) for the client's current terms version, realm-wide or for one organization.
        Users signing in are not asked for the covered scopes; their consent is recorded with mode preauthorized.
        offline_access always needs the user's own consent.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - scopes
                - reason
              properties:
                organization_id:
                  type: string
                  description: Limit the pre-authorization to users signing in to this organization; omit for the whole realm.
                scopes:
                  type: array
                  minItems: 1
                  maxItems: 50
                  items:
                    type: string
                reason:
                  type: string
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  client:
                    type: string
                  organization_id:
                    type: string
                  scopes:
                    type: array
                    items:
                      type: string
                  terms_version:
                    type: string
                  reason:
                    type: string
                  granted_by_id:
                    type: string
                  granted_at:
                    type: string
                    format: date-time
                  revoked_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/clients/{client}/consent-preauthorizations/{id}:
    delete:
      operationId: revokeConsentPreauthorization
      tags:
        - Clients
      summary: Revoke a consent pre-authorization
      description: Also revokes every consent recorded under it and the grants built on those consents.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/join-requests/{id}/reviewers:
    post:
      operationId: assignJoinReviewers
      tags:
        - Organizations
      summary: Assign reviewers to a join request
      description: >-
        Only the assigned reviewers (or a member administrator) may then decide (INV-013). Every reviewer must hold
        org.join_requests.review in the organization and none may be the requester; assignees are notified without the
        requester being named.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.members.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - reviewer_ids
              properties:
                reviewer_ids:
                  type: array
                  minItems: 1
                  maxItems: 10
                  items:
                    type: string
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/join-requests/{id}/withdraw:
    post:
      operationId: withdrawJoinRequest
      tags:
        - Self-service
      summary: Withdraw my join request
      description: Ends a pending request and releases its pending_approval membership.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/join-requests:
    get:
      operationId: listMyJoinRequests
      tags:
        - Self-service
      summary: List my join requests
      description: Organization, state and dates only; reviewers and other requests are never shown.
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/JoinRequest'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/notification-settings/smtp:
    get:
      operationId: getOrganizationSMTP
      tags:
        - Organizations
      summary: Read the organization's own mail server
      description: Customer-owned mail server (TEN-022); the password is never returned (has_password says whether one is stored).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  host:
                    type: string
                  port:
                    type: integer
                    enum:
                      - 25
                      - 465
                      - 587
                      - 2525
                  username:
                    type: string
                  tls_mode:
                    type: string
                    enum:
                      - starttls
                      - implicit
                  has_password:
                    type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: setOrganizationSMTP
      tags:
        - Organizations
      summary: Set the organization's own mail server
      description: >-
        The organization's mail is then sent through this server. TLS is required (starttls or implicit). The password
        is encrypted and bound to the realm and organization, so it can only be used for this organization's mail;
        connections go only to addresses the delivery egress policy allows. Requires an MFA session; audited as
        notification.smtp.updated without the secret.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - host
                - port
                - tls_mode
              properties:
                host:
                  type: string
                port:
                  type: integer
                  enum:
                    - 25
                    - 465
                    - 587
                    - 2525
                username:
                  type: string
                  maxLength: 256
                tls_mode:
                  type: string
                  enum:
                    - starttls
                    - implicit
                password:
                  type: string
                  format: password
                  x-secret: true
                  description: Omit to keep the stored password. Never returned.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  host:
                    type: string
                  port:
                    type: integer
                    enum:
                      - 25
                      - 465
                      - 587
                      - 2525
                  username:
                    type: string
                  tls_mode:
                    type: string
                    enum:
                      - starttls
                      - implicit
                  has_password:
                    type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: clearOrganizationSMTP
      tags:
        - Organizations
      summary: Remove the organization's own mail server
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organization-templates:
    get:
      operationId: listOrganizationTemplates
      tags:
        - Organizations
      summary: List organization templates
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.organizations.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/QueryTemplateName'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                        version:
                          type: integer
                        description:
                          type: string
                        document:
                          type: object
                          additionalProperties: false
                          properties:
                            policy:
                              type: object
                              description: Organization policy (same members as the organization policy object).
                            roles:
                              type: array
                              maxItems: 50
                              items:
                                type: object
                                additionalProperties: false
                                required:
                                  - name
                                  - permissions
                                properties:
                                  name:
                                    type: string
                                    maxLength: 100
                                  description:
                                    type: string
                                  permissions:
                                    type: array
                                    minItems: 1
                                    maxItems: 100
                                    items:
                                      type: string
                            groups:
                              type: array
                              maxItems: 50
                              items:
                                type: object
                                additionalProperties: false
                                required:
                                  - name
                                properties:
                                  name:
                                    type: string
                                    maxLength: 200
                                  description:
                                    type: string
                                  role_names:
                                    type: array
                                    maxItems: 20
                                    items:
                                      type: string
                            service_principals:
                              type: array
                              maxItems: 20
                              description: >-
                                Organization-owned service principals, named <organization slug>-<name>, with
                                organization roles. Credentials are never issued by a template. Applying needs
                                org.service_principals.write.
                              items:
                                type: object
                                additionalProperties: false
                                required:
                                  - name
                                properties:
                                  name:
                                    type: string
                                    pattern: ^[a-z0-9][a-z0-9-]{0,62}$
                                  description:
                                    type: string
                                    maxLength: 500
                                  role_names:
                                    type: array
                                    maxItems: 20
                                    items:
                                      type: string
                            webhooks:
                              type: array
                              maxItems: 20
                              description: >-
                                Webhook subscriptions scoped to the organization (https destinations checked against the
                                egress policy; no private networks). Applying needs org.integrations.write; each new
                                subscription signing secret is returned once in webhook_secrets.
                              items:
                                type: object
                                additionalProperties: false
                                required:
                                  - name
                                  - destination_url
                                  - event_types
                                properties:
                                  name:
                                    type: string
                                    maxLength: 200
                                  destination_url:
                                    type: string
                                    format: uri
                                    pattern: ^https://
                                  event_types:
                                    type: array
                                    minItems: 1
                                    items:
                                      type: string
                                  payload_form:
                                    type: string
                                    enum:
                                      - minimal
                                      - standard
                                    default: minimal
                        created_by_id:
                          type: string
                        created_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: saveOrganizationTemplate
      tags:
        - Organizations
      summary: Save a new organization template version
      description: >-
        Versioned onboarding templates (TEN-017): policy, custom roles, groups with their roles, organization-owned
        service principals with their roles, and organization webhooks. Template roles cannot carry realm or support
        permissions. Each save creates the next version; versions are immutable.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.organizations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - name
                - document
              properties:
                name:
                  type: string
                  pattern: ^[a-z0-9][a-z0-9-]{0,62}$
                description:
                  type: string
                document:
                  type: object
                  additionalProperties: false
                  properties:
                    policy:
                      type: object
                      description: Organization policy (same members as the organization policy object).
                    roles:
                      type: array
                      maxItems: 50
                      items:
                        type: object
                        additionalProperties: false
                        required:
                          - name
                          - permissions
                        properties:
                          name:
                            type: string
                            maxLength: 100
                          description:
                            type: string
                          permissions:
                            type: array
                            minItems: 1
                            maxItems: 100
                            items:
                              type: string
                    groups:
                      type: array
                      maxItems: 50
                      items:
                        type: object
                        additionalProperties: false
                        required:
                          - name
                        properties:
                          name:
                            type: string
                            maxLength: 200
                          description:
                            type: string
                          role_names:
                            type: array
                            maxItems: 20
                            items:
                              type: string
                    service_principals:
                      type: array
                      maxItems: 20
                      description: >-
                        Organization-owned service principals, named <organization slug>-<name>, with organization
                        roles. Credentials are never issued by a template. Applying needs org.service_principals.write.
                      items:
                        type: object
                        additionalProperties: false
                        required:
                          - name
                        properties:
                          name:
                            type: string
                            pattern: ^[a-z0-9][a-z0-9-]{0,62}$
                          description:
                            type: string
                            maxLength: 500
                          role_names:
                            type: array
                            maxItems: 20
                            items:
                              type: string
                    webhooks:
                      type: array
                      maxItems: 20
                      description: >-
                        Webhook subscriptions scoped to the organization (https destinations checked against the egress
                        policy; no private networks). Applying needs org.integrations.write; each new subscription
                        signing secret is returned once in webhook_secrets.
                      items:
                        type: object
                        additionalProperties: false
                        required:
                          - name
                          - destination_url
                          - event_types
                        properties:
                          name:
                            type: string
                            maxLength: 200
                          destination_url:
                            type: string
                            format: uri
                            pattern: ^https://
                          event_types:
                            type: array
                            minItems: 1
                            items:
                              type: string
                          payload_form:
                            type: string
                            enum:
                              - minimal
                              - standard
                            default: minimal
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  name:
                    type: string
                  version:
                    type: integer
                  description:
                    type: string
                  document:
                    type: object
                    additionalProperties: false
                    properties:
                      policy:
                        type: object
                        description: Organization policy (same members as the organization policy object).
                      roles:
                        type: array
                        maxItems: 50
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - name
                            - permissions
                          properties:
                            name:
                              type: string
                              maxLength: 100
                            description:
                              type: string
                            permissions:
                              type: array
                              minItems: 1
                              maxItems: 100
                              items:
                                type: string
                      groups:
                        type: array
                        maxItems: 50
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - name
                          properties:
                            name:
                              type: string
                              maxLength: 200
                            description:
                              type: string
                            role_names:
                              type: array
                              maxItems: 20
                              items:
                                type: string
                      service_principals:
                        type: array
                        maxItems: 20
                        description: >-
                          Organization-owned service principals, named <organization slug>-<name>, with organization
                          roles. Credentials are never issued by a template. Applying needs
                          org.service_principals.write.
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - name
                          properties:
                            name:
                              type: string
                              pattern: ^[a-z0-9][a-z0-9-]{0,62}$
                            description:
                              type: string
                              maxLength: 500
                            role_names:
                              type: array
                              maxItems: 20
                              items:
                                type: string
                      webhooks:
                        type: array
                        maxItems: 20
                        description: >-
                          Webhook subscriptions scoped to the organization (https destinations checked against the
                          egress policy; no private networks). Applying needs org.integrations.write; each new
                          subscription signing secret is returned once in webhook_secrets.
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - name
                            - destination_url
                            - event_types
                          properties:
                            name:
                              type: string
                              maxLength: 200
                            destination_url:
                              type: string
                              format: uri
                              pattern: ^https://
                            event_types:
                              type: array
                              minItems: 1
                              items:
                                type: string
                            payload_form:
                              type: string
                              enum:
                                - minimal
                                - standard
                              default: minimal
                  created_by_id:
                    type: string
                  created_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/template-applications:
    post:
      operationId: applyOrganizationTemplate
      tags:
        - Organizations
      summary: Apply an organization template
      description: >-
        Plans (dry_run) or applies a template version in one transaction. Missing roles, groups, group grants, service
        principals, their grants and webhooks are created with the caller's authority (delegation ceilings apply;
        service principals need org.service_principals.write and webhooks org.integrations.write, otherwise the plan
        lists a conflict); a differing policy is replaced; existing roles with other permissions are conflicts, never
        rewritten, and a non-dry-run application with conflicts fails with 409. Grants that direct assignment (POST
        /role-assignments) would hold for an independent approver (a role that requires approval, or a privileged role
        for an agent service principal, MCH-017) are conflicts too ("... needs an independent approver: assign it
        through POST /role-assignments"); once such a grant is approved directly, the template reports it unchanged.
        Re-applying is idempotent. Audited as organization.template.applied.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.update
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - template
              properties:
                template:
                  type: string
                version:
                  type: integer
                  minimum: 1
                  description: Omit for the latest version.
                dry_run:
                  type: boolean
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  template:
                    type: string
                  version:
                    type: integer
                  create:
                    type: array
                    items:
                      type: string
                  update:
                    type: array
                    items:
                      type: string
                  unchanged:
                    type: array
                    items:
                      type: string
                  conflicts:
                    type: array
                    items:
                      type: string
                  applied:
                    type: boolean
                  webhook_secrets:
                    type: object
                    additionalProperties:
                      type: string
                    description: >-
                      Signing secret of each webhook this application created, by name; shown once (Cache-Control
                      no-store, never replayed for an Idempotency-Key).
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/groups/{group}/dynamic-rule:
    get:
      operationId: getGroupDynamicRule
      tags:
        - Organizations
      summary: Read a group's dynamic membership rule
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  rule:
                    type: object
                    additionalProperties: false
                    required:
                      - all
                    properties:
                      all:
                        type: array
                        minItems: 1
                        maxItems: 5
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - attribute
                          properties:
                            attribute:
                              type: string
                              description: A profile attribute users cannot edit themselves.
                            equals:
                              type: string
                            in:
                              type: array
                              maxItems: 20
                              items:
                                type: string
                  recomputed_at:
                    type: string
                    format: date-time
                  member_count:
                    type: integer
                  error:
                    type: string
                    description: Set when the rule no longer validates; rule-derived members are then removed.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: setGroupDynamicRule
      tags:
        - Organizations
      summary: Make a group dynamic
      description: >-
        Derives members from authoritative attributes (TEN-014): active members whose profile matches every condition.
        Attributes users can edit are refused, so nobody joins by editing their own profile. The caller must be able to
        assign every role the group grants. Manual members are removed, manual changes are then refused (409), and the
        worker recomputes every 10 minutes (groups.dynamic). A rule that stops validating fails closed.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - all
              properties:
                all:
                  type: array
                  minItems: 1
                  maxItems: 5
                  items:
                    type: object
                    additionalProperties: false
                    required:
                      - attribute
                    properties:
                      attribute:
                        type: string
                        description: A profile attribute users cannot edit themselves.
                      equals:
                        type: string
                      in:
                        type: array
                        maxItems: 20
                        items:
                          type: string
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  rule:
                    type: object
                    additionalProperties: false
                    required:
                      - all
                    properties:
                      all:
                        type: array
                        minItems: 1
                        maxItems: 5
                        items:
                          type: object
                          additionalProperties: false
                          required:
                            - attribute
                          properties:
                            attribute:
                              type: string
                              description: A profile attribute users cannot edit themselves.
                            equals:
                              type: string
                            in:
                              type: array
                              maxItems: 20
                              items:
                                type: string
                  recomputed_at:
                    type: string
                    format: date-time
                  member_count:
                    type: integer
                  error:
                    type: string
                    description: Set when the rule no longer validates; rule-derived members are then removed.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: clearGroupDynamicRule
      tags:
        - Organizations
      summary: Make a group static again
      description: Keeps the current members as rule-derived until removed by hand.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.groups.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_group'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/aliases:
    get:
      operationId: listOrganizationAliases
      tags:
        - Organizations
      summary: List an organization's aliases
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: addOrganizationAlias
      tags:
        - Organizations
      summary: Add an organization alias
      description: >-
        Aliases (TEN-011) resolve wherever an organization slug is accepted and cannot be another organization's slug or
        alias (409). A renamed organization keeps its former slug as an alias automatically.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.update
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - alias
              properties:
                alias:
                  type: string
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/aliases/{alias}:
    delete:
      operationId: removeOrganizationAlias
      tags:
        - Organizations
      summary: Remove an organization alias
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.update
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_alias'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/audit-legal-holds:
    get:
      operationId: listAuditLegalHolds
      tags:
        - Audit
      summary: List audit legal holds
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.legal_hold
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        organization_id:
                          type: string
                        subject_id:
                          type: string
                        reason:
                          type: string
                        created_by_id:
                          type: string
                        created_at:
                          type: string
                          format: date-time
                        released_by_id:
                          type: string
                        released_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: placeAuditLegalHold
      tags:
        - Audit
      summary: Place an audit legal hold
      description: >-
        Events matching an active hold (realm, optionally one organization and/or one subject as subject or actor) are
        never removed by retention (AUD-009). Requires an MFA session; audited as audit.legal_hold.placed.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.legal_hold
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - reason
              properties:
                organization_id:
                  type: string
                  description: Hold one organization's evidence; omit for the whole realm.
                subject_id:
                  type: string
                  description: Hold evidence about or by one subject.
                reason:
                  type: string
                  minLength: 5
                  maxLength: 500
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  organization_id:
                    type: string
                  subject_id:
                    type: string
                  reason:
                    type: string
                  created_by_id:
                    type: string
                  created_at:
                    type: string
                    format: date-time
                  released_by_id:
                    type: string
                  released_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/audit-legal-holds/{id}/release:
    post:
      operationId: releaseAuditLegalHold
      tags:
        - Audit
      summary: Release an audit legal hold
      description: Retention applies to the held events again from the next run.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.legal_hold
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/activity-events:
    post:
      operationId: reportApplicationActivity
      tags:
        - Audit
      summary: Report application activity
      description: >-
        Services (not users) report their own activity into the audit log (AUD-013). Reported events carry source
        application, the reporting service (client ID) and category application, use the app. type namespace so they can
        never pass for server-generated evidence, and are sealed into the same hash chain.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - realm.activity.report
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - type
              properties:
                type:
                  type: string
                  pattern: ^app\.[a-z0-9_.]{1,96}$
                occurred_at:
                  type: string
                  format: date-time
                  description: Within the last 24 hours (and at most 5 minutes ahead); defaults to now.
                organization_id:
                  type: string
                subject:
                  type: object
                  additionalProperties: false
                  properties:
                    type:
                      type: string
                      enum:
                        - user
                        - service_principal
                    id:
                      type: string
                outcome:
                  type: string
                  enum:
                    - success
                    - failure
                    - denied
                metadata:
                  type: object
                  description: At most 4 KiB; secret-like keys are redacted before storage.
      responses:
        '202':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  source:
                    type: string
                    enum:
                      - application
                  reporting_service:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/webhooks/{id}/backlog:
    get:
      operationId: getWebhookBacklog
      tags:
        - Webhooks
      summary: Read a subscription's delivery backlog
      description: >-
        Per-destination backlog (EXT-005): deliveries by state, the age of the oldest due delivery, the last successful
        delivery and the last failure category.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  pending:
                    type: integer
                  retrying:
                    type: integer
                  dead_letter:
                    type: integer
                  delivered:
                    type: integer
                  oldest_due_seconds:
                    type: integer
                  last_delivered_at:
                    type: string
                    format: date-time
                  last_failure_category:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/hooks/{id}/diagnostics:
    get:
      operationId: getHookDiagnostics
      tags:
        - Hooks
      summary: Read a hook's recent invocations
      description: >-
        Extension diagnostics (EXT-017): the last 100 invocations with outcome, latency and a coarse error category,
        plus health and latency percentiles. Payloads, responses and secrets are never recorded; records are kept for 7
        days.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.hooks.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  health:
                    type: string
                    enum:
                      - healthy
                      - degraded
                      - unknown
                  recent_invocations:
                    type: integer
                  recent_failures:
                    type: integer
                  latency_p50_ms:
                    type: integer
                  latency_p95_ms:
                    type: integer
                  invocations:
                    type: array
                    items:
                      type: object
                      properties:
                        invoked_at:
                          type: string
                          format: date-time
                        outcome:
                          type: string
                          enum:
                            - ok
                            - failure
                        latency_ms:
                          type: integer
                        error_category:
                          type: string
                          enum:
                            - status
                            - egress_denied
                            - timeout
                            - malformed_response
                            - unreachable
                            - error
                        status_code:
                          type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/user-import-formats:
    get:
      operationId: listUserImportFormats
      tags:
        - Imports and exports
      summary: List supported user import formats
      description: >-
        The import formats this release accepts (MIG-002), each with the source products it covers, its schema, what it
        carries over and what it cannot. POST /user-imports declares one in format; compatibility is never inferred from
        source_system.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        format:
                          type: string
                        source_products:
                          type: array
                          items:
                            type: string
                        schema:
                          type: string
                        supports:
                          type: array
                          items:
                            type: string
                        unsupported:
                          type: array
                          items:
                            type: string
                      required:
                        - format
                        - source_products
                        - schema
                        - supports
                        - unsupported
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/user-imports/reconciliation:
    get:
      operationId: reconcileUserImport
      tags:
        - Imports and exports
      summary: Reconcile imported users with the source
      description: >-
        Counts what the realm holds now for the users imported from one source_system (MIG-012): accounts by state,
        memberships, privileged assignments, sign-in methods and verified emails. Expected counts from the source
        export, given as expected_* parameters, are compared and every difference is listed in mismatches. Returns no
        credentials or contact data. 404 when nothing was imported from the source.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: source_system
          in: query
          required: true
          schema:
            type: string
          description: The source_system of the imports.
        - name: expected_users
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
          description: Expected number of (non-deleted) accounts.
        - name: expected_memberships
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
          description: Expected number of active memberships.
        - name: expected_privileged_assignments
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
          description: Expected number of privileged role assignments.
        - name: expected_password_verifiers
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
          description: Expected number of accounts with a password.
        - name: expected_totp_factors
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
          description: Expected number of accounts with TOTP.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  source_system:
                    type: string
                  generated_at:
                    type: string
                    format: date-time
                  mappings:
                    type: object
                    description: >-
                      Import mappings of the source system, total and by current account state (deleted for accounts
                      deleted since import, missing when the account row no longer exists).
                    properties:
                      total:
                        type: integer
                      by_state:
                        type: object
                        additionalProperties:
                          type: integer
                  users:
                    type: integer
                    description: Mapped accounts that are not deleted.
                  memberships:
                    type: object
                    properties:
                      active:
                        type: integer
                      from_import:
                        type: integer
                      organizations:
                        type: integer
                  privileged_assignments:
                    type: object
                    description: >-
                      Role assignments of mapped accounts whose role is privileged (an owner role, a realm role, or a
                      role with a permission the catalog marks privileged, directly or through a composed role). At most
                      200 items.
                    properties:
                      total:
                        type: integer
                      truncated:
                        type: boolean
                      items:
                        type: array
                        items:
                          type: object
                          properties:
                            user_id:
                              type: string
                            source_id:
                              type: string
                            role:
                              type: string
                            scope_type:
                              type: string
                            scope_id:
                              type: string
                            assignment_source:
                              type: string
                  credentials:
                    type: object
                    description: >-
                      Accounts (not credentials) with each kind of sign-in method; without_sign_in_method counts
                      accounts with no password, passkey or federated link, which must recover or enroll.
                    properties:
                      password:
                        type: integer
                      password_not_yet_rehashed:
                        type: integer
                      totp:
                        type: integer
                      passkey:
                        type: integer
                      federated:
                        type: integer
                      without_sign_in_method:
                        type: integer
                  verified_emails:
                    type: integer
                  signed_in_since:
                    type: integer
                  subject_continuity:
                    type: object
                    properties:
                      resolvable_source_ids:
                        type: integer
                      deleted_since_import:
                        type: integer
                  mismatches:
                    type: array
                    items:
                      type: object
                      properties:
                        measure:
                          type: string
                          enum:
                            - users
                            - memberships
                            - privileged_assignments
                            - password_verifiers
                            - totp_factors
                        expected:
                          type: integer
                        actual:
                          type: integer
                  reconciled:
                    type: boolean
                    description: True when every expected_* count given matches.
                required:
                  - source_system
                  - mappings
                  - users
                  - memberships
                  - privileged_assignments
                  - credentials
                  - mismatches
                  - reconciled
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/audit-imports:
    post:
      operationId: importAuditHistory
      tags:
        - Audit
      summary: Import historical audit records
      description: >-
        Files historical events from a source system (MIG-016) apart from the evidence this server witnessed: they are
        never sealed into the local hash chain, are always reported with source import and verified false, and keep the
        source identifiers. Each record is checked on its own; the inserts and one local audit.history.imported event,
        which commits to the records through batch_digest, are stored together. Requires an MFA session. Imported
        records are kept for the retention period counted from the import (category imported of
        privacy.audit_retention_by_category, else privacy.audit_retention), subject to legal holds; deleting an account
        removes the metadata, source subject ID and actor display name of imported records about it.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                source_system:
                  type: string
                  pattern: ^[a-z0-9][a-z0-9._-]{0,62}$
                  description: >-
                    Source system name; subject_source_id values are mapped through the user import mappings of the same
                    name.
                events:
                  type: array
                  minItems: 1
                  maxItems: 500
                  items:
                    type: object
                    properties:
                      source_event_id:
                        type: string
                        minLength: 1
                        maxLength: 256
                        description: >-
                          The event ID in the source; a value already imported from the same source is a duplicate and
                          left unchanged.
                      occurred_at:
                        type: string
                        format: date-time
                        description: When the source says the event happened; any time in the past.
                      type:
                        type: string
                        pattern: ^[A-Za-z0-9][A-Za-z0-9_.:/-]{0,127}$
                        description: The source event type, kept as given.
                      organization:
                        type: string
                        description: Organization ID or slug in this realm.
                      actor:
                        type: object
                        properties:
                          type:
                            type: string
                            maxLength: 64
                          id:
                            type: string
                            maxLength: 256
                          display:
                            type: string
                            maxLength: 256
                        required:
                          - type
                        additionalProperties: false
                      subject_source_id:
                        type: string
                        maxLength: 256
                        description: The subject user ID in the source system.
                      outcome:
                        type: string
                        enum:
                          - success
                          - failure
                          - denied
                          - unknown
                        default: unknown
                      metadata:
                        type: object
                        additionalProperties: {}
                        description: At most 4 KiB of JSON.
                    required:
                      - source_event_id
                      - occurred_at
                      - type
                    additionalProperties: false
              required:
                - source_system
                - events
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  batch_id:
                    type: string
                  counts:
                    type: object
                    additionalProperties:
                      type: integer
                  batch_digest:
                    type: string
                    description: >-
                      Hex SHA-256 over the content_hash of every record imported by this request, in order; also
                      recorded in the local audit.history.imported event.
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        index:
                          type: integer
                        source_event_id:
                          type: string
                        status:
                          type: string
                          enum:
                            - imported
                            - duplicate
                            - error
                        id:
                          type: string
                        subject_id:
                          type: string
                        error:
                          type: string
                required:
                  - batch_id
                  - counts
                  - batch_digest
                  - results
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/imported-audit-events:
    get:
      operationId: listImportedAuditEvents
      tags:
        - Audit
      summary: List imported historical audit records
      description: >-
        Imported historical records (MIG-016), newest occurred_at first, at most 1000 per query before pagination. They
        are never returned by GET /audit-events.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
        - name: source_system
          in: query
          required: false
          schema:
            type: string
          description: Filter by source system.
        - name: subject_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by mapped local account.
        - name: organization_id
          in: query
          required: false
          schema:
            type: string
          description: Filter by organization.
        - name: type
          in: query
          required: false
          schema:
            type: string
          description: Exact source event type.
        - name: batch_id
          in: query
          required: false
          schema:
            type: string
          description: Records of one import request.
        - name: from
          in: query
          required: false
          schema:
            type: string
            format: date-time
          description: Earliest occurred_at (RFC 3339).
        - name: to
          in: query
          required: false
          schema:
            type: string
            format: date-time
          description: Occurred before (RFC 3339).
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        source:
                          type: string
                          enum:
                            - import
                        verified:
                          type: boolean
                          enum:
                            - false
                        source_system:
                          type: string
                        source_event_id:
                          type: string
                        occurred_at:
                          type: string
                          format: date-time
                        type:
                          type: string
                        organization_id:
                          type: string
                        actor:
                          type: object
                          properties:
                            type:
                              type: string
                            id:
                              type: string
                            display:
                              type: string
                        subject_id:
                          type: string
                          description: The local account mapped from source_subject_id when the record was imported.
                        source_subject_id:
                          type: string
                        outcome:
                          type: string
                        metadata:
                          type: object
                          additionalProperties: {}
                        content_hash:
                          type: string
                          description: Hex SHA-256 of the record as submitted.
                        batch_id:
                          type: string
                        imported_at:
                          type: string
                          format: date-time
                        imported_by:
                          type: object
                          properties:
                            type:
                              type: string
                            id:
                              type: string
                        redacted_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/deletion-status:
    get:
      operationId: getUserDeletionStatus
      tags:
        - Users
      summary: Report how an account deletion has propagated
      description: >-
        PRV-005: for a deleted account, the state of every place its data lived, derived from what is stored now:
        primary storage, sessions and grants, export results (until privacy.export_retention after the deletion),
        notification payloads and recipients, connectors (the user.deleted event and its webhook deliveries; pending
        while any is undelivered), imported audit history (pending while source-supplied details remain unredacted,
        which a legal hold keeps), caches (until the decision cache TTL, at least a minute), audit evidence (retained by
        ID until the longest applicable audit retention after the deletion: privacy.audit_retention, any
        privacy.audit_retention_by_category override and the realm's audit.retention_days; organization retention may
        keep their organization's events longer; with an active legal hold covering the account or the whole realm there
        is no until, as the hold keeps them until it is released; organization legal holds are mentioned in details) and
        backups (retained until privacy.backup_retention after the deletion, then done; unknown when it is not set;
        never reported erased early, and restore reconciliation re-applies the deletion). 404 for an unknown account;
        409 (with the extension state) when the account is not deleted.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  user_id:
                    type: string
                  deleted_at:
                    type: string
                    format: date-time
                  stages:
                    type: array
                    items:
                      type: object
                      properties:
                        stage:
                          type: string
                          enum:
                            - primary_storage
                            - sessions_and_grants
                            - exports
                            - notifications
                            - connectors
                            - imported_audit_history
                            - caches
                            - audit_evidence
                            - backups
                        state:
                          type: string
                          enum:
                            - done
                            - pending
                            - retained
                            - unknown
                        count:
                          type: integer
                        until:
                          type: string
                          format: date-time
                          description: When the stage is expected to finish (purge, retention or backup expiry).
                        details:
                          type: string
                      required:
                        - stage
                        - state
                        - details
                required:
                  - user_id
                  - deleted_at
                  - stages
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/custom-domains:
    get:
      operationId: listCustomDomains
      tags:
        - Realm
      summary: List custom domains
      description: >-
        Custom hostnames (DEP-014) on which the realm endpoints may be served besides the public origin. Under
        server.host_policy strict, only the public origin host and verified custom domains are served, each custom
        domain only for its own realm paths, and any other Host gets 421. A custom domain never changes the issuer or
        any subject: discovery and tokens keep the canonical issuer; cookies are per host; passkeys work there only when
        passkeys_usable is true.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        host:
                          type: string
                        state:
                          type: string
                          enum:
                            - pending
                            - verified
                        challenge_expires_at:
                          type: string
                          format: date-time
                        verified_at:
                          type: string
                          format: date-time
                        created_at:
                          type: string
                          format: date-time
                        passkeys_usable:
                          type: boolean
                          description: >-
                            True when the realm WebAuthn RP ID is this host or a parent domain, so the realm passkeys
                            work here.
                      required:
                        - id
                        - host
                        - state
                        - created_at
                        - passkeys_usable
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: addCustomDomain
      tags:
        - Realm
      summary: Add a custom domain
      description: >-
        Registers a host and returns a DNS TXT proof to publish at _proudauth-challenge.<host> within 7 days, then call
        verify. Requires an MFA session. Audited as realm.custom_domain.added.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                host:
                  type: string
                  description: A DNS name other than the public origin host.
              required:
                - host
              additionalProperties: false
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  domain:
                    type: object
                    properties:
                      id:
                        type: string
                      host:
                        type: string
                      state:
                        type: string
                        enum:
                          - pending
                          - verified
                      challenge_expires_at:
                        type: string
                        format: date-time
                      verified_at:
                        type: string
                        format: date-time
                      created_at:
                        type: string
                        format: date-time
                      passkeys_usable:
                        type: boolean
                        description: >-
                          True when the realm WebAuthn RP ID is this host or a parent domain, so the realm passkeys work
                          here.
                    required:
                      - id
                      - host
                      - state
                      - created_at
                      - passkeys_usable
                  dns_record_name:
                    type: string
                  dns_record_type:
                    type: string
                    enum:
                      - TXT
                  dns_record_value:
                    type: string
                required:
                  - domain
                  - dns_record_name
                  - dns_record_type
                  - dns_record_value
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/custom-domains/{id}/verify:
    post:
      operationId: verifyCustomDomain
      tags:
        - Realm
      summary: Verify a custom domain
      description: >-
        Checks the DNS TXT proof (_proudauth-challenge.<host>, looked up for at most 5 seconds); a verified host starts
        serving the realm under a strict host policy. A domain that is already verified is returned unchanged (200). 422
        when the record is missing or wrong. 409 when the challenge expired (remove and add the domain again), the
        domain was removed, another realm verified the same host first (field host), or the domain changed while it was
        being verified. Requires an MFA session. Audited as realm.custom_domain.verified.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  host:
                    type: string
                  state:
                    type: string
                    enum:
                      - pending
                      - verified
                  challenge_expires_at:
                    type: string
                    format: date-time
                  verified_at:
                    type: string
                    format: date-time
                  created_at:
                    type: string
                    format: date-time
                  passkeys_usable:
                    type: boolean
                    description: >-
                      True when the realm WebAuthn RP ID is this host or a parent domain, so the realm passkeys work
                      here.
                required:
                  - id
                  - host
                  - state
                  - created_at
                  - passkeys_usable
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/custom-domains/{id}:
    delete:
      operationId: removeCustomDomain
      tags:
        - Realm
      summary: Remove a custom domain
      description: Stops serving the realm on the host at once. Requires an MFA session. Audited as realm.custom_domain.removed.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/scim/v2/ServiceProviderConfig:
    get:
      operationId: scimServiceProviderConfig
      tags:
        - Provisioning
      summary: SCIM service provider configuration
      description: 'Advertises exactly what is implemented: PATCH, filtering and ETags; no bulk, sort or password change (PROV-009).'
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
  /api/v1/realms/{realm}/scim/v2/ResourceTypes:
    get:
      operationId: scimResourceTypes
      tags:
        - Provisioning
      summary: SCIM resource types
      description: Resource types the connector may use.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimListResponse'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
  /api/v1/realms/{realm}/scim/v2/Schemas:
    get:
      operationId: scimSchemas
      tags:
        - Provisioning
      summary: SCIM schemas
      description: Attributes stored for Users and Groups; other attributes are accepted and ignored.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimListResponse'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
  /api/v1/realms/{realm}/scim/v2/Users:
    get:
      operationId: scimListUsers
      tags:
        - Provisioning
      summary: List SCIM users
      description: >-
        Lists users provisioned by this connector in its organization. Supports filter (eq, ne, co, sw, ew, gt, ge, lt,
        le, pr, and, or, not, value paths), startIndex, count (at most 200), attributes and excludedAttributes.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/ScimFilter'
        - $ref: '#/components/parameters/ScimStartIndex'
        - $ref: '#/components/parameters/ScimCount'
        - $ref: '#/components/parameters/ScimAttributes'
        - $ref: '#/components/parameters/ScimExcludedAttributes'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimListResponse'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    post:
      operationId: scimCreateUser
      tags:
        - Provisioning
      summary: Create a SCIM user
      description: >-
        Provisions an account in the connector organization. An existing account is adopted only when its verified email
        is in a domain the organization has verified, and never when it is protected, privileged or mapped to another
        external ID (PROV-002, PROV-004).
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: SCIM JSON (application/scim+json or application/json); duplicate members are rejected.
        required: true
        content:
          application/scim+json:
            schema:
              $ref: '#/components/schemas/ScimUser'
          application/json:
            schema:
              $ref: '#/components/schemas/ScimUser'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
            Location:
              description: URL of the created resource.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
  /api/v1/realms/{realm}/scim/v2/Users/{id}:
    get:
      operationId: scimGetUser
      tags:
        - Provisioning
      summary: Get a SCIM user
      description: Returns a user provisioned by this connector.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimAttributes'
        - $ref: '#/components/parameters/ScimExcludedAttributes'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '304':
          description: Not Modified (If-None-Match matched the current ETag).
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    put:
      operationId: scimReplaceUser
      tags:
        - Provisioning
      summary: Replace a SCIM user
      description: >-
        Replaces the user. Identity attributes change only on accounts this connector owns; active maps to the
        organization membership state, never the account state (PROV-005).
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimIfMatch'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: SCIM JSON (application/scim+json or application/json); duplicate members are rejected.
        required: true
        content:
          application/scim+json:
            schema:
              $ref: '#/components/schemas/ScimUser'
          application/json:
            schema:
              $ref: '#/components/schemas/ScimUser'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    patch:
      operationId: scimPatchUser
      tags:
        - Provisioning
      summary: Patch a SCIM user
      description: Applies RFC 7644 PATCH operations (add, replace, remove; op names are case-insensitive).
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimIfMatch'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: SCIM JSON (application/scim+json or application/json); duplicate members are rejected.
        required: true
        content:
          application/scim+json:
            schema:
              $ref: '#/components/schemas/ScimPatchOp'
          application/json:
            schema:
              $ref: '#/components/schemas/ScimPatchOp'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    delete:
      operationId: scimDeleteUser
      tags:
        - Provisioning
      summary: Delete a SCIM user
      description: >-
        Removes the user from the connector organization only; the account and other memberships are untouched
        (PROV-005).
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimIfMatch'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
  /api/v1/realms/{realm}/scim/v2/Groups:
    get:
      operationId: scimListGroups
      tags:
        - Provisioning
      summary: List SCIM groups
      description: >-
        Lists groups provisioned by this connector in its organization. Supports filter (eq, ne, co, sw, ew, gt, ge, lt,
        le, pr, and, or, not, value paths), startIndex, count (at most 200), attributes and excludedAttributes.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/ScimFilter'
        - $ref: '#/components/parameters/ScimStartIndex'
        - $ref: '#/components/parameters/ScimCount'
        - $ref: '#/components/parameters/ScimAttributes'
        - $ref: '#/components/parameters/ScimExcludedAttributes'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimListResponse'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    post:
      operationId: scimCreateGroup
      tags:
        - Provisioning
      summary: Create a SCIM group
      description: >-
        Creates a group in the connector organization. Roles come only from the connector approved group mappings within
        its role ceiling (PROV-006). Members must be users this connector provisioned.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: SCIM JSON (application/scim+json or application/json); duplicate members are rejected.
        required: true
        content:
          application/scim+json:
            schema:
              $ref: '#/components/schemas/ScimGroup'
          application/json:
            schema:
              $ref: '#/components/schemas/ScimGroup'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
            Location:
              description: URL of the created resource.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
  /api/v1/realms/{realm}/scim/v2/Groups/{id}:
    get:
      operationId: scimGetGroup
      tags:
        - Provisioning
      summary: Get a SCIM group
      description: Returns a group provisioned by this connector.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimAttributes'
        - $ref: '#/components/parameters/ScimExcludedAttributes'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '304':
          description: Not Modified (If-None-Match matched the current ETag).
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    put:
      operationId: scimReplaceGroup
      tags:
        - Provisioning
      summary: Replace a SCIM group
      description: Replaces the group name and members.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimIfMatch'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: SCIM JSON (application/scim+json or application/json); duplicate members are rejected.
        required: true
        content:
          application/scim+json:
            schema:
              $ref: '#/components/schemas/ScimGroup'
          application/json:
            schema:
              $ref: '#/components/schemas/ScimGroup'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    patch:
      operationId: scimPatchGroup
      tags:
        - Provisioning
      summary: Patch a SCIM group
      description: Applies RFC 7644 PATCH operations (add, replace, remove; op names are case-insensitive).
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimIfMatch'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: SCIM JSON (application/scim+json or application/json); duplicate members are rejected.
        required: true
        content:
          application/scim+json:
            schema:
              $ref: '#/components/schemas/ScimPatchOp'
          application/json:
            schema:
              $ref: '#/components/schemas/ScimPatchOp'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              description: Weak entity tag of the resource version.
              schema:
                type: string
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/ScimResource'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
    delete:
      operationId: scimDeleteGroup
      tags:
        - Provisioning
      summary: Delete a SCIM group
      description: Deletes the group and its connector-sourced role assignments.
      security:
        - scimConnectorToken: []
      x-trust-class: provisioning
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/ScimIfMatch'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/ScimError'
        '401':
          $ref: '#/components/responses/ScimError'
        '403':
          $ref: '#/components/responses/ScimError'
        '404':
          $ref: '#/components/responses/ScimError'
        '409':
          $ref: '#/components/responses/ScimError'
        '412':
          $ref: '#/components/responses/ScimError'
        '429':
          $ref: '#/components/responses/ScimError'
        '500':
          $ref: '#/components/responses/ScimError'
  /api/v1/realms/{realm}/organizations/{org}/provisioning-connectors:
    get:
      operationId: listProvisioningConnectors
      tags:
        - Provisioning
      summary: List provisioning connectors
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProvisioningConnector'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createProvisioningConnector
      tags:
        - Provisioning
      summary: Create a provisioning connector
      description: >-
        Creates an inbound SCIM connector bound to the organization. The role ceiling must be within the creator own
        ceiling (PROV-003). The token is shown once. Requires an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProvisioningConnectorInput'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  connector:
                    $ref: '#/components/schemas/ProvisioningConnector'
                  token:
                    type: string
                    description: Connector bearer token (pa_scim_...), shown once.
                  scim_base_url:
                    type: string
                required:
                  - connector
                  - token
                  - scim_base_url
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/provisioning-connectors/{id}:
    get:
      operationId: getProvisioningConnector
      tags:
        - Provisioning
      summary: Get a provisioning connector
      description: 'Includes operational evidence: last_sync_at, last_error and per-operation stats (PROV-018).'
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProvisioningConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: updateProvisioningConnector
      tags:
        - Provisioning
      summary: Update a provisioning connector
      description: >-
        Replaces the connector settings; state disabled stops the token working at once. Requires If-Match and an MFA
        session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchRequired'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/ProvisioningConnectorInput'
                - type: object
                  properties:
                    state:
                      type: string
                      enum:
                        - active
                        - disabled
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProvisioningConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/provisioning-connectors/{id}/token:
    post:
      operationId: rotateProvisioningConnectorToken
      tags:
        - Provisioning
      summary: Rotate a connector token
      description: Issues a new token; the old one stops working at once. Requires an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                required:
                  - token
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/hooks/{id}/ownership-transfer:
    post:
      operationId: transferHookOwnership
      tags:
        - Hooks
      summary: Change the accountable owner of a pre-action hook
      description: >-
        DOM-009: sets owner_user_id (an active or recovery_restricted account of the realm) of a pre-action hook, also
        when it has none or its owner left; a plugin-managed part keeps its plugin (plugin_id). Audited as
        hook.ownership_transferred (metadata previous_owner_user_id, owner_user_id); the version moves. Honors If-Match.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.hooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner_user_id:
                  type: string
              required:
                - owner_user_id
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                type: object
                properties:
                  kind:
                    type: string
                    enum:
                      - hook
                  id:
                    type: string
                  owner_user_id:
                    type: string
                  previous_owner_user_id:
                    type: string
                    description: Empty when it had no owner.
                  version:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/webhooks/{id}/ownership-transfer:
    post:
      operationId: transferWebhookOwnership
      tags:
        - Webhooks
      summary: Change the accountable owner of a webhook subscription
      description: >-
        DOM-009: sets owner_user_id (an active or recovery_restricted account of the realm) of a webhook subscription,
        also when it has none or its owner left; a plugin-managed part keeps its plugin (plugin_id). Audited as
        webhook.ownership_transferred (metadata previous_owner_user_id, owner_user_id); the version moves. Honors
        If-Match.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.webhooks.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner_user_id:
                  type: string
              required:
                - owner_user_id
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                type: object
                properties:
                  kind:
                    type: string
                    enum:
                      - webhook
                  id:
                    type: string
                  owner_user_id:
                    type: string
                  previous_owner_user_id:
                    type: string
                    description: Empty when it had no owner.
                  version:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/policies/{policy}/ownership-transfer:
    post:
      operationId: transferPolicyOwnership
      tags:
        - Authorization
      summary: Change the accountable owner of an authorization policy
      description: >-
        DOM-009: sets owner_user_id (an active or recovery_restricted account of the realm) of an authorization policy,
        also when it has none or its owner left; a plugin-managed part keeps its plugin (plugin_id). Audited as
        authorization_policy.ownership_transferred (metadata previous_owner_user_id, owner_user_id); the version moves.
        Honors If-Match.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.policies.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_policy'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                owner_user_id:
                  type: string
              required:
                - owner_user_id
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                type: object
                properties:
                  kind:
                    type: string
                    enum:
                      - authorization_policy
                  id:
                    type: string
                  owner_user_id:
                    type: string
                  previous_owner_user_id:
                    type: string
                    description: Empty when it had no owner.
                  version:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/ownership-transfer:
    post:
      operationId: transferUserOwnership
      tags:
        - Users
      summary: Transfer everything a user owns
      description: >-
        Offboarding (USR-020): moves the projects, clients, service principals, resources, connections, pre-action
        hooks, webhook subscriptions and authorization policies the user owns to another active account (plugin-managed
        hooks and subscriptions keep their plugin); each move is audited as <kind>.ownership_transferred. Needs the
        write permission of every kind.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.projects.write
        - realm.clients.write
        - realm.service_principals.write
        - realm.resources.write
        - realm.identity_providers.write
        - realm.hooks.write
        - realm.webhooks.write
        - realm.policies.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                to_user_id:
                  type: string
              required:
                - to_user_id
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  transferred:
                    type: object
                    additionalProperties:
                      type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/audit-events/{id}/corrections:
    post:
      operationId: correctAuditEvent
      tags:
        - Audit
      summary: Record a correction to an audit event
      description: >-
        Evidence is never edited (AUD-007): the correction is a new audit.correction event targeting the original
        (target_id), with the reason and the corrected values; both stay queryable.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.correct
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
                  minLength: 5
                  maxLength: 1000
                correction:
                  type: object
                  additionalProperties: true
                  description: Corrected values, at most 8 KiB.
              required:
                - reason
              additionalProperties: false
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  event_id:
                    type: string
                  corrects_event_id:
                    type: string
                required:
                  - event_id
                  - corrects_event_id
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/invitations/{id}:
    get:
      operationId: getInvitation
      tags:
        - Invitations
      summary: Get an invitation
      description: One invitation of the organization with its state and an ETag (INV-001); the secret is never returned.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.invites.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Invitation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/data-exports:
    post:
      operationId: createRealmDataExport
      tags:
        - Imports and exports
      summary: Export the realm data
      description: >-
        Portable exit (OSS-008, MIG-014): a job (realm.export) writes the realm as NDJSON records {kind, data} with
        stable IDs - header (format proudauth.realm-export.v1 and the excluded list), configuration, user, organization,
        membership, group, role_assignment, authorization_policy, project, service_principal, identity_provider,
        webhook, hook. Credential secrets, keys, live tokens and audit evidence are excluded. Download through POST
        /jobs/{id}/downloads; the permission is re-checked when the job runs and at download.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.data.export
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '202':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_id:
                    type: string
                required:
                  - job_id
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ownership-report:
    get:
      operationId: getOwnershipReport
      tags:
        - Realm
      summary: Report objects without an accountable owner
      description: >-
        DOM-009, APP-014, MCH-007: live clients (with or without secrets), projects, service principals, resources,
        identity providers, webhooks, hooks and authorization policies that have no owner (no owner user, owning
        organization or client contacts) or whose owner is no longer active; flags ownerless and owner_departed.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        kind:
                          type: string
                        id:
                          type: string
                        name:
                          type: string
                        owner_user_id:
                          type: string
                        owner_organization_id:
                          type: string
                        flags:
                          type: array
                          items:
                            type: string
                            enum:
                              - ownerless
                              - owner_departed
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/clients/{client}/workload-trusts:
    get:
      operationId: listWorkloadTrusts
      tags:
        - Clients
      summary: List workload trusts
      description: >-
        Workload federation trusts of a client (MCH-011..MCH-013): external workload identity issuers whose assertions
        the client may exchange for its service principal's tokens with the jwt-bearer grant.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WorkloadTrust'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createWorkloadTrust
      tags:
        - Clients
      summary: Create a workload trust
      description: >-
        A credential change (audited as client.workload_trust.created). The client must be a machine client with a
        service principal and the urn:ietf:params:oauth:grant-type:jwt-bearer grant (409 otherwise). Profiles:
        github_actions (fixed issuer and key set, subject naming the repository, jti required), kubernetes (one service
        account: system:serviceaccount:<namespace>:<name>, no wildcards), spiffe (a SPIFFE ID or path prefix ending in
        /*; iss may be absent from JWT-SVIDs), generic (exact subject or one trailing *). Exactly one of jwks_uri and
        jwks; key sets from jwks_uri are fetched under the federation egress rules.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.credentials
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkloadTrustInput'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkloadTrust'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/clients/{client}/workload-trusts/{id}:
    get:
      operationId: getWorkloadTrust
      tags:
        - Clients
      summary: Get a workload trust
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkloadTrust'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: replaceWorkloadTrust
      tags:
        - Clients
      summary: Replace a workload trust
      description: Requires If-Match (428 without it, 412 when stale). state=disabled stops the trust at once.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.credentials
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchRequired'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkloadTrustInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkloadTrust'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteWorkloadTrust
      tags:
        - Clients
      summary: Delete a workload trust
      description: Tokens already issued expire on their own (they never outlive the assertion they came from).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.credentials
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/oauth/register:
    post:
      operationId: registerClient
      tags:
        - OAuth
      summary: Dynamic client registration (RFC 7591)
      description: >-
        APP-016, ADV-003: only when the realm enables client_registration (404 otherwise). With an initial access token
        (Bearer) the client receives the non-privileged scopes the token allows; without one, only when the realm allows
        open registration, and the client is held for approval. Registered clients are third-party clients that ask for
        consent. 20 registrations per hour per network and 500 per realm (fails closed).
      security:
        - initialAccessToken: []
        - {}
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: >-
                Client metadata (RFC 7591). Unknown members are ignored. Accepted: redirect_uris (1 to 20, exact-match
                rules), post_logout_redirect_uris, token_endpoint_auth_method (client_secret_basic default,
                client_secret_post, private_key_jwt with inline jwks, none for public or native clients), grant_types
                (authorization_code, refresh_token), response_types ([code]), client_name, scope, contacts, jwks,
                software_id, software_version, client_uri, logo_uri, policy_uri, tos_uri (https, never fetched),
                frontchannel_logout_uri, response encryption and signing options. Refused: jwks_uri (no metadata
                fetching), software_statement, other grant and response types.
              properties:
                redirect_uris:
                  type: array
                  items:
                    type: string
                post_logout_redirect_uris:
                  type: array
                  items:
                    type: string
                token_endpoint_auth_method:
                  type: string
                  enum:
                    - client_secret_basic
                    - client_secret_post
                    - private_key_jwt
                    - none
                grant_types:
                  type: array
                  items:
                    type: string
                    enum:
                      - authorization_code
                      - refresh_token
                response_types:
                  type: array
                  items:
                    type: string
                    enum:
                      - code
                client_name:
                  type: string
                scope:
                  type: string
                contacts:
                  type: array
                  items:
                    type: string
                jwks:
                  type: object
                software_id:
                  type: string
                software_version:
                  type: string
                client_uri:
                  type: string
                logo_uri:
                  type: string
                policy_uri:
                  type: string
                tos_uri:
                  type: string
                rotate_secret:
                  type: boolean
                  description: >-
                    Management updates only (extension): issue a new client secret; the previous one stays valid for an
                    hour.
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                description: >-
                  Client information (RFC 7591 §3.2.1): the registered metadata plus client_id, client_id_issued_at,
                  client_secret and client_secret_expires_at (0: does not expire) when one was issued (only at
                  registration or on rotation), registration_access_token (at registration and after every update),
                  registration_client_uri, scope (what was granted), proudauth_approval_state (approved or pending) and
                  proudauth_client_state (a pending registration is suspended until approved).
                properties:
                  client_id:
                    type: string
                  client_secret:
                    type: string
                    x-secret: true
                  client_secret_expires_at:
                    type: integer
                  client_id_issued_at:
                    type: integer
                  registration_access_token:
                    type: string
                    x-secret: true
                  registration_client_uri:
                    type: string
                  scope:
                    type: string
                  proudauth_approval_state:
                    type: string
                    enum:
                      - approved
                      - pending
                  proudauth_client_state:
                    type: string
                additionalProperties: true
        '400':
          description: 'RFC 7591 error: invalid_redirect_uri, invalid_client_metadata or unapproved_software_statement.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '401':
          description: Missing, invalid, expired, revoked or exhausted token (error invalid_token, WWW-Authenticate Bearer).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '404':
          description: Dynamic registration is not enabled in this realm.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/oauth/register/{client_id}:
    get:
      operationId: readClientRegistration
      tags:
        - OAuth
      summary: Read a registered client (RFC 7592)
      description: Authenticated by the client's registration access token.
      security:
        - registrationAccessToken: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: client_id
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                description: >-
                  Client information (RFC 7591 §3.2.1): the registered metadata plus client_id, client_id_issued_at,
                  client_secret and client_secret_expires_at (0: does not expire) when one was issued (only at
                  registration or on rotation), registration_access_token (at registration and after every update),
                  registration_client_uri, scope (what was granted), proudauth_approval_state (approved or pending) and
                  proudauth_client_state (a pending registration is suspended until approved).
                properties:
                  client_id:
                    type: string
                  client_secret:
                    type: string
                    x-secret: true
                  client_secret_expires_at:
                    type: integer
                  client_id_issued_at:
                    type: integer
                  registration_access_token:
                    type: string
                    x-secret: true
                  registration_client_uri:
                    type: string
                  scope:
                    type: string
                  proudauth_approval_state:
                    type: string
                    enum:
                      - approved
                      - pending
                  proudauth_client_state:
                    type: string
                additionalProperties: true
        '400':
          description: 'RFC 7591 error: invalid_redirect_uri, invalid_client_metadata or unapproved_software_statement.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '401':
          description: Missing, invalid, expired, revoked or exhausted token (error invalid_token, WWW-Authenticate Bearer).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '404':
          description: Dynamic registration is not enabled in this realm.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: updateClientRegistration
      tags:
        - OAuth
      summary: Update a registered client (RFC 7592)
      description: >-
        Replaces the registrant's metadata (client_id must match): client_name, redirect and post-logout redirect URIs,
        grant types, the authentication method within the client type, contacts, software_id/version and the protocol
        options. The client type and granted scopes cannot change, and settings an administrator controls through the
        client API (description, security profile and consent settings, offline access, remember-me, default resource,
        environment, project, owner, subject_type and sector_identifier, login UI and back-channel logout URIs, allowed
        origins, claim mappings, token_policy) are kept, not reset; metadata that conflicts with them is refused (for
        example redirect URIs outside a pairwise sector). A new registration_access_token is returned and the old one
        stops working; rotate_secret=true issues a new secret. The update is one transaction: when any part fails
        (invalid metadata, or a rotation beyond limits.client_secrets_max, which counts only secrets not yet expired:
        409), nothing changes and the presented registration access token stays valid.
      security:
        - registrationAccessToken: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: client_id
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              description: >-
                Client metadata (RFC 7591). Unknown members are ignored. Accepted: redirect_uris (1 to 20, exact-match
                rules), post_logout_redirect_uris, token_endpoint_auth_method (client_secret_basic default,
                client_secret_post, private_key_jwt with inline jwks, none for public or native clients), grant_types
                (authorization_code, refresh_token), response_types ([code]), client_name, scope, contacts, jwks,
                software_id, software_version, client_uri, logo_uri, policy_uri, tos_uri (https, never fetched),
                frontchannel_logout_uri, response encryption and signing options. Refused: jwks_uri (no metadata
                fetching), software_statement, other grant and response types.
              properties:
                redirect_uris:
                  type: array
                  items:
                    type: string
                post_logout_redirect_uris:
                  type: array
                  items:
                    type: string
                token_endpoint_auth_method:
                  type: string
                  enum:
                    - client_secret_basic
                    - client_secret_post
                    - private_key_jwt
                    - none
                grant_types:
                  type: array
                  items:
                    type: string
                    enum:
                      - authorization_code
                      - refresh_token
                response_types:
                  type: array
                  items:
                    type: string
                    enum:
                      - code
                client_name:
                  type: string
                scope:
                  type: string
                contacts:
                  type: array
                  items:
                    type: string
                jwks:
                  type: object
                software_id:
                  type: string
                software_version:
                  type: string
                client_uri:
                  type: string
                logo_uri:
                  type: string
                policy_uri:
                  type: string
                tos_uri:
                  type: string
                rotate_secret:
                  type: boolean
                  description: >-
                    Management updates only (extension): issue a new client secret; the previous one stays valid for an
                    hour.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                description: >-
                  Client information (RFC 7591 §3.2.1): the registered metadata plus client_id, client_id_issued_at,
                  client_secret and client_secret_expires_at (0: does not expire) when one was issued (only at
                  registration or on rotation), registration_access_token (at registration and after every update),
                  registration_client_uri, scope (what was granted), proudauth_approval_state (approved or pending) and
                  proudauth_client_state (a pending registration is suspended until approved).
                properties:
                  client_id:
                    type: string
                  client_secret:
                    type: string
                    x-secret: true
                  client_secret_expires_at:
                    type: integer
                  client_id_issued_at:
                    type: integer
                  registration_access_token:
                    type: string
                    x-secret: true
                  registration_client_uri:
                    type: string
                  scope:
                    type: string
                  proudauth_approval_state:
                    type: string
                    enum:
                      - approved
                      - pending
                  proudauth_client_state:
                    type: string
                additionalProperties: true
        '400':
          description: 'RFC 7591 error: invalid_redirect_uri, invalid_client_metadata or unapproved_software_statement.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '401':
          description: Missing, invalid, expired, revoked or exhausted token (error invalid_token, WWW-Authenticate Bearer).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '404':
          description: Dynamic registration is not enabled in this realm.
        '409':
          $ref: '#/components/responses/Conflict'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteClientRegistration
      tags:
        - OAuth
      summary: Delete a registered client (RFC 7592)
      description: 'Decommissions the client: its grants and tokens end and its registration access token stops working.'
      security:
        - registrationAccessToken: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - name: client_id
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          description: 'RFC 7591 error: invalid_redirect_uri, invalid_client_metadata or unapproved_software_statement.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '401':
          description: Missing, invalid, expired, revoked or exhausted token (error invalid_token, WWW-Authenticate Bearer).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OAuthError'
        '404':
          description: Dynamic registration is not enabled in this realm.
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/client-registration-tokens:
    get:
      operationId: listInitialAccessTokens
      tags:
        - Clients
      summary: List initial access tokens
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/RegistrationToken'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createInitialAccessToken
      tags:
        - Clients
      summary: Issue an initial access token
      description: >-
        ADV-003 initial registration authority: allowed_scopes name business resources and non-privileged scopes
        registered clients may receive (privileged scopes are refused, and re-checked at use); max_uses defaults to 1,
        expiry to 7 days. The plaintext is returned once.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.credentials
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                description:
                  type: string
                  maxLength: 200
                allowed_scopes:
                  type: array
                  maxItems: 20
                  items:
                    type: object
                    additionalProperties: false
                    properties:
                      resource_id:
                        type: string
                      scopes:
                        type: array
                        items:
                          type: string
                    required:
                      - resource_id
                      - scopes
                project_id:
                  type: string
                max_uses:
                  type: integer
                  minimum: 1
                  maximum: 1000
                expires_in_seconds:
                  type: integer
                  minimum: 60
                  maximum: 7776000
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  initial_access_token:
                    type: string
                    x-secret: true
                  token:
                    $ref: '#/components/schemas/RegistrationToken'
                  notice:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/client-registration-tokens/{id}:
    delete:
      operationId: revokeInitialAccessToken
      tags:
        - Clients
      summary: Revoke an initial access token
      description: Clients already registered with it are unaffected.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.credentials
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/client-registrations:
    get:
      operationId: listClientRegistrations
      tags:
        - Clients
      summary: List dynamically registered clients
      description: Filter with approval_state=pending, approved or rejected.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        client_ref:
                          type: string
                        client_id:
                          type: string
                        name:
                          type: string
                        client_type:
                          type: string
                        approval_state:
                          type: string
                        initial_token_id:
                          type: string
                        software_id:
                          type: string
                        software_version:
                          type: string
                        redirect_uris:
                          type: array
                          items:
                            type: string
                        created_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/client-registrations/{client}/approve:
    post:
      operationId: approveClientRegistration
      tags:
        - Clients
      summary: Approve a pending registration
      description: Activates the client (audited client.registration.approved).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/client-registrations/{client}/reject:
    post:
      operationId: rejectClientRegistration
      tags:
        - Clients
      summary: Reject a pending registration
      description: Decommissions the client (audited client.registration.rejected).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_client'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/resource-types:
    get:
      operationId: listResourceTypes
      tags:
        - Authorization
      summary: List resource types
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resource_types.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ResourceType'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/resource-types/{name}:
    get:
      operationId: getResourceType
      tags:
        - Authorization
      summary: Get a resource type
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resource_types.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_name'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResourceType'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: putResourceType
      tags:
        - Authorization
      summary: Register or replace a resource type
      description: >-
        AZ-022: services register their object types and permission schemas; the identity provider keeps relationships,
        never the objects. 201 when registered, 200 when replaced (If-Match required then: 428 without it, 412 when
        stale). Relations must be identifiers, implied_by must not form a cycle, permissions must be registered
        application permissions, link.relation needs a relation whose subjects are objects of another type,
        shareable_relations need a share_permission.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resource_types.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_name'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                resource_id:
                  type: string
                  description: The business resource (API) that owns the type.
                relations:
                  type: array
                  maxItems: 32
                  items:
                    type: object
                    additionalProperties: false
                    properties:
                      name:
                        type: string
                      subject_types:
                        type: array
                        items:
                          type: string
                        description: >-
                          user, service_principal, group, organization or a registered resource type (links such as
                          parent).
                      implied_by:
                        type: array
                        items:
                          type: string
                    required:
                      - name
                permissions:
                  type: object
                  additionalProperties:
                    type: array
                    items:
                      type: string
                  description: >-
                    Registered application permission -> relations that give it: relation, or link.relation through a
                    relation whose subjects are objects of another type.
                shareable_relations:
                  type: array
                  items:
                    type: string
                share_permission:
                  type: string
              required:
                - resource_id
                - relations
                - permissions
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResourceType'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteResourceType
      tags:
        - Authorization
      summary: Delete a resource type
      description: 409 while relationships use the type.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resource_types.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_name'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/relationships:
    post:
      operationId: writeRelationships
      tags:
        - Authorization
      summary: Write relationships
      description: >-
        AZ-021: adds and removes up to 100 tuples atomically in one active organization (audited as
        authorization.relationships.written). Subjects stay inside the organization: active members, its groups, the
        organization itself, service principals allowed in it, or objects of registered types. expires_at makes a tuple
        lapse on its own.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.relationships.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                writes:
                  type: array
                  minItems: 1
                  maxItems: 100
                  items:
                    type: object
                    additionalProperties: false
                    properties:
                      op:
                        type: string
                        enum:
                          - add
                          - remove
                      object_type:
                        type: string
                      object_id:
                        type: string
                        maxLength: 256
                      relation:
                        type: string
                      subject_type:
                        type: string
                      subject_id:
                        type: string
                      expires_at:
                        type: string
                        format: date-time
                    required:
                      - op
                      - object_type
                      - object_id
                      - relation
                      - subject_type
                      - subject_id
              required:
                - writes
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                  writes:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: listRelationships
      tags:
        - Authorization
      summary: List relationships
      description: 'Filters: object_type, object_id, subject_type, subject_id; limit (1..500, default 100) and cursor.'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.relationships.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        organization_id:
                          type: string
                        object_type:
                          type: string
                        object_id:
                          type: string
                        relation:
                          type: string
                        subject_type:
                          type: string
                        subject_id:
                          type: string
                        source:
                          type: string
                        expires_at:
                          type: string
                          format: date-time
                        created_by_id:
                          type: string
                        created_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/authorization/list-objects:
    post:
      operationId: listAuthorizedObjects
      tags:
        - Authorization
      summary: List objects a subject may act on
      description: >-
        AZ-023: within one organization. all=true when an organization-wide grant (RBAC) covers the action; otherwise
        the objects of the type verified one by one through relationships, ordered by id after cursor. Never returns an
        unverified object; truncated=true when a bound was reached, also when an object's own evaluation reached one and
        it was left out. limit defaults to 100; a larger value than 500 is clamped to 500. Support tokens list read
        actions only.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.authorization.check
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                subject_token:
                  type: string
                  x-secret: true
                subject:
                  type: object
                  properties:
                    type:
                      type: string
                    id:
                      type: string
                action:
                  type: string
                resource:
                  type: object
                  properties:
                    type:
                      type: string
                    org_id:
                      type: string
                context:
                  type: object
                limit:
                  type: integer
                  minimum: 1
                  maximum: 500
                cursor:
                  type: string
              required:
                - action
                - resource
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  all:
                    type: boolean
                    description: True when an organization-wide grant covers the action for every object; objects is then empty.
                  objects:
                    type: array
                    items:
                      type: string
                  organization_id:
                    type: string
                  truncated:
                    type: boolean
                    description: A bound was reached; only verified objects are returned.
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/shares:
    post:
      operationId: offerShare
      tags:
        - Self-service
      summary: Offer to share an object
      description: >-
        AZ-027 user-managed sharing: the caller must hold the type's share_permission on the object; relation must be
        one of the type's shareable_relations; the recipient must be an active member of the same organization. The
        share is pending until the recipient accepts. Requires recent authentication.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                organization_id:
                  type: string
                resource_type:
                  type: string
                object_id:
                  type: string
                relation:
                  type: string
                recipient_user_id:
                  type: string
                message:
                  type: string
                  maxLength: 500
                expires_at:
                  type: string
                  format: date-time
              required:
                - organization_id
                - resource_type
                - object_id
                - relation
                - recipient_user_id
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResourceShare'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: listShares
      tags:
        - Self-service
      summary: List shares
      description: >-
        direction=received (default) or sent; optional state. A pending or accepted share past its expires_at is listed,
        and filtered, as expired.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ResourceShare'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/shares/{id}/accept:
    post:
      operationId: acceptShare
      tags:
        - Self-service
      summary: Accept a share
      description: >-
        Creates the relationship tuple, after re-checking that the sharer may still share and the relation is still
        shareable. An offer past its expires_at is 409 and stored as expired.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResourceShare'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/shares/{id}/decline:
    post:
      operationId: declineShare
      tags:
        - Self-service
      summary: Decline a share
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ResourceShare'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/shares/{id}:
    delete:
      operationId: revokeShare
      tags:
        - Self-service
      summary: Revoke or give back a share
      description: The sharer withdraws an offer or access, or the recipient gives access back; the relationship tuple is removed.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/elevation-eligibilities:
    post:
      operationId: createElevationEligibility
      tags:
        - Authorization
      summary: Make a person eligible for a role
      description: >-
        AZ-024: only someone who could assign the role at that scope (delegation ceiling) may create it, from an MFA
        session, and not for themselves. The person must be an active, non-guest user.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                user_id:
                  type: string
                role_id:
                  type: string
                scope:
                  type: object
                  properties:
                    type:
                      type: string
                      enum:
                        - realm
                        - organization
                        - project
                    id:
                      type: string
                max_duration_seconds:
                  type: integer
                  minimum: 300
                  maximum: 604800
                requires_approval:
                  type: boolean
                  description: Default true; privileged roles always require approval.
              required:
                - user_id
                - role_id
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ElevationEligibility'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: listElevationEligibilities
      tags:
        - Authorization
      summary: List eligibilities
      description: Filter with user_id.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ElevationEligibility'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/elevation-eligibilities/{id}:
    delete:
      operationId: revokeElevationEligibility
      tags:
        - Authorization
      summary: Revoke an eligibility
      description: Pending requests under it are cancelled and an elevation in progress ends now.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/elevations:
    get:
      operationId: listElevations
      tags:
        - Authorization
      summary: List elevation requests
      description: 'Filters: state (pending, active, rejected, ended, expired, cancelled), user_id.'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Elevation'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/elevations/{id}/approve:
    post:
      operationId: approveElevation
      tags:
        - Authorization
      summary: Approve an elevation
      description: >-
        The approver must be able to assign the role at the scope and must not be the requester; users need recent
        authentication. The role is assigned (source elevation) until requested duration elapses from approval.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Elevation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/elevations/{id}/reject:
    post:
      operationId: rejectElevation
      tags:
        - Authorization
      summary: Reject an elevation
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Elevation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/elevations/{id}/end:
    post:
      operationId: endElevation
      tags:
        - Authorization
      summary: End an elevation
      description: Ends an active elevation now (removing its assignment) or cancels a pending request.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/elevation-eligibilities:
    get:
      operationId: listMyElevationEligibilities
      tags:
        - Self-service
      summary: List my eligibilities
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ElevationEligibility'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/elevations:
    post:
      operationId: requestElevation
      tags:
        - Self-service
      summary: Ask for an elevation
      description: >-
        Needs a recent multi-factor session (403 step_up_required otherwise). Pending until approved when the
        eligibility requires approval, otherwise active at once. 409 while another request under the same eligibility is
        pending or active.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                eligibility_id:
                  type: string
                duration_seconds:
                  type: integer
                  description: 300 up to the eligibility maximum (default the maximum).
                reason:
                  type: string
                  minLength: 3
                  maxLength: 500
              required:
                - eligibility_id
                - reason
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Elevation'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: listMyElevations
      tags:
        - Self-service
      summary: List my elevations
      description: Optional state filter.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Elevation'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/elevations/{id}/end:
    post:
      operationId: endMyElevation
      tags:
        - Self-service
      summary: End my elevation
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/access-reviews:
    post:
      operationId: createAccessReview
      tags:
        - Authorization
      summary: Start an access review campaign
      description: >-
        AZ-025: snapshots up to 10000 role assignments in scope (filtered by roles and privilege) as items. Reviewers
        are active users who decide through /me/access-reviews.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.access_reviews.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                name:
                  type: string
                  maxLength: 200
                description:
                  type: string
                  maxLength: 2000
                organization_id:
                  type: string
                  description: Review one organization's assignments; omitted for every assignment in the realm.
                reviewer_ids:
                  type: array
                  minItems: 1
                  maxItems: 20
                  items:
                    type: string
                role_ids:
                  type: array
                  items:
                    type: string
                privileged_only:
                  type: boolean
                on_no_decision:
                  type: string
                  enum:
                    - keep
                    - revoke
                due_at:
                  type: string
                  format: date-time
              required:
                - name
                - reviewer_ids
                - due_at
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccessReview'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: listAccessReviews
      tags:
        - Authorization
      summary: List access review campaigns
      description: Optional state filter (open, closed, cancelled).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.access_reviews.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AccessReview'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/access-reviews/{id}:
    get:
      operationId: getAccessReview
      tags:
        - Authorization
      summary: Get a campaign
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.access_reviews.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccessReview'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/access-reviews/{id}/items:
    get:
      operationId: listAccessReviewItems
      tags:
        - Authorization
      summary: List campaign items
      description: 'decision filter: undecided, keep or revoke; limit (1..500) and cursor.'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.access_reviews.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AccessReviewItem'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/access-reviews/{id}/close:
    post:
      operationId: closeAccessReview
      tags:
        - Authorization
      summary: Close and apply a campaign
      description: >-
        Revokes items decided revoke (and undecided ones when on_no_decision is revoke) whose assignment still exists;
        records each outcome (kept, revoked, already_removed, revoke_failed — e.g. the last owner of an organization)
        and a summary. Campaigns past their due date are closed by the worker in the same way.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.access_reviews.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccessReview'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/access-reviews/{id}/cancel:
    post:
      operationId: cancelAccessReview
      tags:
        - Authorization
      summary: Cancel a campaign
      description: Nothing is applied.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.access_reviews.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/access-reviews/{id}/evidence:
    get:
      operationId: exportAccessReviewEvidence
      tags:
        - Authorization
      summary: Export campaign evidence
      description: >-
        Every item with its decision, reviewer, time, comment and outcome. The export documents an access review; it is
        not a regulatory certification. Audited as access_review.evidence_exported.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.access_reviews.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  review:
                    $ref: '#/components/schemas/AccessReview'
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AccessReviewItem'
                  generated_at:
                    type: string
                    format: date-time
                  statement:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/access-reviews:
    get:
      operationId: listMyAccessReviews
      tags:
        - Self-service
      summary: List campaigns I review
      description: state defaults to open.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AccessReview'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/access-reviews/{id}/items:
    get:
      operationId: listMyAccessReviewItems
      tags:
        - Self-service
      summary: List items of a campaign I review
      description: 404 unless the caller is one of the campaign's reviewers. Filters as for administrators.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AccessReviewItem'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/access-reviews/{id}/items/{item}/decision:
    post:
      operationId: decideAccessReviewItem
      tags:
        - Self-service
      summary: Decide an item
      description: >-
        Reviewers never decide on their own access (403). Decisions can change until the campaign closes (409
        afterwards).
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_item'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                decision:
                  type: string
                  enum:
                    - keep
                    - revoke
                comment:
                  type: string
                  maxLength: 1000
                  description: Required when revoking.
              required:
                - decision
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccessReviewItem'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/certificate-trust-anchors:
    post:
      operationId: addCertificateTrustAnchor
      tags:
        - Clients
      summary: Trust a certificate authority
      description: >-
        MCH-014, PROV-016: client anchors (realm.clients.credentials) for mutual-TLS client authentication; user anchors
        (realm.settings.write) for X.509 sign-in. 409 while an active anchor already trusts the authority for that
        purpose (a removed anchor's authority can be added again, as a new anchor). With revocation crl, crl_pem must
        carry a nextUpdate; every certificate of the chain below the anchor is checked against its issuer's CRL, and a
        certificate issued by an intermediate (whose CRL the anchor does not hold) is refused.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                purpose:
                  type: string
                  enum:
                    - client
                    - user
                name:
                  type: string
                  maxLength: 100
                certificate_pem:
                  type: string
                  description: Exactly one PEM CA certificate (basic constraints CA, not expired).
                revocation:
                  type: string
                  enum:
                    - none
                    - crl
                crl_pem:
                  type: string
                  description: >-
                    With revocation crl: a PEM X509 CRL signed by this authority; certificates are refused once it
                    passes its next update.
                map_san_email:
                  type: boolean
                  description: >-
                    User anchors: a certificate's single e-mail address signs in the account that verified that address,
                    without a binding.
                multi_factor:
                  type: boolean
                  description: >-
                    User anchors: the certificate key is protected by a second factor (smart card and PIN); sign-in
                    counts as phishing-resistant MFA.
              required:
                - purpose
                - name
                - certificate_pem
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CertificateTrustAnchor'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: listCertificateTrustAnchors
      tags:
        - Clients
      summary: List trust anchors
      description: Optional purpose filter.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/CertificateTrustAnchor'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/certificate-trust-anchors/{id}/crl:
    put:
      operationId: updateTrustAnchorCRL
      tags:
        - Clients
      summary: Replace a trust anchor CRL
      description: >-
        A newer CRL signed by the authority: a greater CRL number (or, when either list has none, a later thisUpdate),
        or the identical list again; an equal number with other content, an older list or a list without nextUpdate is
        422. Switches the anchor to revocation crl.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                crl_pem:
                  type: string
              required:
                - crl_pem
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CertificateTrustAnchor'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/certificate-trust-anchors/{id}:
    delete:
      operationId: removeCertificateTrustAnchor
      tags:
        - Clients
      summary: Stop trusting an authority
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/certificate-bindings:
    post:
      operationId: bindUserCertificate
      tags:
        - Users
      summary: Bind a certificate identity to an account
      description: >-
        PROV-016: certificates under the user anchor with this issuer and subject name sign in this account (a renewed
        certificate with the same names keeps working). A sample certificate_pem must be accepted by the anchor named in
        anchor_id (422 otherwise). MFA session required. 409 when the identity is bound to another account.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.credentials.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                anchor_id:
                  type: string
                issuer_dn:
                  type: string
                subject_dn:
                  type: string
                certificate_pem:
                  type: string
                  description: A sample certificate (verified against the anchor) instead of the names.
              required:
                - anchor_id
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CertificateBinding'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: listUserCertificateBindings
      tags:
        - Users
      summary: List certificate bindings
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/CertificateBinding'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/certificate-bindings/{id}:
    delete:
      operationId: unbindUserCertificate
      tags:
        - Users
      summary: Remove a certificate binding
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.credentials.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/auth/transactions/{id}/certificate:
    post:
      operationId: certificateStep
      tags:
        - Interaction
      summary: Sign in with an X.509 certificate
      description: >-
        PROV-016, only when the realm enables login.certificates (409 otherwise). The certificate comes from the TLS
        connection (send this step to the mutual-TLS endpoint) or a trusted proxy header, never from the body. It must
        chain to a user trust anchor, be valid and not revoked, and be bound to the account (or map by e-mail); when the
        transaction already names an account it must be that one. Failures count as failed proofs (400) and are audited
        as authentication.certificate.failed with a reason code.
      security:
        - transactionToken: []
        - transactionCookie: []
          csrfHeader: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionState'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/authentication-flow/revisions:
    get:
      operationId: listAuthFlowRevisions
      tags:
        - Authentication flows
      summary: List authentication-flow revisions
      description: AUT-019. Newest first, including drafts, published, superseded and discarded revisions.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/AuthFlowRevision'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createAuthFlowDraft
      tags:
        - Authentication flows
      summary: Save an authentication-flow draft
      description: >-
        AUT-019. Validates the definition, records the live flow it is based on and stores the reachability and bypass
        analysis. At most 20 open drafts.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - definition
              properties:
                definition:
                  $ref: '#/components/schemas/AuthFlowDefinition'
                note:
                  type: string
                  maxLength: 500
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthFlowRevision'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/authentication-flow/revisions/{revision}:
    get:
      operationId: getAuthFlowRevision
      tags:
        - Authentication flows
      summary: Get an authentication-flow revision
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_revision'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthFlowRevision'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: discardAuthFlowDraft
      tags:
        - Authentication flows
      summary: Discard an authentication-flow draft
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_revision'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/authentication-flow/revisions/{revision}/simulate:
    post:
      operationId: simulateAuthFlowRevision
      tags:
        - Authentication flows
      summary: Simulate a revision against the live flow
      description: AUT-019. Evaluates each case with the evaluator sign-in uses. An empty ip or risk is a missing signal.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_revision'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - cases
              properties:
                cases:
                  type: array
                  minItems: 1
                  maxItems: 200
                  items:
                    $ref: '#/components/schemas/AuthFlowCase'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - revision
                  - live_policy_revision
                  - results
                  - summary
                  - analysis
                properties:
                  revision:
                    type: integer
                  live_policy_revision:
                    type: integer
                  results:
                    type: array
                    items:
                      type: object
                      required:
                        - case
                        - current
                        - candidate
                        - change
                      properties:
                        case:
                          type: string
                        current:
                          $ref: '#/components/schemas/AuthFlowResult'
                        candidate:
                          $ref: '#/components/schemas/AuthFlowResult'
                        change:
                          type: string
                          enum:
                            - unchanged
                            - stricter
                            - weaker
                            - rule_changed
                  summary:
                    type: object
                    additionalProperties:
                      type: integer
                  analysis:
                    $ref: '#/components/schemas/AuthFlowAnalysis'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/authentication-flow/revisions/{revision}/publish:
    post:
      operationId: publishAuthFlowRevision
      tags:
        - Authentication flows
      summary: Publish an authentication-flow draft
      description: >-
        AUT-019. Refuses (409) a draft whose base no longer matches the live flow, (422) a definition with bypass errors
        and (422) unacknowledged warnings. Advances the realm policy revision.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_revision'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                acknowledge_warnings:
                  type: boolean
                  description: Required when the analysis reports warnings.
                reason:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - revision
                  - policy_revision
                  - version
                properties:
                  revision:
                    $ref: '#/components/schemas/AuthFlowRevision'
                  policy_revision:
                    type: integer
                  version:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/authentication-flow/revisions/{revision}/rollback:
    post:
      operationId: rollbackAuthFlow
      tags:
        - Authentication flows
      summary: Republish an earlier revision
      description: AUT-019. Copies a previously published revision into a new revision and publishes it after analysing it again.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_revision'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                acknowledge_warnings:
                  type: boolean
                  description: Required when the analysis reports warnings.
                reason:
                  type: string
                  maxLength: 500
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - revision
                  - policy_revision
                  - version
                properties:
                  revision:
                    $ref: '#/components/schemas/AuthFlowRevision'
                  policy_revision:
                    type: integer
                  version:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /.well-known/ssf-configuration/realms/{realm}:
    get:
      operationId: ssfConfigurationWellKnown
      tags:
        - Shared signals
      summary: Shared Signals transmitter metadata (path-inserted form)
      description: >-
        AUD-016. Shared Signals Framework 1.0 transmitter metadata; 404 unless the realm policy sets
        shared_signals.enabled.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFConfiguration'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/.well-known/ssf-configuration:
    get:
      operationId: ssfConfiguration
      tags:
        - Shared signals
      summary: Shared Signals transmitter metadata
      description: >-
        AUD-016. Shared Signals Framework 1.0 transmitter metadata; 404 unless the realm policy sets
        shared_signals.enabled.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFConfiguration'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/ssf/streams:
    post:
      operationId: createSSFStream
      tags:
        - Shared signals
      summary: Create an event stream
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. Poll streams get a transmitter-assigned endpoint_url. subject_scope all is reserved to administrators.
        At most 5 streams per receiver.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SSFStreamInput'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    get:
      operationId: getSSFStreams
      tags:
        - Shared signals
      summary: Read one stream or list the caller's streams
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. With stream_id, one stream; without, an array.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Query_stream_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/SSFStream'
                  - type: array
                    items:
                      $ref: '#/components/schemas/SSFStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    patch:
      operationId: updateSSFStream
      tags:
        - Shared signals
      summary: Update a stream
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. Members not given are unchanged.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SSFStreamInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: replaceSSFStream
      tags:
        - Shared signals
      summary: Replace a stream configuration
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. delivery and events_requested are required; read-only members may be echoed back.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SSFStreamInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteSSFStream
      tags:
        - Shared signals
      summary: Delete a stream
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. Queued events are discarded.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Query_stream_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/ssf/streams/status:
    get:
      operationId: getSSFStreamStatus
      tags:
        - Shared signals
      summary: Read a stream status
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Query_stream_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - stream_id
                  - status
                properties:
                  stream_id:
                    type: string
                  status:
                    type: string
                    enum:
                      - enabled
                      - paused
                      - disabled
                  reason:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: setSSFStreamStatus
      tags:
        - Shared signals
      summary: Enable, pause or disable a stream
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. A paused stream keeps queueing events and delivers them when enabled; disabling discards queued events.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - stream_id
                - status
              properties:
                stream_id:
                  type: string
                status:
                  type: string
                  enum:
                    - enabled
                    - paused
                    - disabled
                reason:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - stream_id
                  - status
                properties:
                  stream_id:
                    type: string
                  status:
                    type: string
                    enum:
                      - enabled
                      - paused
                      - disabled
                  reason:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/ssf/streams/subjects/add:
    post:
      operationId: addSSFSubject
      tags:
        - Shared signals
      summary: Add a subject to a stream
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. Unknown subjects, and users who never authorized the receiver, are accepted without effect so the
        endpoint reveals nothing about accounts.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - stream_id
                - subject
              properties:
                stream_id:
                  type: string
                subject:
                  type: object
                  description: >-
                    A subject identifier (RFC 9493): {format: iss_sub, iss, sub} with sub as this client knows it
                    (pairwise included), or {format: email, email} for a verified address.
                  additionalProperties: true
                verified:
                  type: boolean
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/ssf/streams/subjects/remove:
    post:
      operationId: removeSSFSubject
      tags:
        - Shared signals
      summary: Remove a subject from a stream
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - stream_id
                - subject
              properties:
                stream_id:
                  type: string
                subject:
                  type: object
                  description: >-
                    A subject identifier (RFC 9493): {format: iss_sub, iss, sub} with sub as this client knows it
                    (pairwise included), or {format: email, email} for a verified address.
                  additionalProperties: true
                verified:
                  type: boolean
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/ssf/streams/verify:
    post:
      operationId: verifySSFStream
      tags:
        - Shared signals
      summary: Request a verification event
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. At most once per min_verification_interval (60 s; 429 otherwise).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - stream_id
              properties:
                stream_id:
                  type: string
                state:
                  type: string
                  maxLength: 256
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/ssf/streams/{id}/poll:
    post:
      operationId: pollSSFStream
      tags:
        - Shared signals
      summary: Poll for Security Event Tokens (RFC 8936)
      description: >-
        AUD-016. Callable by a machine client (client-credentials token for the admin API) holding
        realm.ssf_streams.manage, on a realm with shared_signals.enabled (404 otherwise). Streams belong to the calling
        client. Acknowledges (ack) or rejects (setErrs) earlier tokens, then returns up to maxEvents (default 50, at
        most 100) outstanding tokens. Unacknowledged tokens are returned again, unchanged. Responds immediately.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                ack:
                  type: array
                  maxItems: 1000
                  items:
                    type: string
                setErrs:
                  type: object
                  additionalProperties:
                    type: object
                    properties:
                      err:
                        type: string
                      description:
                        type: string
                maxEvents:
                  type: integer
                  minimum: 0
                returnImmediately:
                  type: boolean
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - sets
                  - moreAvailable
                properties:
                  sets:
                    type: object
                    description: Security Event Tokens keyed by jti.
                    additionalProperties:
                      type: string
                  moreAvailable:
                    type: boolean
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-streams:
    get:
      operationId: listSSFStreamsAdmin
      tags:
        - Shared signals
      summary: List every shared-signals stream
      description: AUD-016.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SSFStream'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-streams/{id}:
    get:
      operationId: getSSFStreamAdmin
      tags:
        - Shared signals
      summary: Get a stream
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    patch:
      operationId: updateSSFStreamAdmin
      tags:
        - Shared signals
      summary: Change a stream subject scope
      description: >-
        AUD-016. Only administrators can set all (events about every user of the realm); the receiver cannot change it
        back.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                subject_scope:
                  type: string
                  enum:
                    - client_users
                    - listed
                    - all
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteSSFStreamAdmin
      tags:
        - Shared signals
      summary: Delete a stream
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-streams/{id}/status:
    post:
      operationId: setSSFStreamStatusAdmin
      tags:
        - Shared signals
      summary: Change a stream status
      description: AUD-016. The receiver is sent a stream-updated event.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - status
              properties:
                status:
                  type: string
                  enum:
                    - enabled
                    - paused
                    - disabled
                reason:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFStream'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-streams/{id}/events:
    get:
      operationId: listSSFStreamEvents
      tags:
        - Shared signals
      summary: List a stream's recent events
      description: AUD-016. Delivery state of the newest 200 events; tokens are not returned.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.ssf_streams.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        jti:
                          type: string
                        event_type:
                          type: string
                        state:
                          type: string
                          enum:
                            - pending
                            - delivered
                            - acknowledged
                            - failed
                            - expired
                        attempts:
                          type: integer
                        occurred_at:
                          type: string
                          format: date-time
                        delivered_at:
                          type: string
                          format: date-time
                        last_status_code:
                          type: integer
                        last_error:
                          type: string
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/saml/metadata:
    get:
      operationId: getSAMLIdentityProviderMetadata
      tags:
        - SAML
      summary: SAML identity provider metadata
      description: >-
        Realm IdP metadata (SAML-001, SAML-005): entityID is the realm issuer; HTTP-Redirect and HTTP-POST
        SingleSignOnService and SingleLogoutService at /saml/sso and /saml/slo; NameIDFormat persistent, emailAddress,
        unspecified and transient; every published signing certificate (KeyDescriptor use=signing): the next key before
        it signs and the previous key while it retires (SAML-002). No artifact binding, no encryption key, no attribute
        authority. Unsigned (served over TLS). Cacheable for 300 seconds. Returns 404 feature_disabled unless
        saml.enabled.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Cache-Control:
              schema:
                type: string
              description: public, max-age=300
          content:
            application/samlmetadata+xml:
              schema:
                type: string
                description: md:EntityDescriptor with an IDPSSODescriptor.
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/saml/sso:
    get:
      operationId: samlSingleSignOnRedirect
      tags:
        - SAML
      summary: SAML single sign-on (HTTP-Redirect)
      description: >-
        Single sign-on (HTTP-Redirect binding): AuthnRequest in SAMLRequest (DEFLATE + base64) with RelayState and, when
        signed, SigAlg and Signature over the received query octets. Validated before anything is sent anywhere (local
        400 problem with extension reason): issuer is a registered SAML application (saml_unknown_service_provider),
        signature with the application's registered certificates when present or required (saml_signature;
        RSA-SHA256/384/512 only, SHA-1 refused), Version 2.0, IssueInstant within the application's skew and not older
        than 10 minutes, Destination equal to this endpoint when present, AssertionConsumerServiceURL registered exactly
        (or a registered index, or the default ACS) with the HTTP-POST binding (saml_unregistered_acs), each request ID
        once (saml_request_replay), DTD/entities/comments/oversized messages refused (saml_invalid_request). Requests
        the IdP cannot honor are answered with a signed SAML error Response to the validated ACS (200 HTML form):
        unsupported NameIDPolicy Format (InvalidNameIDPolicy), unknown or unsatisfiable RequestedAuthnContext
        (NoAuthnContext), a Subject (RequestUnsupported), IsPassive with ForceAuthn (NoPassive). Accepted requests set
        the pa_saml browser-binding cookie and run the realm's authentication transaction for the application's backing
        client: an SSO session (pa_sid) is reused unless ForceAuthn; IsPassive never shows a login page; requested MFA
        contexts require step-up. Results: 302 to the login interface (with pa_tx), 200 auto-submitting form to the ACS
        when the session completes silently. Returns 404 feature_disabled unless saml.enabled.
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: SAMLRequest
          in: query
          required: false
          schema:
            type: string
          description: DEFLATE-compressed, base64-encoded AuthnRequest.
        - name: RelayState
          in: query
          required: false
          schema:
            type: string
          description: Opaque service provider state, returned unchanged (at most 1024 bytes).
        - name: SigAlg
          in: query
          required: false
          schema:
            type: string
          description: Signature algorithm URI (rsa-sha256, rsa-sha384 or rsa-sha512).
        - name: Signature
          in: query
          required: false
          schema:
            type: string
          description: Base64 signature over SAMLRequest, RelayState and SigAlg as received.
      responses:
        '200':
          description: SAML Response (success or error status) posted to the validated assertion consumer service.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Content-Security-Policy:
              schema:
                type: string
              description: default-src 'none'; script-src 'nonce-<per response>'; frame-ancestors 'none'; base-uri 'none'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            text/html:
              schema:
                type: string
                description: >-
                  Auto-submitting HTML form (SAMLResponse and RelayState hidden inputs) with a no-script Continue
                  button.
        '302':
          description: Redirect to the login interface with transaction_id (sets pa_tx and pa_saml).
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: samlSingleSignOnPost
      tags:
        - SAML
      summary: SAML single sign-on (HTTP-POST)
      description: >-
        HTTP-POST binding: base64 AuthnRequest in SAMLRequest, optionally with an enveloped XML signature (required when
        the application requires signed requests; Destination is then mandatory). Validation as for the HTTP-Redirect
        binding. A cross-site form post carries no SameSite=Lax cookies, so an accepted request is continued by a 303 to
        GET /saml/sso/continue?request=..., which does. Returns 404 feature_disabled unless saml.enabled.
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              description: Size-bounded by saml.max_message_bytes.
              properties:
                SAMLRequest:
                  type: string
                  description: Base64-encoded AuthnRequest.
                RelayState:
                  type: string
                  description: Opaque service provider state (at most 1024 bytes).
              required:
                - SAMLRequest
      responses:
        '200':
          description: SAML error Response posted to the validated assertion consumer service.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Content-Security-Policy:
              schema:
                type: string
              description: default-src 'none'; script-src 'nonce-<per response>'; frame-ancestors 'none'; base-uri 'none'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            text/html:
              schema:
                type: string
                description: >-
                  Auto-submitting HTML form (SAMLResponse and RelayState hidden inputs) with a no-script Continue
                  button.
        '303':
          description: Continue at GET /saml/sso/continue?request=... (sets pa_saml).
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/saml/sso/continue:
    get:
      operationId: samlSingleSignOnContinue
      tags:
        - SAML
      summary: Continue or complete SAML single sign-on
      description: >-
        With request: starts the recorded request in this browser (pa_saml must match). With code and state (or error
        and state): the authentication transaction's completion, addressed to this endpoint; the request is consumed
        once, only by the browser holding its pa_saml binding secret; the internal authorization code is redeemed here
        with the server-held PKCE verifier and must belong to the request's transaction and the application's backing
        client. Then a signed Response is posted to the ACS: bearer SubjectConfirmation (Recipient, InResponseTo,
        NotOnOrAfter), audience restriction, AuthnStatement with SessionIndex and AuthnContextClassRef, the mapped
        attributes. Errors: RequestDenied (cancelled, organization membership missing, emergency switch), NoPassive,
        NoAuthnContext, InvalidNameIDPolicy (no verified email for emailAddress), AuthnFailed. A missing or foreign
        binding cookie, replay or expiry gives 400 transaction_invalid (reason saml_request_invalid). Returns 404
        feature_disabled unless saml.enabled.
      security: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: request
          in: query
          required: false
          schema:
            type: string
          description: Recorded request reference (sir_...).
        - name: code
          in: query
          required: false
          schema:
            type: string
            x-secret: true
          description: Internal authorization code.
        - name: state
          in: query
          required: false
          schema:
            type: string
          description: Request state.
        - name: error
          in: query
          required: false
          schema:
            type: string
          description: Transaction error (access_denied, ...).
        - name: iss
          in: query
          required: false
          schema:
            type: string
          description: Issuer (ignored).
      responses:
        '200':
          description: SAML Response posted to the request's assertion consumer service.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Content-Security-Policy:
              schema:
                type: string
              description: default-src 'none'; script-src 'nonce-<per response>'; frame-ancestors 'none'; base-uri 'none'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            text/html:
              schema:
                type: string
                description: >-
                  Auto-submitting HTML form (SAMLResponse and RelayState hidden inputs) with a no-script Continue
                  button.
        '302':
          description: Redirect to the login interface with transaction_id (sets pa_tx).
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/saml/idp-initiated:
    get:
      operationId: samlIdPInitiatedSignOn
      tags:
        - SAML
      summary: IdP-initiated SAML sign-on
      description: >-
        Unsolicited sign-in to sp (entity ID or application ID), refused with 403 (reason saml_unsolicited_disabled)
        unless the application sets allow_idp_initiated (SAML-007). Policy: the destination is always the application's
        default ACS, RelayState is only the registered idp_initiated_relay_state (never taken from the request), the
        Response carries no InResponseTo, the assertion is bound to this browser (pa_saml) and each use is audited.
        Returns 404 feature_disabled unless saml.enabled.
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: sp
          in: query
          required: false
          schema:
            type: string
          description: Service provider entity ID or SAML application ID.
      responses:
        '200':
          description: SAML Response posted to the default assertion consumer service.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Content-Security-Policy:
              schema:
                type: string
              description: default-src 'none'; script-src 'nonce-<per response>'; frame-ancestors 'none'; base-uri 'none'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            text/html:
              schema:
                type: string
                description: >-
                  Auto-submitting HTML form (SAMLResponse and RelayState hidden inputs) with a no-script Continue
                  button.
        '302':
          description: Redirect to the login interface with transaction_id (sets pa_tx and pa_saml).
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/saml/slo:
    get:
      operationId: samlSingleLogoutRedirect
      tags:
        - SAML
      summary: SAML single logout (HTTP-Redirect)
      description: >-
        Single logout (SAML-008), declared subset: SP-initiated LogoutRequest only, always signed with a registered key
        of the issuing application (HTTP-Redirect detached signature or HTTP-POST enveloped signature), Destination
        equal to this endpoint when present, IssueInstant within skew, NotOnOrAfter honored. The NameID (and
        SessionIndex values, or all of that subject's sessions with the application) select IdP sessions the application
        received assertions for; they end with their grants and refresh tokens (OIDC clients with back-channel logout
        are notified). The signed LogoutResponse goes to the application's registered logout endpoint in its binding,
        with status Success, and second-level PartialLogout when other SAML applications or OIDC clients without
        back-channel logout took part in the session and were not notified. The browser's pa_sid is cleared when its
        session ended. LogoutResponses (IdP-initiated logout) are not implemented and refused with 400. Returns 404
        feature_disabled unless saml.enabled.
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: SAMLRequest
          in: query
          required: false
          schema:
            type: string
          description: DEFLATE-compressed, base64-encoded LogoutRequest.
        - name: RelayState
          in: query
          required: false
          schema:
            type: string
          description: Opaque state, returned unchanged.
        - name: SigAlg
          in: query
          required: false
          schema:
            type: string
          description: Signature algorithm URI.
        - name: Signature
          in: query
          required: false
          schema:
            type: string
          description: Base64 signature over the query as received.
      responses:
        '200':
          description: Signed LogoutResponse posted to an HTTP-POST logout endpoint.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Content-Security-Policy:
              schema:
                type: string
              description: default-src 'none'; script-src 'nonce-<per response>'; frame-ancestors 'none'; base-uri 'none'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            text/html:
              schema:
                type: string
                description: >-
                  Auto-submitting HTML form (SAMLResponse and RelayState hidden inputs) with a no-script Continue
                  button.
        '302':
          description: Signed LogoutResponse to an HTTP-Redirect logout endpoint (clears pa_sid when that session ended).
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: samlSingleLogoutPost
      tags:
        - SAML
      summary: SAML single logout (HTTP-POST)
      description: >-
        Single logout (SAML-008), declared subset: SP-initiated LogoutRequest only, always signed with a registered key
        of the issuing application (HTTP-Redirect detached signature or HTTP-POST enveloped signature), Destination
        equal to this endpoint when present, IssueInstant within skew, NotOnOrAfter honored. The NameID (and
        SessionIndex values, or all of that subject's sessions with the application) select IdP sessions the application
        received assertions for; they end with their grants and refresh tokens (OIDC clients with back-channel logout
        are notified). The signed LogoutResponse goes to the application's registered logout endpoint in its binding,
        with status Success, and second-level PartialLogout when other SAML applications or OIDC clients without
        back-channel logout took part in the session and were not notified. The browser's pa_sid is cleared when its
        session ended. LogoutResponses (IdP-initiated logout) are not implemented and refused with 400. Returns 404
        feature_disabled unless saml.enabled.
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              description: Size-bounded by saml.max_message_bytes.
              properties:
                SAMLRequest:
                  type: string
                  description: Base64-encoded, enveloped-signed LogoutRequest.
                RelayState:
                  type: string
                  description: Opaque state.
              required:
                - SAMLRequest
      responses:
        '200':
          description: Signed LogoutResponse posted to an HTTP-POST logout endpoint.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Content-Security-Policy:
              schema:
                type: string
              description: default-src 'none'; script-src 'nonce-<per response>'; frame-ancestors 'none'; base-uri 'none'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
          content:
            text/html:
              schema:
                type: string
                description: >-
                  Auto-submitting HTML form (SAMLResponse and RelayState hidden inputs) with a no-script Continue
                  button.
        '302':
          description: Signed LogoutResponse to an HTTP-Redirect logout endpoint.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/saml/sp/{connection}:
    get:
      operationId: getSAMLServiceProviderMetadata
      tags:
        - SAML
      summary: SAML service provider metadata of a connection
      description: >-
        This realm's service provider metadata for a SAML connection (FED-014): entityID (the connection's sp_entity_id,
        default this URL), AuthnRequestsSigned, WantAssertionsSigned=true, the realm SAML signing certificates (next key
        included), the requested NameIDFormat and the HTTP-POST AssertionConsumerService at /saml/acs/{connection}. No
        SingleLogoutService: upstream SAML sessions are not ended by the broker. Returns 404 feature_disabled unless
        saml.enabled and federation.enabled.
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_connection'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Cache-Control:
              schema:
                type: string
              description: public, max-age=300
          content:
            application/samlmetadata+xml:
              schema:
                type: string
                description: md:EntityDescriptor with an SPSSODescriptor.
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /realms/{realm}/saml/acs/{connection}:
    post:
      operationId: samlAssertionConsumerService
      tags:
        - SAML
      summary: SAML assertion consumer service (HTTP-POST)
      description: >-
        Receives a connection's SAML Response (FED-014). Unsolicited responses (no InResponseTo), unknown, replayed or
        expired requests, a RelayState that does not match the request's secret, and unparseable or unsafe XML (DTD,
        entities, comments, processing instructions, duplicate IDs, oversized) are refused with 400 invalid_proof before
        any transaction is touched. Otherwise the request is consumed once and the response validated (SAML-003,
        SAML-004, SAML-009): Success status; exactly one Assertion, a direct child, no EncryptedAssertion; a valid
        RSA-SHA256+ signature by a trusted connection certificate over the assertion or the response (overlapping
        certificates for rollover), values read only from the signed element; Destination = this ACS and InResponseTo =
        the request; Issuer = the connection's IdP entity ID; IssueInstant, Conditions NotBefore/NotOnOrAfter within the
        connection's skew; every AudienceRestriction contains the SP entity ID; no unknown condition; a bearer
        SubjectConfirmation with Recipient = this ACS, InResponseTo = the request and a live NotOnOrAfter;
        AuthnStatement present and SessionNotOnOrAfter not passed; the assertion ID not seen before (replay). The
        identity then goes through the federation linking, JIT and organization rules. The outcome is reported like an
        OIDC callback: 303 to the login interface with transaction_id (federation_error on failure), or JSON for
        headless realms. Returns 404 feature_disabled unless saml.enabled and federation.enabled.
      security: []
      x-trust-class: transaction-bound
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_connection'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              description: Size-bounded by saml.max_message_bytes.
              properties:
                SAMLResponse:
                  type: string
                  description: Base64-encoded Response.
                RelayState:
                  type: string
                  description: The RelayState sent with the AuthnRequest.
              required:
                - SAMLResponse
                - RelayState
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    title: CallbackOutcome
                    properties:
                      transaction_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - ok
                          - error
                      error:
                        type: string
                        description: >-
                          upstream_invalid_response, upstream_denied, account_conflict, no_linked_account,
                          email_domain_not_allowed, account_unavailable, account_mismatch, connection_disabled (the
                          connection was disabled while the user was at the upstream).
                    required:
                      - status
                  - type: object
                    title: LinkPendingConfirmation
                    properties:
                      status:
                        type: string
                        const: link_pending_confirmation
                      link_code:
                        type: string
                        x-secret: true
                        description: Single-use code for POST /me/linked-identities/confirm.
                    required:
                      - status
                      - link_code
        '303':
          description: Redirect to the realm login UI.
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Location:
              $ref: '#/components/headers/Location'
            Set-Cookie:
              $ref: '#/components/headers/Set-Cookie'
        '400':
          $ref: '#/components/responses/BadRequest'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/saml/applications:
    get:
      operationId: listSAMLApplications
      tags:
        - SAML
      summary: List SAML applications
      description: Registered service providers of the realm (APP-018). Returns 404 feature_disabled unless saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SAMLApplication'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createSAMLApplication
      tags:
        - SAML
      summary: Register a SAML application
      description: >-
        Registers a service provider and its backing client (protocol saml). metadata_xml (uploaded SPSSODescriptor
        metadata; never fetched from a URL) fills entity ID, HTTP-POST ACS, logout endpoints and signing certificates
        that are not given explicitly. Validation (422): entity ID an absolute URI; 1..10 HTTP-POST ACS URLs with
        exact-redirect rules (https outside development, no fragment, userinfo, wildcard or traversal); 0..4 logout
        endpoints (HTTP-Redirect or HTTP-POST), which need a signing certificate; signing certificates RSA >= 2048 bits,
        not expired, at most 4 (overlap for rollover); encrypt_assertions needs an RSA >= 2048 encryption certificate
        (explicit, or the metadata's encryption key) and allows only aes256-gcm/aes128-gcm content and
        rsa-oaep-mgf1p/xmlenc11 rsa-oaep key transport (CBC and RSA 1.5 refused); an encryption certificate without
        encrypt_assertions is refused; signature_algorithm rsa-sha256 (default), rsa-sha384 or rsa-sha512; at least one
        of sign_response / sign_assertion; attribute sources from the fixed list, static values never under protected
        identity names (email names carry only the verified email, identifier names only user_id, subject, email or
        preferred_username); clock_skew_seconds <= saml.max_clock_skew; assertion_lifetime_seconds 60..1800;
        authn_context_map values are local ACRs. 409 when the entity ID is registered. Returns 404 feature_disabled
        unless saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SAMLApplicationInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAMLApplication'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/saml/applications/{id}:
    get:
      operationId: getSAMLApplication
      tags:
        - SAML
      summary: Get a SAML application
      description: Returns 404 feature_disabled unless saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAMLApplication'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: replaceSAMLApplication
      tags:
        - SAML
      summary: Replace a SAML application
      description: >-
        Replaces the application and its backing client's name, consent and assurance settings; the environment is
        fixed. Certificate, attribute and IdP-initiated changes are audited (saml.application.updated). Returns 404
        feature_disabled unless saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchRequired'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SAMLApplicationInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAMLApplication'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteSAMLApplication
      tags:
        - SAML
      summary: Delete a SAML application
      description: >-
        Removes the application (its pending requests and logout records) and decommissions the backing client, which
        revokes its grants. The entity ID can then be registered again. Suspend an application instead with POST
        /clients/{client_ref}/suspend. Returns 404 feature_disabled unless saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.clients.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/saml/connections:
    get:
      operationId: listSAMLConnections
      tags:
        - SAML
      summary: List SAML connections
      description: >-
        Upstream SAML identity providers of the realm (FED-014). Returns 404 feature_disabled unless saml.enabled and
        federation.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SAMLConnection'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createSAMLConnection
      tags:
        - SAML
      summary: Create a SAML connection
      description: >-
        Creates an identity_providers connection of kind saml. metadata_xml (uploaded IDPSSODescriptor metadata; never
        fetched) fills the IdP entity ID, the HTTP-Redirect SSO endpoint and the signing certificates that are not given
        explicitly. Validation (422): IdP entity ID an absolute URI; sso_url https (http only outside production); at
        least one trusted signing certificate (RSA >= 2048, not expired, at most 4 for overlap); a transient
        name_id_format needs subject_attribute; trust_upstream_mfa needs trusted_authn_contexts; trusted_verified_email
        linking needs trust_email_verified and allowed_email_domains; jit_default_role_id needs organization_id and must
        be assignable by the caller; clock_skew_seconds <= saml.max_clock_skew. Certificate fingerprints are audited
        (federation.provider.created). Returns 404 feature_disabled unless saml.enabled and federation.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SAMLConnectionInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAMLConnection'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/saml/connections/{id}:
    get:
      operationId: getSAMLConnection
      tags:
        - SAML
      summary: Get a SAML connection
      description: >-
        The connection, its trusted certificates (with fingerprints and validity) and this realm's service provider
        endpoints to register with the IdP. Returns 404 feature_disabled unless saml.enabled and federation.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAMLConnection'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    put:
      operationId: replaceSAMLConnection
      tags:
        - SAML
      summary: Replace a SAML connection
      description: >-
        alias cannot change; the IdP entity ID cannot change while identities are linked (409). Certificate rollover:
        list the current and the next certificate together (both are trusted), then remove the old one; added and
        removed fingerprints are audited (federation.provider.updated, SAML-002). Returns 404 feature_disabled unless
        saml.enabled and federation.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IfMatchRequired'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SAMLConnectionInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAMLConnection'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    delete:
      operationId: deleteSAMLConnection
      tags:
        - SAML
      summary: Delete a SAML connection
      description: >-
        Deletes a connection without linked identities (409 otherwise: disable it instead), with its pending requests
        and replay records. Returns 404 feature_disabled unless saml.enabled and federation.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/saml/signing-keys:
    get:
      operationId: listSAMLSigningKeys
      tags:
        - SAML
      summary: List SAML signing keys
      description: >-
        The realm's SAML signing keys (RSA, self-signed certificates), separate from the JWT signing keys: state pending
        (published next key), active, retiring (published until publish_until) or retired, and whether each is currently
        published in metadata. Public certificates only. The first key is created on first use. Returns 404
        feature_disabled unless saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.keys.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SAMLSigningKey'
                required:
                  - items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: prepareSAMLSigningKey
      tags:
        - SAML
      summary: Publish the next SAML signing key
      description: >-
        Creates the next key in state pending: published in IdP and SP metadata at once, signing nothing until activated
        (controlled rollover, SAML-002). 409 when a next key is already published. Returns 404 feature_disabled unless
        saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.keys.rotate
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            Idempotent-Replayed:
              $ref: '#/components/headers/Idempotent-Replayed'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SAMLSigningKey'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/saml/signing-keys/{id}/activate:
    post:
      operationId: activateSAMLSigningKey
      tags:
        - SAML
      summary: Activate the next SAML signing key
      description: >-
        Promotes the pending key to active; the previous active key retires and stays published for
        saml.retired_key_publication. Refused (409) until the key has been published for saml.key_prepublish, unless
        force is set with a reason (422 without one). Returns 404 feature_disabled unless saml.enabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.keys.rotate
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                force:
                  type: boolean
                  description: >-
                    Activate before saml.key_prepublish has elapsed (an emergency; needs a reason of at least 10
                    characters; audited in the emergency category).
                reason:
                  type: string
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SAMLSigningKey'
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '415':
          $ref: '#/components/responses/UnsupportedMediaType'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /api/v1/realms/{realm}/directory-connectors:
    get:
      operationId: listRealmDirectoryConnectors
      tags:
        - Directory
      summary: List directory and outbound connectors
      description: >-
        Lists LDAP/Active Directory connectors (kind ldap) and outbound SCIM connectors (kind scim_outbound).
        Credentials are never returned (credential_set only). Realm administration: every connector of the realm,
        realm-wide (workforce) and organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.read
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DirectoryConnector'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createRealmDirectoryConnector
      tags:
        - Directory
      summary: Create a directory or outbound connector
      description: >-
        Creates a connector with its write-only credential (the service-account bind password for ldap, the downstream
        bearer token for scim_outbound), stored encrypted. Organization connectors' role ceiling must lie within the
        creator's own ceiling and group mappings within the ceiling (PROV-003, PROV-007, TEST-049); realm connectors
        grant no roles or memberships (FED-015). LDAP endpoints must use ldaps:// or StartTLS outside development;
        outbound destinations pass the egress policy (EXT-007). The realm API may bind the connector to an organization
        with organization_id. Realm administration: every connector of the realm, realm-wide (workforce) and
        organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectoryConnectorInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}:
    get:
      operationId: getRealmDirectoryConnector
      tags:
        - Directory
      summary: Get a directory or outbound connector
      description: >-
        Returns the connector definition with last_sync_at, last_success_at, last_error and consecutive_failures
        (PROV-018). Realm administration: every connector of the realm, realm-wide (workforce) and organization-bound.
        Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.read
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: updateRealmDirectoryConnector
      tags:
        - Directory
      summary: Update a directory or outbound connector
      description: >-
        Replaces the definition (not the credential; use PUT .../credential); kind and organization are fixed. state
        disabled stops runs and deliveries at once and fails directory sign-in of the connector's accounts closed
        (upstream_unavailable). Requires If-Match. Realm administration: every connector of the realm, realm-wide
        (workforce) and organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchRequired'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectoryConnectorUpdate'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteRealmDirectoryConnector
      tags:
        - Directory
      summary: Delete a disabled connector
      description: >-
        Deletes a connector that was disabled first (409 otherwise), with its links, runs and deliveries. Accounts stay;
        their owners recover sign-in through the realm's recovery methods. Realm administration: every connector of the
        realm, realm-wide (workforce) and organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: Deleted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/credential:
    put:
      operationId: setRealmDirectoryConnectorCredential
      tags:
        - Directory
      summary: Replace the connector credential
      description: >-
        Replaces the encrypted bind password or bearer token; the previous one is never used again. The credential is
        write-only. Realm administration: every connector of the realm, realm-wide (workforce) and organization-bound.
        Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                credential:
                  type: string
                  minLength: 1
                  maxLength: 4096
                  x-secret: true
              required:
                - credential
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/test:
    post:
      operationId: testRealmDirectoryConnector
      tags:
        - Directory
      summary: Test a connector
      description: >-
        Connects, negotiates TLS and binds as the service account (ldap), or reads the downstream ServiceProviderConfig
        (scim_outbound). Changes nothing; recorded as an operator action (PROV-018). Realm administration: every
        connector of the realm, realm-wide (workforce) and organization-bound. Requires an administration token and an
        MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryTestResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/runs:
    get:
      operationId: listRealmDirectoryRuns
      tags:
        - Directory
      summary: List synchronization and reconciliation runs
      description: >-
        Newest first (PROV-012, PROV-017). Realm administration: every connector of the realm, realm-wide (workforce)
        and organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.read
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DirectoryRun'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: requestRealmDirectoryRun
      tags:
        - Directory
      summary: Request a run
      description: >-
        Queues a full or incremental directory synchronization, or an outbound reconciliation, as a job; at most one run
        of a connector is queued or running (409 with run_id). dry_run computes the plan with the same logic and changes
        nothing. allow_mass_deprovision overrides the deletion threshold for one applied full run and needs a reason; it
        is audited. Realm administration: every connector of the realm, realm-wide (workforce) and organization-bound.
        Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectoryRunRequest'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryRun'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/runs/{run}:
    get:
      operationId: getRealmDirectoryRun
      tags:
        - Directory
      summary: Get a run
      description: >-
        State, counts, cursors and the endpoint used. Realm administration: every connector of the realm, realm-wide
        (workforce) and organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.read
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_run'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryRun'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/runs/{run}/findings:
    get:
      operationId: listRealmDirectoryRunFindings
      tags:
        - Directory
      summary: List a run's findings
      description: >-
        Plan items, applied changes, conflicts, divergences and errors of a run (at most 5000 stored per run; counts
        stay complete). Page with after=next_after. Realm administration: every connector of the realm, realm-wide
        (workforce) and organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.read
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_run'
        - $ref: '#/components/parameters/DirectoryFindingKind'
        - $ref: '#/components/parameters/DirectoryFindingsAfter'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DirectoryFinding'
                  next_after:
                    type: string
                    description: Pass as after for the next page; empty on the last page.
                required:
                  - items
                  - next_after
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/health:
    get:
      operationId: getRealmDirectoryConnectorHealth
      tags:
        - Directory
      summary: Connector operational evidence
      description: >-
        Health status, last successful run, lag, endpoint health, managed record counts, outbound backlog and the latest
        operator actions (PROV-018). Never contains credentials. Realm administration: every connector of the realm,
        realm-wide (workforce) and organization-bound. Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.read
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryHealth'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/deliveries:
    get:
      operationId: listRealmOutboundDeliveries
      tags:
        - Directory
      summary: List outbound deliveries
      description: >-
        Outbound provisioning deliveries (scim_outbound connectors), newest first; no payloads or credentials. Realm
        administration: every connector of the realm, realm-wide (workforce) and organization-bound. Requires an
        administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.read
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/OutboundDeliveryState'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OutboundDelivery'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/directory-connectors/{id}/deliveries/{delivery}/replay:
    post:
      operationId: replayRealmOutboundDelivery
      tags:
        - Directory
      summary: Replay a dead-lettered delivery
      description: >-
        Re-opens a dead-lettered delivery as a fresh attempt series (409 for other states); recorded as an operator
        action. Realm administration: every connector of the realm, realm-wide (workforce) and organization-bound.
        Requires an administration token and an MFA session.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.provisioning.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_outbound_delivery'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors:
    get:
      operationId: listOrgDirectoryConnectors
      tags:
        - Directory
      summary: List directory and outbound connectors
      description: >-
        Lists LDAP/Active Directory connectors (kind ldap) and outbound SCIM connectors (kind scim_outbound).
        Credentials are never returned (credential_set only). Organization scope: only the organization's own connectors
        are visible (others return 404).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DirectoryConnector'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createOrgDirectoryConnector
      tags:
        - Directory
      summary: Create a directory or outbound connector
      description: >-
        Creates a connector with its write-only credential (the service-account bind password for ldap, the downstream
        bearer token for scim_outbound), stored encrypted. Organization connectors' role ceiling must lie within the
        creator's own ceiling and group mappings within the ceiling (PROV-003, PROV-007, TEST-049); realm connectors
        grant no roles or memberships (FED-015). LDAP endpoints must use ldaps:// or StartTLS outside development;
        outbound destinations pass the egress policy (EXT-007). Organization scope: only the organization's own
        connectors are visible (others return 404). Changes require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectoryConnectorInput'
      responses:
        '201':
          description: Created
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}:
    get:
      operationId: getOrgDirectoryConnector
      tags:
        - Directory
      summary: Get a directory or outbound connector
      description: >-
        Returns the connector definition with last_sync_at, last_success_at, last_error and consecutive_failures
        (PROV-018). Organization scope: only the organization's own connectors are visible (others return 404).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: updateOrgDirectoryConnector
      tags:
        - Directory
      summary: Update a directory or outbound connector
      description: >-
        Replaces the definition (not the credential; use PUT .../credential); kind and organization are fixed. state
        disabled stops runs and deliveries at once and fails directory sign-in of the connector's accounts closed
        (upstream_unavailable). Requires If-Match. Organization scope: only the organization's own connectors are
        visible (others return 404). Changes require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchRequired'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectoryConnectorUpdate'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '428':
          $ref: '#/components/responses/PreconditionRequired'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteOrgDirectoryConnector
      tags:
        - Directory
      summary: Delete a disabled connector
      description: >-
        Deletes a connector that was disabled first (409 otherwise), with its links, runs and deliveries. Accounts stay;
        their owners recover sign-in through the realm's recovery methods. Organization scope: only the organization's
        own connectors are visible (others return 404). Changes require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: Deleted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/credential:
    put:
      operationId: setOrgDirectoryConnectorCredential
      tags:
        - Directory
      summary: Replace the connector credential
      description: >-
        Replaces the encrypted bind password or bearer token; the previous one is never used again. The credential is
        write-only. Organization scope: only the organization's own connectors are visible (others return 404). Changes
        require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                credential:
                  type: string
                  minLength: 1
                  maxLength: 4096
                  x-secret: true
              required:
                - credential
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
            ETag:
              $ref: '#/components/headers/ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryConnector'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/test:
    post:
      operationId: testOrgDirectoryConnector
      tags:
        - Directory
      summary: Test a connector
      description: >-
        Connects, negotiates TLS and binds as the service account (ldap), or reads the downstream ServiceProviderConfig
        (scim_outbound). Changes nothing; recorded as an operator action (PROV-018). Organization scope: only the
        organization's own connectors are visible (others return 404). Changes require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryTestResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/runs:
    get:
      operationId: listOrgDirectoryRuns
      tags:
        - Directory
      summary: List synchronization and reconciliation runs
      description: >-
        Newest first (PROV-012, PROV-017). Organization scope: only the organization's own connectors are visible
        (others return 404).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DirectoryRun'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: requestOrgDirectoryRun
      tags:
        - Directory
      summary: Request a run
      description: >-
        Queues a full or incremental directory synchronization, or an outbound reconciliation, as a job; at most one run
        of a connector is queued or running (409 with run_id). dry_run computes the plan with the same logic and changes
        nothing. allow_mass_deprovision overrides the deletion threshold for one applied full run and needs a reason; it
        is audited. Organization scope: only the organization's own connectors are visible (others return 404). Changes
        require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DirectoryRunRequest'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryRun'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/runs/{run}:
    get:
      operationId: getOrgDirectoryRun
      tags:
        - Directory
      summary: Get a run
      description: >-
        State, counts, cursors and the endpoint used. Organization scope: only the organization's own connectors are
        visible (others return 404).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_run'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryRun'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/runs/{run}/findings:
    get:
      operationId: listOrgDirectoryRunFindings
      tags:
        - Directory
      summary: List a run's findings
      description: >-
        Plan items, applied changes, conflicts, divergences and errors of a run (at most 5000 stored per run; counts
        stay complete). Page with after=next_after. Organization scope: only the organization's own connectors are
        visible (others return 404).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_run'
        - $ref: '#/components/parameters/DirectoryFindingKind'
        - $ref: '#/components/parameters/DirectoryFindingsAfter'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/DirectoryFinding'
                  next_after:
                    type: string
                    description: Pass as after for the next page; empty on the last page.
                required:
                  - items
                  - next_after
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/health:
    get:
      operationId: getOrgDirectoryConnectorHealth
      tags:
        - Directory
      summary: Connector operational evidence
      description: >-
        Health status, last successful run, lag, endpoint health, managed record counts, outbound backlog and the latest
        operator actions (PROV-018). Never contains credentials. Organization scope: only the organization's own
        connectors are visible (others return 404).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DirectoryHealth'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/deliveries:
    get:
      operationId: listOrgOutboundDeliveries
      tags:
        - Directory
      summary: List outbound deliveries
      description: >-
        Outbound provisioning deliveries (scim_outbound connectors), newest first; no payloads or credentials.
        Organization scope: only the organization's own connectors are visible (others return 404).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/OutboundDeliveryState'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OutboundDelivery'
                  next_cursor:
                    type: string
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/directory-connectors/{id}/deliveries/{delivery}/replay:
    post:
      operationId: replayOrgOutboundDelivery
      tags:
        - Directory
      summary: Replay a dead-lettered delivery
      description: >-
        Re-opens a dead-lettered delivery as a fresh attempt series (409 for other states); recorded as an operator
        action. Organization scope: only the organization's own connectors are visible (others return 404). Changes
        require an MFA session.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: user-self-service-or-administrative
      x-permissions:
        - org.integrations.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_outbound_delivery'
        - $ref: '#/components/parameters/IdempotencyKey'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/attribute-authority:
    get:
      operationId: getMyAttributeAuthority
      tags:
        - Self-service
      summary: Declare own attribute authority
      description: >-
        Which attributes and operations of the caller's account are locally editable (local), externally managed by a
        directory (externally_managed, refused with 409 conflict naming the attributes in externally_managed) or written
        back to the directory (write_back) (USR-022, PROV-013).
      security:
        - accountToken: []
      x-trust-class: user-self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttributeAuthority'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/users/{user}/attribute-authority:
    get:
      operationId: getUserAttributeAuthority
      tags:
        - Users
      summary: Declare a user's attribute authority
      description: >-
        Which attributes and operations of the account are locally editable, externally managed or written back
        (USR-022).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_user'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AttributeAuthority'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/webauthn/trusted-authenticators:
    get:
      operationId: listTrustedAuthenticators
      tags:
        - Passkeys
      summary: List trusted authenticator models
      description: >-
        PASS-009. Realm-trusted authenticator models; with the operator FIDO metadata they are the trusted metadata for
        webauthn.require_trusted_attestation.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/TrustedAuthenticator'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: addTrustedAuthenticator
      tags:
        - Passkeys
      summary: Trust an authenticator model
      description: >-
        PASS-009. Registrations claiming this AAGUID must carry a packed/TPM/Android attestation whose certificate
        chains to one of the roots. At most 200 per realm; 409 for a duplicate AAGUID.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - aaguid
                - description
                - root_certificates
              properties:
                aaguid:
                  type: string
                  description: Lower-case, non-zero AAGUID.
                description:
                  type: string
                  maxLength: 200
                root_certificates:
                  type: array
                  minItems: 1
                  maxItems: 10
                  items:
                    type: string
                    description: One PEM CA certificate (unexpired).
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrustedAuthenticator'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/webauthn/trusted-authenticators/{id}:
    delete:
      operationId: removeTrustedAuthenticator
      tags:
        - Passkeys
      summary: Stop trusting an authenticator model
      description: PASS-009. Enrolled passkeys keep working; new registrations need other trusted metadata.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /.well-known/webauthn:
    get:
      operationId: webauthnRelatedOrigins
      tags:
        - Passkeys
      summary: WebAuthn related origins document
      description: >-
        PASS-010, WebAuthn Level 3 §5.11. Served for the request host when it is the explicit rp_id of realms that
        declared webauthn.related_origins and the operator set webauthn.related_origins; 404 otherwise. Lists the
        realms' origins and related origins (at most five registrable domains).
      security: []
      x-trust-class: public-metadata
      parameters:
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - origins
                properties:
                  origins:
                    type: array
                    items:
                      type: string
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/federation-transfers:
    get:
      operationId: listFederationTransfers
      tags:
        - Federation
      summary: List federation transfers
      description: FED-016.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/FederationTransfer'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createFederationTransfer
      tags:
        - Federation
      summary: Plan a federation transfer
      description: >-
        FED-016. Moves account links from one provider connection to another (same organization scope) by a migration
        map: map takes explicit entries (more can be added to the draft, up to 50000); same_subject maps every source
        link to the same subject at the target. The plan is analysed at once (summary by outcome). Accounts are never
        relinked by email.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - source_provider_id
                - target_provider_id
                - mode
                - reason
              properties:
                source_provider_id:
                  type: string
                target_provider_id:
                  type: string
                mode:
                  type: string
                  enum:
                    - map
                    - same_subject
                target_tenant:
                  type: string
                reason:
                  type: string
                  maxLength: 500
                entries:
                  type: array
                  maxItems: 2000
                  items:
                    type: object
                    additionalProperties: false
                    required:
                      - source_subject
                      - target_subject
                    properties:
                      source_subject:
                        type: string
                        maxLength: 255
                      source_issuer:
                        type: string
                        description: Needed when the subject is linked under several source issuers (multi-tenant source).
                      target_subject:
                        type: string
                        maxLength: 255
                      target_tenant:
                        type: string
                        description: Tenant substituted into a multi-tenant target issuer.
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FederationTransfer'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/federation-transfers/{id}:
    get:
      operationId: getFederationTransfer
      tags:
        - Federation
      summary: Get a federation transfer
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FederationTransfer'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/federation-transfers/{id}/entries:
    get:
      operationId: listFederationTransferEntries
      tags:
        - Federation
      summary: List transfer entries and their outcomes
      description: FED-016. Query outcome filters by outcome; after (the last seq seen) and limit page through entries.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/FederationTransferEntry'
                  next_after:
                    type: integer
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: addFederationTransferEntries
      tags:
        - Federation
      summary: Add map entries to a draft
      description: FED-016. Only for draft map transfers; the plan is analysed again.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - entries
              properties:
                entries:
                  type: array
                  minItems: 1
                  maxItems: 2000
                  items:
                    type: object
                    additionalProperties: false
                    required:
                      - source_subject
                      - target_subject
                    properties:
                      source_subject:
                        type: string
                        maxLength: 255
                      source_issuer:
                        type: string
                        description: Needed when the subject is linked under several source issuers (multi-tenant source).
                      target_subject:
                        type: string
                        maxLength: 255
                      target_tenant:
                        type: string
                        description: Tenant substituted into a multi-tenant target issuer.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FederationTransfer'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/federation-transfers/{id}/approve:
    post:
      operationId: approveFederationTransfer
      tags:
        - Federation
      summary: Approve a federation transfer
      description: >-
        FED-016. By an administrator other than the author (403 otherwise). The plan is analysed again; 409 when nothing
        could be applied.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FederationTransfer'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/federation-transfers/{id}/apply:
    post:
      operationId: applyFederationTransfer
      tags:
        - Federation
      summary: Apply an approved federation transfer
      description: >-
        FED-016. Analyses again under lock and moves only entries still ready (the link keeps its ID and account; tokens
        kept for the old connection are discarded); entries already linked at the target drop their source link.
        Collisions and duplicates are skipped and stay in the report. Applies once.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FederationTransfer'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/federation-transfers/{id}/cancel:
    post:
      operationId: cancelFederationTransfer
      tags:
        - Federation
      summary: Cancel a federation transfer
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.identity_providers.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/migration-adapters:
    get:
      operationId: listMigrationAdapters
      tags:
        - Imports and exports
      summary: List the first-party migration adapters
      description: >-
        The source products this release converts (MIG-002, MIG-018): Keycloak, ZITADEL and SuperTokens, each with the
        source versions it accepts and was tested with, how to produce the export and what converts, converts with loss
        or is unsupported. An export of another version is refused; compatibility is never inferred from the product
        name.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/MigrationAdapter'
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/migration-plans:
    post:
      operationId: planMigration
      tags:
        - Imports and exports
      summary: Convert a source export and report what would carry over (read-only)
      description: >-
        Converts a Keycloak, ZITADEL or SuperTokens export in memory (MIG-018) and returns its capability report: per
        entity type the items converted, converted with loss (and what was lost), unsupported (credential algorithms or
        parameters outside the accepted bounds, passkeys, client secrets, flows and policies, roles without a reviewed
        translation) and ignored, plus the mapping review and a mapping template. target checks the conversion against
        the realm without writing (MIG-003): which target organizations exist (by the external ID an earlier run set, or
        by the slug the mapping names), conflict (an existing organization only sharing the proposed slug, MIG-004) or
        will be created; which mapped organization roles exist; which source IDs are already imported or were deleted
        (MIG-017); and which records meet an email or username of another account. The response names records by source
        ID only and never returns credentials, seeds or contact data; the exports are not stored. Nothing is imported:
        identity-cli migrate-from --apply submits the documents through POST /organizations and POST /user-imports. The
        request is bounded by limits.max_body_bytes (256 KiB by default): plan larger exports with identity-cli
        migrate-from --plan.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.users.import
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                source:
                  type: string
                  enum:
                    - keycloak
                    - zitadel
                    - supertokens
                source_version:
                  type: string
                  description: >-
                    The source product's version. Required when the export does not state it (ZITADEL; the SuperTokens
                    core API list); when the export states one, this must be that version or a leading part of it such
                    as its major version (26 for 26.8.0), otherwise 422. A version outside the adapter's supported range
                    is refused with 422.
                source_system:
                  type: string
                  pattern: ^[a-z0-9][a-z0-9._-]{0,62}$
                  description: Name qualifying every source ID (import_mappings); default <source>-<realm or app>.
                exports:
                  type: array
                  minItems: 1
                  maxItems: 20
                  items:
                    type: object
                    additionalProperties: true
                  description: >-
                    The export documents as produced by the source (a Keycloak directory export has a realm file and
                    users files).
                mapping:
                  $ref: '#/components/schemas/MigrationMapping'
                keep_attributes:
                  type: boolean
                  description: Keep source attributes and metadata as administrator-only metadata.
                import_totp:
                  type: boolean
                  description: Carry compatible TOTP seeds over (the import itself needs import_totp and its authority).
              required:
                - source
                - exports
              additionalProperties: false
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  report:
                    $ref: '#/components/schemas/MigrationReport'
                  target:
                    type: object
                    properties:
                      users:
                        type: integer
                        description: Records the conversion produced.
                      organizations:
                        type: array
                        items:
                          type: object
                          properties:
                            source_key:
                              type: string
                            slug:
                              type: string
                            display_name:
                              type: string
                            external_id:
                              type: string
                            from_mapping:
                              type: boolean
                            members:
                              type: integer
                            status:
                              type: string
                              enum:
                                - exists
                                - will_create
                                - conflict
                            id:
                              type: string
                          required:
                            - slug
                            - status
                      roles:
                        type: array
                        items:
                          type: object
                          properties:
                            name:
                              type: string
                            exists:
                              type: boolean
                            privileged:
                              type: boolean
                            owner:
                              type: boolean
                          required:
                            - name
                            - exists
                      already_imported:
                        type: array
                        items:
                          type: string
                        description: Source IDs already imported from this source system.
                      skipped_deleted:
                        type: array
                        items:
                          type: string
                        description: Source IDs whose account was deleted here; they are never recreated (MIG-017).
                      identifier_conflicts:
                        type: array
                        items:
                          type: string
                        description: Source IDs whose email or username belongs to another account (imports never merge, MIG-004).
                    required:
                      - users
                      - organizations
                      - roles
                      - already_imported
                      - skipped_deleted
                      - identifier_conflicts
                  mapping_template:
                    $ref: '#/components/schemas/MigrationMapping'
                required:
                  - report
                  - target
                  - mapping_template
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organization-relationships:
    get:
      operationId: listAllOrganizationRelationships
      tags:
        - Organizations
      summary: List every organization relationship
      description: TEN-021. A relationship grants no access by itself.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.organizations.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationRelationship'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/organization-relationships:
    get:
      operationId: listOrganizationRelationships
      tags:
        - Organizations
      summary: List an organization's relationships
      description: TEN-021. Both directions. A relationship grants no access by itself.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.relationships.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OrganizationRelationship'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: proposeOrganizationRelationship
      tags:
        - Organizations
      summary: Propose an organization relationship
      description: >-
        TEN-021. From an organization administrator it is proposed until the other organization accepts; from a realm
        administrator (realm.organizations.write) it is active at once. 409 for a duplicate, a second parent or a cycle;
        hierarchies are at most 10 levels. A relationship grants no access by itself.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.relationships.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - kind
                - target_organization_id
              properties:
                kind:
                  type: string
                  enum:
                    - parent_child
                    - partner
                  description: For parent_child the path organization is the parent.
                target_organization_id:
                  type: string
                note:
                  type: string
                  maxLength: 500
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationRelationship'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/organization-relationships/{id}/accept:
    post:
      operationId: acceptOrganizationRelationship
      tags:
        - Organizations
      summary: Accept a relationship proposal
      description: TEN-021. Only the proposed-to organization decides (403 for the proposer).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.relationships.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationRelationship'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/organization-relationships/{id}/decline:
    post:
      operationId: declineOrganizationRelationship
      tags:
        - Organizations
      summary: Decline a relationship proposal
      description: TEN-021.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.relationships.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationRelationship'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/organization-relationships/{id}/end:
    post:
      operationId: endOrganizationRelationship
      tags:
        - Organizations
      summary: End a relationship
      description: >-
        TEN-021. Either side. Existing project grants stay until their owners revoke them; new tenant grants need an
        active relationship.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.relationships.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/projects/{project}/grants:
    get:
      operationId: listOwnedProjectGrants
      tags:
        - Organizations
      summary: List grants of an organization's project
      description: TEN-020. The path organization must own the project (404 otherwise).
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.projects.share
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProjectGrant'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: shareOwnedProject
      tags:
        - Organizations
      summary: Grant project roles to a related organization
      description: >-
        TEN-020. The grantee must have an active relationship with the owner organization (422 otherwise) unless the
        caller holds realm.projects.write. allowed_role_ids are roles of this project; the grantee can assign only
        those.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.projects.share
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - organization_id
                - allowed_role_ids
              properties:
                organization_id:
                  type: string
                allowed_role_ids:
                  type: array
                  maxItems: 50
                  items:
                    type: string
                valid_until:
                  type: string
                  format: date-time
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectGrant'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/projects/{project}/grants/{id}/revoke:
    post:
      operationId: revokeOwnedProjectGrant
      tags:
        - Organizations
      summary: Revoke a project grant
      description: TEN-020. Project roles assigned through the grant are removed in the same transaction.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.projects.share
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_project'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/project-grants:
    get:
      operationId: listReceivedProjectGrants
      tags:
        - Organizations
      summary: List project grants the organization holds
      description: TEN-020. Live grants only.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProjectGrant'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/project-role-assignments:
    get:
      operationId: listPartnerProjectRoleAssignments
      tags:
        - Organizations
      summary: List project roles the organization assigned
      description: TEN-020.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.roles.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ProjectRoleAssignment'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: assignPartnerProjectRole
      tags:
        - Organizations
      summary: Assign a project role to a member
      description: >-
        TEN-020. The user must be an active member of the organization. For a project the organization does not own, the
        role must be in its active project grant (403 grant_ceiling otherwise). The assignment ends with the grant or
        the membership.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - project_id
                - role_id
                - user_id
              properties:
                project_id:
                  type: string
                role_id:
                  type: string
                user_id:
                  type: string
                expires_at:
                  type: string
                  format: date-time
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectRoleAssignment'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/organizations/{org}/project-role-assignments/{id}:
    delete:
      operationId: removePartnerProjectRole
      tags:
        - Organizations
      summary: Remove a project role the organization assigned
      description: TEN-020.
      security:
        - accountToken: []
        - adminToken: []
      x-trust-class: tenant
      x-permissions:
        - org.roles.assign
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_org'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows:
    get:
      operationId: listWorkflows
      tags:
        - Extensions
      summary: List lifecycle workflows
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Workflow'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createWorkflow
      tags:
        - Extensions
      summary: Create a lifecycle workflow (draft revision 1)
      description: >-
        Stores a strictly validated definition (api/workflows/definition.v1.json) as draft revision 1. Every referenced
        role, group, approver, organization and webhook subscription must exist in the realm. requires_approval is
        forced on when the realm policy extensions.workflow_publish_approval is set (EXT-015).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowCreate'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  workflow:
                    $ref: '#/components/schemas/Workflow'
                  revision:
                    $ref: '#/components/schemas/WorkflowRevision'
                required:
                  - workflow
                  - revision
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}:
    get:
      operationId: getWorkflow
      tags:
        - Extensions
      summary: Get a lifecycle workflow
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteWorkflow
      tags:
        - Extensions
      summary: Delete a workflow that never ran
      description: >-
        A workflow with runs is kept as evidence (409; disable it instead). Plugin-managed workflows change with their
        plugin (409).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/diagnostics:
    get:
      operationId: getWorkflowDiagnostics
      tags:
        - Extensions
      summary: Workflow health and step failures
      description: Counts, failure categories and latency over recent runs (EXT-017); never inputs, results or subjects.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowDiagnostics'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/revisions:
    get:
      operationId: listWorkflowRevisions
      tags:
        - Extensions
      summary: List revisions, newest first
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WorkflowRevision'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createWorkflowRevision
      tags:
        - Extensions
      summary: Stage a new draft revision
      description: Revisions are immutable. Runs already started keep the revision they started with.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - definition
              properties:
                definition:
                  $ref: '#/components/schemas/WorkflowDefinition'
                note:
                  type: string
                  maxLength: 500
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowRevision'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/revisions/{revision}:
    get:
      operationId: getWorkflowRevision
      tags:
        - Extensions
      summary: Get a revision
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_workflow_revision'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowRevision'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/revisions/{revision}/approve:
    post:
      operationId: approveWorkflowRevision
      tags:
        - Extensions
      summary: Approve a draft revision
      description: The revision's author cannot approve it (403, AZ-018).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_workflow_revision'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                note:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowRevision'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/revisions/{revision}/reject:
    post:
      operationId: rejectWorkflowRevision
      tags:
        - Extensions
      summary: Reject a draft revision
      description: The revision's author cannot reject it (403).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_workflow_revision'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                note:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowRevision'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/revisions/{revision}/publish:
    post:
      operationId: publishWorkflowRevision
      tags:
        - Extensions
      summary: Publish a revision
      description: >-
        Requires recent authentication. The publisher becomes the accountable actor of every run of the revision: every
        step must be within the publisher's authority (delegation ceiling: the same checks as assigning the role or
        managing the group directly; 403 grant_ceiling_exceeded or forbidden with the offending step in errors).
        Workflows that require approval publish only approved revisions (403). A draft workflow becomes active; a
        disabled one stays disabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_workflow_revision'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/rollback:
    post:
      operationId: rollbackWorkflow
      tags:
        - Extensions
      summary: Republish an earlier revision
      description: >-
        Requires recent authentication. Publishes the content of a previously published revision as a new revision
        (history stays immutable); its approval carries over. The administrator rolling back becomes the accountable
        publisher, so their authority is checked.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - revision
              properties:
                revision:
                  type: integer
                  minimum: 1
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/enable:
    post:
      operationId: enableWorkflow
      tags:
        - Extensions
      summary: Enable a workflow
      description: Triggers fire again and paused runs resume. Requires a published revision (409).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  maxLength: 64
                  description: Reason code recorded in the audit event.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/disable:
    post:
      operationId: disableWorkflow
      tags:
        - Extensions
      summary: Disable a workflow
      description: >-
        Emergency control (SEC-020, audited as category emergency): nothing fires and runs in flight pause; compensation
        and cancellation still proceed.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.publish
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  maxLength: 64
                  description: Reason code recorded in the audit event.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Workflow'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflows/{id}/runs:
    get:
      operationId: listWorkflowRuns
      tags:
        - Extensions
      summary: List a workflow's runs, newest first
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - name: state
          in: query
          required: false
          schema:
            type: string
            enum:
              - pending
              - running
              - waiting
              - awaiting_approval
              - compensating
              - succeeded
              - failed
              - compensated
              - compensation_failed
              - cancelled
          description: Only runs in this state.
        - name: subject_id
          in: query
          required: false
          schema:
            type: string
          description: Only runs about this user.
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WorkflowRun'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: startWorkflowRun
      tags:
        - Extensions
      summary: Start a run by hand
      description: >-
        Only for workflows with a manual trigger (409 otherwise). The run executes under the publisher's authority, and
        the starter's own authority must also cover every step (403); nobody starts a run about themselves (403).
        Idempotency-Key makes a retried request return the same run.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.run
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WorkflowRunStart'
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowRun'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflow-runs:
    get:
      operationId: listAllWorkflowRuns
      tags:
        - Extensions
      summary: List runs across workflows
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: state
          in: query
          required: false
          schema:
            type: string
            enum:
              - pending
              - running
              - waiting
              - awaiting_approval
              - compensating
              - succeeded
              - failed
              - compensated
              - compensation_failed
              - cancelled
          description: Only runs in this state.
        - name: subject_id
          in: query
          required: false
          schema:
            type: string
          description: Only runs about this user.
        - name: workflow_id
          in: query
          required: false
          schema:
            type: string
          description: Only runs of this workflow.
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WorkflowRun'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflow-runs/{id}:
    get:
      operationId: getWorkflowRun
      tags:
        - Extensions
      summary: Get a run with its step attempts and approvals
      description: >-
        Each attempt records its input version, result, retry policy, idempotency key and compensation strategy and
        state (EXT-016).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowRun'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/workflow-runs/{id}/cancel:
    post:
      operationId: cancelWorkflowRun
      tags:
        - Extensions
      summary: Cancel a run
      description: >-
        The worker compensates what the run did (like a failure) and ends it cancelled. 409 when the run already
        finished or is being cancelled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.workflows.run
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowRun'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/workflow-approvals:
    get:
      operationId: listMyWorkflowApprovals
      tags:
        - Self-service
      summary: List workflow approvals I am named on
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: state
          in: query
          required: false
          schema:
            type: string
            enum:
              - pending
              - approved
              - rejected
              - expired
              - cancelled
          description: Defaults to pending.
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/WorkflowApproval'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/me/workflow-approvals/{id}/decision:
    post:
      operationId: decideWorkflowApproval
      tags:
        - Self-service
      summary: Approve or reject a workflow step
      description: >-
        Only a named approver decides (404 for anyone else), never the run's subject (also 404, the approval is
        concealed from them), once (409) and before the expiry (409). The run resumes on the next worker pass.
      security:
        - accountToken: []
      x-trust-class: self-service
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - decision
              properties:
                decision:
                  type: string
                  enum:
                    - approve
                    - reject
                comment:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WorkflowApproval'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins:
    get:
      operationId: listPlugins
      tags:
        - Extensions
      summary: List plugins
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Plugin'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: uploadPlugin
      tags:
        - Extensions
      summary: Upload a signed plugin version
      description: >-
        Requires recent authentication. The package (api/plugins/package.v1.json) must be signed with Ed25519 by a
        publisher key in the operator's extensions.plugin_publishers (403 otherwise; there is no unsigned mode), the
        payload must match the signed digest (403), the manifest must declare every permission its parts need and only
        known ones (422), the server must support a version of every contract it requires (422 with incompatible: true),
        and every part is validated exactly like the corresponding API (422 with the part's location in errors). The
        uploader must hold every declared permission (403 grant_ceiling_exceeded). The version waits for review unless
        the realm policy extensions.plugin_review is single_admin. A plugin name belongs to its first publisher (409).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PluginPackage'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  plugin:
                    $ref: '#/components/schemas/Plugin'
                  version:
                    $ref: '#/components/schemas/PluginVersion'
                required:
                  - plugin
                  - version
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}:
    get:
      operationId: getPlugin
      tags:
        - Extensions
      summary: Get a plugin with its parts
      description: '{id} is the plugin ID or name.'
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plugin'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: uninstallPlugin
      tags:
        - Extensions
      summary: Uninstall a plugin
      description: >-
        Requires recent authentication. Removes every hook and webhook subscription the plugin manages; workflows that
        ran stay, disabled, as evidence. Stored versions remain. 409 while an enabled plugin depends on it.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plugin'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/versions:
    get:
      operationId: listPluginVersions
      tags:
        - Extensions
      summary: List a plugin's versions
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/PluginVersion'
                  next_cursor:
                    type: string
                    description: Opaque cursor for the next page; empty on the last page (API-004).
                required:
                  - items
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/versions/{version}:
    get:
      operationId: getPluginVersion
      tags:
        - Extensions
      summary: Get a version with its payload (for review)
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_plugin_version'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PluginVersion'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/versions/{version}/approve:
    post:
      operationId: approvePluginVersion
      tags:
        - Extensions
      summary: Approve a version
      description: >-
        Requires recent authentication. A second administrator: the uploader cannot approve (403), and the reviewer must
        hold every declared permission (403 grant_ceiling_exceeded).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.approve
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_plugin_version'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                note:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PluginVersion'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/versions/{version}/reject:
    post:
      operationId: rejectPluginVersion
      tags:
        - Extensions
      summary: Reject a version
      description: The uploader cannot reject their own version (403).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.approve
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_plugin_version'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                note:
                  type: string
                  maxLength: 500
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PluginVersion'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/versions/{version}/install:
    post:
      operationId: installPluginVersion
      tags:
        - Extensions
      summary: Install, upgrade to or downgrade to a version
      description: >-
        Requires recent authentication. The version must be approved (403 while awaiting review) or previously
        installed. Signature, publisher key validity, contract compatibility, part validation and the installer's
        permissions are checked again; dependencies must be installed, enabled and recent enough (409 with
        missing_dependency). Parts are reconciled by name in one transaction: existing parts keep their IDs and signing
        secrets, new parts' secrets are returned once in signing_secrets, parts the version drops are removed. The
        previous version is kept for rollback.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/Path_plugin_version'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PluginInstallResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/rollback:
    post:
      operationId: rollbackPlugin
      tags:
        - Extensions
      summary: Reinstall the previous version
      description: >-
        Requires recent authentication. Reinstalls previous_version without a new review (it was reviewed and installed
        before); trust and compatibility are re-checked.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PluginInstallResult'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/enable:
    post:
      operationId: enablePlugin
      tags:
        - Extensions
      summary: Enable every part of a plugin
      description: All parts become active in one transaction. 409 when a dependency is missing or disabled.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  maxLength: 64
                  description: Reason code recorded in the audit event.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plugin'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/plugins/{id}/disable:
    post:
      operationId: disablePlugin
      tags:
        - Extensions
      summary: Disable every part of a plugin
      description: >-
        Emergency control (SEC-020, audited as category emergency): every hook, webhook subscription and workflow the
        plugin manages is disabled in one transaction. 409 while an enabled plugin depends on it.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.plugins.manage
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  maxLength: 64
                  description: Reason code recorded in the audit event.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Plugin'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/extension-contracts:
    get:
      operationId: listExtensionContracts
      tags:
        - Extensions
      summary: Extension contract versions this server supports
      description: >-
        Webhook event schemas, the hook contract, plugin manifests, workflow definitions and the administration API are
        versioned independently (EXT-018). Any of realm.plugins.read, realm.webhooks.read, realm.hooks.read or
        realm.workflows.read suffices.
      security:
        - adminToken: []
      x-trust-class: administrative
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/ExtensionContract'
                  support_window_months:
                    type: integer
                required:
                  - items
                  - support_window_months
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/registry-services:
    get:
      operationId: listRegistryServices
      tags:
        - Registry
      summary: List registry services
      description: ADV-010.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/RegistryService'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createRegistryService
      tags:
        - Registry
      summary: Configure a registry service
      description: >-
        ADV-010. service is the registry service name (token audience); audience names the API resource whose personal
        access tokens and API keys authenticate to it (scopes pull, push, delete cap the actions). Rules are ordered;
        the first whose repository pattern matches decides.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegistryServiceInput'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegistryService'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/registry-services/{id}:
    get:
      operationId: getRegistryService
      tags:
        - Registry
      summary: Get a registry service
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegistryService'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: updateRegistryService
      tags:
        - Registry
      summary: Replace a registry service
      description: ADV-010. The service name cannot change.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegistryServiceInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegistryService'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteRegistryService
      tags:
        - Registry
      summary: Delete a registry service
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.resources.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/registry/token:
    get:
      operationId: registryToken
      tags:
        - Registry
      summary: Container-registry token (Distribution token authentication)
      description: >-
        ADV-010. Credentials are HTTP Basic: the password is a personal access token or API key minted for the registry
        service's API resource, or a machine client's secret with the client ID as user name (its service principal and
        resource grant decide). Without credentials the caller is anonymous and gets only anonymous pulls. The token
        (aud = service, short-lived, signed with the realm's signing keys published at jwks_uri) lists only granted
        actions; denied actions are left out. 401 (WWW-Authenticate: Basic) for invalid credentials; 400 for an unknown
        or disabled service. Errors use the Distribution error format.
      security: []
      x-trust-class: public-protocol-initiation
      x-optional-security:
        - registryBasic
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
        - name: service
          in: query
          required: true
          schema:
            type: string
          description: Registry service name.
        - name: scope
          in: query
          required: false
          schema:
            type: string
          description: repository:<name>:<actions>, repeatable.
        - name: account
          in: query
          required: false
          schema:
            type: string
          description: Ignored.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - token
                  - access_token
                  - expires_in
                  - issued_at
                properties:
                  token:
                    type: string
                    x-secret: true
                  access_token:
                    type: string
                    x-secret: true
                  expires_in:
                    type: integer
                  issued_at:
                    type: string
                    format: date-time
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/investigations/entitlements:
    post:
      operationId: reconstructEntitlements
      tags:
        - Audit
      summary: Reconstruct historical entitlements
      description: >-
        ADV-011. Rebuilds what the subject was entitled to at the instant from retained evidence: account state,
        memberships, groups, role assignments (direct and through groups) with role definitions as they stood, the
        resulting permissions, live OAuth grants, the ABAC policy versions and realm policy revision in force.
        completeness lists caveats: application-owned facts and hook/engine decisions are never reproduced; instants
        before the retained evidence, built-in roles and roles older than the evidence are marked. The request is
        audited (investigation.entitlements.reconstructed).
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.audit.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                - subject_type
                - subject_id
                - at
                - reason
              properties:
                subject_type:
                  type: string
                  enum:
                    - user
                    - service_principal
                subject_id:
                  type: string
                at:
                  type: string
                  format: date-time
                  description: A past instant.
                reason:
                  type: string
                  maxLength: 500
                  description: Investigation reference, recorded in the audit log.
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EntitlementHistory'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-transmitters:
    get:
      operationId: listSSFTransmitters
      tags:
        - Shared signals
      summary: List registered transmitters
      description: ADV-007.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SSFTransmitter'
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: registerSSFTransmitter
      tags:
        - Shared signals
      summary: Register a trusted transmitter
      description: >-
        ADV-007. Registers a source of security events: its issuer, keys (jwks_uri fetched under the delivery egress
        policy, or static public jwks), subject mapping (iss_sub through provider_id; email only with
        allow_email_subjects, verified addresses only) and an explicit action per event type. Unlisted event types are
        recorded only. The response carries the push endpoint (also the expected aud) and a push secret, shown once.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SSFTransmitterInput'
      responses:
        '201':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - transmitter
                  - push_secret
                properties:
                  transmitter:
                    $ref: '#/components/schemas/SSFTransmitter'
                  push_secret:
                    type: string
                    x-secret: true
                    description: Returned once; the transmitter sends it as a Bearer token with every push.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-transmitters/{id}:
    get:
      operationId: getSSFTransmitter
      tags:
        - Shared signals
      summary: Get a transmitter
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFTransmitter'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    put:
      operationId: updateSSFTransmitter
      tags:
        - Shared signals
      summary: Replace a transmitter
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/IfMatchOptional'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        description: 'Strict JSON (application/json): duplicate members, unknown members and excess depth are rejected.'
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SSFTransmitterInput'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFTransmitter'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
    delete:
      operationId: deleteSSFTransmitter
      tags:
        - Shared signals
      summary: Delete a transmitter
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '204':
          description: No Content
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-transmitters/{id}/rotate-secret:
    post:
      operationId: rotateSSFTransmitterSecret
      tags:
        - Shared signals
      summary: Rotate the push secret
      description: ADV-007. The previous secret stops working at once.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.write
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - transmitter
                  - push_secret
                properties:
                  transmitter:
                    $ref: '#/components/schemas/SSFTransmitter'
                  push_secret:
                    type: string
                    x-secret: true
                    description: Returned once; the transmitter sends it as a Bearer token with every push.
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /api/v1/realms/{realm}/ssf-transmitters/{id}/events:
    get:
      operationId: listSSFReceivedEvents
      tags:
        - Shared signals
      summary: List received events
      description: ADV-007. Minimal records (no token, no subject identifiers), kept 30 days.
      security:
        - adminToken: []
      x-trust-class: administrative
      x-permissions:
        - realm.settings.read
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: OK
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        jti:
                          type: string
                        event_type:
                          type: string
                        subject_format:
                          type: string
                        user_id:
                          type: string
                        action:
                          type: string
                        outcome:
                          type: string
                        received_at:
                          type: string
                          format: date-time
                  next_cursor:
                    type: string
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '500':
          $ref: '#/components/responses/InternalError'
  /realms/{realm}/ssf/receivers/{id}/events:
    post:
      operationId: pushSecurityEvent
      tags:
        - Shared signals
      summary: Receive a pushed Security Event Token (RFC 8935)
      description: >-
        ADV-007. For a registered transmitter: Authorization: Bearer <push secret>; body is one signed SET
        (application/secevent+jwt). Checked: secret, signature against the transmitter's keys, iss, aud (this endpoint),
        jti and an iat within max_event_age_seconds (5 minutes of future skew). A replayed jti is accepted without
        effect. Each event applies the transmitter's configured action for its type (record_only otherwise); unknown
        subjects are recorded without action and answered alike. Protected accounts are never suspended (their sessions
        end instead). 202 on acceptance; 400/401 with {err, description}: invalid_request, invalid_key, invalid_issuer,
        invalid_audience, authentication_failed.
      security: []
      x-trust-class: public-protocol-initiation
      parameters:
        - $ref: '#/components/parameters/Path_realm'
        - $ref: '#/components/parameters/Path_id'
        - $ref: '#/components/parameters/RequestId'
      requestBody:
        required: true
        content:
          application/secevent+jwt:
            schema:
              type: string
              maxLength: 65536
      responses:
        '202':
          description: Accepted
          headers:
            X-Request-Id:
              $ref: '#/components/headers/X-Request-Id'
        '400':
          description: Rejected token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFPushError'
        '401':
          description: Push credentials not valid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SSFPushError'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  securitySchemes:
    initialAccessToken:
      type: http
      scheme: bearer
      description: >-
        Initial access token (pa_iat_...) issued by an administrator for dynamic client registration (ADV-003). It
        bounds the scopes registered clients receive, counts uses and expires.
    registrationAccessToken:
      type: http
      scheme: bearer
      description: >-
        Registration access token (pa_rat_...) returned at registration (RFC 7592). It manages that one client and
        nothing else; every update returns a new one.
    scimConnectorToken:
      type: http
      scheme: bearer
      description: >-
        Provisioning connector token (pa_scim_...) issued when an organization administrator creates or rotates an
        inbound SCIM connector. It acts only within that connector organization, resource types and role ceiling.
    accountToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        User access token whose audience is the realm's account resource and which carries the proudauth:account scope,
        sent only in the Authorization header (tokens in query strings are rejected). The session, user and client must
        be live (strict-online). Refresh tokens, authorization codes, exchange tokens and support (impersonation) tokens
        are rejected.
    adminToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        Access token whose audience is the realm's admin resource and which carries the proudauth:admin scope. User
        tokens must come from an MFA session that is not recovery-restricted; service-principal (client_credentials)
        tokens are accepted where the operation allows. Support tokens are rejected (impersonation_restricted).
    transactionToken:
      type: apiKey
      in: header
      name: X-Transaction-Token
      description: Continuation token returned when a headless transaction is started (continuation_token).
    transactionCookie:
      type: apiKey
      in: cookie
      name: pa_tx
      description: >-
        HttpOnly transaction cookie set by the authorization endpoint for browser login surfaces. State-changing steps
        also require csrfHeader and an allowed Origin.
    csrfHeader:
      type: apiKey
      in: header
      name: X-CSRF-Token
      description: >-
        CSRF token from GET .../auth/transactions/{id} (csrf_token), required with transactionCookie on state-changing
        steps.
    sessionCookie:
      type: apiKey
      in: cookie
      name: pa_sid
      description: Browser SSO session cookie (path /realms/{realm}/).
    clientSecretBasic:
      type: http
      scheme: basic
      description: >-
        OAuth client authentication with client_secret_basic. client_secret_post (client_id and client_secret form
        parameters) and private_key_jwt (client_assertion_type and client_assertion form parameters) are sent in the
        form body, which OpenAPI security schemes cannot model.
    userAccessToken:
      type: http
      scheme: bearer
      description: Access token intended for UserInfo.
    registryBasic:
      type: http
      scheme: basic
      description: >-
        Container-registry login (ADV-010): a personal access token or API key minted for the registry's resource as the
        password, or a machine client's client_id and client_secret.
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        maxLength: 255
      description: >-
        Actor/realm/route-bound idempotency key (API-005) for POST requests, at most 255 characters (422 otherwise),
        kept for 24 hours; only a digest of the key is stored. The request is identified by its method, exact path and
        body: a replay with the same path and body returns the stored status and response with Idempotent-Replayed:
        true; the same key with a different body or another path on the same route (another resource) returns 422
        idempotency_key_reused; a request still in progress returns 409. Only successful responses are recorded: when
        the original request failed (an error or a status of 400 or above) the key is released and a retry runs again.
        Responses containing one-time secrets (members such as client_secret, token, api_key, access_token,
        refresh_token, id_token, recovery_codes, secret or webhook_secrets) are never stored or replayed (409 with
        original_status).
    IfMatchOptional:
      name: If-Match
      in: header
      required: false
      schema:
        type: string
        examples:
          - W/"v12"
      description: Expected resource version from the ETag (W/"v12" or "v12"). Stale versions return 412.
    IfMatchRequired:
      name: If-Match
      in: header
      required: true
      schema:
        type: string
        examples:
          - W/"v12"
      description: 'Expected resource version from the ETag. Required: missing returns 428, stale returns 412.'
    Cursor:
      name: cursor
      in: query
      required: false
      schema:
        type: string
      description: Opaque cursor from a previous page (next_cursor). Cursors are HMAC-bound to the realm and listing.
    Limit:
      name: limit
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
      description: Page size; defaults to limits.default_page_size and is capped at limits.max_page_size.
    RequestId:
      name: X-Request-Id
      in: header
      required: false
      schema:
        type: string
        maxLength: 64
        pattern: ^[\x21-\x7e]+$
      description: >-
        Optional caller-supplied correlation ID (printable ASCII, at most 64 characters); otherwise generated. Echoed in
        X-Request-Id and problem request_id.
    Path_policy:
      name: policy
      in: path
      required: true
      schema:
        type: string
      description: Policy ID or name.
    Path_version:
      name: version
      in: path
      required: true
      schema:
        type: integer
        minimum: 1
      description: Policy revision number.
    Path_source:
      name: source
      in: path
      required: true
      schema:
        type: string
        pattern: ^[a-z0-9][a-z0-9._-]{0,62}$
      description: Source system name.
    QueryHistory:
      name: history
      in: query
      required: false
      schema:
        type: boolean
      description: Include revoked consents.
    QueryTemplateName:
      name: name
      in: query
      required: false
      schema:
        type: string
      description: Only this template's versions.
    Path_alias:
      name: alias
      in: path
      required: true
      schema:
        type: string
    ScimFilter:
      name: filter
      in: query
      required: false
      schema:
        type: string
      description: RFC 7644 filter expression.
    ScimStartIndex:
      name: startIndex
      in: query
      required: false
      schema:
        type: integer
        minimum: 1
    ScimCount:
      name: count
      in: query
      required: false
      schema:
        type: integer
        minimum: 0
        maximum: 200
    ScimAttributes:
      name: attributes
      in: query
      required: false
      schema:
        type: string
      description: Comma-separated attributes to return.
    ScimExcludedAttributes:
      name: excludedAttributes
      in: query
      required: false
      schema:
        type: string
      description: Comma-separated attributes to omit.
    ScimIfMatch:
      name: If-Match
      in: header
      required: false
      schema:
        type: string
      description: ETag from a previous response; a stale value fails with 412.
    Path_name:
      name: name
      in: path
      required: true
      schema:
        type: string
      description: Resource type name.
    Path_item:
      name: item
      in: path
      required: true
      schema:
        type: string
    Path_revision:
      name: revision
      in: path
      required: true
      schema:
        type: integer
        minimum: 1
      description: Authentication-flow revision number.
    Query_stream_id:
      name: stream_id
      in: query
      required: false
      schema:
        type: string
      description: Shared-signals stream identifier.
    Path_run:
      name: run
      in: path
      required: true
      schema:
        type: string
      description: Synchronization or reconciliation run identifier.
    Path_outbound_delivery:
      name: delivery
      in: path
      required: true
      schema:
        type: string
      description: Outbound provisioning delivery identifier.
    DirectoryFindingKind:
      name: kind
      in: query
      required: false
      schema:
        type: string
      description: >-
        Only findings of this kind (create, update, link, suspend, reactivate, deprovision, conflict, divergence, skip,
        error, group, missing_remote, drift, orphan_remote, unmanaged_remote).
    DirectoryFindingsAfter:
      name: after
      in: query
      required: false
      schema:
        type: integer
        minimum: 0
      description: Return findings after this sequence number (next_after).
    OutboundDeliveryState:
      name: state
      in: query
      required: false
      schema:
        type: string
        enum:
          - pending
          - retrying
          - delivered
          - dead_letter
          - replayed
    Path_workflow_revision:
      name: revision
      in: path
      required: true
      schema:
        type: integer
        minimum: 1
      description: Workflow revision number.
    Path_plugin_version:
      name: version
      in: path
      required: true
      schema:
        type: string
        pattern: ^(0|[1-9][0-9]{0,5})\.(0|[1-9][0-9]{0,5})\.(0|[1-9][0-9]{0,5})$
      description: Plugin version (MAJOR.MINOR.PATCH).
    Path_realm:
      name: realm
      in: path
      required: true
      schema:
        type: string
      description: Realm name (path-based issuer). Unknown realms return 404.
    Path_id:
      name: id
      in: path
      required: true
      schema:
        type: string
      description: Resource identifier.
    Path_org:
      name: org
      in: path
      required: true
      schema:
        type: string
      description: Organization identifier (a selector; access is checked, API-003).
    Path_membership:
      name: membership
      in: path
      required: true
      schema:
        type: string
      description: Membership identifier.
    Path_assignment:
      name: assignment
      in: path
      required: true
      schema:
        type: string
      description: Role assignment identifier.
    Path_role:
      name: role
      in: path
      required: true
      schema:
        type: string
      description: Role identifier.
    Path_group:
      name: group
      in: path
      required: true
      schema:
        type: string
      description: Group identifier.
    Path_member:
      name: member
      in: path
      required: true
      schema:
        type: string
      description: Membership identifier of the group member.
    Path_user:
      name: user
      in: path
      required: true
      schema:
        type: string
      description: User identifier.
    Path_project:
      name: project
      in: path
      required: true
      schema:
        type: string
      description: Project identifier.
    Path_client:
      name: client
      in: path
      required: true
      schema:
        type: string
      description: Client reference (internal client id, not the OAuth client_id).
    Path_resource:
      name: resource
      in: path
      required: true
      schema:
        type: string
      description: Resource (API) identifier.
    Path_scope:
      name: scope
      in: path
      required: true
      schema:
        type: string
      description: Scope identifier.
    Path_subject:
      name: subject
      in: path
      required: true
      schema:
        type: string
      description: Subject identifier (svc_ prefix denotes a service principal).
    Path_delivery:
      name: delivery
      in: path
      required: true
      schema:
        type: string
      description: Webhook delivery identifier.
    Path_connection:
      name: connection
      in: path
      required: true
      schema:
        type: string
      description: Federation connection (identity provider) alias.
  headers:
    X-Request-Id:
      description: Correlation identifier for this request.
      schema:
        type: string
    ETag:
      description: Weak resource version, W/"v{version}". Send it back in If-Match.
      schema:
        type: string
    Retry-After:
      description: Seconds to wait before retrying.
      schema:
        type: integer
    Idempotent-Replayed:
      description: Present (true) when the response was replayed from the idempotency store.
      schema:
        type: string
        enum:
          - 'true'
    Location:
      description: Redirect target.
      schema:
        type: string
        format: uri
    WWW-Authenticate:
      description: Authentication challenge.
      schema:
        type: string
    Set-Cookie:
      description: >-
        HttpOnly, Secure (outside insecure development mode) cookie: pa_tx (path /api/v1/realms/{realm}/auth/) or pa_sid
        (path /realms/{realm}/).
      schema:
        type: string
  responses:
    ScimError:
      description: SCIM error (RFC 7644 section 3.12).
      content:
        application/scim+json:
          schema:
            $ref: '#/components/schemas/ScimErrorDocument'
    BadRequest:
      description: >-
        Malformed request, invalid JSON (duplicate members, unknown fields, wrong types), invalid cursor or invalid
        transaction (code invalid_request, transaction_invalid, invalid_proof, invitation_invalid).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthorized:
      description: Missing or invalid credentials (code unauthenticated or invalid_credentials). Includes WWW-Authenticate.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        WWW-Authenticate:
          $ref: '#/components/headers/WWW-Authenticate'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Forbidden:
      description: >-
        Authenticated but not allowed (code forbidden, mfa_required, step_up_required, recent_authentication_required,
        grant_ceiling_exceeded, impersonation_restricted, account_unavailable, sso_required, recovery_restricted).
        Step-up problems carry obligations.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotFound:
      description: Unknown realm or resource, or existence concealed from the caller (code not_found, feature_disabled).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Conflict:
      description: >-
        Conflicts with current state, or an idempotent request with the same key is still in progress / carried a
        one-time secret (code conflict, unexpected_step, last_owner, last_sign_in_method).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Gone:
      description: The authentication transaction expired (code transaction_expired).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    PreconditionFailed:
      description: If-Match does not match the current version (code precondition_failed).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    PayloadTooLarge:
      description: Body exceeds limits.max_body_bytes (code payload_too_large).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    UnsupportedMediaType:
      description: Wrong Content-Type (code unsupported_media_type).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    UnprocessableEntity:
      description: >-
        Validation failed (code validation_failed, password_policy, idempotency_key_reused); errors maps fields to
        messages.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    PreconditionRequired:
      description: If-Match header is required (code precondition_required).
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    TooManyRequests:
      description: Rate limited (code rate_limited). Includes Retry-After; never discloses per-user state.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    InternalError:
      description: Unexpected error (code internal_error); no stack traces or secrets.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    ServiceUnavailable:
      description: >-
        Load shedding, realm unavailable or dependency failure (code unavailable, upstream_unavailable). May include
        Retry-After.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NoContent:
      description: Success; no content.
      headers:
        X-Request-Id:
          $ref: '#/components/headers/X-Request-Id'
    OAuthError:
      description: >-
        OAuth 2.0 error (RFC 6749). invalid_client responses use 401 with WWW-Authenticate; throttled requests include
        Retry-After.
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        WWW-Authenticate:
          $ref: '#/components/headers/WWW-Authenticate'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/OAuthError'
  schemas:
    AdminUser:
      type: object
      description: Administrative user view.
      properties:
        id:
          type: string
        state:
          type: string
          enum:
            - pending_verification
            - active
            - suspended
            - locked
            - recovery_restricted
            - pending_deletion
            - deleted
        display_name:
          type: string
        given_name:
          type: string
        family_name:
          type: string
        locale:
          type: string
        zoneinfo:
          type: string
        profile:
          type:
            - object
            - 'null'
          additionalProperties: true
        identifiers:
          type: array
          items:
            $ref: '#/components/schemas/UserIdentifier'
        required_actions:
          type:
            - array
            - 'null'
          items:
            type: string
            enum:
              - update_password
              - verify_email
              - configure_totp
              - accept_terms
              - complete_profile
              - verify_contact
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        version:
          type: integer
          format: int64
        deletion_scheduled_at:
          type:
            - string
            - 'null'
          format: date-time
        admin_metadata:
          type:
            - object
            - 'null'
          additionalProperties: true
        protected:
          type: boolean
        authz_revision:
          type: integer
          format: int64
        last_login_at:
          type:
            - string
            - 'null'
          format: date-time
        created_via:
          type: string
        locked_until:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - id
        - state
        - display_name
        - given_name
        - family_name
        - locale
        - zoneinfo
        - profile
        - identifiers
        - required_actions
        - created_at
        - updated_at
        - version
        - deletion_scheduled_at
        - admin_metadata
        - protected
        - authz_revision
        - last_login_at
        - created_via
        - locked_until
    AdminUserPatch:
      additionalProperties: false
      properties:
        admin_metadata:
          additionalProperties: {}
          type:
            - object
            - 'null'
        display_name:
          type:
            - string
            - 'null'
        family_name:
          type:
            - string
            - 'null'
        given_name:
          type:
            - string
            - 'null'
        locale:
          type:
            - string
            - 'null'
        profile:
          additionalProperties: {}
          type:
            - object
            - 'null'
        zoneinfo:
          type:
            - string
            - 'null'
      type: object
    ApplicationImpersonationPolicy:
      additionalProperties: false
      properties:
        allowed_scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        contract_validated_at:
          type: string
        contract_version:
          type: string
        support_client_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        write_scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        write_actions:
          description: >-
            Reviewed state-changing actions an allowlisted_write support token may perform through the decision API
            (IMP-011).
          items:
            type: string
          type:
            - array
            - 'null'
      type: object
    ApplicationScope:
      additionalProperties: false
      properties:
        consent_text:
          type: string
        description:
          type: string
        id:
          type: string
        is_default:
          type: boolean
          description: >-
            Granted by default (APP-007) when a request names the scope's resource but none of its scopes, subject to
            the checks of a requested scope; see ScopeInput.is_default. Has no effect on protocol (oidc) scopes.
        kind:
          type: string
        name:
          type: string
        resource_id:
          type: string
        sensitivity:
          type: string
      required:
        - id
        - is_default
        - kind
        - name
        - sensitivity
      type: object
    ApplicationTokenPolicy:
      additionalProperties: false
      properties:
        access_token_ttl_seconds:
          type: integer
        refresh_absolute_seconds:
          type: integer
        refresh_idle_seconds:
          type: integer
        require_dpop:
          type: boolean
        require_mfa:
          type: boolean
        require_par:
          type: boolean
        max_session_age_seconds:
          type: integer
          minimum: 0
          maximum: 7776000
          description: Re-authenticate users whose SSO session is older than this (SES-002).
      type: object
    AuditEvent:
      additionalProperties: false
      properties:
        actor:
          $ref: '#/components/schemas/AuditRef'
        batch_id:
          type: string
        category:
          type: string
        client_id:
          type: string
        content_hash:
          type: string
        grant_id:
          type: string
        id:
          type: string
        impersonation_grant_id:
          type: string
        ip_context:
          type: string
        metadata:
          additionalProperties: {}
          type:
            - object
            - 'null'
        occurred_at:
          format: date-time
          type: string
        org_id:
          type: string
        outcome:
          type: string
        realm_id:
          type: string
        reason_code:
          type: string
        reporting_service:
          type: string
        request_id:
          type: string
        schema_version:
          type: integer
        session_id:
          type: string
        source:
          type: string
        subject:
          oneOf:
            - $ref: '#/components/schemas/AuditRef'
            - type: 'null'
        target:
          oneOf:
            - $ref: '#/components/schemas/AuditRef'
            - type: 'null'
        type:
          type: string
      required:
        - actor
        - id
        - occurred_at
        - outcome
        - schema_version
        - source
        - type
      type: object
    AuditRef:
      additionalProperties: false
      properties:
        id:
          type: string
        session_id:
          type: string
        type:
          type: string
      required:
        - id
        - type
      type: object
    AuditVerificationReport:
      additionalProperties: false
      properties:
        batches_checked:
          type: integer
        events_checked:
          type: integer
        ok:
          type: boolean
        problems:
          items:
            type: string
          type:
            - array
            - 'null'
        unsealed_events:
          type: integer
      required:
        - batches_checked
        - events_checked
        - ok
        - problems
        - unsealed_events
      type: object
    AuthzScope:
      additionalProperties: false
      properties:
        id:
          type: string
        type:
          type: string
          description: realm, organization or project.
      type: object
    AuthzSubject:
      additionalProperties: false
      properties:
        id:
          type: string
        type:
          type: string
          description: user, group or service_principal.
      type: object
    ClaimFieldMapping:
      additionalProperties: false
      properties:
        claim:
          type: string
        mode:
          type: string
          enum:
            - on_create
            - sync
          description: on_create (default) fills the field only at account creation; sync refreshes it on every upstream login.
      type: object
    ClaimMapping:
      additionalProperties: false
      properties:
        display_name:
          $ref: '#/components/schemas/ClaimFieldMapping'
        family_name:
          $ref: '#/components/schemas/ClaimFieldMapping'
        given_name:
          $ref: '#/components/schemas/ClaimFieldMapping'
        locale:
          $ref: '#/components/schemas/ClaimFieldMapping'
        zoneinfo:
          $ref: '#/components/schemas/ClaimFieldMapping'
      type: object
    Client:
      additionalProperties: false
      properties:
        access_token_claims:
          additionalProperties: {}
          type:
            - object
            - 'null'
        allow_offline_access:
          type: boolean
        allow_remember_me:
          type: boolean
        allowed_origins:
          items:
            type: string
          type:
            - array
            - 'null'
        backchannel_logout_uri:
          type: string
        frontchannel_logout_uri:
          type: string
          description: >-
            Front-channel logout (SES-018): loaded in an iframe when a session the client took part in ends at the
            logout endpoint. Same scheme, host and port as a registered redirect URI. Browser privacy controls may keep
            it from working; back-channel logout is the reliable mechanism.
        frontchannel_logout_session_required:
          type: boolean
          description: Add iss and sid to frontchannel_logout_uri. Requires frontchannel_logout_uri.
        id_token_encrypted_response_alg:
          type: string
          enum:
            - RSA-OAEP-256
            - ECDH-ES
            - ECDH-ES+A128KW
            - ECDH-ES+A256KW
          description: >-
            TOK-020: encrypt ID tokens (signed, then encrypted: a nested JWT) to the client's newest active registered
            public key that fits (use enc or no use; RSA for RSA-OAEP-256, EC for ECDH-ES). Issuance fails with
            unauthorized_client when no key fits.
        id_token_encrypted_response_enc:
          type: string
          enum:
            - A128GCM
            - A256GCM
          description: Required with id_token_encrypted_response_alg (the specification default A128CBC-HS256 is not offered).
        userinfo_signed_response_alg:
          type: string
          enum:
            - RS256
            - PS256
            - ES256
            - EdDSA
          description: 'OIDC-013: return UserInfo as a JWT signed with the realm key; must be the realm''s signing algorithm.'
        userinfo_encrypted_response_alg:
          type: string
          enum:
            - RSA-OAEP-256
            - ECDH-ES
            - ECDH-ES+A128KW
            - ECDH-ES+A256KW
        userinfo_encrypted_response_enc:
          type: string
          enum:
            - A128GCM
            - A256GCM
        authorization_signed_response_alg:
          type: string
          enum:
            - RS256
            - PS256
            - ES256
            - EdDSA
          description: >-
            JARM (ADV-002): the signing algorithm of JWT authorization responses; must be the realm's (responses are
            always signed with the realm key).
        authorization_encrypted_response_alg:
          type: string
          enum:
            - RSA-OAEP-256
            - ECDH-ES
            - ECDH-ES+A128KW
            - ECDH-ES+A256KW
          description: 'JARM: encrypt JWT authorization responses (nested, signed first) to the client''s registered key.'
        authorization_encrypted_response_enc:
          type: string
          enum:
            - A128GCM
            - A256GCM
        tls_client_auth_subject_dn:
          type: string
          description: >-
            tls_client_auth (RFC 8705): the certificate must chain to a realm client trust anchor and carry exactly one
            registered identity: this subject DN (RFC 4514 as Go prints it) or one SAN below.
        tls_client_auth_san_dns:
          type: string
        tls_client_auth_san_uri:
          type: string
        tls_client_auth_san_ip:
          type: string
        tls_client_auth_san_email:
          type: string
        tls_client_certificate_bound_access_tokens:
          type: boolean
          description: >-
            TOK-019: every access token is bound to the presented TLS client certificate (cnf x5t#S256); a token request
            without a certificate is refused (invalid_request), never answered with a bearer token.
        client_id:
          type: string
        client_type:
          type: string
          enum:
            - confidential
            - public_browser
            - native
            - device
            - machine
        consent_mode:
          type: string
        consent_terms_version:
          type: string
        contacts:
          items:
            type: string
          type:
            - array
            - 'null'
        created_at:
          format: date-time
          type: string
        default_resource_id:
          type: string
        description:
          type: string
        dynamically_registered:
          type: boolean
        environment:
          type: string
        first_party:
          type: boolean
        grant_types:
          items:
            type: string
          type:
            - array
            - 'null'
        id:
          type: string
        id_token_claims:
          additionalProperties: {}
          type:
            - object
            - 'null'
        login_ui_url:
          type: string
        name:
          type: string
        owner_user_id:
          type: string
        post_logout_redirect_uris:
          items:
            type: string
          type:
            - array
            - 'null'
        project_id:
          type: string
        realm_id:
          type: string
        redirect_uris:
          items:
            type: string
          type:
            - array
            - 'null'
        sector_identifier:
          type: string
        protocol:
          type: string
          enum:
            - oidc
            - saml
          description: >-
            saml for the client backing a SAML application; managed only through /saml/applications (PUT
            /clients/{client} answers 409) and refused by every OAuth endpoint.
        security_profile:
          type: string
        service_principal_id:
          type: string
        state:
          type: string
          enum:
            - active
            - suspended
            - decommissioned
        subject_type:
          type: string
        token_endpoint_auth_method:
          type: string
        token_policy:
          $ref: '#/components/schemas/ApplicationTokenPolicy'
        updated_at:
          format: date-time
          type: string
        version:
          format: int64
          type: integer
      required:
        - allow_offline_access
        - allow_remember_me
        - allowed_origins
        - client_id
        - client_type
        - consent_mode
        - created_at
        - dynamically_registered
        - environment
        - first_party
        - grant_types
        - id
        - name
        - post_logout_redirect_uris
        - realm_id
        - redirect_uris
        - security_profile
        - state
        - subject_type
        - token_endpoint_auth_method
        - token_policy
        - updated_at
        - version
      type: object
    ClientCredential:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        display_prefix:
          type: string
        expires_at:
          format: date-time
          type:
            - string
            - 'null'
        id:
          type: string
        key_id:
          type: string
        kind:
          type: string
        last_used_at:
          format: date-time
          type:
            - string
            - 'null'
        state:
          type: string
      required:
        - created_at
        - id
        - kind
        - state
      type: object
    ClientInput:
      additionalProperties: false
      properties:
        access_token_claims:
          additionalProperties: {}
          type:
            - object
            - 'null'
          description: >-
            Static values, or attribute mappings {"$attr": "user.<given_name|family_name|display_name|locale|zoneinfo>"
            or "profile.<claimable attribute>", "transform": "lower|upper", "default": "..."} (APP-011). At most 20
            claims; reserved claims are refused; profile attributes not marked claimable are never released.
        allow_offline_access:
          type: boolean
        allow_remember_me:
          type: boolean
        allowed_origins:
          items:
            type: string
          type:
            - array
            - 'null'
        backchannel_logout_uri:
          type: string
        frontchannel_logout_uri:
          type: string
          description: >-
            Front-channel logout (SES-018): loaded in an iframe when a session the client took part in ends at the
            logout endpoint. Same scheme, host and port as a registered redirect URI. Browser privacy controls may keep
            it from working; back-channel logout is the reliable mechanism.
        frontchannel_logout_session_required:
          type: boolean
          description: Add iss and sid to frontchannel_logout_uri. Requires frontchannel_logout_uri.
        id_token_encrypted_response_alg:
          type: string
          enum:
            - RSA-OAEP-256
            - ECDH-ES
            - ECDH-ES+A128KW
            - ECDH-ES+A256KW
          description: >-
            TOK-020: encrypt ID tokens (signed, then encrypted: a nested JWT) to the client's newest active registered
            public key that fits (use enc or no use; RSA for RSA-OAEP-256, EC for ECDH-ES). Issuance fails with
            unauthorized_client when no key fits.
        id_token_encrypted_response_enc:
          type: string
          enum:
            - A128GCM
            - A256GCM
          description: Required with id_token_encrypted_response_alg (the specification default A128CBC-HS256 is not offered).
        userinfo_signed_response_alg:
          type: string
          enum:
            - RS256
            - PS256
            - ES256
            - EdDSA
          description: 'OIDC-013: return UserInfo as a JWT signed with the realm key; must be the realm''s signing algorithm.'
        userinfo_encrypted_response_alg:
          type: string
          enum:
            - RSA-OAEP-256
            - ECDH-ES
            - ECDH-ES+A128KW
            - ECDH-ES+A256KW
        userinfo_encrypted_response_enc:
          type: string
          enum:
            - A128GCM
            - A256GCM
        authorization_signed_response_alg:
          type: string
          enum:
            - RS256
            - PS256
            - ES256
            - EdDSA
          description: >-
            JARM (ADV-002): the signing algorithm of JWT authorization responses; must be the realm's (responses are
            always signed with the realm key).
        authorization_encrypted_response_alg:
          type: string
          enum:
            - RSA-OAEP-256
            - ECDH-ES
            - ECDH-ES+A128KW
            - ECDH-ES+A256KW
          description: 'JARM: encrypt JWT authorization responses (nested, signed first) to the client''s registered key.'
        authorization_encrypted_response_enc:
          type: string
          enum:
            - A128GCM
            - A256GCM
        tls_client_auth_subject_dn:
          type: string
          description: >-
            tls_client_auth (RFC 8705): the certificate must chain to a realm client trust anchor and carry exactly one
            registered identity: this subject DN (RFC 4514 as Go prints it) or one SAN below.
        tls_client_auth_san_dns:
          type: string
        tls_client_auth_san_uri:
          type: string
        tls_client_auth_san_ip:
          type: string
        tls_client_auth_san_email:
          type: string
        tls_client_certificate_bound_access_tokens:
          type: boolean
          description: >-
            TOK-019: every access token is bound to the presented TLS client certificate (cnf x5t#S256); a token request
            without a certificate is refused (invalid_request), never answered with a bearer token.
        client_id:
          type: string
          maxLength: 128
          description: Generated when omitted; at most 128 URL-safe characters.
        client_type:
          type: string
          enum:
            - confidential
            - public_browser
            - native
            - device
            - machine
        consent_mode:
          type: string
          description: Defaults to preauthorized for first-party clients and required otherwise.
        consent_terms_version:
          type: string
          maxLength: 64
          description: >-
            The client's current terms (APP-013). Consents record the version they were given for; a consent for another
            version no longer covers the client, so users are asked again.
        contacts:
          items:
            type: string
          type:
            - array
            - 'null'
        default_resource_id:
          type: string
        description:
          type: string
        environment:
          type: string
          description: >-
            Defaults to production (or the project's environment); controls redirect URI and origin registration rules.
            Fixed at registration (APP-015): register a new client instead of changing it. Clients of a project must use
            the project's environment, and token exchange never accepts a token minted for a client of another
            environment.
        first_party:
          type: boolean
        grant_types:
          items:
            type: string
          type:
            - array
            - 'null'
          description: Allowed per client type; password and implicit grants are unsupported. Defaults depend on client_type.
        id_token_claims:
          additionalProperties: {}
          type:
            - object
            - 'null'
          description: >-
            Static values, or attribute mappings {"$attr": "user.<given_name|family_name|display_name|locale|zoneinfo>"
            or "profile.<claimable attribute>", "transform": "lower|upper", "default": "..."} (APP-011). At most 20
            claims; reserved claims are refused and standard user claims are released by scope, never mapped; profile
            attributes not marked claimable are never released.
        jwks:
          description: Public JWK Set for private_key_jwt client authentication.
        login_ui_url:
          type: string
        name:
          type: string
          maxLength: 200
        owner_user_id:
          type: string
        post_logout_redirect_uris:
          items:
            type: string
          type:
            - array
            - 'null'
        project_id:
          type: string
        redirect_uris:
          items:
            type: string
          type:
            - array
            - 'null'
        sector_identifier:
          type: string
        security_profile:
          type: string
          enum:
            - standard
            - third_party
            - privileged
            - high_assurance
            - fapi2
          description: >-
            Defaults to standard. fapi2 (ADV-001) enforces the FAPI 2.0 Security Profile: confidential client,
            private_key_jwt (PS256, ES256 or EdDSA) or mutual TLS, authorization code (and refresh tokens) only, PAR
            required, sender-constrained tokens (require_dpop or tls_client_certificate_bound_access_tokens), https
            redirects, a realm signing algorithm of PS256/ES256/EdDSA, 60-second codes, access tokens of at most 10
            minutes, refresh tokens not rotated. Not certified by the OpenID Foundation.
        service_principal_id:
          type: string
        subject_type:
          type: string
          enum:
            - public
            - pairwise
          description: Defaults to public; pairwise requires sector_identifier.
        token_endpoint_auth_method:
          type: string
          enum:
            - client_secret_basic
            - client_secret_post
            - private_key_jwt
            - none
            - tls_client_auth
            - self_signed_tls_client_auth
          description: >-
            Defaults to client_secret_basic for confidential and machine clients and none for public, native and device
            clients. tls_client_auth and self_signed_tls_client_auth (RFC 8705, MCH-014; confidential and machine
            clients) authenticate with the TLS client certificate presented on the mutual-TLS endpoint (or through a
            trusted proxy).
        token_policy:
          $ref: '#/components/schemas/ApplicationTokenPolicy'
      type: object
      required:
        - client_type
        - name
    ConfigDocument:
      type: object
      description: Configuration-as-code document (also published as api/schemas/config-document.schema.json).
      additionalProperties: false
      properties:
        client_resource_grants:
          additionalProperties:
            additionalProperties:
              items:
                type: string
              type:
                - array
                - 'null'
            type:
              - object
              - 'null'
          type:
            - object
            - 'null'
          description: client_id -> resource audience -> allowed scopes.
        clients:
          items:
            $ref: '#/components/schemas/ClientInput'
          type:
            - array
            - 'null'
        format:
          type: string
        permissions:
          items:
            $ref: '#/components/schemas/Permission'
          type:
            - array
            - 'null'
        policy:
          oneOf:
            - $ref: '#/components/schemas/RealmPolicy'
            - type: 'null'
        resources:
          items:
            $ref: '#/components/schemas/ResourceInput'
          type:
            - array
            - 'null'
        roles:
          items:
            $ref: '#/components/schemas/RoleInput'
          type:
            - array
            - 'null'
    ConfigPlan:
      additionalProperties: false
      properties:
        drift:
          items:
            type: string
          type: array
          description: >-
            Existing objects that differ from the document, with the differing members (SDK-012), for example "client
            web-bff: redirect_uris differ". An import never rewrites existing objects: reconcile them through the API.
        create:
          items:
            type: string
          type:
            - array
            - 'null'
        errors:
          items:
            type: string
          type:
            - array
            - 'null'
        notes:
          items:
            type: string
          type:
            - array
            - 'null'
        unchanged:
          items:
            type: string
          type:
            - array
            - 'null'
        update:
          items:
            type: string
          type:
            - array
            - 'null'
      required:
        - create
        - errors
        - notes
        - unchanged
        - update
      type: object
    Consent:
      type: object
      properties:
        id:
          type: string
        client_id:
          type: string
        client_name:
          type: string
        scopes:
          type:
            - array
            - 'null'
          items:
            type: string
        granted_at:
          type: string
          format: date-time
        client:
          type: string
          description: Client reference (cli_...).
        resource_ids:
          type: array
          items:
            type: string
        terms_version:
          type: string
        mode:
          type: string
          enum:
            - user
            - preauthorized
          description: >-
            user: given by the user on the consent screen; preauthorized: covered by an administrative
            pre-authorization.
        preauthorization_id:
          type: string
        revoked_at:
          type: string
          format: date-time
      required:
        - id
        - client_id
        - client_name
        - scopes
        - granted_at
    CredentialInventoryItem:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        display_prefix:
          type: string
        expires_at:
          format: date-time
          type: string
        flags:
          items:
            type: string
          type:
            - array
            - 'null'
        id:
          type: string
        kind:
          type: string
        last_used_at:
          format: date-time
          type:
            - string
            - 'null'
        name:
          type: string
        organization_id:
          type: string
        owner_id:
          type: string
        owner_type:
          type: string
        resource_id:
          type: string
        revoked_at:
          format: date-time
          type:
            - string
            - 'null'
        scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        state:
          type: string
      required:
        - created_at
        - display_prefix
        - expires_at
        - flags
        - id
        - kind
        - name
        - owner_id
        - owner_type
        - resource_id
        - scopes
        - state
      type: object
    CustomerSupportGrant:
      type: object
      properties:
        id:
          type: string
        organization_id:
          type: string
        mode:
          type: string
        state:
          type: string
        expires_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        revoked_at:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - id
        - organization_id
        - mode
        - state
        - expires_at
        - created_at
        - revoked_at
    Policy:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        scope_type:
          type: string
          enum:
            - realm
            - organization
        scope_id:
          type: string
        state:
          type: string
          enum:
            - draft
            - active
            - disabled
        active_version:
          type: integer
        requires_approval:
          type: boolean
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    PolicyCreate:
      type: object
      properties:
        owner_user_id:
          type: string
          description: Accountable owner (DOM-009); defaults to the creating user.
        name:
          type: string
          maxLength: 100
        description:
          type: string
        scope_type:
          type: string
          enum:
            - realm
            - organization
        scope_id:
          type: string
        requires_approval:
          type: boolean
        definition:
          $ref: '#/components/schemas/PolicyDefinition'
        note:
          type: string
          maxLength: 500
      required:
        - name
        - definition
      additionalProperties: false
    PolicyVersion:
      type: object
      properties:
        id:
          type: string
        policy_id:
          type: string
        version_number:
          type: integer
        definition:
          $ref: '#/components/schemas/PolicyDefinition'
        definition_hash:
          type: string
        status:
          type: string
          enum:
            - staged
            - approved
            - published
            - superseded
            - rejected
        author_id:
          type: string
        approved_by_id:
          type: string
        note:
          type: string
        created_at:
          type: string
          format: date-time
        approved_at:
          type: string
          format: date-time
        published_at:
          type: string
          format: date-time
    PolicyDefinition:
      type: object
      description: >-
        Typed, bounded policy (≤ 50 rules, condition depth ≤ 8, ≤ 64 nodes, ≤ 64 KiB). Attributes: action, subject.*
        (id, type, assurance, acr, roles, is_support, actor_id, client_id, org_id, auth_age_seconds), resource.* (type,
        id, org_id), context.* (asserted by the calling service), environment.* (now_unix, hour_utc, weekday).
      properties:
        description:
          type: string
        target:
          type: object
          properties:
            actions:
              type: array
              items:
                type: string
                description: Exact action or namespace prefix ending in .*
            resource_types:
              type: array
              items:
                type: string
          required:
            - actions
          additionalProperties: false
        rules:
          type: array
          maxItems: 50
          items:
            type: object
            properties:
              id:
                type: string
              description:
                type: string
              effect:
                type: string
                enum:
                  - deny
                  - require
              actions:
                type: array
                items:
                  type: string
              when:
                $ref: '#/components/schemas/PolicyCondition'
              reason_code:
                type: string
              obligations:
                type: array
                items:
                  type: object
                  properties:
                    type:
                      type: string
                      enum:
                        - reauthenticate
                        - approval
                        - justification
                    required_profile:
                      type: string
                      enum:
                        - mfa
                        - phishing_resistant
                    max_age_seconds:
                      type: integer
                    approvals:
                      type: integer
                  required:
                    - type
                  additionalProperties: false
            required:
              - id
              - effect
            additionalProperties: false
      required:
        - target
        - rules
      additionalProperties: false
    PolicyCondition:
      type: object
      description: >-
        Exactly one of all, any, not or op. Comparisons over missing attributes are unknown, and unknown rule conditions
        apply the rule (fail closed).
      properties:
        all:
          type: array
          items:
            $ref: '#/components/schemas/PolicyCondition'
        any:
          type: array
          items:
            $ref: '#/components/schemas/PolicyCondition'
        not:
          $ref: '#/components/schemas/PolicyCondition'
        op:
          type: string
          enum:
            - eq
            - ne
            - lt
            - le
            - gt
            - ge
            - in
            - contains
            - starts_with
            - exists
        attr:
          type: string
        value: {}
        value_attr:
          type: string
      additionalProperties: false
    Decision:
      additionalProperties: false
      properties:
        allowed:
          type: boolean
        cache_ttl_seconds:
          type: integer
          description: >-
            Cache contract (AZ-019): reuse the decision for at most this many seconds, only for requests with the same
            cache_key; 0 means do not cache. Decisions that involve ABAC policies, hooks, step-up obligations, support
            access or privileged actions are never cacheable.
        cache_key:
          type: string
          description: >-
            Opaque key covering realm, subject, actor, client, organization, resource, action, the subject's
            authorization revision, the policy version and the asserted context; any role, membership or policy change
            produces a different key.
        decision_id:
          type: string
        obligations:
          items:
            additionalProperties: {}
            type:
              - object
              - 'null'
          type:
            - array
            - 'null'
        policy_version:
          type: string
        reason_code:
          type: string
      required:
        - allowed
        - cache_ttl_seconds
        - decision_id
        - obligations
        - policy_version
        - reason_code
      type: object
    DecisionRequest:
      additionalProperties: false
      properties:
        action:
          type: string
        context:
          additionalProperties: {}
          type:
            - object
            - 'null'
        resource:
          additionalProperties: false
          properties:
            id:
              type: string
            org_id:
              type: string
            project_id:
              type: string
              maxLength: 128
              description: >-
                Project the resource belongs to (AZ-002): the subject's project-scoped roles for it are evaluated too,
                and only there. It must exist in the realm and, with an organization, belong to it (owned, or shared
                through an active project grant).
            type:
              type: string
          required:
            - id
            - org_id
            - type
          type: object
        subject:
          additionalProperties: false
          properties:
            id:
              type: string
            type:
              type: string
          required:
            - id
            - type
          type:
            - object
            - 'null'
          description: Free-form subject; only evaluated for callers holding realm.authorization.simulate.
        subject_token:
          type: string
          x-secret: true
          description: The end user's access token, validated with introspection authority of the calling resource server.
      type: object
    DevMail:
      type: object
      properties:
        id:
          type: string
        recipient:
          type: string
        subject:
          type: string
        body:
          type: string
        template:
          type: string
        created_at:
          type: string
          format: date-time
    DeviceAuthorizationResponse:
      additionalProperties: false
      properties:
        device_code:
          type: string
          x-secret: true
        expires_in:
          type: integer
        interval:
          type: integer
        user_code:
          type: string
        verification_uri:
          type: string
        verification_uri_complete:
          type: string
      required:
        - device_code
        - expires_in
        - interval
        - user_code
        - verification_uri
      type: object
    Domain:
      additionalProperties: false
      properties:
        challenge_expires_at:
          format: date-time
          type:
            - string
            - 'null'
        created_at:
          format: date-time
          type: string
        domain:
          type: string
        id:
          type: string
        recheck_at:
          format: date-time
          type:
            - string
            - 'null'
        state:
          type: string
        verified_at:
          format: date-time
          type:
            - string
            - 'null'
      required:
        - created_at
        - domain
        - id
        - state
      type: object
    DomainChallenge:
      additionalProperties: false
      properties:
        dns_record_name:
          type: string
        dns_record_type:
          type: string
        dns_record_value:
          type: string
        domain:
          $ref: '#/components/schemas/Domain'
      required:
        - dns_record_name
        - dns_record_type
        - dns_record_value
        - domain
      type: object
    EffectivePermissions:
      type: object
      properties:
        scope:
          $ref: '#/components/schemas/AuthzScope'
        roles:
          type:
            - array
            - 'null'
          items:
            type: string
        permissions:
          type:
            - array
            - 'null'
          items:
            type: string
        provenance:
          type: object
          additionalProperties:
            type:
              - array
              - 'null'
            items:
              type: string
          description: permission -> granting role names
        denied_permissions:
          type: array
          items:
            type: string
        sources:
          type: array
          description: >-
            Assignments producing the permissions (AZ-009): via realm, organization, group or project; conditional
            grants report whether they apply now. Realm-level sources are redacted for organization administrators.
          items:
            type: object
            properties:
              assignment_id:
                type: string
              role_id:
                type: string
              role_name:
                type: string
              via:
                type: string
                enum:
                  - realm
                  - organization
                  - group
                  - project
              group_id:
                type: string
              conditional:
                type: boolean
              applies:
                type: boolean
              expires_at:
                type: string
                format: date-time
              permissions:
                type: array
                items:
                  type: string
              redacted:
                type: boolean
        policies:
          type: array
          description: >-
            Published policies that may restrict decisions; named only for callers holding realm.policies.read.
            Definitions are never included.
          items:
            type: object
            properties:
              id:
                type: string
              name:
                type: string
              version:
                type: integer
              scope:
                type: string
        restricting_policies:
          type: integer
        project_id:
          type: string
          description: >-
            The project whose project-scoped assignments were evaluated with the scope (query parameter project_id,
            AZ-002).
      required:
        - scope
        - roles
        - permissions
        - provenance
    ExchangePolicy:
      additionalProperties: false
      properties:
        accept_from_audiences:
          items:
            type: string
          type:
            - array
            - 'null'
        max_scopes:
          items:
            type: string
          type:
            - array
            - 'null'
      type: object
    Group:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        description:
          type: string
        external_id:
          type: string
        id:
          type: string
        metadata:
          additionalProperties: {}
          type:
            - object
            - 'null'
        name:
          type: string
        organization_id:
          type: string
        parent_id:
          type: string
        source:
          type: string
        version:
          format: int64
          type: integer
      required:
        - created_at
        - id
        - metadata
        - name
        - organization_id
        - source
        - version
      type: object
    GroupInput:
      additionalProperties: false
      properties:
        description:
          type: string
        external_id:
          type: string
        metadata:
          additionalProperties: {}
          type:
            - object
            - 'null'
        name:
          type: string
        parent_id:
          type:
            - string
            - 'null'
      type: object
    GroupMember:
      type: object
      properties:
        membership_id:
          type: string
        user_id:
          type: string
        source:
          type: string
        added_at:
          type: string
          format: date-time
      required:
        - membership_id
        - user_id
        - source
        - added_at
    IdentityProvider:
      additionalProperties: false
      properties:
        adapter:
          type: string
          description: The provider adapter; saml for a SAML connection (FED-014).
        alias:
          type: string
        claim_mapping:
          $ref: '#/components/schemas/ClaimMapping'
        config:
          $ref: '#/components/schemas/IdentityProviderConfig'
        created_at:
          format: date-time
          type: string
        display_name:
          type: string
        has_client_secret:
          type: boolean
        id:
          type: string
        issuer:
          type: string
        jit_default_role_id:
          type: string
        jit_provisioning:
          type: boolean
        kind:
          type: string
          description: >-
            oidc, oauth2_social or saml. SAML connections are listed here; PUT answers 409 for them (manage them under
            /saml/connections) and POST /identity-providers/{id}/test reports SAML certificate diagnostics without
            contacting the provider.
        linking_policy:
          type: string
        mapping_revision:
          format: int64
          type: integer
        organization_id:
          type: string
        state:
          type: string
        trust_upstream_mfa:
          type: boolean
        updated_at:
          format: date-time
          type: string
        version:
          format: int64
          type: integer
      required:
        - adapter
        - alias
        - claim_mapping
        - config
        - created_at
        - display_name
        - has_client_secret
        - id
        - issuer
        - jit_provisioning
        - kind
        - linking_policy
        - mapping_revision
        - state
        - trust_upstream_mfa
        - updated_at
        - version
      type: object
    IdentityProviderConfig:
      additionalProperties: false
      properties:
        algorithms:
          items:
            type: string
          type:
            - array
            - 'null'
        allowed_email_domains:
          items:
            type: string
          type:
            - array
            - 'null'
        allowed_tenants:
          items:
            type: string
          type:
            - array
            - 'null'
        api_base_url:
          type: string
        authorization_endpoint:
          type: string
        client_auth:
          type: string
          enum:
            - client_secret_basic
            - client_secret_post
          description: Defaults to client_secret_basic.
        client_id:
          type: string
        discovery_url:
          type: string
        end_session_endpoint:
          type: string
        jwks_uri:
          type: string
        multi_tenant_issuer:
          type: boolean
        scopes:
          items:
            type: string
          type:
            - array
            - 'null'
          maxItems: 20
          description: OIDC connections must request openid.
        tenant_claim:
          type: string
        token_endpoint:
          type: string
        trusted_acr_values:
          items:
            type: string
          type:
            - array
            - 'null'
      type: object
      required:
        - client_id
    IdentityProviderDiagnostics:
      additionalProperties: false
      properties:
        authorization_endpoint:
          type: string
        issuer:
          type: string
        jwks_uri:
          type: string
        ok:
          type: boolean
        problems:
          items:
            type: string
          type:
            - array
            - 'null'
        signing_keys:
          type: integer
        supports_pkce_s256:
          type: boolean
        token_endpoint:
          type: string
      required:
        - issuer
        - ok
        - problems
        - signing_keys
        - supports_pkce_s256
      type: object
    IdentityProviderInput:
      additionalProperties: false
      properties:
        adapter:
          type: string
          pattern: ^[a-z][a-z0-9_-]{0,31}$
          description: >-
            Defaults to oidc. Built-in adapters (FED-002): oidc (generic OpenID Connect), github (OAuth 2.0 with the
            REST user API; numeric account ID as subject; only verified emails), google (fixed issuer
            https://accounts.google.com; allowed_tenants restricts to Workspace domains through the hd claim), microsoft
            (Entra ID work and school accounts: issuer https://login.microsoftonline.com/{tenant}/v2.0 selected by tid,
            allowed_tenants required; its email claim is never treated as verified, so trusted_verified_email linking is
            refused). Deployments can register further adapters in code; unknown names are refused.
        alias:
          type: string
          description: Lower-case letters, digits and dashes (2..63). Part of the registered callback URL; cannot be changed.
        claim_mapping:
          oneOf:
            - $ref: '#/components/schemas/ClaimMapping'
            - type: 'null'
        client_secret:
          type:
            - string
            - 'null'
          x-secret: true
          format: password
          description: >-
            Upstream client secret (write-only; stored encrypted and never returned, see has_client_secret). On PUT,
            omit to keep the current secret; an empty string clears it.
        config:
          $ref: '#/components/schemas/IdentityProviderConfig'
        display_name:
          type: string
          maxLength: 100
        issuer:
          type: string
          description: >-
            Upstream issuer; required for OIDC connections. May contain {tenant} for multi-tenant issuers. Cannot change
            while identities are linked.
        jit_default_role_id:
          type: string
        jit_provisioning:
          type: boolean
        linking_policy:
          type: string
          enum:
            - verify_existing
            - trusted_verified_email
            - create_only
        organization_id:
          type: string
        state:
          type: string
          enum:
            - active
            - disabled
        trust_upstream_mfa:
          type: boolean
      type: object
      required:
        - alias
        - config
        - display_name
    ImpersonationGrant:
      additionalProperties: false
      properties:
        actor_user_id:
          type: string
        created_at:
          format: date-time
          type: string
        expires_at:
          format: date-time
          type: string
        id:
          type: string
        mode:
          type: string
        organization_id:
          type: string
        request_id:
          type: string
        resource_id:
          type: string
        revoke_reason:
          type: string
        revoked_at:
          format: date-time
          type:
            - string
            - 'null'
        scope_ceiling:
          items:
            type: string
          type:
            - array
            - 'null'
        state:
          type: string
        target_user_id:
          type: string
      required:
        - actor_user_id
        - created_at
        - expires_at
        - id
        - mode
        - organization_id
        - request_id
        - resource_id
        - scope_ceiling
        - state
        - target_user_id
      type: object
    ImpersonationIssued:
      additionalProperties: false
      properties:
        access_token:
          type: string
          x-secret: true
          description: Support (impersonation) access token. Returned once; never replayed.
        expires_in:
          type: integer
        grant:
          $ref: '#/components/schemas/ImpersonationGrant'
        scope:
          type: string
        token_type:
          type: string
      required:
        - access_token
        - expires_in
        - grant
        - scope
        - token_type
      type: object
    ImpersonationRequest:
      additionalProperties: false
      properties:
        actor_user_id:
          type: string
        approval_required:
          type: string
        approved_by:
          type: string
        created_at:
          format: date-time
          type: string
        expires_at:
          format: date-time
          type: string
        id:
          type: string
        mode:
          type: string
        organization_id:
          type: string
        resource_id:
          type: string
        scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        state:
          type: string
        target_user_id:
          type: string
        ticket_reference:
          type: string
      required:
        - actor_user_id
        - approval_required
        - created_at
        - expires_at
        - id
        - mode
        - organization_id
        - resource_id
        - scopes
        - state
        - target_user_id
      type: object
    ImpersonationRequestInput:
      additionalProperties: false
      properties:
        audience:
          type: string
        client_id:
          type: string
        mode:
          type: string
          enum:
            - read_only
            - allowlisted_write
        organization_id:
          type: string
        reason:
          type: string
        scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        target_user_id:
          type: string
        ticket_reference:
          type: string
        ttl_seconds:
          type: integer
      type: object
      required:
        - reason
        - target_user_id
    IntrospectionResponse:
      type: object
      additionalProperties: true
      description: >-
        RFC 7662 introspection response. Inactive, unknown, revoked or out-of-audience tokens return only {"active":
        false}.
      properties:
        active:
          type: boolean
        iss:
          type: string
        sub:
          type: string
        aud:
          type: string
        client_id:
          type: string
        scope:
          type: string
        exp:
          type: integer
          format: int64
        iat:
          type: integer
          format: int64
        jti:
          type: string
        token_kind:
          type: string
        token_type:
          type: string
          enum:
            - Bearer
            - DPoP
          description: >-
            DPoP for a token bound to a DPoP key (cnf.jkt, RFC 9449 section 6.2); Bearer otherwise, also for
            certificate-bound tokens (RFC 8705).
        authz_version:
          type: integer
          format: int64
        org_id:
          type: string
        sid:
          type: string
        auth_time:
          type: integer
          format: int64
        acr:
          type: string
        act:
          type: object
          additionalProperties: true
        cnf:
          type: object
          additionalProperties: true
        agent:
          type: boolean
          const: true
          description: >-
            Present (true) when the subject is a service principal registered as an autonomous agent (MCH-017): for its
            JWT and opaque access tokens and its API keys.
        subject_type:
          type: string
        impersonation_grant_id:
          type: string
      required:
        - active
    Invitation:
      additionalProperties: false
      properties:
        accepted_at:
          format: date-time
          type:
            - string
            - 'null'
        accepted_by_user_id:
          type: string
        allowed_domains:
          items:
            type: string
          type:
            - array
            - 'null'
        created_at:
          format: date-time
          type: string
        delivery_state:
          type: string
        expires_at:
          format: date-time
          type: string
        id:
          type: string
        inviter_id:
          type: string
        inviter_type:
          type: string
        max_uses:
          type: integer
        batch_id:
          type: string
        superseded_by:
          type: string
          description: Set when an administrator reassigned this invitation (INV-014).
        membership_id:
          type: string
        organization_id:
          type: string
        project_id:
          type: string
        purpose:
          type: string
        role_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        secret_version:
          type: integer
        send_count:
          type: integer
        state:
          type: string
        target_email:
          type: string
        target_user_id:
          type: string
        use_count:
          type: integer
        version:
          format: int64
          type: integer
      required:
        - created_at
        - delivery_state
        - expires_at
        - id
        - inviter_id
        - inviter_type
        - max_uses
        - organization_id
        - purpose
        - role_ids
        - secret_version
        - send_count
        - state
        - use_count
        - version
      type: object
    InvitationAcceptance:
      additionalProperties: false
      description: >-
        Organization invitations return membership_id; project invitations (INV-012) return project_id and
        assignment_ids and create no membership.
      properties:
        invitation_id:
          type: string
        membership_id:
          type: string
        organization_id:
          type: string
        project_id:
          type: string
        assignment_ids:
          type: array
          items:
            type: string
      required:
        - invitation_id
        - organization_id
      type: object
    InvitationInput:
      additionalProperties: false
      properties:
        allowed_domains:
          items:
            type: string
          type:
            - array
            - 'null'
        email:
          type: string
          description: Target email; an email or user_id is required unless purpose is shared_link.
        locale:
          type: string
        max_uses:
          type: integer
        message:
          type: string
        project_id:
          type: string
        purpose:
          type: string
          enum:
            - organization_membership
            - project_access
            - shared_link
          description: Defaults to organization_membership.
        role_ids:
          items:
            type: string
          type:
            - array
            - 'null'
          maxItems: 10
        ttl_hours:
          type: integer
        user_id:
          type: string
      type: object
    InvitationInspection:
      additionalProperties: false
      properties:
        expires_at:
          format: date-time
          type: string
        organization_id:
          type: string
        organization_name:
          type: string
        purpose:
          type: string
        requires_account:
          type: boolean
      required:
        - expires_at
        - organization_id
        - organization_name
        - purpose
        - requires_account
      type: object
    JWKSet:
      type: object
      description: Public verification keys (RFC 7517). Never contains private key material.
      properties:
        keys:
          type: array
          items:
            type: object
            additionalProperties: true
      required:
        - keys
    Job:
      additionalProperties: false
      properties:
        attempts:
          type: integer
        cancel_requested:
          type: boolean
        created_at:
          format: date-time
          type: string
        dry_run:
          type: boolean
        finished_at:
          format: date-time
          type:
            - string
            - 'null'
        has_protected_result:
          type: boolean
        id:
          type: string
        input:
          additionalProperties: {}
          type:
            - object
            - 'null'
          description: >-
            The non-secret job input as submitted. Secret-bearing input (user.import records with password verifiers,
            TOTP seeds and contact data) is stored as protected input: encrypted at rest, never returned here, and
            erased when the job finishes.
        last_error:
          type: string
        organization_id:
          type: string
        progress:
          additionalProperties: {}
          type:
            - object
            - 'null'
        realm_id:
          type: string
        requested_by_id:
          type: string
        requested_by_type:
          type: string
        result:
          additionalProperties: {}
          type:
            - object
            - 'null'
        result_expires_at:
          format: date-time
          type:
            - string
            - 'null'
        state:
          type: string
          description: queued, running, succeeded, failed or cancelled.
        type:
          type: string
      required:
        - attempts
        - cancel_requested
        - created_at
        - dry_run
        - has_protected_result
        - id
        - progress
        - requested_by_id
        - requested_by_type
        - state
        - type
      type: object
    JobAccepted:
      type: object
      description: Reference to an asynchronous job; poll GET /api/v1/realms/{realm}/jobs/{id}.
      properties:
        job_id:
          type: string
      required:
        - job_id
    JoinRequest:
      additionalProperties: false
      properties:
        reviewer_ids:
          type: array
          items:
            type: string
          description: >-
            Assigned reviewers; empty when any member holding org.join_requests.review may decide. Always empty in the
            requester's own listing.
        created_at:
          format: date-time
          type: string
        decided_at:
          format: date-time
          type:
            - string
            - 'null'
        decided_by:
          type: string
        expires_at:
          format: date-time
          type: string
        id:
          type: string
        organization_id:
          type: string
        reason:
          type: string
        state:
          type: string
        user_id:
          type: string
      required:
        - created_at
        - expires_at
        - id
        - organization_id
        - state
        - user_id
      type: object
    LinkedIdentity:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        email_hint:
          type: string
        id:
          type: string
        last_used_at:
          format: date-time
          type:
            - string
            - 'null'
        provenance:
          type: string
        provider:
          type: string
        provider_display_name:
          type: string
        provider_id:
          type: string
      required:
        - created_at
        - id
        - provenance
        - provider
        - provider_display_name
        - provider_id
      type: object
    MachineCredential:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        display_prefix:
          type: string
        expires_at:
          format: date-time
          type: string
        id:
          type: string
        kind:
          type: string
          enum:
            - api_key
            - personal_token
        last_used_at:
          format: date-time
          type:
            - string
            - 'null'
        name:
          type: string
        organization_id:
          type: string
        owner_id:
          type: string
        owner_type:
          type: string
        resource_id:
          type: string
        revoked_at:
          format: date-time
          type:
            - string
            - 'null'
        scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        state:
          type: string
      required:
        - created_at
        - display_prefix
        - expires_at
        - id
        - kind
        - name
        - owner_id
        - owner_type
        - resource_id
        - scopes
        - state
      type: object
    MachineCredentialInput:
      additionalProperties: false
      properties:
        audience:
          type: string
        name:
          type: string
        organization_id:
          type: string
        scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        ttl_days:
          type: integer
          maximum: 365
          description: Expiry is mandatory; at most 365 days.
      type: object
      required:
        - audience
        - name
        - scopes
    MaskedUser:
      type: object
      description: Masked view returned to support operators holding only support.users.read (identifier values are masked).
      properties:
        id:
          type: string
        state:
          type: string
        display_name:
          type: string
        identifiers:
          type: array
          items:
            $ref: '#/components/schemas/UserIdentifier'
        created_at:
          type: string
          format: date-time
        last_login_at:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - id
        - state
        - display_name
        - identifiers
        - created_at
        - last_login_at
    Membership:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        display_name:
          type: string
        email:
          type: string
        expires_at:
          format: date-time
          type:
            - string
            - 'null'
        external_id:
          type: string
        id:
          type: string
        joined_at:
          format: date-time
          type:
            - string
            - 'null'
        metadata:
          type: object
          additionalProperties: true
          description: >-
            Organization membership metadata (USR-009), at most limits.metadata_bytes as JSON. Present only for callers
            holding org.members.write in the organization; never shown to the member or put in tokens.
        organization_id:
          type: string
        removed_at:
          format: date-time
          type:
            - string
            - 'null'
        revision:
          format: int64
          type: integer
        roles:
          items:
            type: string
          type:
            - array
            - 'null'
        source:
          type: string
        source_reference:
          type: string
        state:
          type: string
        user_id:
          type: string
      required:
        - created_at
        - id
        - organization_id
        - revision
        - source
        - state
        - user_id
      type: object
    MembershipSummary:
      type: object
      properties:
        membership_id:
          type: string
        organization_id:
          type: string
        slug:
          type: string
        display_name:
          type: string
        membership_state:
          type: string
        organization_state:
          type: string
        joined_at:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - membership_id
        - organization_id
        - slug
        - display_name
        - membership_state
        - organization_state
        - joined_at
    NotificationJob:
      additionalProperties: false
      properties:
        attempts:
          type: integer
        channel:
          type: string
        created_at:
          format: date-time
          type: string
        id:
          type: string
        last_error:
          type: string
        recipient_hint:
          type: string
        reference_id:
          type: string
        reference_type:
          type: string
        state:
          type: string
        template:
          type: string
        updated_at:
          format: date-time
          type: string
      required:
        - attempts
        - channel
        - created_at
        - id
        - recipient_hint
        - state
        - template
        - updated_at
      type: object
    NotificationTemplate:
      type: object
      properties:
        id:
          type: string
        organization_id:
          type: string
        event_type:
          type: string
        locale:
          type: string
        subject:
          type: string
        body_text:
          type: string
        version:
          type: integer
      required:
        - id
        - organization_id
        - event_type
        - locale
        - subject
        - body_text
        - version
    OAuthError:
      type: object
      description: OAuth 2.0 error response (RFC 6749 section 5.2) used by protocol endpoints.
      properties:
        error:
          type: string
        error_description:
          type: string
      required:
        - error
    Obligation:
      type: object
      description: A mandatory condition the caller must satisfy (or deny).
      properties:
        type:
          type: string
          enum:
            - reauthenticate
        required_profile:
          type: string
        max_age_seconds:
          type: integer
      required:
        - type
    OpenIDConfiguration:
      type: object
      description: >-
        OpenID Provider / OAuth 2.0 Authorization Server metadata. Optional endpoints are advertised only when the
        capability is enabled.
      properties:
        issuer:
          type: string
          format: uri
        authorization_endpoint:
          type: string
        token_endpoint:
          type: string
        jwks_uri:
          type: string
        userinfo_endpoint:
          type: string
        introspection_endpoint:
          type: string
        revocation_endpoint:
          type: string
        end_session_endpoint:
          type: string
        device_authorization_endpoint:
          type: string
        pushed_authorization_request_endpoint:
          type: string
        registration_endpoint:
          type: string
        check_session_iframe:
          type: string
          description: OpenID Connect Session Management 1.0 (OIDC-014); present only when the realm turned it on.
        response_types_supported:
          type: array
          items:
            type: string
        response_modes_supported:
          type: array
          items:
            type: string
        grant_types_supported:
          type: array
          items:
            type: string
        subject_types_supported:
          type: array
          items:
            type: string
        id_token_signing_alg_values_supported:
          type: array
          items:
            type: string
        userinfo_signing_alg_values_supported:
          type: array
          items:
            type: string
        token_endpoint_auth_methods_supported:
          type: array
          items:
            type: string
        token_endpoint_auth_signing_alg_values_supported:
          type: array
          items:
            type: string
        introspection_endpoint_auth_methods_supported:
          type: array
          items:
            type: string
        revocation_endpoint_auth_methods_supported:
          type: array
          items:
            type: string
        code_challenge_methods_supported:
          type: array
          items:
            type: string
        scopes_supported:
          type: array
          items:
            type: string
        claims_supported:
          type: array
          items:
            type: string
        claims_parameter_supported:
          type: boolean
        request_parameter_supported:
          type: boolean
        request_uri_parameter_supported:
          type: boolean
        require_request_uri_registration:
          type: boolean
        require_pushed_authorization_requests:
          type: boolean
        prompt_values_supported:
          type: array
          items:
            type: string
        acr_values_supported:
          type: array
          items:
            type: string
        authorization_response_iss_parameter_supported:
          type: boolean
        authorization_signing_alg_values_supported:
          type: array
          items:
            type: string
          description: 'JARM (ADV-002): algorithms of the published signing keys.'
        authorization_encryption_alg_values_supported:
          type: array
          items:
            type: string
          description: 'JARM response encryption: RSA-OAEP-256, ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A256KW.'
        authorization_encryption_enc_values_supported:
          type: array
          items:
            type: string
          description: 'JARM content encryption: A128GCM, A256GCM.'
        id_token_encryption_alg_values_supported:
          type: array
          items:
            type: string
          description: 'TOK-020: RSA-OAEP-256, ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A256KW.'
        id_token_encryption_enc_values_supported:
          type: array
          items:
            type: string
          description: A128GCM, A256GCM.
        userinfo_encryption_alg_values_supported:
          type: array
          items:
            type: string
          description: 'OIDC-013: RSA-OAEP-256, ECDH-ES, ECDH-ES+A128KW, ECDH-ES+A256KW.'
        userinfo_encryption_enc_values_supported:
          type: array
          items:
            type: string
          description: A128GCM, A256GCM.
        tls_client_certificate_bound_access_tokens:
          type: boolean
          description: >-
            true when client certificates reach the server (server.mtls_listen or server.client_cert_header; RFC 8705,
            TOK-019); false otherwise.
        mtls_endpoint_aliases:
          type: object
          description: >-
            RFC 8705 §5: the mutual-TLS listener's endpoints, present only when server.mtls_origin is set.
            pushed_authorization_request_endpoint and device_authorization_endpoint appear with those capabilities.
          properties:
            token_endpoint:
              type: string
            introspection_endpoint:
              type: string
            revocation_endpoint:
              type: string
            userinfo_endpoint:
              type: string
            pushed_authorization_request_endpoint:
              type: string
            device_authorization_endpoint:
              type: string
          additionalProperties: false
        frontchannel_logout_supported:
          type: boolean
          description: 'OIDC Front-Channel Logout 1.0 (SES-018): true with the logout endpoint.'
        frontchannel_logout_session_supported:
          type: boolean
          description: >-
            true with the logout endpoint: iss and sid are added to the front-channel logout URI when the client asks
            for them.
        backchannel_logout_supported:
          type: boolean
        backchannel_logout_session_supported:
          type: boolean
        dpop_signing_alg_values_supported:
          type: array
          items:
            type: string
        service_documentation:
          type: string
      required:
        - issuer
        - authorization_endpoint
        - token_endpoint
        - jwks_uri
        - response_types_supported
        - subject_types_supported
        - id_token_signing_alg_values_supported
    OrgPolicy:
      additionalProperties: false
      properties:
        audit_retention_days:
          type: integer
          minimum: 30
          maximum: 3650
          description: >-
            Keeps this organization's audit evidence at least this many days (AUD-009); it never shortens the realm's or
            deployment's retention.
        personal_tokens:
          type: string
          enum:
            - allowed
            - disabled
          description: disabled forbids personal access tokens in this organization's context (MCH-006).
        personal_token_max_days:
          type: integer
          minimum: 0
          maximum: 365
        registration_mode:
          type: string
          enum:
            - inherit
            - public
            - closed
            - invitation_only
            - domain_restricted
          description: >-
            Narrows realm registration in this organization's context (REG-001): requested organization, invited
            organization, or the organization owning the email domain. It can only tighten the realm mode.
        allowed_scopes:
          type: array
          items:
            type: string
          description: >-
            Organization scope ceiling (TOK-008); tokens in this organization's context carry only these business
            scopes.
        allowed_email_domains:
          items:
            type: string
          type:
            - array
            - 'null'
        allowed_login_methods:
          items:
            type: string
          type:
            - array
            - 'null'
        impersonation_approval:
          type: string
        invitations_enabled:
          type:
            - boolean
            - 'null'
        join_requests_enabled:
          type: boolean
        mfa_required:
          type: boolean
        session_absolute_seconds:
          type: integer
        session_idle_seconds:
          type: integer
        sso_provider_id:
          type: string
        sso_required:
          type: boolean
        support_access_opt_out:
          type: boolean
      type: object
    Organization:
      additionalProperties: false
      properties:
        authz_revision:
          format: int64
          type: integer
        contact:
          additionalProperties: {}
          type:
            - object
            - 'null'
        created_at:
          format: date-time
          type: string
        display_name:
          type: string
        external_id:
          type: string
        id:
          type: string
        locale:
          type: string
        metadata:
          additionalProperties: {}
          type:
            - object
            - 'null'
        policy:
          $ref: '#/components/schemas/OrgPolicy'
        realm_id:
          type: string
        slug:
          type: string
        state:
          type: string
        time_zone:
          type: string
        updated_at:
          format: date-time
          type: string
        version:
          format: int64
          type: integer
      required:
        - authz_revision
        - contact
        - created_at
        - display_name
        - id
        - metadata
        - policy
        - realm_id
        - slug
        - state
        - updated_at
        - version
      type: object
    OrganizationDeletionPreview:
      additionalProperties: false
      properties:
        active_grants:
          type: integer
        active_members:
          type: integer
        active_support_grants:
          type: integer
        owned_projects:
          type: integer
        owned_clients:
          type: integer
          description: Active clients of the organization's projects and service principals; suspended at once.
        pending_invitations:
          type: integer
        provisioning_connectors:
          type: integer
        role_assignments:
          type: integer
          description: Role assignments scoped to the organization; removed.
        groups:
          type: integer
        verified_domains:
          type: integer
        owned_service_principals:
          type: integer
          description: Service principals owned by the organization; disabled at once.
        active_automation_credentials:
          type: integer
          description: API keys and personal tokens in the organization; revoked at once.
        webhook_subscriptions:
          type: integer
          description: Organization webhooks; disabled at once and deleted with their secrets when the deletion finishes.
        identity_providers:
          type: integer
          description: Organization identity providers; disabled at once, client secrets erased when the deletion finishes.
        mail_server_configured:
          type: boolean
          description: An organization mail server (TEN-022); its configuration and credential are erased.
        consent_preauthorizations:
          type: integer
          description: Live administrative consent pre-authorizations for the organization; revoked at once.
        export_results:
          type: integer
          description: Job results (exports) of the organization still downloadable; erased at once.
        pending_jobs:
          type: integer
          description: Queued or running jobs of the organization; cancelled at once.
        retained_audit_events:
          type: integer
          description: Audit events about the organization; retained under the audit retention policy and legal holds.
        active_legal_holds:
          type: integer
          description: >-
            Active legal holds that keep evidence of the organization: realm-wide holds, holds on the organization, and
            holds on an account that is a member of it (in any membership state).
        retained:
          type: array
          items:
            type: string
          description: What the deletion keeps.
      required:
        - active_grants
        - active_members
        - active_support_grants
        - owned_projects
        - pending_invitations
        - provisioning_connectors
      type: object
    OrganizationInput:
      additionalProperties: false
      properties:
        contact:
          additionalProperties: {}
          type:
            - object
            - 'null'
        display_name:
          type: string
          maxLength: 200
        external_id:
          type: string
        locale:
          type: string
        metadata:
          additionalProperties: {}
          type:
            - object
            - 'null'
        policy:
          oneOf:
            - $ref: '#/components/schemas/OrgPolicy'
            - type: 'null'
        slug:
          type: string
          description: 2-63 lowercase letters, digits or dashes; derived when omitted.
        time_zone:
          type: string
      type: object
      required:
        - display_name
    Passkey:
      additionalProperties: false
      properties:
        aaguid:
          type: string
        attestation_trusted:
          type: boolean
          description: 'PASS-009: the attestation chained to trusted metadata; otherwise the AAGUID is self-reported.'
        attestation_format:
          type: string
        backup_eligible:
          type: boolean
        created_at:
          format: date-time
          type: string
        discoverable:
          type: boolean
        id:
          type: string
        last_used_at:
          format: date-time
          type:
            - string
            - 'null'
        name:
          type: string
        synced:
          type: boolean
        transports:
          items:
            type: string
          type:
            - array
            - 'null'
        user_verified:
          type: boolean
      required:
        - backup_eligible
        - created_at
        - discoverable
        - id
        - name
        - synced
        - transports
        - user_verified
      type: object
    PasskeyRegistrationOptions:
      type: object
      properties:
        ceremony_id:
          type: string
        public_key:
          type: object
          additionalProperties: true
          description: W3C WebAuthn PublicKeyCredentialCreationOptions (JSON encoding) to pass to navigator.credentials.create().
        expires_at:
          type: string
          format: date-time
      required:
        - ceremony_id
        - public_key
        - expires_at
    PasswordResetRequested:
      additionalProperties: false
      properties:
        expires_at:
          format: date-time
          type: string
        message:
          type: string
        reset_id:
          type: string
      required:
        - expires_at
        - message
        - reset_id
      type: object
    Permission:
      additionalProperties: false
      properties:
        built_in:
          type: boolean
        description:
          type: string
        id:
          type: string
        name:
          type: string
        namespace:
          type: string
        owner_resource_id:
          type: string
        resource_type:
          type: string
        sensitivity:
          type: string
          description: Defaults to normal. Privileged permissions produce step-up obligations in decisions.
      type: object
      required:
        - name
    RememberedDevice:
      type: object
      properties:
        id:
          type: string
        label:
          type: string
        created_at:
          type: string
          format: date-time
        last_used_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
    AssignmentRequest:
      type: object
      properties:
        id:
          type: string
        role_id:
          type: string
        subject:
          type: object
          properties:
            type:
              type: string
            id:
              type: string
        scope:
          type: object
          properties:
            type:
              type: string
            id:
              type: string
        conditions:
          $ref: '#/components/schemas/GrantConditions'
        valid_from:
          type: string
          format: date-time
        assignment_expires_at:
          type: string
          format: date-time
        reason:
          type: string
        requested_by:
          type: string
        state:
          type: string
          enum:
            - pending
            - approved
            - rejected
            - expired
        decided_by:
          type: string
        decided_at:
          type: string
          format: date-time
        assignment_id:
          type: string
        expires_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
    HookInput:
      type: object
      properties:
        owner_user_id:
          type: string
          description: Accountable owner (DOM-009); defaults to the creating user.
        name:
          type: string
        kind:
          type: string
          enum:
            - registration.eligibility
            - profile.validation
            - token.claims
            - authorization.decision
            - authentication.risk
        url:
          type: string
          format: uri
        timeout_ms:
          type: integer
          minimum: 100
          maximum: 5000
        failure_mode:
          type: string
          enum:
            - deny
            - skip
        client_ids:
          type: array
          items:
            type: string
        allow_private_network:
          type: boolean
        state:
          type: string
          enum:
            - active
            - disabled
        contract_version:
          type: integer
          enum:
            - 1
          description: Hook contract version (EXT-018), sent as ProudAuth-Hook-Version; default 1. See api/hooks.
      required:
        - name
        - kind
        - url
      additionalProperties: false
    Hook:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        kind:
          type: string
        url:
          type: string
        timeout_ms:
          type: integer
        failure_mode:
          type: string
        client_ids:
          type: array
          items:
            type: string
        allow_private_network:
          type: boolean
        state:
          type: string
        invocations:
          type: integer
        failures:
          type: integer
        last_latency_ms:
          type: integer
        last_failure_at:
          type: string
          format: date-time
        last_error:
          type: string
        contract_version:
          type: integer
          description: Hook contract version (EXT-018).
        plugin_id:
          type: string
          description: Set when a plugin manages the hook; PUT and DELETE then return 409 (EXT-014).
        version:
          type: integer
        created_at:
          type: string
          format: date-time
    ActivityEvent:
      type: object
      properties:
        type:
          type: string
        occurred_at:
          type: string
          format: date-time
        outcome:
          type: string
        network:
          type: string
          description: Privacy-reduced network context.
        client_id:
          type: string
        performed_by:
          type: string
          description: Actor type when someone other than the account owner acted.
        support_grant_id:
          type: string
        reason_code:
          type: string
        details:
          type: object
    InvitationBatchResult:
      type: object
      properties:
        index:
          type: integer
        status:
          type: integer
          description: HTTP status the entry would have produced on its own.
        invitation_id:
          type: string
        error:
          type: object
          description: Problem summary (code, title, detail, errors) for a failed entry.
      required:
        - index
        - status
    ProjectGrant:
      type: object
      properties:
        id:
          type: string
        project_id:
          type: string
        organization_id:
          type: string
        allowed_role_ids:
          type: array
          items:
            type: string
        state:
          type: string
          enum:
            - active
            - suspended
            - revoked
        valid_until:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
    GrantConditions:
      type: object
      additionalProperties: false
      description: >-
        Conditions on a role assignment (AZ-012). Unknown members are rejected; a condition that cannot be evaluated for
        the trusted request context fails closed. The support capability members (IMP-002, IMP-007) apply only to
        support access and bound the organizations, target categories, modes and scopes an operator may use, re-checked
        on every use of a grant.
      properties:
        client_ids:
          type: array
          maxItems: 50
          items:
            type: string
        resources:
          type: array
          maxItems: 50
          items:
            type: string
          description: Resource IDs or audiences.
        min_assurance:
          type: string
          enum:
            - mfa
            - phishing_resistant
        max_auth_age_seconds:
          type: integer
          minimum: 0
          maximum: 86400
        active_hours_utc:
          type: array
          minItems: 2
          maxItems: 2
          items:
            type: integer
        weekdays:
          type: array
          items:
            type: integer
            minimum: 0
            maximum: 6
        organization_ids:
          type: array
          maxItems: 200
          items:
            type: string
        subject_categories:
          type: array
          items:
            type: string
            enum:
              - member
              - guest
        support_modes:
          type: array
          items:
            type: string
            enum:
              - read_only
              - allowlisted_write
        support_scopes:
          type: array
          maxItems: 50
          items:
            type: string
    ScimResource:
      type: object
      description: A SCIM resource or discovery document.
      additionalProperties: true
      properties:
        schemas:
          type: array
          items:
            type: string
        id:
          type: string
        externalId:
          type: string
        meta:
          type: object
          additionalProperties: true
    ScimListResponse:
      type: object
      properties:
        schemas:
          type: array
          items:
            type: string
        totalResults:
          type: integer
        startIndex:
          type: integer
        itemsPerPage:
          type: integer
        Resources:
          type: array
          items:
            $ref: '#/components/schemas/ScimResource'
      required:
        - schemas
        - totalResults
    ScimUser:
      type: object
      additionalProperties: true
      properties:
        schemas:
          type: array
          items:
            type: string
        userName:
          type: string
        externalId:
          type: string
        displayName:
          type: string
        name:
          type: object
          properties:
            givenName:
              type: string
            familyName:
              type: string
        emails:
          type: array
          items:
            type: object
            properties:
              value:
                type: string
              type:
                type: string
              primary:
                type: boolean
        active:
          type: boolean
          description: Membership state in the connector organization.
      required:
        - userName
    ScimGroup:
      type: object
      additionalProperties: true
      properties:
        schemas:
          type: array
          items:
            type: string
        displayName:
          type: string
        externalId:
          type: string
        members:
          type: array
          items:
            type: object
            properties:
              value:
                type: string
      required:
        - displayName
    ScimPatchOp:
      type: object
      additionalProperties: true
      properties:
        schemas:
          type: array
          items:
            type: string
        Operations:
          type: array
          items:
            type: object
            properties:
              op:
                type: string
                description: add, replace or remove (case-insensitive).
              path:
                type: string
              value: {}
            required:
              - op
      required:
        - Operations
    ScimErrorDocument:
      type: object
      properties:
        schemas:
          type: array
          items:
            type: string
        status:
          type: string
        scimType:
          type: string
        detail:
          type: string
      required:
        - schemas
        - status
    ProvisioningConnectorInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
        kind:
          type: string
          enum:
            - scim_inbound
        allowed_resource_types:
          type: array
          items:
            type: string
            enum:
              - User
              - Group
        role_ceiling_ids:
          type: array
          items:
            type: string
          description: Roles the connector may ever grant; within the creator own ceiling.
        group_role_mappings:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Approved mappings from SCIM group display names to role IDs within the ceiling.
        default_role_id:
          type: string
        config:
          type: object
          additionalProperties: true
      required:
        - name
    ProvisioningConnector:
      type: object
      properties:
        id:
          type: string
        organization_id:
          type: string
        name:
          type: string
        kind:
          type: string
        state:
          type: string
          enum:
            - active
            - disabled
        allowed_resource_types:
          type: array
          items:
            type: string
        role_ceiling_ids:
          type: array
          items:
            type: string
        group_role_mappings:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
        default_role_id:
          type: string
        config:
          type: object
          additionalProperties: true
        last_sync_at:
          type: string
          format: date-time
        last_error:
          type: string
        stats:
          type: object
          additionalProperties: true
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - name
        - state
        - version
    WorkloadTrustInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          maxLength: 100
        profile:
          type: string
          enum:
            - generic
            - github_actions
            - kubernetes
            - spiffe
        issuer:
          type: string
          description: >-
            https issuer the assertion's iss must equal (github_actions defaults to
            https://token.actions.githubusercontent.com; spiffe defaults to spiffe://<trust domain> for JWT-SVIDs
            without iss).
        jwks_uri:
          type: string
        jwks:
          type: object
          description: Inline JSON Web Key Set of the issuer's public signing keys (1 to 20).
        audience:
          type: string
          description: The exact audience the assertion must carry (in aud, string or array).
        subject:
          type: string
          description: Exact subject, or a prefix ending in * where the profile allows it.
        claim_constraints:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: >-
            Claims that must have one of the listed values; nested claims use / (for example kubernetes.io/namespace).
            iss, sub, aud, exp, nbf, iat and jti are not allowed here.
        algorithms:
          type: array
          items:
            type: string
            enum:
              - RS256
              - PS256
              - ES256
              - ES384
              - EdDSA
        max_assertion_lifetime_seconds:
          type: integer
          minimum: 60
          maximum: 86400
          description: Longest accepted exp minus iat (default 3600).
        require_jti:
          type: boolean
          description: >-
            Refuse assertions without jti (default true for github_actions). A jti, when present, is single-use per
            trust.
        state:
          type: string
          enum:
            - active
            - disabled
      required:
        - name
        - audience
        - subject
    WorkloadTrust:
      type: object
      properties:
        id:
          type: string
        client_id:
          type: string
          description: The client's internal reference.
        name:
          type: string
        profile:
          type: string
        issuer:
          type: string
        jwks_uri:
          type: string
        jwks:
          type: object
        audience:
          type: string
        subject:
          type: string
        claim_constraints:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
        algorithms:
          type: array
          items:
            type: string
        max_assertion_lifetime_seconds:
          type: integer
        require_jti:
          type: boolean
        state:
          type: string
        version:
          type: integer
        created_by_id:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        last_used_at:
          type: string
          format: date-time
    RegistrationToken:
      type: object
      properties:
        id:
          type: string
        kind:
          type: string
          enum:
            - initial
            - registration
        description:
          type: string
        allowed_scopes:
          type: array
          items:
            type: object
            properties:
              resource_id:
                type: string
              scopes:
                type: array
                items:
                  type: string
        project_id:
          type: string
        max_uses:
          type: integer
        uses:
          type: integer
        expires_at:
          type: string
          format: date-time
        state:
          type: string
          enum:
            - active
            - expired
            - revoked
            - exhausted
          description: 'expired: an initial access token past its expires_at (refused at registration; it can still be revoked).'
        created_by_id:
          type: string
        created_at:
          type: string
          format: date-time
        last_used_at:
          type: string
          format: date-time
    ResourceType:
      type: object
      properties:
        id:
          type: string
        resource_id:
          type: string
        name:
          type: string
        relations:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              subject_types:
                type: array
                items:
                  type: string
              implied_by:
                type: array
                items:
                  type: string
        permissions:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
        shareable_relations:
          type: array
          items:
            type: string
        share_permission:
          type: string
        version:
          type: integer
        created_by_id:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    ResourceShare:
      type: object
      properties:
        id:
          type: string
        organization_id:
          type: string
        resource_type:
          type: string
        object_id:
          type: string
        relation:
          type: string
        owner_user_id:
          type: string
        recipient_user_id:
          type: string
        state:
          type: string
          enum:
            - pending
            - accepted
            - declined
            - revoked
            - expired
        message:
          type: string
        expires_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        decided_at:
          type: string
          format: date-time
    ElevationEligibility:
      type: object
      properties:
        id:
          type: string
        user_id:
          type: string
        role_id:
          type: string
        role_name:
          type: string
        scope:
          type: object
          properties:
            type:
              type: string
            id:
              type: string
        max_duration_seconds:
          type: integer
        requires_approval:
          type: boolean
        state:
          type: string
          enum:
            - active
            - revoked
        created_by_id:
          type: string
        created_at:
          type: string
          format: date-time
    Elevation:
      type: object
      properties:
        id:
          type: string
        eligibility_id:
          type: string
        user_id:
          type: string
        role_id:
          type: string
        role_name:
          type: string
        scope:
          type: object
          properties:
            type:
              type: string
            id:
              type: string
        reason:
          type: string
        duration_seconds:
          type: integer
        state:
          type: string
          enum:
            - pending
            - active
            - rejected
            - ended
            - expired
            - cancelled
        requested_at:
          type: string
          format: date-time
        decided_by_id:
          type: string
        decided_at:
          type: string
          format: date-time
        starts_at:
          type: string
          format: date-time
        ends_at:
          type: string
          format: date-time
        assignment_id:
          type: string
    AccessReview:
      type: object
      properties:
        id:
          type: string
        organization_id:
          type: string
        name:
          type: string
        description:
          type: string
        state:
          type: string
          enum:
            - open
            - closed
            - cancelled
        reviewer_ids:
          type: array
          items:
            type: string
        role_ids:
          type: array
          items:
            type: string
        privileged_only:
          type: boolean
        on_no_decision:
          type: string
          enum:
            - keep
            - revoke
        due_at:
          type: string
          format: date-time
        overdue:
          type: boolean
        items_total:
          type: integer
        items_decided:
          type: integer
        summary:
          type: object
          additionalProperties:
            type: integer
        created_by_id:
          type: string
        created_at:
          type: string
          format: date-time
        closed_by_id:
          type: string
        closed_at:
          type: string
          format: date-time
    AccessReviewItem:
      type: object
      properties:
        id:
          type: string
        assignment_id:
          type: string
        role_id:
          type: string
        role_name:
          type: string
        subject:
          type: object
          properties:
            type:
              type: string
            id:
              type: string
        scope:
          type: object
          properties:
            type:
              type: string
            id:
              type: string
        source:
          type: string
        granted_by_id:
          type: string
        granted_at:
          type: string
          format: date-time
        privileged:
          type: boolean
        decision:
          type: string
          enum:
            - keep
            - revoke
        decided_by_id:
          type: string
        decided_at:
          type: string
          format: date-time
        comment:
          type: string
        outcome:
          type: string
          enum:
            - kept
            - revoked
            - already_removed
            - revoke_failed
        applied_at:
          type: string
          format: date-time
    CertificateTrustAnchor:
      type: object
      properties:
        id:
          type: string
        purpose:
          type: string
          enum:
            - client
            - user
        name:
          type: string
        certificate_pem:
          type: string
        subject:
          type: string
        fingerprint:
          type: string
          description: base64url SHA-256 of the authority certificate.
        not_after:
          type: string
          format: date-time
        revocation:
          type: string
          enum:
            - none
            - crl
        crl_next_update:
          type: string
          format: date-time
        map_san_email:
          type: boolean
        multi_factor:
          type: boolean
        state:
          type: string
        created_by_id:
          type: string
        created_at:
          type: string
          format: date-time
    CertificateBinding:
      type: object
      properties:
        id:
          type: string
        user_id:
          type: string
        anchor_id:
          type: string
        issuer_dn:
          type: string
        subject_dn:
          type: string
        state:
          type: string
        created_by_id:
          type: string
        created_at:
          type: string
          format: date-time
        last_used_at:
          type: string
          format: date-time
    AuthFlowDefinition:
      type: object
      description: The realm policy authentication_flow member (AUT-012).
      additionalProperties: true
      properties:
        rules:
          type: array
          maxItems: 50
          items:
            type: object
            additionalProperties: true
        challenge_provider:
          type: string
        email_code_alternative:
          type: boolean
    AuthFlowFinding:
      type: object
      required:
        - severity
        - code
        - rule
        - index
        - message
      properties:
        severity:
          type: string
          enum:
            - error
            - warning
        code:
          type: string
          enum:
            - bypass
            - unreachable
            - partial_bypass
            - skip_on_missing
            - deny_all
        rule:
          type: string
        index:
          type: integer
        by:
          type: string
        message:
          type: string
    AuthFlowAnalysis:
      type: object
      required:
        - errors
        - warnings
        - unreachable_rules
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/AuthFlowFinding'
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/AuthFlowFinding'
        unreachable_rules:
          type: array
          items:
            type: string
    AuthFlowResult:
      type: object
      required:
        - outcome
      properties:
        outcome:
          type: string
          enum:
            - allow
            - review
            - challenge
            - require_mfa
            - require_phishing_resistant
            - deny
        rule:
          type: string
        missing_signals:
          type: array
          items:
            type: string
    AuthFlowCase:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
        client_id:
          type: string
        organization_id:
          type: string
        method:
          type: string
        resources:
          type: array
          items:
            type: string
        ip:
          type: string
        known_device:
          type: boolean
        failed_attempts:
          type: integer
        risk:
          type: string
          enum:
            - low
            - medium
            - high
        risk_partial:
          type: boolean
        privileged:
          type: boolean
        assurance:
          type: string
    AuthFlowRevision:
      type: object
      required:
        - revision
        - state
        - definition
        - definition_hash
        - base_hash
        - analysis
        - created_by
        - created_at
      properties:
        revision:
          type: integer
        state:
          type: string
          enum:
            - draft
            - published
            - superseded
            - discarded
        definition:
          $ref: '#/components/schemas/AuthFlowDefinition'
        definition_hash:
          type: string
        base_hash:
          type: string
        note:
          type: string
        analysis:
          $ref: '#/components/schemas/AuthFlowAnalysis'
        rollback_of:
          type: integer
        policy_revision:
          type: integer
        created_by:
          type: object
        created_at:
          type: string
          format: date-time
        published_by:
          type: object
        published_at:
          type: string
          format: date-time
    SSFConfiguration:
      type: object
      properties:
        spec_version:
          type: string
        issuer:
          type: string
        jwks_uri:
          type: string
        delivery_methods_supported:
          type: array
          items:
            type: string
        configuration_endpoint:
          type: string
        status_endpoint:
          type: string
        add_subject_endpoint:
          type: string
        remove_subject_endpoint:
          type: string
        verification_endpoint:
          type: string
        authorization_schemes:
          type: array
          items:
            type: object
        default_subjects:
          type: string
        events_supported:
          type: array
          items:
            type: string
    SSFDelivery:
      type: object
      additionalProperties: false
      required:
        - method
      properties:
        method:
          type: string
          enum:
            - urn:ietf:rfc:8935
            - urn:ietf:rfc:8936
        endpoint_url:
          type: string
          description: Push target (receiver-supplied); for poll, assigned by the transmitter.
        authorization_header:
          type: string
          x-secret: true
          description: Write-only. Sent as the Authorization header of each push; stored encrypted and never returned.
    SSFStreamInput:
      type: object
      additionalProperties: false
      properties:
        stream_id:
          type: string
        delivery:
          $ref: '#/components/schemas/SSFDelivery'
        events_requested:
          type: array
          maxItems: 50
          items:
            type: string
        description:
          type: string
          maxLength: 500
        subject_scope:
          type: string
          enum:
            - client_users
            - listed
        iss: {}
        aud: {}
        events_supported: {}
        events_delivered: {}
        min_verification_interval: {}
        status: {}
        reason: {}
        client_id: {}
        created_at: {}
        updated_at: {}
    SSFStream:
      type: object
      required:
        - stream_id
        - iss
        - aud
        - delivery
        - events_supported
        - events_requested
        - events_delivered
        - min_verification_interval
        - subject_scope
        - status
      properties:
        stream_id:
          type: string
        iss:
          type: string
        aud:
          type: string
        delivery:
          $ref: '#/components/schemas/SSFDelivery'
        events_supported:
          type: array
          items:
            type: string
        events_requested:
          type: array
          items:
            type: string
        events_delivered:
          type: array
          items:
            type: string
        description:
          type: string
        min_verification_interval:
          type: integer
        subject_scope:
          type: string
          enum:
            - client_users
            - listed
            - all
        status:
          type: string
          enum:
            - enabled
            - paused
            - disabled
        reason:
          type: string
        client_id:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    SAMLEndpoint:
      type: object
      additionalProperties: false
      properties:
        binding:
          type: string
          enum:
            - urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect
            - urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
          description: 'Assertion consumer services: HTTP-POST only (default). Logout endpoints: HTTP-Redirect or HTTP-POST.'
        url:
          type: string
          format: uri
        response_url:
          type: string
          format: uri
          description: 'Logout endpoints: where LogoutResponses go (default url).'
        index:
          type: integer
          description: Assertion consumer service index (assigned in order when all are 0).
        is_default:
          type: boolean
          description: The default assertion consumer service (the first when none is marked).
      required:
        - url
    SAMLCertificate:
      type: object
      additionalProperties: false
      properties:
        pem:
          type: string
          description: PEM certificate.
        sha256_fingerprint:
          type: string
        subject:
          type: string
        not_before:
          type: string
          format: date-time
        not_after:
          type: string
          format: date-time
      required:
        - pem
        - sha256_fingerprint
        - not_before
        - not_after
    SAMLAttributeMapping:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          maxLength: 256
        name_format:
          type: string
          enum:
            - urn:oasis:names:tc:SAML:2.0:attrname-format:basic
            - urn:oasis:names:tc:SAML:2.0:attrname-format:uri
            - urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified
          description: 'Default: uri when the name contains a colon, basic otherwise.'
        friendly_name:
          type: string
          maxLength: 128
        source:
          type: string
          enum:
            - email
            - email_verified
            - name
            - given_name
            - family_name
            - preferred_username
            - locale
            - zoneinfo
            - phone_number
            - user_id
            - subject
            - organization_id
            - static
          description: >-
            email and phone_number release verified identifiers only; subject is the NameID value; an empty value is not
            released.
        value:
          type: string
          maxLength: 512
          description: Static attributes only; never under a protected identity name (SAML-006).
      required:
        - name
        - source
    SAMLIdentityProviderEndpoints:
      type: object
      additionalProperties: false
      properties:
        entity_id:
          type: string
          description: The realm issuer.
        metadata_url:
          type: string
        sso_url:
          type: string
        slo_url:
          type: string
      required:
        - entity_id
        - metadata_url
        - sso_url
        - slo_url
    SAMLApplication:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        entity_id:
          type: string
        client_ref:
          type: string
          description: Backing client (protocol saml).
        client_id:
          type: string
        state:
          type: string
          enum:
            - active
            - suspended
            - decommissioned
        name:
          type: string
          maxLength: 200
        description:
          type: string
        organization_id:
          type: string
          description: Only that organization's active members receive assertions; its policies apply to the sign-in.
        project_id:
          type: string
        environment:
          type: string
          enum:
            - production
            - staging
            - development
        first_party:
          type: boolean
        consent_mode:
          type: string
          enum:
            - required
            - preauthorized
          description: 'Default: preauthorized for first-party, required otherwise.'
        consent_terms_version:
          type: string
        require_mfa:
          type: boolean
        max_session_age_seconds:
          type: integer
        allow_remember_me:
          type: boolean
        login_ui_url:
          type: string
          description: 'Login interface for this application (default: the realm''s).'
        assertion_consumer_services:
          type: array
          items:
            $ref: '#/components/schemas/SAMLEndpoint'
        single_logout_services:
          type: array
          items:
            $ref: '#/components/schemas/SAMLEndpoint'
        require_signed_requests:
          type: boolean
          description: 'AuthnRequests must be signed with a registered certificate (default: true when certificates are registered).'
        name_id_format:
          type: string
          enum:
            - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
            - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
            - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
            - urn:oasis:names:tc:SAML:2.0:nameid-format:transient
          description: >-
            persistent (default): opaque, stable and different per application; emailAddress: the verified email only;
            unspecified: the account ID; transient: new per assertion.
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SAMLAttributeMapping'
        sign_response:
          type: boolean
          description: Sign the Response (default true).
        sign_assertion:
          type: boolean
          description: Sign the Assertion (default true).
        signature_algorithm:
          type: string
          enum:
            - http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
            - http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
            - http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
        allow_idp_initiated:
          type: boolean
          description: Allow unsolicited (IdP-initiated) responses (SAML-007); default false.
        idp_initiated_relay_state:
          type: string
          maxLength: 1024
        clock_skew_seconds:
          type: integer
          description: Default 120; at most saml.max_clock_skew.
        assertion_lifetime_seconds:
          type: integer
          description: Default 300; 60..1800.
        additional_audiences:
          type: array
          items:
            type: string
          description: Further Audience values (at most 5).
        encrypt_assertions:
          type: boolean
          description: Encrypt assertions (sign, then encrypt) to the encryption certificate.
        data_encryption_algorithm:
          type: string
          enum:
            - http://www.w3.org/2009/xmlenc11#aes256-gcm
            - http://www.w3.org/2009/xmlenc11#aes128-gcm
          description: Default aes256-gcm. AES-CBC is not offered (SAML-009).
        key_transport_algorithm:
          type: string
          enum:
            - http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p
            - http://www.w3.org/2009/xmlenc11#rsa-oaep
          description: Default rsa-oaep-mgf1p; xmlenc11 rsa-oaep uses SHA-256 and MGF1-SHA-256. RSA PKCS#1 v1.5 is not offered.
        authn_context_map:
          type: object
          additionalProperties:
            type: string
          description: >-
            AuthnContextClassRef -> local ACR (urn:proudauth:acr:...), extending the built-in mapping
            (PasswordProtectedTransport, Password, unspecified = single factor; MobileTwoFactorContract, TimeSyncToken,
            multipleauthn, REFEDS MFA = mfa).
        signing_certificates:
          type: array
          items:
            $ref: '#/components/schemas/SAMLCertificate'
        encryption_certificate:
          $ref: '#/components/schemas/SAMLCertificate'
        identity_provider:
          $ref: '#/components/schemas/SAMLIdentityProviderEndpoints'
        version:
          type: integer
          format: int64
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - entity_id
        - client_ref
        - client_id
        - state
        - assertion_consumer_services
        - name_id_format
        - attributes
        - signing_certificates
        - identity_provider
        - version
    SAMLApplicationInput:
      type: object
      additionalProperties: false
      properties:
        entity_id:
          type: string
          description: Required unless metadata_xml supplies it.
        metadata_xml:
          type: string
          description: Uploaded SP metadata (EntityDescriptor with an SPSSODescriptor).
        name:
          type: string
          maxLength: 200
        description:
          type: string
        organization_id:
          type: string
          description: Only that organization's active members receive assertions; its policies apply to the sign-in.
        project_id:
          type: string
        environment:
          type: string
          enum:
            - production
            - staging
            - development
        first_party:
          type: boolean
        consent_mode:
          type: string
          enum:
            - required
            - preauthorized
          description: 'Default: preauthorized for first-party, required otherwise.'
        consent_terms_version:
          type: string
        require_mfa:
          type: boolean
        max_session_age_seconds:
          type: integer
        allow_remember_me:
          type: boolean
        login_ui_url:
          type: string
          description: 'Login interface for this application (default: the realm''s).'
        assertion_consumer_services:
          type: array
          items:
            $ref: '#/components/schemas/SAMLEndpoint'
        single_logout_services:
          type: array
          items:
            $ref: '#/components/schemas/SAMLEndpoint'
        require_signed_requests:
          type: boolean
          description: 'AuthnRequests must be signed with a registered certificate (default: true when certificates are registered).'
        name_id_format:
          type: string
          enum:
            - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
            - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
            - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
            - urn:oasis:names:tc:SAML:2.0:nameid-format:transient
          description: >-
            persistent (default): opaque, stable and different per application; emailAddress: the verified email only;
            unspecified: the account ID; transient: new per assertion.
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/SAMLAttributeMapping'
        sign_response:
          type: boolean
          description: Sign the Response (default true).
        sign_assertion:
          type: boolean
          description: Sign the Assertion (default true).
        signature_algorithm:
          type: string
          enum:
            - http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
            - http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
            - http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
        allow_idp_initiated:
          type: boolean
          description: Allow unsolicited (IdP-initiated) responses (SAML-007); default false.
        idp_initiated_relay_state:
          type: string
          maxLength: 1024
        clock_skew_seconds:
          type: integer
          description: Default 120; at most saml.max_clock_skew.
        assertion_lifetime_seconds:
          type: integer
          description: Default 300; 60..1800.
        additional_audiences:
          type: array
          items:
            type: string
          description: Further Audience values (at most 5).
        encrypt_assertions:
          type: boolean
          description: Encrypt assertions (sign, then encrypt) to the encryption certificate.
        data_encryption_algorithm:
          type: string
          enum:
            - http://www.w3.org/2009/xmlenc11#aes256-gcm
            - http://www.w3.org/2009/xmlenc11#aes128-gcm
          description: Default aes256-gcm. AES-CBC is not offered (SAML-009).
        key_transport_algorithm:
          type: string
          enum:
            - http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p
            - http://www.w3.org/2009/xmlenc11#rsa-oaep
          description: Default rsa-oaep-mgf1p; xmlenc11 rsa-oaep uses SHA-256 and MGF1-SHA-256. RSA PKCS#1 v1.5 is not offered.
        authn_context_map:
          type: object
          additionalProperties:
            type: string
          description: >-
            AuthnContextClassRef -> local ACR (urn:proudauth:acr:...), extending the built-in mapping
            (PasswordProtectedTransport, Password, unspecified = single factor; MobileTwoFactorContract, TimeSyncToken,
            multipleauthn, REFEDS MFA = mfa).
        signing_certificates:
          type: array
          items:
            type: string
          description: PEM or base64 DER certificates for request and logout signatures.
        encryption_certificate:
          type: string
          description: PEM or base64 DER RSA certificate for encrypted assertions (requires encrypt_assertions).
      required:
        - name
    SAMLConnectionSettings:
      type: object
      additionalProperties: false
      properties:
        idp_entity_id:
          type: string
        sso_url:
          type: string
          description: HTTP-Redirect single sign-on endpoint.
        sp_entity_id:
          type: string
          description: Overrides the default service provider entity ID.
        sign_authn_requests:
          type: boolean
          description: Sign AuthnRequests with the realm SAML key (default true).
        require_signed_assertions:
          type: boolean
          description: Refuse assertions covered only by the response signature.
        name_id_format:
          type: string
          enum:
            - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
            - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
            - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
            - urn:oasis:names:tc:SAML:2.0:nameid-format:transient
        subject_attribute:
          type: string
          description: Take the stable subject from this attribute instead of the NameID (required for transient NameIDs).
        email_attribute:
          type: string
          description: 'Email attribute (default: the NameID when its format is emailAddress).'
        trust_email_verified:
          type: boolean
          description: Treat the asserted email as verified (SAML has no verification flag).
        trusted_authn_contexts:
          type: array
          items:
            type: string
          description: AuthnContextClassRef values that mean MFA, used with trust_upstream_mfa (FED-009).
        requested_authn_contexts:
          type: array
          items:
            type: string
          description: Sent as RequestedAuthnContext Comparison=minimum.
        force_authn:
          type: boolean
        clock_skew_seconds:
          type: integer
          description: Default 120; at most saml.max_clock_skew.
        signing_certificates:
          type: array
          items:
            $ref: '#/components/schemas/SAMLCertificate'
    SAMLServiceProvider:
      description: This realm's service provider side of the connection, to register with the identity provider.
      type: object
      additionalProperties: false
      properties:
        entity_id:
          type: string
        acs_url:
          type: string
        metadata_url:
          type: string
      required:
        - entity_id
        - acs_url
        - metadata_url
    SAMLConnection:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        organization_id:
          type: string
        alias:
          type: string
        display_name:
          type: string
          maxLength: 100
        state:
          type: string
          enum:
            - active
            - disabled
        linking_policy:
          type: string
          enum:
            - verify_existing
            - trusted_verified_email
            - create_only
        jit_provisioning:
          type: boolean
        jit_default_role_id:
          type: string
        trust_upstream_mfa:
          type: boolean
        allowed_email_domains:
          type: array
          items:
            type: string
        claim_mapping:
          $ref: '#/components/schemas/ClaimMapping'
          description: Maps SAML attribute names to profile fields (default displayName, givenName, sn).
        saml:
          $ref: '#/components/schemas/SAMLConnectionSettings'
        service_provider:
          $ref: '#/components/schemas/SAMLServiceProvider'
        version:
          type: integer
          format: int64
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - alias
        - display_name
        - state
        - linking_policy
        - saml
        - service_provider
        - version
    SAMLConnectionInput:
      type: object
      additionalProperties: false
      properties:
        organization_id:
          type: string
        alias:
          type: string
        display_name:
          type: string
          maxLength: 100
        state:
          type: string
          enum:
            - active
            - disabled
        linking_policy:
          type: string
          enum:
            - verify_existing
            - trusted_verified_email
            - create_only
        jit_provisioning:
          type: boolean
        jit_default_role_id:
          type: string
        trust_upstream_mfa:
          type: boolean
        allowed_email_domains:
          type: array
          items:
            type: string
        claim_mapping:
          $ref: '#/components/schemas/ClaimMapping'
          description: Maps SAML attribute names to profile fields (default displayName, givenName, sn).
        metadata_xml:
          type: string
          description: Uploaded IdP metadata (EntityDescriptor with an IDPSSODescriptor).
        idp_entity_id:
          type: string
        sso_url:
          type: string
          description: HTTP-Redirect single sign-on endpoint.
        sp_entity_id:
          type: string
          description: Overrides the default service provider entity ID.
        sign_authn_requests:
          type: boolean
          description: Sign AuthnRequests with the realm SAML key (default true).
        require_signed_assertions:
          type: boolean
          description: Refuse assertions covered only by the response signature.
        name_id_format:
          type: string
          enum:
            - urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
            - urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
            - urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
            - urn:oasis:names:tc:SAML:2.0:nameid-format:transient
        subject_attribute:
          type: string
          description: Take the stable subject from this attribute instead of the NameID (required for transient NameIDs).
        email_attribute:
          type: string
          description: 'Email attribute (default: the NameID when its format is emailAddress).'
        trust_email_verified:
          type: boolean
          description: Treat the asserted email as verified (SAML has no verification flag).
        trusted_authn_contexts:
          type: array
          items:
            type: string
          description: AuthnContextClassRef values that mean MFA, used with trust_upstream_mfa (FED-009).
        requested_authn_contexts:
          type: array
          items:
            type: string
          description: Sent as RequestedAuthnContext Comparison=minimum.
        force_authn:
          type: boolean
        clock_skew_seconds:
          type: integer
          description: Default 120; at most saml.max_clock_skew.
        signing_certificates:
          type: array
          items:
            type: string
          description: Trusted PEM or base64 DER certificates (at most 4; list two to overlap a rollover).
      required:
        - alias
        - display_name
    SAMLSigningKey:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        state:
          type: string
          enum:
            - pending
            - active
            - retiring
            - retired
        published:
          type: boolean
          description: Listed in metadata now.
        certificate:
          $ref: '#/components/schemas/SAMLCertificate'
        created_at:
          type: string
          format: date-time
        activated_at:
          type: string
          format: date-time
        retiring_at:
          type: string
          format: date-time
        publish_until:
          type: string
          format: date-time
      required:
        - id
        - state
        - published
        - certificate
        - created_at
    LDAPConnectorConfig:
      type: object
      additionalProperties: false
      description: >-
        LDAP/Active Directory connector configuration (PROV-011). Defaults follow the dialect. Never contains the bind
        password.
      properties:
        endpoints:
          type: array
          minItems: 1
          maxItems: 8
          items:
            type: string
          description: >-
            ldaps://host[:port] or ldap://host[:port] URLs, tried in order; the next one is used only after a transport
            failure (connect, TLS, timeout, server busy/unavailable), never after an answer such as invalid credentials.
            Referrals are never followed (PROV-014).
        start_tls:
          type: boolean
          default: true
          description: Upgrade ldap:// endpoints with StartTLS before any credential is sent; false only in development mode.
        ca_certificates_pem:
          type: string
          maxLength: 65536
          description: >-
            Additional trusted roots for this connector (PEM). Server certificates are always verified, including the
            host name.
        connect_timeout_seconds:
          type: integer
          minimum: 0
          maximum: 60
          description: '0: directory.connect_timeout.'
        operation_timeout_seconds:
          type: integer
          minimum: 0
          maximum: 120
          description: '0: directory.operation_timeout.'
        bind_dn:
          type: string
          description: Service account DN.
        dialect:
          type: string
          enum:
            - openldap
            - active_directory
          default: openldap
        user_base_dn:
          type: string
        user_scope:
          type: string
          enum:
            - sub
            - one
          default: sub
        user_filter:
          type: string
          description: >-
            RFC 4515 filter; default (objectClass=inetOrgPerson) or, for Active Directory,
            (&(objectCategory=person)(objectClass=user)).
        id_attribute:
          type: string
          description: 'Immutable entry identifier: entryUUID (default) or objectGUID (Active Directory).'
        login_attributes:
          type: array
          maxItems: 4
          items:
            type: string
          description: >-
            Attributes a sign-in identifier is matched against for first sign-in provisioning; the identifier is escaped
            (RFC 4515).
        attribute_mapping:
          type: object
          additionalProperties:
            type: string
          description: >-
            Local attribute (username, email, display_name, given_name, family_name, locale, zoneinfo, profile.<name>)
            to directory attribute.
        mode:
          type: string
          enum:
            - read_only
            - import_only
            - write_back
          default: read_only
          description: >-
            read_only: the directory owns the mapped attributes (local edits refused); import_only: attributes are
            imported at creation and locally owned afterwards (differences reported as divergence); write_back:
            write_back_attributes are editable and written to the directory first. The directory always owns the
            password and the account lifecycle (PROV-013).
        attribute_authority:
          type: object
          additionalProperties:
            type: string
            enum:
              - directory
              - local
          description: Per-attribute override of the mode's authority.
        write_back_attributes:
          type: array
          items:
            type: string
          description: write_back mode only; never username, email or the password.
        disabled_attribute:
          type: string
          description: Marks disabled entries outside Active Directory (whose userAccountControl is always honored).
        disabled_values:
          type: array
          items:
            type: string
        change_tracking:
          type: string
          enum:
            - usn
            - modify_timestamp
            - none
          description: >-
            Incremental cursor: Active Directory uSNChanged (bound to the domain controller; another controller forces a
            full run), modifyTimestamp (re-reads a 5-minute overlap), or none.
        page_size:
          type: integer
          minimum: 1
          maximum: 5000
          default: 500
          description: Simple paged results (RFC 2696) page size.
        max_entries:
          type: integer
          minimum: 0
          maximum: 1000000
          description: '0: directory.max_entries_per_run.'
        group_base_dn:
          type: string
        group_filter:
          type: string
        group_name_attribute:
          type: string
        group_member_attribute:
          type: string
          enum:
            - member
            - uniqueMember
            - memberUid
        jit_provisioning:
          type: boolean
          default: false
          description: Import an account at its first successful sign-in (FED-015).
        incremental_interval_seconds:
          type: integer
          description: '0 or 60..604800: scheduled incremental runs.'
        full_interval_seconds:
          type: integer
          description: '0 or 300..2592000: scheduled full runs (deletion detection).'
        deletion_threshold_percent:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
          description: A full run refuses to deprovision more than this share of linked accounts without allow_mass_deprovision.
        deletion_threshold_count:
          type: integer
          minimum: 0
          description: 'Optional absolute cap on deprovisioning per run (0: none).'
        deprovision_action:
          type: string
          enum:
            - suspend_account
            - remove_membership
            - suspend_membership
            - report_only
          description: >-
            Realm connectors: suspend_account (default) or report_only — accounts are never deleted. Organization
            connectors: remove_membership (default), suspend_membership or report_only — only the organization's access
            changes (PROV-005).
      required:
        - endpoints
        - bind_dn
        - user_base_dn
    OutboundConnectorConfig:
      type: object
      additionalProperties: false
      description: Outbound SCIM 2.0 connector configuration (PROV-010). Never contains the bearer token.
      properties:
        base_url:
          type: string
          description: >-
            SCIM base URL (https outside development); checked against the egress policy at configuration and on every
            connection.
        allow_private_network:
          type: boolean
          default: false
          description: >-
            Allow a private destination where the operator policy (delivery.allow_private_webhooks or
            delivery.egress_allowlist) permits it.
        timeout_seconds:
          type: integer
          minimum: 1
          maximum: 60
          default: 10
        max_attempts:
          type: integer
          minimum: 1
          maximum: 20
          default: 8
          description: >-
            Attempts before a delivery is dead-lettered; retries back off exponentially with jitter and honor
            Retry-After.
        eligible_organization_ids:
          type: array
          items:
            type: string
          description: >-
            Realm connectors: push accounts with an active membership in one of these organizations (every non-guest
            account when empty).
        eligible_group_ids:
          type: array
          items:
            type: string
          description: 'Organization connectors: push only members of one of these groups.'
        exclude_created_via:
          type: array
          items:
            type: string
          description: >-
            Skip accounts by provenance (for example scim:<connector> for accounts an inbound connector created from the
            same system), preventing loops (PROV-017).
        attribute_mapping:
          type: object
          additionalProperties:
            type: string
          description: >-
            SCIM attribute (userName, displayName, name.givenName, name.familyName, emails, locale, timezone, title) to
            local source (username, email, display_name, given_name, family_name, locale, zoneinfo, user_id,
            profile.<name>). externalId is always the local account ID. Only verified emails are pushed.
        deprovision_action:
          type: string
          enum:
            - deactivate
            - delete
          default: deactivate
        push_group_ids:
          type: array
          items:
            type: string
          description: Organization groups pushed with the downstream IDs of their members.
        reconcile_interval_seconds:
          type: integer
          description: '0 or 300..2592000: scheduled reconciliation runs.'
      required:
        - base_url
    DirectoryConnectorInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 100
        kind:
          type: string
          enum:
            - ldap
            - scim_outbound
        organization_id:
          type: string
          description: 'Realm API only: bind the connector to an organization.'
        config:
          oneOf:
            - $ref: '#/components/schemas/LDAPConnectorConfig'
            - $ref: '#/components/schemas/OutboundConnectorConfig'
          description: Kind-specific configuration.
        role_ceiling_ids:
          type: array
          items:
            type: string
          description: 'Organization connectors: roles the connector may ever grant, within the creator''s own ceiling.'
        group_role_mappings:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: Approved mappings from directory group names or DNs to role IDs within the ceiling.
        default_role_id:
          type: string
        credential:
          type: string
          maxLength: 4096
          x-secret: true
          description: >-
            Write-only: bind password (ldap) or downstream bearer token (scim_outbound). Stored encrypted; never
            returned.
      required:
        - name
        - kind
        - config
        - credential
    DirectoryConnectorUpdate:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 100
        kind:
          type: string
          description: Fixed after creation; must match when sent.
        organization_id:
          type: string
          description: Fixed after creation; must match when sent.
        config:
          oneOf:
            - $ref: '#/components/schemas/LDAPConnectorConfig'
            - $ref: '#/components/schemas/OutboundConnectorConfig'
        role_ceiling_ids:
          type: array
          items:
            type: string
        group_role_mappings:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
        default_role_id:
          type: string
        credential:
          type: string
          description: Not accepted here; use PUT .../credential.
        state:
          type: string
          enum:
            - active
            - disabled
      required:
        - name
        - config
    DirectoryConnector:
      type: object
      properties:
        id:
          type: string
        organization_id:
          type: string
          description: Absent for realm-wide (workforce) connectors.
        name:
          type: string
        kind:
          type: string
          enum:
            - ldap
            - scim_outbound
        state:
          type: string
          enum:
            - active
            - disabled
        config:
          oneOf:
            - $ref: '#/components/schemas/LDAPConnectorConfig'
            - $ref: '#/components/schemas/OutboundConnectorConfig'
        role_ceiling_ids:
          type: array
          items:
            type: string
        group_role_mappings:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
        default_role_id:
          type: string
        credential_set:
          type: boolean
        credential_set_at:
          type: string
          format: date-time
        last_sync_at:
          type: string
          format: date-time
        last_success_at:
          type: string
          format: date-time
        last_error:
          type: string
        consecutive_failures:
          type: integer
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - name
        - kind
        - state
        - config
        - credential_set
        - version
    DirectoryRunRequest:
      type: object
      additionalProperties: false
      properties:
        mode:
          type: string
          enum:
            - full
            - incremental
            - reconcile
          description: >-
            Directories: incremental (default; promoted to full without a usable cursor) or full (also detects
            deletions). Outbound connectors: reconcile.
        dry_run:
          type: boolean
          default: false
        allow_mass_deprovision:
          type: boolean
          default: false
        reason:
          type: string
          maxLength: 500
          description: Required (10+ characters) with allow_mass_deprovision.
    DirectoryRun:
      type: object
      properties:
        id:
          type: string
        connector_id:
          type: string
        organization_id:
          type: string
        job_id:
          type: string
        mode:
          type: string
          enum:
            - full
            - incremental
            - reconcile
        dry_run:
          type: boolean
        trigger:
          type: string
          enum:
            - manual
            - schedule
            - login
        state:
          type: string
          enum:
            - queued
            - running
            - succeeded
            - failed
            - refused
            - cancelled
          description: 'refused: the deletion threshold stopped deprovisioning; other changes of the run were applied.'
        allow_mass_deprovision:
          type: boolean
        requested_by_type:
          type: string
        requested_by_id:
          type: string
        reason:
          type: string
        cursor_before:
          type: string
        cursor_after:
          type: string
        endpoint:
          type: string
          description: Host of the endpoint that served the run.
        counts:
          type: object
          additionalProperties:
            type: integer
          description: >-
            Totals per finding kind plus entries_seen, linked_accounts, deprovision_refused,
            incremental_promoted_to_full, findings_truncated, candidates.
        error:
          type: string
        created_at:
          type: string
          format: date-time
        started_at:
          type: string
          format: date-time
        finished_at:
          type: string
          format: date-time
      required:
        - id
        - connector_id
        - mode
        - dry_run
        - state
        - counts
    DirectoryFinding:
      type: object
      properties:
        seq:
          type: integer
        kind:
          type: string
        reason:
          type: string
        external_id:
          type: string
        source_dn:
          type: string
        local_id:
          type: string
        attributes:
          type: array
          items:
            type: string
          description: Attribute names only, never values.
        applied:
          type: boolean
        detail:
          type: object
          additionalProperties: true
      required:
        - seq
        - kind
        - attributes
        - applied
    DirectoryEndpointHealth:
      type: object
      properties:
        last_ok_at:
          type: string
          format: date-time
        last_failure_at:
          type: string
          format: date-time
        last_failure_category:
          type: string
          description: connect, dns, tls, timeout, network, server_unavailable, egress_denied or service_bind_failed.
        consecutive_failures:
          type: integer
    DirectoryHealth:
      type: object
      properties:
        connector_id:
          type: string
        kind:
          type: string
        state:
          type: string
        status:
          type: string
          enum:
            - healthy
            - degraded
            - disabled
            - needs_configuration
            - needs_credential
        configuration_error:
          type: string
          description: >-
            Why an outbound connector cannot deliver (status needs_configuration), for example a legacy scim_outbound
            row without base_url.
        credential_set_at:
          type: string
          format: date-time
        last_sync_at:
          type: string
          format: date-time
        last_success_at:
          type: string
          format: date-time
        lag_seconds:
          type: integer
        consecutive_failures:
          type: integer
        last_error:
          type: string
        endpoints:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/DirectoryEndpointHealth'
          description: Keyed by host:port.
        last_run:
          $ref: '#/components/schemas/DirectoryRun'
        managed_accounts:
          type: object
          additionalProperties:
            type: integer
          description: >-
            Linked accounts by source state (active, disabled, missing, deleted for erased accounts; deactivated for
            outbound).
        managed_groups:
          type: integer
        deliveries:
          type: object
          additionalProperties:
            type: integer
          description: Outbound deliveries by state.
        oldest_due_seconds:
          type: integer
        last_delivered_at:
          type: string
          format: date-time
        operator_actions:
          type: array
          items:
            type: object
            properties:
              action:
                type: string
              actor_type:
                type: string
              actor_id:
                type: string
              at:
                type: string
                format: date-time
          description: The latest 20 operator actions.
      required:
        - connector_id
        - status
        - operator_actions
    DirectoryTestResult:
      type: object
      properties:
        ok:
          type: boolean
        endpoint:
          type: string
        error:
          type: string
        details:
          type: object
          additionalProperties: true
        checked_at:
          type: string
          format: date-time
      required:
        - ok
        - checked_at
    OutboundDelivery:
      type: object
      properties:
        id:
          type: string
        resource_type:
          type: string
          enum:
            - User
            - Group
        local_id:
          type: string
        trigger:
          type: string
        state:
          type: string
          enum:
            - pending
            - retrying
            - delivered
            - dead_letter
            - replayed
        attempts:
          type: integer
        operation:
          type: string
          enum:
            - create
            - update
            - deactivate
            - delete
            - noop
            - read
        last_status_code:
          type: integer
        last_error_category:
          type: string
          description: >-
            network_error, egress_denied, server_error, throttled, unauthorized, rejected, conflict, invalid_response,
            credential_unavailable or local_error.
        next_attempt_at:
          type: string
          format: date-time
        delivered_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - resource_type
        - local_id
        - state
        - attempts
    AttributeAuthority:
      type: object
      properties:
        source:
          oneOf:
            - type: 'null'
            - type: object
              properties:
                type:
                  type: string
                  enum:
                    - directory
                connector_id:
                  type: string
                name:
                  type: string
                organization_id:
                  type: string
                mode:
                  type: string
                state:
                  type: string
                  description: 'The linked entry''s state: active, disabled or missing.'
        attributes:
          type: object
          additionalProperties:
            type: string
            enum:
              - local
              - externally_managed
              - write_back
        operations:
          type: object
          additionalProperties:
            type: string
            enum:
              - local
              - externally_managed
              - write_back
          description: password_change, password_reset and reactivation.
      required:
        - source
        - attributes
        - operations
    TrustedAuthenticator:
      type: object
      required:
        - id
        - aaguid
        - description
        - root_certificates
        - created_at
      properties:
        id:
          type: string
        aaguid:
          type: string
        description:
          type: string
        root_certificates:
          type: array
          items:
            type: string
        created_at:
          type: string
          format: date-time
    FederationTransfer:
      type: object
      required:
        - id
        - source_provider_id
        - target_provider_id
        - mode
        - state
        - reason
        - summary
        - created_by_id
        - created_at
        - version
      properties:
        id:
          type: string
        source_provider_id:
          type: string
        target_provider_id:
          type: string
        mode:
          type: string
          enum:
            - map
            - same_subject
        target_tenant:
          type: string
        state:
          type: string
          enum:
            - draft
            - approved
            - applied
            - cancelled
        reason:
          type: string
        summary:
          type: object
          description: Entry count by outcome, plus total.
          additionalProperties:
            type: integer
        created_by_id:
          type: string
        approved_by_id:
          type: string
        applied_by_id:
          type: string
        created_at:
          type: string
          format: date-time
        approved_at:
          type: string
          format: date-time
        applied_at:
          type: string
          format: date-time
        version:
          type: integer
    FederationTransferEntry:
      type: object
      required:
        - seq
        - source_subject
        - target_subject
        - outcome
      properties:
        seq:
          type: integer
        source_subject:
          type: string
        source_issuer:
          type: string
        target_subject:
          type: string
        target_tenant:
          type: string
        user_id:
          type: string
        outcome:
          type: string
          enum:
            - pending
            - ready
            - already_linked
            - missing_source
            - ambiguous_source
            - duplicate_source
            - duplicate_target
            - collision_target
            - collision_user
            - target_tenant_required
            - applied
        detail:
          type: string
    MigrationAdapter:
      additionalProperties: false
      properties:
        source:
          type: string
          enum:
            - keycloak
            - zitadel
            - supertokens
        product:
          type: string
        supported_versions:
          type: string
          examples:
            - 26.x
        tested_versions:
          type: array
          items:
            type: string
        export_format:
          type: string
        export_command:
          type: string
        converts:
          type: array
          items:
            type: string
        converts_with_loss:
          type: array
          items:
            type: string
        unsupported:
          type: array
          items:
            type: string
      required:
        - source
        - product
        - supported_versions
        - tested_versions
        - export_format
        - export_command
        - converts
        - converts_with_loss
        - unsupported
      type: object
    MigrationMapping:
      description: >-
        proudauth.migration-mapping.v1: the reviewed translation (MIG-005). organizations maps a source organization key
        (Keycloak org:<alias> or group:<path>, ZITADEL org:<id>, SuperTokens tenant:<id>) to the organization it
        becomes, or null to exclude it. roles maps a source role key (Keycloak realm-role:<name>,
        client-role:<client>:<role>, group:<path>; ZITADEL org-member:<ROLE>, project-member:<project id>:<ROLE>,
        project-role:<project id>:<key>; SuperTokens role:<name>) to realm-wide organization roles; an unlisted key is
        reported unsupported and grants nothing.
      additionalProperties: false
      properties:
        format:
          type: string
          enum:
            - proudauth.migration-mapping.v1
        organizations:
          type: object
          additionalProperties:
            type:
              - object
              - 'null'
            additionalProperties: false
            properties:
              slug:
                type: string
                pattern: ^[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$
              display_name:
                type: string
              note:
                type: string
            required:
              - slug
        membership_roles:
          type: array
          items:
            type: string
        roles:
          type: object
          additionalProperties:
            type:
              - object
              - 'null'
            additionalProperties: false
            properties:
              organization:
                type: string
                description: Target organization slug; without it the roles apply in the source grant's own scope.
              roles:
                type: array
                items:
                  type: string
              note:
                type: string
            required:
              - roles
      type: object
    MigrationEntityReport:
      additionalProperties: false
      properties:
        total:
          type: integer
        converted:
          type: integer
        converted_with_loss:
          type: integer
        unsupported:
          type: integer
        ignored:
          type: integer
        reasons:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              outcome:
                type: string
                enum:
                  - converted_with_loss
                  - unsupported
                  - ignored
              reason:
                type: string
              count:
                type: integer
            required:
              - outcome
              - reason
              - count
      required:
        - total
        - converted
        - converted_with_loss
        - unsupported
        - ignored
      type: object
    MigrationReport:
      description: >-
        proudauth.migration-report.v1, the capability report of one conversion (MIG-018). Records are named by source ID
        only.
      additionalProperties: false
      properties:
        format:
          type: string
          enum:
            - proudauth.migration-report.v1
        generated_at:
          type: string
          format: date-time
        source:
          type: object
          additionalProperties: false
          properties:
            product:
              type: string
            source:
              type: string
            version:
              type: string
            tested_versions:
              type: array
              items:
                type: string
            realm:
              type: string
          required:
            - product
            - source
            - version
            - tested_versions
        source_system:
          type: string
        options:
          type: object
          additionalProperties: false
          properties:
            import_totp:
              type: boolean
            keep_attributes:
              type: boolean
            mapping_given:
              type: boolean
          required:
            - import_totp
            - keep_attributes
            - mapping_given
        summary:
          type: object
          additionalProperties: false
          properties:
            users:
              type: integer
            users_to_import:
              type: integer
            passwords_migrated:
              type: integer
            password_resets_required:
              type: integer
            totp_migrated:
              type: integer
            mfa_reenrollments_required:
              type: integer
            suspended_accounts:
              type: integer
            organizations:
              type: integer
            memberships:
              type: integer
            role_assignments:
              type: integer
            untranslated_role_grants:
              type: integer
          required:
            - users
            - users_to_import
            - passwords_migrated
            - password_resets_required
            - totp_migrated
            - mfa_reenrollments_required
            - suspended_accounts
            - organizations
            - memberships
            - role_assignments
            - untranslated_role_grants
        entities:
          type: object
          description: >-
            Per entity type (users, service_accounts, organizations, groups, tenants, memberships, role_assignments,
            role_definitions, password_credentials, totp_factors, webauthn_credentials, recovery_codes,
            other_credentials, federated_identities, phone_numbers, attributes, required_actions, clients,
            identity_providers, authentication_flows, realm_policies, user_federation, client_scopes, projects,
            project_grants, actions, keys, other_configuration, sessions).
          additionalProperties:
            $ref: '#/components/schemas/MigrationEntityReport'
        mapping:
          type: object
          additionalProperties: false
          properties:
            organizations:
              type: array
              items:
                type: object
                additionalProperties: false
                properties:
                  key:
                    type: string
                  name:
                    type: string
                  status:
                    type: string
                    enum:
                      - auto
                      - mapped
                      - excluded
                      - not_an_organization
                  slug:
                    type: string
                  members:
                    type: integer
                required:
                  - key
                  - name
                  - status
                  - members
            roles:
              type: array
              items:
                type: object
                additionalProperties: false
                properties:
                  key:
                    type: string
                  note:
                    type: string
                  grants:
                    type: integer
                  status:
                    type: string
                    enum:
                      - mapped
                      - no_roles
                      - untranslated
                      - ignored
                  organization:
                    type: string
                  roles:
                    type: array
                    items:
                      type: string
                required:
                  - key
                  - grants
                  - status
            unknown_keys:
              type: array
              items:
                type: string
          required:
            - organizations
            - roles
        items:
          type: array
          description: Every source item that was not simply converted, with its reasons.
          items:
            type: object
            additionalProperties: false
            properties:
              entity:
                type: string
              source_id:
                type: string
              outcome:
                type: string
                enum:
                  - converted_with_loss
                  - unsupported
                  - ignored
              reasons:
                type: array
                items:
                  type: string
            required:
              - entity
              - source_id
              - outcome
              - reasons
        notes:
          type: array
          items:
            type: string
        import:
          type: object
          description: Filled by identity-cli migrate-from after a dry run or an import.
          additionalProperties: false
          properties:
            dry_run:
              type: boolean
            jobs:
              type: array
              items:
                type: string
            counts:
              type: object
              additionalProperties:
                type: integer
            totals:
              type: object
              additionalProperties:
                type: integer
            organizations:
              type: array
              items:
                type: object
                additionalProperties: false
                properties:
                  slug:
                    type: string
                  id:
                    type: string
                  status:
                    type: string
                    enum:
                      - exists
                      - created
                      - will_create
                      - conflict
                  detail:
                    type: string
                required:
                  - slug
                  - status
            records:
              type: array
              items:
                type: object
                additionalProperties: false
                properties:
                  source_id:
                    type: string
                  status:
                    type: string
                  user_id:
                    type: string
                  error:
                    type: string
                required:
                  - source_id
                  - status
            reconciliation:
              type: object
              additionalProperties: true
          required:
            - dry_run
            - jobs
            - counts
            - totals
            - organizations
      required:
        - format
        - generated_at
        - source
        - source_system
        - options
        - summary
        - entities
        - mapping
        - items
      type: object
    OrganizationRelationship:
      type: object
      required:
        - id
        - kind
        - source_organization_id
        - target_organization_id
        - state
        - created_by
        - created_at
      properties:
        id:
          type: string
        kind:
          type: string
          enum:
            - parent_child
            - partner
        source_organization_id:
          type: string
          description: The parent, or the proposing partner.
        target_organization_id:
          type: string
        state:
          type: string
          enum:
            - proposed
            - active
            - declined
            - ended
        note:
          type: string
        created_by:
          type: object
        decided_by_id:
          type: string
        created_at:
          type: string
          format: date-time
        decided_at:
          type: string
          format: date-time
        ended_at:
          type: string
          format: date-time
    ProjectRoleAssignment:
      type: object
      required:
        - id
        - project_id
        - role_id
        - user_id
        - created_at
      properties:
        id:
          type: string
        project_id:
          type: string
        role_id:
          type: string
        user_id:
          type: string
        project_grant_id:
          type: string
        expires_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
    WorkflowDefinition:
      type: object
      description: >-
        Lifecycle workflow definition, schema_version 1. The authoritative schema is api/workflows/definition.v1.json
        (bounded step vocabulary: wait, approval, assign_role, add_to_group, remove_access, notify, call_webhook,
        suspend_user, end).
      required:
        - schema_version
        - triggers
        - steps
      properties:
        schema_version:
          type: integer
          enum:
            - 1
        triggers:
          type: array
          minItems: 1
          maxItems: 5
          items:
            type: object
        steps:
          type: array
          minItems: 1
          maxItems: 20
          items:
            type: object
        retry:
          type: object
          properties:
            max_attempts:
              type: integer
              minimum: 1
              maximum: 10
            backoff:
              type: string
    WorkflowCreate:
      type: object
      additionalProperties: false
      required:
        - name
        - definition
      properties:
        name:
          type: string
          maxLength: 100
        description:
          type: string
          maxLength: 500
        definition:
          $ref: '#/components/schemas/WorkflowDefinition'
        note:
          type: string
          maxLength: 500
        requires_approval:
          type: boolean
          description: >-
            Require a second administrator's approval of each revision; forced on by the realm policy
            extensions.workflow_publish_approval.
        owner_user_id:
          type: string
          description: Accountable owner (DOM-009); defaults to the creating user.
    Workflow:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        description:
          type: string
        state:
          type: string
          enum:
            - draft
            - active
            - disabled
        active_revision:
          type: integer
        published_by_id:
          type: string
          description: 'Publisher of the active revision: accountable actor of every run.'
        requires_approval:
          type: boolean
        owner_user_id:
          type: string
        plugin_id:
          type: string
          description: Set when a plugin manages the workflow.
        event_types:
          type: array
          items:
            type: string
        next_fire_at:
          type: string
          format: date-time
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - name
        - state
        - requires_approval
        - event_types
        - version
        - created_at
        - updated_at
    WorkflowRevision:
      type: object
      properties:
        id:
          type: string
        workflow_id:
          type: string
        number:
          type: integer
        schema_version:
          type: integer
        definition:
          $ref: '#/components/schemas/WorkflowDefinition'
        definition_hash:
          type: string
        status:
          type: string
          enum:
            - draft
            - approved
            - published
            - superseded
            - rejected
        author_id:
          type: string
        approved_by_id:
          type: string
        approved_at:
          type: string
          format: date-time
        published_by_id:
          type: string
        published_at:
          type: string
          format: date-time
        note:
          type: string
        created_at:
          type: string
          format: date-time
      required:
        - id
        - workflow_id
        - number
        - schema_version
        - definition
        - definition_hash
        - status
        - author_id
        - created_at
    WorkflowRunStart:
      type: object
      additionalProperties: false
      required:
        - subject_id
      properties:
        subject_id:
          type: string
        organization_id:
          type: string
          description: Organization for organization-scoped steps.
    WorkflowStepAttempt:
      type: object
      description: One attempt of one step (EXT-016).
      properties:
        id:
          type: string
        step_index:
          type: integer
        step_id:
          type: string
        step_type:
          type: string
        attempt:
          type: integer
        idempotency_key:
          type: string
          description: Stable for every attempt of the step; sent to endpoints as Idempotency-Key.
        state:
          type: string
          enum:
            - started
            - succeeded
            - failed
        input:
          type: object
        input_version:
          type: string
          description: Revision, definition hash and trigger contract version the attempt ran with.
        result:
          type: object
        error_category:
          type: string
        error:
          type: string
        max_attempts:
          type: integer
        backoff_ms:
          type: integer
        compensation:
          type: string
          enum:
            - none
            - undo
            - notify_endpoint
            - impossible
        compensation_state:
          type: string
          enum:
            - pending
            - done
            - not_needed
            - impossible
            - failed
        compensation_attempts:
          type: integer
        compensation_result:
          type: object
        started_at:
          type: string
          format: date-time
        finished_at:
          type: string
          format: date-time
        compensated_at:
          type: string
          format: date-time
      required:
        - id
        - step_index
        - step_id
        - step_type
        - attempt
        - idempotency_key
        - state
        - input_version
        - max_attempts
        - backoff_ms
        - compensation
        - started_at
    WorkflowApproval:
      type: object
      properties:
        id:
          type: string
        run_id:
          type: string
        workflow_id:
          type: string
        step_index:
          type: integer
        subject_id:
          type: string
        approver_ids:
          type: array
          items:
            type: string
        state:
          type: string
          enum:
            - pending
            - approved
            - rejected
            - expired
            - cancelled
        decided_by_id:
          type: string
        decided_at:
          type: string
          format: date-time
        comment:
          type: string
        expires_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
      required:
        - id
        - run_id
        - workflow_id
        - step_index
        - subject_id
        - approver_ids
        - state
        - expires_at
        - created_at
    WorkflowRun:
      type: object
      properties:
        id:
          type: string
        workflow_id:
          type: string
        organization_id:
          type: string
        revision:
          type: integer
        definition_hash:
          type: string
        schema_version:
          type: integer
        trigger_type:
          type: string
          enum:
            - event
            - schedule
            - manual
        trigger_event_type:
          type: string
        subject_type:
          type: string
        subject_id:
          type: string
        input:
          type: object
          description: Identifiers-only snapshot of the trigger.
        input_version:
          type: integer
        accountable_id:
          type: string
          description: Publisher of the revision; the audit actor of every effect.
        started_by_id:
          type: string
        depth:
          type: integer
        state:
          type: string
          enum:
            - pending
            - running
            - waiting
            - awaiting_approval
            - compensating
            - succeeded
            - failed
            - compensated
            - compensation_failed
            - cancelled
        step_index:
          type: integer
        context:
          type: object
        next_run_at:
          type: string
          format: date-time
        cancel_requested:
          type: boolean
        error_category:
          type: string
        last_error:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        finished_at:
          type: string
          format: date-time
        attempts:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowStepAttempt'
        approvals:
          type: array
          items:
            $ref: '#/components/schemas/WorkflowApproval'
      required:
        - id
        - workflow_id
        - revision
        - trigger_type
        - subject_id
        - state
        - accountable_id
        - created_at
    WorkflowDiagnostics:
      type: object
      properties:
        health:
          type: string
          enum:
            - unknown
            - healthy
            - degraded
            - attention_required
        runs_by_state:
          type: object
          additionalProperties:
            type: integer
        step_failures_by_category:
          type: object
          additionalProperties:
            type: integer
        recent_attempts:
          type: integer
        recent_failed_attempts:
          type: integer
        run_duration_p50_ms:
          type: integer
        run_duration_p95_ms:
          type: integer
        pending_approvals:
          type: integer
        oldest_due_seconds:
          type: integer
        compensation_failures:
          type: integer
    PluginPackage:
      type: object
      additionalProperties: false
      required:
        - manifest
        - payload
        - signature
      description: See api/plugins/package.v1.json and manifest.v1.json.
      properties:
        manifest:
          type: string
          description: base64 of the exact manifest bytes (at most 16 KiB).
        payload:
          type: string
          description: >-
            base64 of the exact payload bytes (at most 160 KiB): {hooks: [HookInput], webhooks: [WebhookInput],
            workflows: [{name, description, definition}]}.
        signature:
          type: object
          additionalProperties: false
          required:
            - key_id
            - algorithm
            - value
          properties:
            key_id:
              type: string
            algorithm:
              type: string
              enum:
                - Ed25519
            value:
              type: string
              description: base64 Ed25519 signature over "proudauth-plugin-v1\n" + manifest bytes.
    PluginPartRef:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        state:
          type: string
      required:
        - id
        - name
        - state
    Plugin:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        publisher:
          type: string
        state:
          type: string
          enum:
            - inactive
            - enabled
            - disabled
        installed_version:
          type: string
        previous_version:
          type: string
          description: Target of POST /plugins/{id}/rollback.
        installed_by_id:
          type: string
        installed_at:
          type: string
          format: date-time
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        parts:
          type: object
          properties:
            hooks:
              type: array
              items:
                $ref: '#/components/schemas/PluginPartRef'
            webhooks:
              type: array
              items:
                $ref: '#/components/schemas/PluginPartRef'
            workflows:
              type: array
              items:
                $ref: '#/components/schemas/PluginPartRef'
      required:
        - id
        - name
        - publisher
        - state
        - version
        - created_at
        - updated_at
    PluginVersion:
      type: object
      properties:
        id:
          type: string
        plugin_id:
          type: string
        version:
          type: string
        manifest_version:
          type: integer
        manifest:
          type: object
          description: The signed manifest (api/plugins/manifest.v1.json).
        payload:
          type: object
          description: Returned by GET .../versions/{version} only, for review.
        package_digest:
          type: string
        signing_key_id:
          type: string
        permissions:
          type: array
          items:
            type: string
        status:
          type: string
          enum:
            - pending_review
            - approved
            - rejected
            - installed
            - superseded
        uploaded_by_id:
          type: string
        reviewed_by_id:
          type: string
        reviewed_at:
          type: string
          format: date-time
        review_note:
          type: string
        installed_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
      required:
        - id
        - plugin_id
        - version
        - manifest_version
        - manifest
        - package_digest
        - signing_key_id
        - permissions
        - status
        - uploaded_by_id
        - created_at
    PluginInstallResult:
      type: object
      properties:
        plugin:
          $ref: '#/components/schemas/Plugin'
        signing_secrets:
          type: array
          description: Signing secrets of parts this installation created, shown once.
          items:
            type: object
            properties:
              kind:
                type: string
                enum:
                  - hook
                  - webhook
              part_id:
                type: string
              name:
                type: string
              secret:
                type: string
                x-secret: true
      required:
        - plugin
        - signing_secrets
    ExtensionContract:
      type: object
      properties:
        name:
          type: string
          enum:
            - webhook_events
            - hook_contract
            - plugin_manifest
            - workflow_definition
            - management_api
        description:
          type: string
        versions:
          type: array
          items:
            type: object
            properties:
              version:
                type: integer
              status:
                type: string
                enum:
                  - current
                  - supported
                  - deprecated
              sunset:
                type: string
                description: Earliest removal date (YYYY-MM-DD).
              default:
                type: boolean
            required:
              - version
              - status
      required:
        - name
        - versions
    RegistryRule:
      type: object
      additionalProperties: false
      required:
        - repository
      properties:
        repository:
          type: string
          description: Repository name or path.Match pattern (acme/* matches acme/app, not acme/team/app).
        organization_id:
          type: string
          description: Evaluate permissions in this organization; credentials bound to another organization get nothing.
        pull:
          type: string
          description: Permission required to pull.
        push:
          type: string
        delete:
          type: string
        anonymous_pull:
          type: boolean
    RegistryServiceInput:
      type: object
      additionalProperties: false
      required:
        - rules
      properties:
        service:
          type: string
        audience:
          type: string
        token_ttl_seconds:
          type: integer
          minimum: 60
          maximum: 3600
        rules:
          type: array
          minItems: 1
          maxItems: 200
          items:
            $ref: '#/components/schemas/RegistryRule'
        state:
          type: string
          enum:
            - active
            - disabled
    RegistryService:
      type: object
      required:
        - id
        - service
        - resource_id
        - token_ttl_seconds
        - rules
        - state
        - version
      properties:
        id:
          type: string
        service:
          type: string
        resource_id:
          type: string
        token_ttl_seconds:
          type: integer
        rules:
          type: array
          items:
            $ref: '#/components/schemas/RegistryRule'
        state:
          type: string
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    EntitlementHistory:
      type: object
      required:
        - subject
        - at
        - account_state
        - memberships
        - groups
        - assignments
        - permissions
        - oauth_grants
        - policies_in_force
        - realm_policy_revision
        - completeness
      properties:
        subject:
          type: object
        at:
          type: string
          format: date-time
        account_state:
          type: string
          description: active, suspended, locked, recovery_restricted, deleted, not_created or unknown.
        memberships:
          type: array
          items:
            type: object
        groups:
          type: array
          items:
            type: object
        assignments:
          type: array
          items:
            type: object
            properties:
              assignment_id:
                type: string
              role_id:
                type: string
              role_name:
                type: string
              scope_type:
                type: string
              scope_id:
                type: string
              source:
                type: string
              via:
                type: string
              since:
                type: string
                format: date-time
              expires_at:
                type: string
                format: date-time
              permissions:
                type: array
                items:
                  type: string
              denied_permissions:
                type: array
                items:
                  type: string
              permissions_evidence:
                type: string
                enum:
                  - reconstructed
                  - current_definition
                  - unknown
              evidence:
                type: array
                items:
                  type: string
                description: Audit event IDs.
        permissions:
          type: array
          items:
            type: string
        oauth_grants:
          type: array
          items:
            type: object
        policies_in_force:
          type: array
          items:
            type: object
        realm_policy_revision:
          type: integer
        completeness:
          type: object
          properties:
            evidence_from:
              type: string
              format: date-time
            complete:
              type: boolean
            caveats:
              type: array
              items:
                type: string
    SSFTransmitterInput:
      type: object
      additionalProperties: false
      required:
        - name
        - issuer
      properties:
        name:
          type: string
          maxLength: 100
        issuer:
          type: string
        jwks_uri:
          type: string
        jwks:
          type: object
          description: Public JSON Web Key Set (instead of jwks_uri).
        provider_id:
          type: string
          description: Federation connection whose links map iss_sub subjects.
        allow_email_subjects:
          type: boolean
        actions:
          type: object
          description: >-
            Event type URI -> action. session-revoked: record_only | revoke_sessions | revoke_all; credential-change and
            assurance-level-change: record_only | revoke_sessions; credential-compromise: record_only | revoke_all |
            mark_password_compromised; account-disabled and account-purged: record_only | revoke_all | suspend_user;
            account-enabled and identifier-changed: record_only.
          additionalProperties:
            type: string
            enum:
              - record_only
              - revoke_sessions
              - revoke_all
              - mark_password_compromised
              - suspend_user
        max_event_age_seconds:
          type: integer
          minimum: 60
          maximum: 604800
        state:
          type: string
          enum:
            - active
            - disabled
    SSFTransmitter:
      type: object
      required:
        - id
        - name
        - issuer
        - actions
        - state
        - push_endpoint
        - audience
        - version
      properties:
        id:
          type: string
        name:
          type: string
        issuer:
          type: string
        jwks_uri:
          type: string
        jwks:
          type: object
        provider_id:
          type: string
        allow_email_subjects:
          type: boolean
        actions:
          type: object
          additionalProperties:
            type: string
        max_event_age_seconds:
          type: integer
        state:
          type: string
        push_endpoint:
          type: string
        audience:
          type: string
        version:
          type: integer
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    SSFPushError:
      type: object
      required:
        - err
        - description
      properties:
        err:
          type: string
        description:
          type: string
    Problem:
      type: object
      description: >-
        RFC 9457 problem details (application/problem+json) used by every custom API. Additional extension members (for
        example obligations or original_status) may be present.
      properties:
        type:
          type: string
          format: uri
          description: https://auth.proudbase.com/problems/{code}
        title:
          type: string
        status:
          type: integer
        code:
          type: string
          enum:
            - invalid_request
            - validation_failed
            - unauthenticated
            - forbidden
            - not_found
            - conflict
            - precondition_failed
            - precondition_required
            - rate_limited
            - unavailable
            - internal_error
            - payload_too_large
            - unsupported_media_type
            - step_up_required
            - recent_authentication_required
            - mfa_required
            - recovery_restricted
            - transaction_invalid
            - transaction_expired
            - invalid_credentials
            - invalid_proof
            - unexpected_step
            - password_policy
            - last_owner
            - grant_ceiling_exceeded
            - impersonation_denied
            - impersonation_restricted
            - feature_disabled
            - invitation_invalid
            - last_sign_in_method
            - idempotency_key_reused
            - account_unavailable
            - sso_required
            - upstream_unavailable
          description: Stable machine-readable error code.
        detail:
          type: string
          description: Client-safe detail; never contains secrets.
        errors:
          type: object
          additionalProperties:
            type: string
          description: Field name -> validation message.
        request_id:
          type: string
          description: Correlation identifier, equal to the X-Request-Id response header.
        obligations:
          type: array
          items:
            $ref: '#/components/schemas/Obligation'
          description: Present on step-up / recent-authentication / MFA problems.
        original_status:
          type: integer
          description: Present when an idempotent replay is refused because the original response carried a one-time secret.
      required:
        - type
        - title
        - status
        - code
      additionalProperties: true
    ProfilePatch:
      additionalProperties: false
      properties:
        display_name:
          type:
            - string
            - 'null'
        family_name:
          type:
            - string
            - 'null'
        given_name:
          type:
            - string
            - 'null'
        locale:
          type:
            - string
            - 'null'
        profile:
          additionalProperties: {}
          type:
            - object
            - 'null'
        zoneinfo:
          type:
            - string
            - 'null'
      type: object
    Project:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        description:
          type: string
        environment:
          type: string
        id:
          type: string
        name:
          type: string
        owner_organization_id:
          type: string
        owner_user_id:
          type: string
        realm_id:
          type: string
        state:
          type: string
          enum:
            - active
            - suspended
            - archived
        version:
          format: int64
          type: integer
      type: object
    PushedAuthorizationResponse:
      additionalProperties: false
      properties:
        expires_in:
          type: integer
        request_uri:
          type: string
      required:
        - expires_in
        - request_uri
      type: object
    RealmImpersonationPolicy:
      additionalProperties: false
      properties:
        allow_customer_opt_out:
          type: boolean
        approval:
          type: string
          enum:
            - none
            - second_operator
            - organization_owner
            - customer
        enabled:
          type: boolean
        max_ttl_seconds:
          type: integer
          minimum: 0
          maximum: 300
        notify_customer:
          type: boolean
        require_ticket:
          type: boolean
      type: object
    RealmInteractionPolicy:
      additionalProperties: false
      properties:
        login_ui_url:
          type: string
      type: object
    RealmLifecyclePolicy:
      additionalProperties: false
      properties:
        dormant_days:
          type: integer
          minimum: 0
          maximum: 3650
          description: Accounts without a sign-in for this many days are dormant (0 disables the rule).
        dormant_action:
          type: string
          enum:
            - report
            - suspend
          description: 'report (default): flag once and audit user.dormant_detected; suspend: suspend the account.'
        guest_ttl_days:
          type: integer
          minimum: 0
          maximum: 3650
          description: Guest accounts unused for this many days are deleted (default 30).
        unverified_account_ttl_hours:
          type: integer
      type: object
    RealmLoginPolicy:
      additionalProperties: false
      properties:
        email_otp:
          type: boolean
        identifiers:
          items:
            type: string
          type:
            - array
            - 'null'
        magic_link:
          type: boolean
        passkeys:
          type: boolean
        password:
          type: boolean
        remember_devices:
          type: boolean
        sms_otp:
          type: boolean
        certificates:
          type: boolean
          description: >-
            PROV-016: offer X.509 sign-in (action certificate) with certificates chaining to a user trust anchor and
            bound to the account.
      type: object
    RealmMFAPolicy:
      additionalProperties: false
      properties:
        admin_phishing_resistant:
          type: boolean
        allowed_factors:
          items:
            type: string
            enum:
              - totp
              - hotp
              - webauthn
              - recovery_code
              - email_otp
              - sms_otp
          type:
            - array
            - 'null'
        org_admin_mfa_optional:
          type: boolean
        hotp:
          type: object
          additionalProperties: false
          description: Counter-based codes (MFA-013), offered only when hotp is listed in allowed_factors.
          properties:
            look_ahead:
              type: integer
              minimum: 0
              maximum: 50
            resync_window:
              type: integer
              minimum: 0
              maximum: 1000
        requirement:
          type: string
          enum:
            - optional
            - required
      type: object
    RealmNotificationPolicy:
      additionalProperties: false
      properties:
        new_login_alerts:
          type: boolean
      type: object
    RealmPasswordPolicy:
      additionalProperties: false
      properties:
        history_count:
          type: integer
        min_length:
          type: integer
          description: 0 keeps the operator default; otherwise at least 8.
        revoke_sessions_on_change:
          type: boolean
      type: object
    RealmPolicy:
      additionalProperties: false
      properties:
        audit:
          type: object
          additionalProperties: false
          description: Audit retention scoped to the realm (AUD-009).
          properties:
            retention_days:
              type: integer
              minimum: 30
              maximum: 3650
              description: >-
                Keeps the realm's evidence at least this many days; never shorter than the deployment's
                privacy.audit_retention.
        recovery:
          type: object
          additionalProperties: false
          description: >-
            Assisted recovery controls (MFA-009): with a cooling-off period or required approval, recovery requests are
            scheduled, announced to the owner at once and can be cancelled by the owner.
          properties:
            cooling_off_hours:
              type: integer
              minimum: 0
              maximum: 168
            require_approval:
              type: boolean
        data_access:
          type: object
          additionalProperties: false
          description: >-
            Evidence of identity data reads (USR-018, AUD-015): when log_identity_reads is on, every administrative or
            support read of an account record (user.read) and every account search (user.search) is audited in the
            data_access category with the actor, the account and whether the view was masked; the data itself is never
            logged. The audit record is written before the data is returned.
          properties:
            log_identity_reads:
              type: boolean
            sample_allowed_decisions_percent:
              type: integer
              minimum: 0
              maximum: 100
              description: >-
                Share of ordinary allowed authorization decisions audited, marked sampled (AZ-020). Denials, privileged
                and support decisions are always audited.
        impersonation:
          $ref: '#/components/schemas/RealmImpersonationPolicy'
        interaction:
          $ref: '#/components/schemas/RealmInteractionPolicy'
        lifecycle:
          $ref: '#/components/schemas/RealmLifecyclePolicy'
        login:
          $ref: '#/components/schemas/RealmLoginPolicy'
        mfa:
          $ref: '#/components/schemas/RealmMFAPolicy'
        notifications:
          $ref: '#/components/schemas/RealmNotificationPolicy'
        password:
          $ref: '#/components/schemas/RealmPasswordPolicy'
        profile:
          $ref: '#/components/schemas/RealmProfilePolicy'
        registration:
          $ref: '#/components/schemas/RealmRegistrationPolicy'
        sessions:
          $ref: '#/components/schemas/RealmSessionPolicy'
        webauthn:
          $ref: '#/components/schemas/RealmWebAuthnPolicy'
        domains:
          type: object
          additionalProperties: false
          description: >-
            Periodic re-verification of organization domains (TEN-009): the accepted DNS proof is re-checked every
            recheck_days (default 30); after lapse_after_failures consecutive daily failures (default 3) the
            verification lapses.
          properties:
            recheck_days:
              type: integer
              minimum: 1
              maximum: 365
            lapse_after_failures:
              type: integer
              minimum: 1
              maximum: 30
        policy_engine:
          type: object
          additionalProperties: false
          description: >-
            External policy engine (AZ-026) named from the operator's security.policy_engines; restrict (default) lets
            it only deny, decide makes its answer final (published policies and hooks still restrict it); on_error deny
            (default) or local.
          properties:
            name:
              type: string
            mode:
              type: string
              enum:
                - restrict
                - decide
            on_error:
              type: string
              enum:
                - deny
                - local
        client_registration:
          type: object
          additionalProperties: false
          description: >-
            Dynamic client registration (APP-016, ADV-003), off by default: registrations need an initial access token
            unless open is set; registrations without a token are always held for approval.
          properties:
            enabled:
              type: boolean
            open:
              type: boolean
            require_approval:
              type: boolean
            open_scopes:
              type: array
              items:
                type: string
                enum:
                  - openid
                  - profile
                  - email
                  - phone
                  - address
        authentication_flow:
          type: object
          additionalProperties: false
          description: >-
            Authentication policy (AUT-012, AUT-014, SEC-014): an ordered list of at most 50 rules evaluated once the
            account is known. The first rule whose conditions all hold decides; with no match the sign-in continues
            under the other policies. A rule whose condition needs an unavailable signal (no or a failing
            authentication.risk hook, no client address) applies a restrictive outcome unless on_missing_signal is skip,
            and an allow rule never matches on a missing signal. Each decision is audited as
            authentication.flow.evaluated with the rule, policy revision, signals and missing signals; review outcomes
            raise the authentication_review security signal.
          properties:
            challenge_provider:
              type: string
              description: >-
                Name of an operator-configured challenge provider (security.challenge_providers) offered for challenge
                outcomes.
            email_code_alternative:
              type: boolean
              default: true
              description: Offer a code sent to the verified email as the accessible alternative to the provider challenge.
            rules:
              type: array
              maxItems: 50
              items:
                type: object
                additionalProperties: false
                required:
                  - name
                  - outcome
                properties:
                  name:
                    type: string
                    minLength: 1
                    maxLength: 100
                  outcome:
                    type: string
                    enum:
                      - allow
                      - require_mfa
                      - require_phishing_resistant
                      - challenge
                      - review
                      - deny
                  on_missing_signal:
                    type: string
                    enum:
                      - apply
                      - skip
                    default: apply
                  when:
                    type: object
                    additionalProperties: false
                    description: Conditions that must all hold; omitted members are not checked.
                    properties:
                      clients:
                        type: array
                        maxItems: 50
                        items:
                          type: string
                        description: OAuth client_id values.
                      organizations:
                        type: array
                        maxItems: 50
                        items:
                          type: string
                        description: Organization IDs of the sign-in context.
                      methods:
                        type: array
                        maxItems: 50
                        items:
                          type: string
                          enum:
                            - password
                            - passkey
                            - email_otp
                            - magic_link
                            - sms_otp
                            - sso
                            - certificate
                        description: Primary method used (realm.FlowMethods; certificate is X.509 sign-in, PROV-016).
                      resources:
                        type: array
                        maxItems: 50
                        items:
                          type: string
                        description: Requested resource audiences (any).
                      networks:
                        type: array
                        maxItems: 50
                        items:
                          type: string
                        description: CIDR prefixes containing the client address.
                      outside_networks:
                        type: array
                        maxItems: 50
                        items:
                          type: string
                        description: CIDR prefixes the client address must be outside of.
                      new_device:
                        type: boolean
                        description: True matches a device not remembered for the account.
                      failed_attempts_at_least:
                        type: integer
                        minimum: 0
                        maximum: 1000
                        description: Failed sign-in attempts on the account in the last hour.
                      risk_at_least:
                        type: string
                        enum:
                          - low
                          - medium
                          - high
                        description: Highest level reported by authentication.risk hooks.
                      privileged:
                        type: boolean
                        description: Protected account or holder of a privileged realm role.
                      assurance_below:
                        type: string
                        enum:
                          - urn:proudauth:acr:mfa
                          - urn:proudauth:acr:phishing_resistant
                        description: The factors completed so far give a lower assurance.
        machine:
          type: object
          additionalProperties: false
          description: >-
            Service principals whose accountable owner is suspended, locked or deleted (MCH-007): flag (default) reports
            the departure once and lists it in the credential inventory; disable disables the principal and revokes its
            credentials after owner_departure_grace_days.
          properties:
            owner_departure:
              type: string
              enum:
                - flag
                - disable
            owner_departure_grace_days:
              type: integer
              minimum: 0
              maximum: 90
        tokens:
          type: object
          additionalProperties: false
          description: >-
            Realm limits on access-token lifetimes (TOK-018). Resources and clients set lifetimes; each limit here only
            shortens them: for every access token, for service principals, for user sessions below MFA, and for support
            (impersonation) tokens. The operator maximum always applies.
          properties:
            access_token_ttl_seconds:
              type: integer
              minimum: 30
              maximum: 86400
            service_access_token_ttl_seconds:
              type: integer
              minimum: 30
              maximum: 86400
            single_factor_access_token_ttl_seconds:
              type: integer
              minimum: 30
              maximum: 86400
            impersonation_access_token_ttl_seconds:
              type: integer
              minimum: 30
              maximum: 86400
      type: object
    RealmProfilePolicy:
      additionalProperties: false
      description: >-
        Custom profile attribute schema (USR-007). Self-service and complete_profile may write only user-editable,
        locally sourced attributes defined here; undefined attributes are rejected.
      properties:
        attributes:
          type: array
          maxItems: 50
          items:
            type: object
            additionalProperties: false
            properties:
              name:
                type: string
                pattern: ^[a-z][a-z0-9_]{0,63}$
              type:
                type: string
                enum:
                  - string
                  - number
                  - boolean
                  - enum
              max_length:
                type: integer
                minimum: 0
                maximum: 4096
              enum:
                type: array
                maxItems: 100
                items:
                  type: string
              pattern:
                type: string
                maxLength: 200
              required:
                type: boolean
              user_editable:
                type: boolean
              visibility:
                type: string
                enum:
                  - self
                  - admin
                  - internal
              source:
                type: string
                enum:
                  - local
                  - federation
                  - directory
              claimable:
                type: boolean
            required:
              - name
      type: object
    RealmRegistrationPolicy:
      additionalProperties: false
      properties:
        require_approval:
          type: boolean
          description: Queue self-registrations for review (REG-008); invited registrations are not queued.
        allow_guests:
          type: boolean
        allow_organization_creation:
          type: boolean
        allowed_domains:
          items:
            type: string
          type:
            - array
            - 'null'
        mode:
          type: string
          enum:
            - public
            - closed
            - invitation_only
            - domain_restricted
        require_email_verification:
          type: boolean
        required_profile_fields:
          items:
            type: string
          type:
            - array
            - 'null'
        terms_version:
          type: string
      type: object
    RealmSessionPolicy:
      additionalProperties: false
      properties:
        absolute_seconds:
          type: integer
        idle_seconds:
          type: integer
        max_concurrent:
          type: integer
      type: object
    RealmSettings:
      type: object
      properties:
        realm:
          type: string
        issuer:
          type: string
          format: uri
        state:
          type: string
        policy:
          $ref: '#/components/schemas/RealmPolicy'
        policy_revision:
          type: integer
          format: int64
        version:
          type: integer
          format: int64
      required:
        - realm
        - issuer
        - state
        - policy
        - policy_revision
        - version
    RealmWebAuthnPolicy:
      additionalProperties: false
      properties:
        allow_synced:
          type: boolean
        origins:
          items:
            type: string
          type:
            - array
            - 'null'
        rp_id:
          type: string
        rp_name:
          type: string
        user_verification:
          type: string
      type: object
    RegistrationInput:
      additionalProperties: false
      properties:
        display_name:
          type: string
        email:
          type: string
        family_name:
          type: string
        given_name:
          type: string
        invitation:
          type: string
          x-secret: true
          description: Invitation secret to accept during registration.
        locale:
          type: string
        organization:
          oneOf:
            - $ref: '#/components/schemas/OrganizationInput'
            - type: 'null'
        password:
          type: string
          format: password
        profile:
          additionalProperties: {}
          type:
            - object
            - 'null'
        terms_version:
          type: string
        username:
          type: string
      type: object
    Resource:
      additionalProperties: false
      properties:
        access_token_ttl_seconds:
          type: integer
        audience:
          type: string
        created_at:
          format: date-time
          type: string
        description:
          type: string
        id:
          type: string
        impersonation_enabled:
          type: boolean
        impersonation_policy:
          $ref: '#/components/schemas/ApplicationImpersonationPolicy'
        kind:
          type: string
        name:
          type: string
        project_id:
          type: string
        realm_id:
          type: string
        requires_organization:
          type: boolean
        scopes:
          items:
            $ref: '#/components/schemas/ApplicationScope'
          type:
            - array
            - 'null'
        signing_algorithm:
          type: string
        state:
          type: string
        token_format:
          type: string
        verification_mode:
          type: string
        version:
          format: int64
          type: integer
      required:
        - access_token_ttl_seconds
        - audience
        - created_at
        - id
        - impersonation_enabled
        - impersonation_policy
        - kind
        - name
        - realm_id
        - requires_organization
        - signing_algorithm
        - state
        - token_format
        - verification_mode
        - version
      type: object
    ResourceGrant:
      additionalProperties: false
      properties:
        allowed_scopes:
          items:
            type: string
          type:
            - array
            - 'null'
        client_ref:
          type: string
        exchange_policy:
          $ref: '#/components/schemas/ExchangePolicy'
        id:
          type: string
        resource_id:
          type: string
        subject_types:
          items:
            type: string
          type:
            - array
            - 'null'
      required:
        - allowed_scopes
        - client_ref
        - exchange_policy
        - id
        - resource_id
        - subject_types
      type: object
    ResourceInput:
      additionalProperties: false
      properties:
        signing_algorithm:
          type: string
          description: >-
            Pins the access-token JWS algorithm (TOK-005). Must be in security.allowed_algorithms; symmetric algorithms
            and none are rejected. Issuance fails closed if the realm's active key uses another algorithm, and key
            rotation to another algorithm is refused while resources pin this one. Defaults to keys.signing_algorithm.
        access_token_ttl_seconds:
          type: integer
        audience:
          type: string
        description:
          type: string
        impersonation_enabled:
          type: boolean
        impersonation_policy:
          $ref: '#/components/schemas/ApplicationImpersonationPolicy'
        name:
          type: string
        project_id:
          type: string
        requires_organization:
          type:
            - boolean
            - 'null'
        scopes:
          items:
            $ref: '#/components/schemas/ScopeInput'
          type:
            - array
            - 'null'
        token_format:
          type: string
          enum:
            - jwt
            - opaque
        verification_mode:
          type: string
          enum:
            - offline
            - bounded_online
            - strict_online
      type: object
      required:
        - audience
        - name
    RevokedSessions:
      type: object
      properties:
        revoked_sessions:
          type: integer
      required:
        - revoked_sessions
    Role:
      additionalProperties: false
      properties:
        boundary_type:
          type: string
        built_in:
          type: boolean
        composite_role_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        created_at:
          format: date-time
          type: string
        denied_permissions:
          items:
            type: string
          type:
            - array
            - 'null'
        description:
          type: string
        id:
          type: string
        incompatible_role_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        is_owner_role:
          type: boolean
        name:
          type: string
        organization_id:
          type: string
        permissions:
          items:
            type: string
          type:
            - array
            - 'null'
        project_id:
          type: string
        protected:
          type: boolean
        realm_id:
          type: string
        requires_approval:
          type: boolean
        version:
          format: int64
          type: integer
      required:
        - boundary_type
        - built_in
        - composite_role_ids
        - created_at
        - id
        - incompatible_role_ids
        - is_owner_role
        - name
        - permissions
        - protected
        - realm_id
        - requires_approval
        - version
      type: object
    RoleAssignment:
      additionalProperties: false
      properties:
        approved_by:
          type: string
        conditions:
          additionalProperties: {}
          type:
            - object
            - 'null'
        created_at:
          format: date-time
          type: string
        expires_at:
          format: date-time
          type:
            - string
            - 'null'
        granted_by:
          type: string
        id:
          type: string
        membership_id:
          type: string
        reason:
          type: string
        role_id:
          type: string
        role_name:
          type: string
        scope:
          $ref: '#/components/schemas/AuthzScope'
        source:
          type: string
        subject:
          $ref: '#/components/schemas/AuthzSubject'
        valid_from:
          format: date-time
          type:
            - string
            - 'null'
      required:
        - created_at
        - id
        - role_id
        - scope
        - source
        - subject
      type: object
    RoleInput:
      additionalProperties: false
      properties:
        boundary_type:
          type: string
          enum:
            - realm
            - organization
            - project
        composite_role_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        denied_permissions:
          items:
            type: string
          type:
            - array
            - 'null'
        description:
          type: string
        incompatible_role_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        name:
          type: string
        organization_id:
          type: string
        permissions:
          items:
            type: string
          type:
            - array
            - 'null'
        project_id:
          type: string
        requires_approval:
          type: boolean
      type: object
      required:
        - name
    ScopeInput:
      additionalProperties: false
      properties:
        required_permissions:
          type: array
          maxItems: 10
          items:
            type: string
          description: >-
            Subject policy (TOK-008); the scope is issued only to subjects holding all of these permissions in the
            token's organization or realm context, re-checked on refresh.
        consent_text:
          type: string
        description:
          type: string
        is_default:
          type: boolean
          description: >-
            Default grant (APP-007): a token or authorization request that names this scope's resource but none of its
            scopes is requested with the resource's default scopes, as far as the client's resource grant lists them.
            They then pass the checks of a requested scope (consent, step-up, the organization's scope ceiling,
            required_permissions), so a default scope is never issued where a requested one would not be. A request
            naming any scope of the resource gets no defaults, and a refresh never adds defaults declared after the
            authorization.
        name:
          type: string
        sensitivity:
          type: string
          description: Defaults to normal. privileged scopes require MFA (step-up) even without step_up_acr.
        step_up_acr:
          type: string
          enum:
            - urn:proudauth:acr:mfa
            - urn:proudauth:acr:phishing_resistant
          description: >-
            Step-up policy (AUT-010): a request for the scope makes this assurance a requirement of the transaction; an
            SSO session below it is stepped up, never downgraded.
        max_auth_age_seconds:
          type: integer
          minimum: 60
          maximum: 86400
          description: >-
            The session's authentication must be at most this old when the scope is requested; refresh drops the scope
            once the grant's authentication is older.
      type: object
      required:
        - name
    SecurityEvent:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
        occurred_at:
          type: string
          format: date-time
        outcome:
          type: string
        network:
          type: string
        actor_type:
          type: string
          description: Present when another party (support or an administrator) acted on the account.
        support_grant_id:
          type: string
      required:
        - id
        - type
        - occurred_at
        - outcome
        - network
    SelfCredential:
      description: Safe authenticator metadata. Verifiers, seeds and public keys are never returned.
      oneOf:
        - type: object
          title: Credential
          properties:
            id:
              type: string
            type:
              type: string
            name:
              type: string
            state:
              type: string
              enum:
                - active
                - compromised
            created_at:
              type: string
              format: date-time
            last_used_at:
              type:
                - string
                - 'null'
              format: date-time
          required:
            - id
            - type
            - name
            - state
            - created_at
            - last_used_at
        - type: object
          title: Passkey
          properties:
            id:
              type: string
            type:
              type: string
              const: webauthn
            name:
              type: string
            synced:
              type: boolean
            backup_eligible:
              type: boolean
            user_verifying:
              type: boolean
            created_at:
              type: string
              format: date-time
            last_used_at:
              type:
                - string
                - 'null'
              format: date-time
          required:
            - id
            - type
            - name
            - synced
            - backup_eligible
            - user_verifying
            - created_at
            - last_used_at
    SelfSession:
      type: object
      properties:
        id:
          type: string
        current:
          type: boolean
        created_at:
          type: string
          format: date-time
        last_activity_at:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time
        amr:
          type:
            - array
            - 'null'
          items:
            type: string
        acr:
          type: string
        user_agent:
          type: string
        remember_me:
          type: boolean
        recovery_restricted:
          type: boolean
        device:
          type: string
          description: Display hint derived from the user agent (SES-013); never a security signal.
        network:
          type: string
          description: Privacy-reduced network (/24 or /48) the session started from.
      required:
        - id
        - current
        - created_at
        - last_activity_at
        - expires_at
        - amr
        - acr
        - user_agent
        - remember_me
        - recovery_restricted
    SelfUser:
      type: object
      description: Self-service view of the calling user.
      properties:
        id:
          type: string
        state:
          type: string
          enum:
            - pending_verification
            - active
            - suspended
            - locked
            - recovery_restricted
            - pending_deletion
            - deleted
        display_name:
          type: string
        given_name:
          type: string
        family_name:
          type: string
        locale:
          type: string
        zoneinfo:
          type: string
        profile:
          type:
            - object
            - 'null'
          additionalProperties: true
        identifiers:
          type: array
          items:
            $ref: '#/components/schemas/UserIdentifier'
        required_actions:
          type:
            - array
            - 'null'
          items:
            type: string
            enum:
              - update_password
              - verify_email
              - configure_totp
              - accept_terms
              - complete_profile
              - verify_contact
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        version:
          type: integer
          format: int64
        deletion_scheduled_at:
          type:
            - string
            - 'null'
          format: date-time
      required:
        - id
        - state
        - display_name
        - given_name
        - family_name
        - locale
        - zoneinfo
        - profile
        - identifiers
        - required_actions
        - created_at
        - updated_at
        - version
        - deletion_scheduled_at
    ServicePrincipal:
      additionalProperties: false
      properties:
        allowed_organization_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        created_at:
          format: date-time
          type: string
        description:
          type: string
        id:
          type: string
        is_agent:
          type: boolean
          description: >-
            An autonomous agent (MCH-017): needs an accountable human owner (owner_user_id; 422 otherwise), privileged
            roles reach it only through two-party approval, and its tokens carry agent=true (and act.agent=true when it
            acts for a person). Agents pass through ordinary authorization like any service.
        name:
          type: string
        owner_organization_id:
          type: string
        owner_user_id:
          type: string
        permission_revision:
          format: int64
          type: integer
        state:
          type: string
          enum:
            - active
            - disabled
            - deleted
        version:
          format: int64
          type: integer
      required:
        - allowed_organization_ids
        - created_at
        - id
        - is_agent
        - name
        - permission_revision
        - state
        - version
      type: object
    ServicePrincipalInput:
      additionalProperties: false
      properties:
        allowed_organization_ids:
          items:
            type: string
          type:
            - array
            - 'null'
        description:
          type: string
        is_agent:
          type: boolean
          description: >-
            An autonomous agent (MCH-017): needs an accountable human owner (owner_user_id; 422 otherwise), privileged
            roles reach it only through two-party approval, and its tokens carry agent=true (and act.agent=true when it
            acts for a person). Agents pass through ordinary authorization like any service.
        name:
          type: string
          maxLength: 200
        owner_organization_id:
          type: string
        owner_user_id:
          type: string
      type: object
      required:
        - name
    Session:
      additionalProperties: false
      properties:
        absolute_expires_at:
          format: date-time
          type: string
        acr:
          type: string
        amr:
          items:
            type: string
          type:
            - array
            - 'null'
        auth_time:
          format: date-time
          type: string
        created_at:
          format: date-time
          type: string
        device_label:
          type: string
        id:
          type: string
        idle_expires_at:
          format: date-time
          type: string
        last_activity_at:
          format: date-time
          type: string
        mfa_time:
          format: date-time
          type:
            - string
            - 'null'
        network:
          type: string
        realm_id:
          type: string
        recovery_restricted:
          type: boolean
        remember_me:
          type: boolean
        revoke_reason:
          type: string
        revoked_at:
          format: date-time
          type:
            - string
            - 'null'
        state:
          type: string
        transient:
          type: boolean
        user_agent:
          type: string
        user_id:
          type: string
      required:
        - absolute_expires_at
        - acr
        - amr
        - auth_time
        - created_at
        - id
        - idle_expires_at
        - last_activity_at
        - realm_id
        - recovery_restricted
        - remember_me
        - state
        - transient
        - user_id
      type: object
    SigningKeyMetadata:
      additionalProperties: false
      properties:
        activated_at:
          format: date-time
          type:
            - string
            - 'null'
        algorithm:
          type: string
        compromised_at:
          format: date-time
          type:
            - string
            - 'null'
        created_at:
          format: date-time
          type: string
        kid:
          type: string
        publish_until:
          format: date-time
          type:
            - string
            - 'null'
        retiring_at:
          format: date-time
          type:
            - string
            - 'null'
        state:
          type: string
      required:
        - algorithm
        - created_at
        - kid
        - state
      type: object
    StateResponse:
      type: object
      properties:
        state:
          type: string
      required:
        - state
    TOTPEnrollment:
      additionalProperties: false
      properties:
        credential_id:
          type: string
        expires_at:
          format: date-time
          type: string
        otpauth_uri:
          type: string
          x-secret: true
          description: otpauth:// provisioning URI containing the seed. Returned once.
        secret:
          type: string
          x-secret: true
          description: Base32 TOTP seed. Returned once during enrollment.
      required:
        - credential_id
        - expires_at
        - otpauth_uri
        - secret
      type: object
    HOTPEnrollment:
      additionalProperties: false
      properties:
        credential_id:
          type: string
        expires_at:
          format: date-time
          type: string
        counter:
          type: integer
          description: The counter the token starts at (0).
        otpauth_uri:
          type: string
          x-secret: true
          description: otpauth://hotp provisioning URI containing the seed and counter. Returned once.
        secret:
          type: string
          x-secret: true
          description: Base32 HOTP seed. Returned once during enrollment.
      required:
        - counter
        - credential_id
        - expires_at
        - otpauth_uri
        - secret
      type: object
    TokenResponse:
      additionalProperties: false
      properties:
        access_token:
          type: string
          x-secret: true
        expires_in:
          type: integer
        id_token:
          type: string
          x-secret: true
        issued_token_type:
          type: string
        refresh_token:
          type: string
          x-secret: true
        scope:
          type: string
        token_type:
          type: string
          enum:
            - Bearer
            - DPoP
          description: >-
            DPoP for an access token bound to a DPoP key (cnf.jkt, RFC 9449); Bearer for every other token,
            certificate-bound tokens (cnf.x5t#S256, RFC 8705) included. The same for every grant, token exchange
            included.
      required:
        - access_token
        - expires_in
        - token_type
      type: object
    TransactionAction:
      additionalProperties: false
      properties:
        fields:
          items:
            type: string
          type:
            - array
            - 'null'
        options:
          additionalProperties: {}
          type:
            - object
            - 'null'
        required:
          type: boolean
        type:
          type: string
      required:
        - required
        - type
      type: object
    TransactionStarted:
      type: object
      properties:
        transaction_id:
          type: string
        continuation_token:
          type: string
          x-secret: true
          description: >-
            Continuation authority for headless clients; send it in X-Transaction-Token on every later step. Returned
            exactly once; it is never stored in plaintext, never shown again and never replayed from the idempotency
            store.
        device_request:
          type: object
          description: Present only when the transaction was started from a device user code.
          properties:
            client_name:
              type: string
            client_id:
              type: string
            scopes:
              type:
                - array
                - 'null'
              items:
                type: string
            expires_at:
              type: string
              format: date-time
        state:
          $ref: '#/components/schemas/TransactionState'
      required:
        - transaction_id
        - continuation_token
        - state
    TransactionState:
      additionalProperties: false
      properties:
        client:
          additionalProperties: {}
          type:
            - object
            - 'null'
        completed_factors:
          items:
            type: string
          type:
            - array
            - 'null'
        csrf_token:
          type: string
          description: Returned only to browser (cookie-bound) callers from an allowed origin; send it back in X-CSRF-Token.
        error:
          type: string
        expires_at:
          format: date-time
          type: string
        external_redirect:
          type: string
          description: Upstream authorization URL the browser must visit (federated sign-in).
        id:
          type: string
        intent:
          type: string
        locale:
          type: string
        next_actions:
          items:
            $ref: '#/components/schemas/TransactionAction'
          type:
            - array
            - 'null'
        notice:
          type: string
          description: Non-terminal condition to show, e.g. upstream_unavailable.
        one_time:
          additionalProperties: {}
          type:
            - object
            - 'null'
          x-secret: true
          description: Secrets displayed exactly once (for example newly generated recovery codes). Never shown again.
        redirect_to:
          type: string
        status:
          type: string
          enum:
            - pending
            - completed
            - cancelled
            - expired
            - failed
        user:
          additionalProperties: {}
          type:
            - object
            - 'null'
        webauthn:
          description: >-
            WebAuthn ceremony options for the client (PublicKeyCredentialRequestOptions or CreationOptions JSON) when a
            passkey step is pending. Not secret.
      required:
        - client
        - completed_factors
        - expires_at
        - id
        - intent
        - next_actions
        - status
      type: object
    UserIdentifier:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
          enum:
            - email
            - phone
            - username
        value:
          type: string
        verified:
          type: boolean
        is_primary:
          type: boolean
      required:
        - id
        - type
        - value
        - verified
        - is_primary
    UserInfo:
      type: object
      additionalProperties: true
      properties:
        sub:
          type: string
      required:
        - sub
      description: Standard OIDC claims permitted by the granted scopes.
    WebhookDelivery:
      additionalProperties: false
      properties:
        attempts:
          type: integer
        created_at:
          format: date-time
          type: string
        delivered_at:
          format: date-time
          type:
            - string
            - 'null'
        event_id:
          type: string
        event_type:
          type: string
        id:
          type: string
        last_response_category:
          type: string
        last_status_code:
          type:
            - integer
            - 'null'
        next_attempt_at:
          format: date-time
          type: string
        state:
          type: string
      required:
        - attempts
        - created_at
        - event_id
        - event_type
        - id
        - next_attempt_at
        - state
      type: object
    WebhookInput:
      additionalProperties: false
      properties:
        allow_private_network:
          type: boolean
        destination_url:
          type: string
          format: uri
          description: HTTPS destination subject to the operator egress policy.
        event_types:
          items:
            type: string
          type:
            - array
            - 'null'
          minItems: 1
          description: Event types from the catalog in api/events (also returned by GET /webhooks as event_types).
        name:
          type: string
        organization_id:
          type: string
        payload_form:
          type: string
          enum:
            - minimal
            - standard
        event_version:
          type: integer
          enum:
            - 1
            - 2
          description: Event schema version deliveries are rendered to (EXT-018); default 1. See api/events/README.md.
      type: object
      required:
        - destination_url
        - event_types
        - name
    WebhookSubscription:
      additionalProperties: false
      properties:
        allow_private_network:
          type: boolean
        created_at:
          format: date-time
          type: string
        destination_url:
          type: string
        event_types:
          items:
            type: string
          type:
            - array
            - 'null'
        id:
          type: string
        name:
          type: string
        organization_id:
          type: string
        owner_user_id:
          type: string
        payload_form:
          type: string
        state:
          type: string
          enum:
            - active
            - paused
            - disabled
        version:
          format: int64
          type: integer
        event_version:
          type: integer
          description: Event schema version of deliveries (EXT-018).
        plugin_id:
          type: string
          description: Set when a plugin manages the subscription; PATCH and DELETE then return 409 (EXT-014).
      required:
        - allow_private_network
        - created_at
        - destination_url
        - event_types
        - id
        - name
        - payload_form
        - state
        - version
        - event_version
