openapi: 3.0.0
info:
  service: common
tags:
  - name: External Sync Tokens
    description: >-
      Manage the tokens an identity provider uses to provision users and groups into a zone over SCIM
    x-displayName: External Sync Tokens
  - name: Zones
    x-displayName: Zones
  - name: Applications
    x-displayName: Applications
  - name: Application Credentials
    x-displayName: Application Credentials
  - name: Delegated Grants
    x-displayName: Delegated Grants
  - name: Providers
    x-displayName: Providers
  - name: Resources
    x-displayName: Resources
  - name: Zone Roles
    x-displayName: Zone Roles
  - name: Groups
    x-displayName: Groups
  - name: Sessions
    x-displayName: Sessions
  - name: User Agents
    x-displayName: User Agents
  - name: Users
    x-displayName: Users
  - name: Organizations
  - name: Organization Invitations
  - name: Service Accounts
  - name: Service Account Credentials
  - name: SSO Connection
  - name: PolicySchemas
    description: >
      Zone-scoped Cedar schema management.


      The Cedar schema defines the entity model used for authorization decisions.

      Key entity types and their attributes:


      - **Keycard::User** — `email` (String), `groups` (Set of String)

      - **Keycard::Application** — `registration_method` (RegistrationMethod entity), `credential_type` (CredentialType entity)

      - **Keycard::RegistrationMethod** — enum entity: `"managed"`, `"dcr"`

      - **Keycard::CredentialType** — enum entity: `"token"`, `"password"`, `"public-key"`, `"url"`, `"public"`

      - **Keycard::Resource** — `id` (String), `name` (String), `scopes` (Set of String)

      - **Keycard::Claims** — `email` (String), `groups` (Set of String), `issuer_claims` (issuer-specific claims record), plus arbitrary additional fields


      Enum-like attributes use Cedar enum entity types (schema version `2026-03-16`+).

      In policies, reference values as `RegistrationMethod::"managed"` or `CredentialType::"token"`.

      See the Credentials API spec for the full entity model reference.

    x-displayName: PolicySchemas
  - name: Policies
    description: Policy CRUD operations
    x-displayName: Policies
  - name: PolicyVersions
    description: Immutable policy version snapshots
    x-displayName: PolicyVersions
  - name: PolicyDrafts
    description: Mutable policy authoring workspace
    x-displayName: PolicyDrafts
  - name: PolicySets
    description: Policy set CRUD and binding management
    x-displayName: PolicySets
  - name: PolicySetVersions
    description: Immutable policy set manifest snapshots
    x-displayName: PolicySetVersions
  - name: PolicySetDrafts
    description: Mutable policy set manifest workspace
    x-displayName: PolicySetDrafts
  - name: PolicySetManifest
    description: Declarative read/apply of a policy set's full content
    x-displayName: PolicySetManifest
  - name: PolicyEvaluations
    description: Stateless policy evaluation testing
    x-displayName: PolicyEvaluations
  - name: PolicyValidations
    description: Stateless Cedar policy validation
    x-displayName: PolicyValidations
  - name: PolicyBindings
    description: |
      Policy set binding management. Active slots are replace-only by design:
      once bound (at zone bootstrap or on a principal's first policy check), an
      active slot is never emptied — evaluation fails closed, so an empty active
      slot would deny all access. Replace the bound version rather than removing
      the binding. DELETE applies to shadow bindings only.
    x-displayName: PolicyBindings
  - name: Secrets
paths:
  /zones:
    servers: []
    post:
      operationId: createZone
      summary: Create zone
      tags:
        - Zones
      description: >-
        Creates a new zone for the authenticated organization. A zone is an isolated environment for IAM resources.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ZoneCreate'
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: A zone for organizing resources within an organization
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Zone'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    get:
      operationId: listZones
      summary: List zones
      tags:
        - Zones
      description: >-
        Returns a list of zones for the authenticated organization. Cursor pagination via `after`/`before` and `limit`, plus `expand[]=total_count`, name substring search, and `sort`, are supported on every request. `filter[permission][in]` narrows the list to zones where the caller holds at least one of the given permissions.
      parameters:
        - schema:
            type: string
          in: query
          name: slug
          required: false
        - schema:
            type: string
          in: query
          name: cursor
          required: false
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
                  - permissions
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
                    - permissions
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: query
          name: filter[organization_id]
          required: false
        - schema:
            anyOf:
              - type: string
              - maxItems: 20
                type: array
                items:
                  type: string
          in: query
          name: filter[permission][in]
          required: false
          description: >-
            Only return zones where the caller is allowed ANY of these permissions (`<resource_type>:<action>`, e.g. `applications:list`). Repeatable (one permission per occurrence); values are unioned, max 20 (a stricter cap than the authorization service's 50). The accessible zone set is resolved by the authorization service and composes with cursor pagination, search, sort and `expand[]=total_count`. Malformed values are a 400.
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - page_info
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Zone'
                  page_info:
                    allOf:
                      - $ref: '#/components/schemas/iam_PageInfo'
                    deprecated: true
                    description: >-
                      Deprecated: read cursor state from `pagination` instead. This field is retained for backward compatibility and will be removed in a future version.
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}:
    servers: []
    get:
      operationId: getZone
      summary: Get zone
      tags:
        - Zones
      description: Returns details of a specific zone by ID
      parameters:
        - schema:
            anyOf:
              - type: string
                enum:
                  - permissions
              - type: array
                items:
                  type: string
                  enum:
                    - permissions
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: A zone for organizing resources within an organization
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Zone'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateZone
      summary: Update zone
      tags:
        - Zones
      description: Updates a zone's configuration (partial update)
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ZoneUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: A zone for organizing resources within an organization
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Zone'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteZone
      summary: Delete zone
      tags:
        - Zones
      description: Permanently deletes a zone and all its associated resources
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications:
    servers: []
    get:
      operationId: listApplications
      summary: List applications
      tags:
        - Applications
      description: >-
        Returns a paginated list of applications in the specified zone. Use cursor pagination via `after`/`before`. Sort: comma-separated field list; prefix with `-` for descending. Use `expand[]=total_count` to include the matching row count. Filter by exact slug via `filter[slug]` and by exact identifier via `filter[identifier]`. Search via `query[name]` / `query[identifier]` / `query[]` (substring match, OR'd across repeated values). `query[]` matches against name and identifier. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of applications — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested application that exists in the zone, in a single page. IDs not in the zone are silently omitted.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact application slug
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[slug]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact application identifier
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[identifier]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to applications with this publicId. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            type: string
            enum:
              - platform
              - customer
          in: query
          name: filter[owner_type]
          required: false
          description: >-
            Filter by owner type: `platform` (Keycard-managed) or `customer` (org-created).
        - schema:
            type: string
            enum:
              - platform
              - customer
          in: query
          name: filter[owner_type][ne]
          required: false
          description: >-
            Exclude applications with this owner type, e.g. `filter[owner_type][ne]=platform` returns only org-created applications.
        - schema:
            type: string
          in: query
          name: slug
          required: false
        - schema:
            type: string
          in: query
          name: identifier
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by name (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[name]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by identifier (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[identifier]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search across name and identifier (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[]
          required: false
        - schema:
            pattern: ^-?(created_at|name|identifier)(,\s*-?(created_at|name|identifier))*$
            type: string
          in: query
          name: sort
          required: false
          description: >-
            Comma-separated sort fields. Prefix with - for descending. Allowed: created_at, name, identifier
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - page_info
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Application'
                  page_info:
                    allOf:
                      - $ref: '#/components/schemas/iam_PageInfo'
                    deprecated: true
                    description: >-
                      Deprecated: read cursor state from `pagination` instead. This field is retained for backward compatibility and will be removed in a future version.
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: createApplication
      summary: Create application
      tags:
        - Applications
      description: >-
        Creates a new Application - a software system with an identity that can access Resources
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ApplicationCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            An Application is a software system with an associated identity that can access Resources. It may act on its own behalf (machine-to-machine) or on behalf of a user (delegated access).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Application'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications/{id}:
    servers: []
    get:
      operationId: getApplication
      summary: Get application
      tags:
        - Applications
      description: Returns details of a specific Application by ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            An Application is a software system with an associated identity that can access Resources. It may act on its own behalf (machine-to-machine) or on behalf of a user (delegated access).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Application'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateApplication
      summary: Update application
      tags:
        - Applications
      description: Updates an Application's configuration and metadata
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ApplicationUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            An Application is a software system with an associated identity that can access Resources. It may act on its own behalf (machine-to-machine) or on behalf of a user (delegated access).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Application'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteApplication
      summary: Delete application
      tags:
        - Applications
      description: Permanently deletes an application
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications/{id}/dependencies:
    servers: []
    get:
      operationId: listApplicationDependencies
      summary: List application dependencies
      tags:
        - Applications
      description: Returns resource dependencies for an application
      parameters:
        - schema:
            type: string
          in: query
          name: when_accessing
          required: false
        - schema:
            type: string
          in: query
          name: cursor
          required: false
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Resource'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications/{id}/dependencies/{dependencyId}:
    servers: []
    put:
      operationId: addApplicationDependency
      summary: Add application dependency
      tags:
        - Applications
      description: Adds a resource dependency to an application
      parameters:
        - schema:
            type: array
            items:
              type: string
          in: query
          name: when_accessing
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
        - schema:
            type: string
          in: path
          name: dependencyId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: removeApplicationDependency
      summary: Remove application dependency
      tags:
        - Applications
      description: Removes a resource dependency from an application
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
        - schema:
            type: string
          in: path
          name: dependencyId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    get:
      operationId: getApplicationDependency
      summary: Get application dependency
      tags:
        - Applications
      description: Retrieves a specific resource dependency of an application
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
        - schema:
            type: string
          in: path
          name: dependencyId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A Resource is a system that exposes protected information or functionality. It requires authentication of the requesting actor, which may be a user or application, before allowing access.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Resource'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications/{id}/application-credentials:
    servers: []
    get:
      operationId: listApplicationCredentialsForApplication
      summary: List application credentials
      tags:
        - Applications
      description: Returns a list of application credentials for a specific application
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - page_info
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_ApplicationCredential'
                  page_info:
                    $ref: '#/components/schemas/iam_PageInfo'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications/{id}/resources:
    servers: []
    get:
      operationId: listApplicationResources
      summary: List application resources
      tags:
        - Applications
      description: Returns a list of resources provided by an application
      parameters:
        - schema:
            type: string
          in: query
          name: cursor
          required: false
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Resource'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/application-credentials:
    servers: []
    get:
      operationId: listApplicationCredentials
      summary: List application credentials
      tags:
        - Application Credentials
      description: >-
        Returns a paginated list of application credentials in the specified zone. Use cursor pagination via `after`/`before`. Use `expand[]=total_count` to include the matching row count. Search via `query[identifier]`, `query[provider_name]`, or `query[]` (identifier or provider name); all are substring matches, OR'd across repeated values.
      parameters:
        - schema:
            type: string
          in: query
          name: slug
          required: false
        - schema:
            type: string
          in: query
          name: applicationId
          required: false
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
            enum:
              - platform
              - customer
          in: query
          name: filter[owner_type][ne]
          required: false
          description: >-
            Exclude credentials whose owning application has this owner type, e.g. `filter[owner_type][ne]=platform` returns only credentials of org-created applications.
        - schema:
            anyOf:
              - type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[traits][ne]
          required: false
          description: >-
            Exclude credentials whose owning application has this trait. A single value excludes that trait; repeated params accumulate into a not-in set (max 100), so a credential matches when its application's traits contain none of them. Each value is a single literal trait; a comma is a literal character in the value, not a delimiter.
        - schema:
            anyOf:
              - type: string
                enum:
                  - token
                  - password
                  - public-key
                  - url
                  - public
                description: >-
                  Filter by credential type; repeated values are OR'd, e.g. `filter[type]=token&filter[type]=password`.
              - maxItems: 100
                type: array
                items:
                  type: string
                  enum:
                    - token
                    - password
                    - public-key
                    - url
                    - public
          in: query
          name: filter[type]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: >-
                  Search by credential identifier (substring match, OR'd across repeated values)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[identifier]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: >-
                  Search by the linked provider's name (substring match, OR'd across repeated values)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[provider_name]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: >-
                  Search across credential identifier and linked provider name (substring match, OR'd across repeated values)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[]
          required: false
        - schema:
            pattern: ^-?created_at(,\s*-?created_at)*$
            type: string
          in: query
          name: sort
          required: false
          description: >-
            Comma-separated sort fields. Prefix with - for descending. Allowed: created_at
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - page_info
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_ApplicationCredential'
                  page_info:
                    allOf:
                      - $ref: '#/components/schemas/iam_PageInfo'
                    deprecated: true
                    description: >-
                      Deprecated: read cursor state from `pagination` instead. This field is retained for backward compatibility and will be removed in a future version.
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: createApplicationCredential
      summary: Create application credential
      tags:
        - Application Credentials
      description: Creates a new application credential
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ApplicationCredentialCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Response for creating a new application credential
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_ApplicationCredentialCreateResponse'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/application-credentials/{id}:
    servers: []
    get:
      operationId: getApplicationCredential
      summary: Get application credential
      tags:
        - Application Credentials
      description: Returns details of a specific application credential by ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Credentials for accessing external services from applications
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_ApplicationCredential'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateApplicationCredential
      summary: Update application credential
      tags:
        - Application Credentials
      description: Updates an application credential's configuration
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ApplicationCredentialUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Credentials for accessing external services from applications
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_ApplicationCredential'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteApplicationCredential
      summary: Delete application credential
      tags:
        - Application Credentials
      description: Permanently deletes an application credential
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/delegated-grants:
    servers: []
    get:
      operationId: listDelegatedGrants
      summary: List delegated grants
      tags:
        - Delegated Grants
      description: >-
        Returns a paginated list of delegated grants in the specified zone. Can be filtered by user, resource, or status. Use cursor pagination via `after`/`before`. Sort: comma-separated field list; prefix with `-` for descending. Use `expand[]=total_count` to include the matching row count.
      parameters:
        - schema:
            type: string
          in: query
          name: user_id
          required: false
          description: Filter by user ID
        - schema:
            type: string
          in: query
          name: resource_id
          required: false
          description: Filter by resource ID
        - schema:
            type: string
            enum:
              - 'true'
          in: query
          name: active
          required: false
        - schema:
            type: string
            enum:
              - active
              - expired
              - revoked
          in: query
          name: status
          required: false
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            pattern: ^-?created_at(,\s*-?created_at)*$
            type: string
          in: query
          name: sort
          required: false
          description: >-
            Comma-separated sort fields. Prefix with - for descending. Allowed: created_at
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_DelegatedGrant'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/delegated-grants/{id}:
    servers: []
    get:
      operationId: getDelegatedGrant
      summary: Get delegated grant
      tags:
        - Delegated Grants
      description: Returns details of a specific delegated grant by grant ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Delegated grant ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            User authorization for a resource to be accessed on their behalf. The grant links the user, resource, and the provider that issued the grant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_DelegatedGrant'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateDelegatedGrant
      summary: Update delegated grant
      tags:
        - Delegated Grants
      description: Revokes an active delegated grant
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - status
              properties:
                status:
                  type: string
                  enum:
                    - revoked
        required: true
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Delegated grant ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            User authorization for a resource to be accessed on their behalf. The grant links the user, resource, and the provider that issued the grant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_DelegatedGrant'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteDelegatedGrant
      summary: Delete delegated grant
      tags:
        - Delegated Grants
      description: >-
        Permanently revokes a delegated grant, removing the user's access to the protected resource
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Delegated grant ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/external-sync-tokens:
    servers: []
    get:
      operationId: listExternalSyncTokens
      summary: List external sync tokens
      tags:
        - External Sync Tokens
      description: >-
        Returns the external sync tokens for a zone, newest first. Token values are never returned; the value is available only in the response that created the token.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_ExternalSyncToken'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: createExternalSyncToken
      summary: Create external sync token
      tags:
        - External Sync Tokens
      description: >-
        Creates a token an identity provider can use to provision users into this zone over SCIM. The zone must have `external_sync_enabled` set and a `user_identity_provider_id` configured; otherwise the request fails with 400.


        The token value is returned only in this response and cannot be retrieved later. Multiple tokens can be active at once: to rotate, create a new token, then delete the old one.
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A new external sync token, including the token value. The value is returned only in this response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_ExternalSyncTokenCreateResponse'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/external-sync-tokens/{id}:
    servers: []
    get:
      operationId: getExternalSyncToken
      summary: Get external sync token
      tags:
        - External Sync Tokens
      description: >-
        Returns an external sync token's metadata. The token value is never returned.
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: External sync token ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            Token an identity provider uses to provision users and groups into a zone over SCIM. The token value is returned once, when the token is created, and is never returned again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_ExternalSyncToken'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteExternalSyncToken
      summary: Delete external sync token
      tags:
        - External Sync Tokens
      description: >-
        Deletes an external sync token. The token stops working immediately and cannot be restored — create a new one instead.
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: External sync token ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/providers:
    servers: []
    get:
      operationId: listProviders
      summary: List providers
      tags:
        - Providers
      description: >-
        Returns a paginated list of providers in the specified zone. Use cursor pagination via `after`/`before`. Sort: comma-separated field list; prefix with `-` for descending. Use `expand[]=total_count` to include the matching row count. Filter by exact slug via `filter[slug]`, exact identifier via `filter[identifier]` and provider type via `filter[type]`. Search via `query[name]` / `query[identifier]` / `query[]` (substring match, OR'd across repeated values). `query[]` matches against name and identifier. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of provider IDs — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested provider that exists in the zone, in a single page. Unknown or malformed IDs are silently omitted.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: query
          name: slug
          required: false
        - schema:
            type: string
          in: query
          name: identifier
          required: false
        - schema:
            type: string
            enum:
              - external
              - keycard-vault
              - keycard-sts
          in: query
          name: type
          required: false
        - schema:
            anyOf:
              - description: Filter by exact provider slug
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[slug]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact provider identifier
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[identifier]
          required: false
        - schema:
            anyOf:
              - type: string
                enum:
                  - external
                  - keycard-vault
                  - keycard-sts
                description: Filter by provider type
              - maxItems: 100
                type: array
                items:
                  type: string
                  enum:
                    - external
                    - keycard-vault
                    - keycard-sts
          in: query
          name: filter[type]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to providers with this ID. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by name (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[name]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by identifier (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[identifier]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search across name and identifier (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[]
          required: false
        - schema:
            pattern: ^-?(created_at|name|identifier)(,\s*-?(created_at|name|identifier))*$
            type: string
          in: query
          name: sort
          required: false
          description: >-
            Comma-separated sort fields. Prefix with - for descending. Allowed: created_at, name, identifier
        - schema:
            type: string
          in: query
          name: cursor
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - page_info
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Provider'
                  page_info:
                    allOf:
                      - $ref: '#/components/schemas/iam_PageInfo'
                    deprecated: true
                    description: >-
                      Deprecated: read cursor state from `pagination` instead. This field is retained for backward compatibility and will be removed in a future version.
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: createProvider
      summary: Create provider
      tags:
        - Providers
      description: >-
        Creates a new Provider - a system that supplies access to Resources and allows actors to authenticate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ProviderCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A Provider is a system that supplies access to Resources and allows actors (Users or Applications) to authenticate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Provider'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/providers/{id}:
    servers: []
    get:
      operationId: getProvider
      summary: Get provider
      tags:
        - Providers
      description: Returns details of a specific Provider by ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A Provider is a system that supplies access to Resources and allows actors (Users or Applications) to authenticate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Provider'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateProvider
      summary: Update provider
      tags:
        - Providers
      description: Updates a Provider's configuration and metadata
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ProviderUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A Provider is a system that supplies access to Resources and allows actors (Users or Applications) to authenticate.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Provider'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteProvider
      summary: Delete provider
      tags:
        - Providers
      description: Permanently deletes a provider
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/providers/{id}/validate:
    servers: []
    post:
      operationId: validateProvider
      summary: Validate provider connection
      tags:
        - Providers
      description: >-
        Runs on-demand OIDC connection checks (issuer reachability, metadata retrieval, endpoint consistency, authorization endpoint reachability, and a demonstration client_credentials exchange) against the provider and returns a per-check result. Results are not persisted.
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
        - schema:
            type: string
          in: path
          name: id
          required: true
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            Result of running the provider OIDC connection checks on demand. Not persisted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_ProviderValidationResult'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '502':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '504':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/resources:
    servers: []
    get:
      operationId: listResources
      summary: List resources
      tags:
        - Resources
      description: >-
        Returns a paginated list of resources in the specified zone. Use cursor pagination via `after`/`before`, and `expand[]=total_count` to include the matching row count. Filter by exact identifier via `filter[identifier]`. Filter by trait via `filter[traits]` (repeated params are OR'd) or `filter[traits][all]` (contains-all). The scalar `identifier` query parameter is a backward-compatible alias for `filter[identifier]`: exact match on a single value, folded into the same exact-match identifier filter.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact resource slug
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[slug]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact resource identifier
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[identifier]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to resources with this publicId. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by name (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[name]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by identifier (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[identifier]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search across name and identifier (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[]
          required: false
        - schema:
            pattern: ^-?(created_at|updated_at|name|identifier)(,\s*-?(created_at|updated_at|name|identifier))*$
            type: string
          in: query
          name: sort
          required: false
          description: >-
            Comma-separated sort fields. Prefix with - for descending. Allowed: created_at, updated_at, name, identifier
        - schema:
            type: string
            enum:
              - platform
              - customer
          in: query
          name: filter[owner_type]
          required: false
          description: >-
            Filter by owner type: `platform` (Keycard-managed) or `customer` (org-created).
        - schema:
            type: string
          in: query
          name: identifier
          required: false
          description: >-
            Backward-compatible alias for `filter[identifier]`: exact match on a single resource identifier.
        - schema:
            type: string
          in: query
          name: credentialProviderId
          required: false
          description: Filter resources by credential provider ID
        - schema:
            type: string
          in: query
          name: slug
          required: false
        - schema:
            anyOf:
              - type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[traits]
          required: false
          description: >-
            Filter by trait. Repeated params are OR'd; each value is a single literal trait (a comma is a literal character). Use `filter[traits][all]` for contains-all.
        - schema:
            anyOf:
              - description: >-
                  Resources that are not a dependency of this application. Repeatable (none of), max 100.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[dependency_of_application_id][ne]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Resource'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - message
                properties:
                  message:
                    type: string
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: createResource
      summary: Create resource
      tags:
        - Resources
      description: >-
        Creates a new Resource - a system that exposes protected information or functionality requiring authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ResourceCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A Resource is a system that exposes protected information or functionality. It requires authentication of the requesting actor, which may be a user or application, before allowing access.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Resource'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/resources/{id}:
    servers: []
    get:
      operationId: getResource
      summary: Get resource
      tags:
        - Resources
      description: Returns details of a specific Resource by ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Resource ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A Resource is a system that exposes protected information or functionality. It requires authentication of the requesting actor, which may be a user or application, before allowing access.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Resource'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateResource
      summary: Update resource
      tags:
        - Resources
      description: Updates a Resource's configuration and metadata
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_ResourceUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Resource ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A Resource is a system that exposes protected information or functionality. It requires authentication of the requesting actor, which may be a user or application, before allowing access.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Resource'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteResource
      summary: Delete resource
      tags:
        - Resources
      description: Permanently deletes a Resource
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Resource ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/roles:
    servers: []
    get:
      operationId: listRoles
      summary: List roles
      tags:
        - Zone Roles
      description: >-
        Returns the roles defined in the specified zone, cursor-paginated. Ordered by identifier.
      parameters:
        - schema:
            type: string
          in: query
          name: identifier
          required: false
          description: Filter roles by identifier
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Role'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: createRole
      summary: Create role
      tags:
        - Zone Roles
      description: >-
        Creates a new customer-owned role in the specified zone. The owner_type is always customer; platform roles are managed by Keycard.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_RoleCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '201':
          description: A role that can be assigned to users within a zone.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Role'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/roles/{roleId}:
    servers: []
    get:
      operationId: getRole
      summary: Get role
      tags:
        - Zone Roles
      description: Returns details of a specific role by ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: roleId
          required: true
          description: Role ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: A role that can be assigned to users within a zone.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Role'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateRole
      summary: Update role
      tags:
        - Zone Roles
      description: >-
        Updates a customer-owned role's description. The identifier is immutable, and platform-owned roles cannot be modified.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_RoleUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: roleId
          required: true
          description: Role ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: A role that can be assigned to users within a zone.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Role'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteRole
      summary: Delete role
      tags:
        - Zone Roles
      description: >-
        Permanently deletes a customer-owned role. Platform-owned roles cannot be deleted, and a role with existing assignments returns 409.
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: roleId
          required: true
          description: Role ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/users/{userId}/roles:
    servers: []
    get:
      operationId: listUserRoleAssignments
      summary: List user role assignments
      tags:
        - Zone Roles
      description: >-
        Returns the roles assigned to the specified user within the zone. Use cursor pagination via `after`/`before`; pass `expand[]=total_count` to include the matching row count. Pass `filter[scope_id]` (repeatable, max 100) to keep only the assignments scoped to those targets, and `filter[scoped]=false` to keep only unscoped assignments (the ones applying to the zone itself), so a known set of targets resolves in a fixed number of requests.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to assignments scoped to this target ID (e.g. a zone ID). Repeatable, max 100; values are OR'd. Unscoped assignments never match.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[scope_id]
          required: false
        - schema:
            type: boolean
          in: query
          name: filter[scoped]
          required: false
          description: >-
            `false` keeps only unscoped assignments (those applying to the zone itself, e.g. an org role); `true` keeps only scoped ones. Omit to list both.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: userId
          required: true
          description: User ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_RoleAssignment'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: assignUserRole
      summary: Assign role to user
      tags:
        - Zone Roles
      description: >-
        Assigns a role to the user. Provide exactly one of role_id or role_identifier; when role_identifier is used, owner_type is required to disambiguate roles that share an identifier across owner types (and must be omitted with role_id). An optional (scope_type, scope_id) pair scopes the grant; only platform roles on the org zone may carry a scope, and a `zone` scope must reference a different zone in the same organization.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_RoleAssignmentCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: userId
          required: true
          description: User ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '201':
          description: Represents a role assigned to a principal within a zone
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_RoleAssignment'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/users/{userId}/role-assignments:
    servers: []
    get:
      operationId: listUserRoleAssignmentsByScope
      summary: List user role assignments by scope
      tags:
        - Zone Roles
      description: >-
        Returns the user's role assignments keyed by the scopes named in the request: one group per `scope_id[]` value (empty when the user holds nothing on it) plus, with `unscoped=true`, the group of assignments applying to the zone itself. Not paginated — the response has exactly as many groups as the request named, so a known set of up to 100 targets always resolves in one request. Use `GET …/roles` to enumerate everything the user holds.
      parameters:
        - schema:
            default: zone
            type: string
          in: query
          name: scope_type
          required: false
          description: >-
            The kind of resource the requested `scope_id[]` values name; echoed as each group's `scope_type`. Defaults to `zone`, the only scope type a grant can carry today.
        - schema:
            maxItems: 100
            type: array
            items:
              type: string
          in: query
          name: scope_id[]
          required: false
          description: >-
            Scope IDs (of `scope_type`) to answer for. Repeatable, max 100; each yields exactly one group, empty when the principal holds nothing on it. Unknown IDs yield an empty group.
        - schema:
            default: false
            type: boolean
          in: query
          name: unscoped
          required: false
          description: >-
            `true` adds the unscoped group (grants applying to the zone itself, e.g. an org role) as the first item.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: userId
          required: true
          description: User ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            Role assignments keyed by requested scope. Not paginated: the number of groups equals the number of scopes named in the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_RoleAssignmentScopeGroupList'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/users/{userId}/roles/{roleId}:
    servers: []
    delete:
      operationId: revokeUserRole
      summary: Revoke role from user
      tags:
        - Zone Roles
      description: >-
        Revokes a role from the user. Provide the same (scope_type, scope_id) pair the grant was created with, or omit both to revoke the unscoped grant.
      parameters:
        - schema:
            minLength: 1
            type: string
          in: query
          name: scope_type
          required: false
          description: Scope kind of the grant to revoke. Provide together with scope_id.
        - schema:
            minLength: 1
            type: string
          in: query
          name: scope_id
          required: false
          description: >-
            Scope target of the grant to revoke. Provide together with scope_type.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: userId
          required: true
          description: User ID
        - schema:
            type: string
          in: path
          name: roleId
          required: true
          description: Role ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications/{applicationId}/roles:
    servers: []
    get:
      operationId: listApplicationRoleAssignments
      summary: List application role assignments
      tags:
        - Zone Roles
      description: >-
        Returns the roles assigned to the specified application within the zone. Use cursor pagination via `after`/`before`; pass `expand[]=total_count` to include the matching row count.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: applicationId
          required: true
          description: Application ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_RoleAssignment'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: assignApplicationRole
      summary: Assign role to application
      tags:
        - Zone Roles
      description: >-
        Assigns a role to the application. Provide exactly one of role_id or role_identifier; when role_identifier is used, owner_type is required to disambiguate roles that share an identifier across owner types (and must be omitted with role_id). An optional (scope_type, scope_id) pair scopes the grant; only platform roles on the org zone may carry a scope, and a `zone` scope must reference a different zone in the same organization.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_RoleAssignmentCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: applicationId
          required: true
          description: Application ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '201':
          description: Represents a role assigned to a principal within a zone
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_RoleAssignment'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/applications/{applicationId}/roles/{roleId}:
    servers: []
    delete:
      operationId: revokeApplicationRole
      summary: Revoke role from application
      tags:
        - Zone Roles
      description: >-
        Revokes a role from the application. Provide the same (scope_type, scope_id) pair the grant was created with, or omit both to revoke the unscoped grant.
      parameters:
        - schema:
            minLength: 1
            type: string
          in: query
          name: scope_type
          required: false
          description: Scope kind of the grant to revoke. Provide together with scope_id.
        - schema:
            minLength: 1
            type: string
          in: query
          name: scope_id
          required: false
          description: >-
            Scope target of the grant to revoke. Provide together with scope_type.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: applicationId
          required: true
          description: Application ID
        - schema:
            type: string
          in: path
          name: roleId
          required: true
          description: Role ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/groups:
    servers: []
    get:
      operationId: listGroups
      summary: List groups
      tags:
        - Groups
      description: >-
        Returns a paginated list of the groups in the specified zone. Use cursor pagination via `after`/`before`. Sort: comma-separated field list; prefix with `-` for descending (allowed: created_at, name, identifier). Pass `expand[]=member_count` to include each group's member count, `expand[]=roles` to include the identifiers of the roles assigned to each group, and `expand[]=total_count` to include the matching row count. Filter by exact identifier via `filter[identifier]` (repeatable, OR'd across values). Search via `query[]` (case-insensitive substring match, OR'd across repeated values); it matches the group's name and identifier. Pass `filter[external]=false` for only groups managed in Keycard or `filter[external]=true` for only groups synced from an external directory; omit it to list both. Filter externally synced groups by their directory issuer via `filter[external_issuer]` (exact match, repeatable, OR'd across values). Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of groups — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested group that exists in the zone, in a single page. IDs not in the zone are silently omitted.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
                  - member_count
                  - roles
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
                    - member_count
                    - roles
          in: query
          name: expand[]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to groups with this ID. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact group identifier
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[identifier]
          required: false
        - schema:
            type: boolean
          in: query
          name: filter[external]
          required: false
          description: >-
            Filter by source: `false` for groups managed in Keycard, `true` for groups synced from an external directory. Omit to list both.
        - schema:
            anyOf:
              - description: >-
                  Filter by exact `external_issuer`: the issuer of the external directory the group was synced from. Groups managed in Keycard have no `external_issuer` and never match.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[external_issuer]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search across name and identifier (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[]
          required: false
        - schema:
            pattern: ^-?(created_at|name|identifier)(,\s*-?(created_at|name|identifier))*$
            type: string
          in: query
          name: sort
          required: false
          description: >-
            Comma-separated sort fields. Prefix with - for descending. Allowed: created_at, name, identifier
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Group'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: createGroup
      summary: Create group
      tags:
        - Groups
      description: >-
        Creates a group in the zone (managed in Keycard). Groups synced from an external directory are created by that directory, not here.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_GroupCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '201':
          description: >-
            A zone-scoped group of users, assignable to roles and usable in policies. Roles assigned to a group are inherited by its members. `external` is false for groups managed in Keycard and true for groups synced from an external directory.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Group'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/groups/{groupId}:
    servers: []
    get:
      operationId: getGroup
      summary: Get group
      tags:
        - Groups
      description: >-
        Returns a group by ID. Pass `expand[]=member_count` for its member count and `expand[]=roles` for the identifiers of its assigned roles.
      parameters:
        - schema:
            anyOf:
              - type: string
                enum:
                  - member_count
                  - roles
              - type: array
                items:
                  type: string
                  enum:
                    - member_count
                    - roles
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A zone-scoped group of users, assignable to roles and usable in policies. Roles assigned to a group are inherited by its members. `external` is false for groups managed in Keycard and true for groups synced from an external directory.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Group'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateGroup
      summary: Update group
      tags:
        - Groups
      description: >-
        Updates a group's name and/or identifier (partial update). A group's source is immutable. The name of a group synced from an external directory cannot be changed while external sync is enabled for the zone; its identifier can.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_GroupUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A zone-scoped group of users, assignable to roles and usable in policies. Roles assigned to a group are inherited by its members. `external` is false for groups managed in Keycard and true for groups synced from an external directory.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Group'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteGroup
      summary: Delete group
      tags:
        - Groups
      description: >-
        Deletes a group and its memberships and role assignments. Groups synced from an external directory can only be deleted by that directory (after external sync is disabled).
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/groups/{groupId}/members:
    servers: []
    get:
      operationId: listGroupMembers
      summary: List group members
      tags:
        - Groups
      description: >-
        Returns a paginated list of the group's members. Use cursor pagination via `after`/`before`. Pass `expand[]=user` to embed each member's full user record and `expand[]=total_count` to include the matching row count. Pass `query[]` (repeatable, 1-255 chars) to search members by their user's email or `subject` (substring match, OR'd across repeated values). Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of members by user ID — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested member that exists in the group, in a single page. IDs not in the group are silently omitted.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
                  - user
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
                    - user
          in: query
          name: expand[]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to the member with this user ID. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: >-
                  Search members by their user's email or `subject` (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_GroupMember'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: addGroupMember
      summary: Add group member
      tags:
        - Groups
      description: >-
        Adds a user to a group managed in Keycard. Membership of externally synced groups is not managed manually.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_GroupMemberCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '201':
          description: A user's membership in a group
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_GroupMember'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/groups/{groupId}/members/{userId}:
    servers: []
    delete:
      operationId: removeGroupMember
      summary: Remove group member
      tags:
        - Groups
      description: >-
        Removes a user from a group managed in Keycard. Membership of externally synced groups is not managed manually. A member is identified by its user's ID.
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
        - schema:
            type: string
          in: path
          name: userId
          required: true
          description: User ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/groups/{groupId}/roles:
    servers: []
    get:
      operationId: listGroupRoleAssignments
      summary: List group role assignments
      tags:
        - Groups
      description: >-
        Returns the roles assigned to the group. Members inherit these roles. Returns the shared role-assignment shape with `principal_type` set to `group`. Use cursor pagination via `after`/`before`; pass `expand[]=total_count` to include the matching row count. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of role assignments, mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested assignment that exists on the group, in a single page. IDs not on the group are silently omitted. Pass `filter[scope_id]` (repeatable, max 100) to keep only the assignments scoped to those targets, and `filter[scoped]=false` to keep only unscoped assignments (the ones applying to the zone itself).
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to the role assignment with this ID. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to assignments scoped to this target ID (e.g. a zone ID). Repeatable, max 100; values are OR'd. Unscoped assignments never match.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[scope_id]
          required: false
        - schema:
            type: boolean
          in: query
          name: filter[scoped]
          required: false
          description: >-
            `false` keeps only unscoped assignments (those applying to the zone itself, e.g. an org role); `true` keeps only scoped ones. Omit to list both.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_RoleAssignment'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    post:
      operationId: assignGroupRole
      summary: Assign role to group
      tags:
        - Groups
      description: >-
        Assigns a role to the group; members inherit it. Provide role_id, or role_identifier with owner_type. Returns the shared role-assignment shape with `principal_type` set to `group`.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_RoleAssignmentCreate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '201':
          description: Represents a role assigned to a principal within a zone
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_RoleAssignment'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/groups/{groupId}/role-assignments:
    servers: []
    get:
      operationId: listGroupRoleAssignmentsByScope
      summary: List group role assignments by scope
      tags:
        - Groups
      description: >-
        Returns the group's role assignments keyed by the scopes named in the request: one group per `scope_id[]` value (empty when the group holds nothing on it) plus, with `unscoped=true`, the group of assignments applying to the zone itself. Not paginated — the response has exactly as many groups as the request named, so a known set of up to 100 targets always resolves in one request. Use `GET …/roles` to enumerate everything the group holds.
      parameters:
        - schema:
            default: zone
            type: string
          in: query
          name: scope_type
          required: false
          description: >-
            The kind of resource the requested `scope_id[]` values name; echoed as each group's `scope_type`. Defaults to `zone`, the only scope type a grant can carry today.
        - schema:
            maxItems: 100
            type: array
            items:
              type: string
          in: query
          name: scope_id[]
          required: false
          description: >-
            Scope IDs (of `scope_type`) to answer for. Repeatable, max 100; each yields exactly one group, empty when the principal holds nothing on it. Unknown IDs yield an empty group.
        - schema:
            default: false
            type: boolean
          in: query
          name: unscoped
          required: false
          description: >-
            `true` adds the unscoped group (grants applying to the zone itself, e.g. an org role) as the first item.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            Role assignments keyed by requested scope. Not paginated: the number of groups equals the number of scopes named in the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_RoleAssignmentScopeGroupList'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/groups/{groupId}/roles/{roleId}:
    servers: []
    delete:
      operationId: revokeGroupRole
      summary: Revoke role from group
      tags:
        - Groups
      description: >-
        Revokes a role from the group. Provide the same (scope_type, scope_id) pair the grant was created with, or omit both to revoke the unscoped grant.
      parameters:
        - schema:
            minLength: 1
            type: string
          in: query
          name: scope_type
          required: false
          description: Scope kind of the grant to revoke. Provide together with scope_id.
        - schema:
            minLength: 1
            type: string
          in: query
          name: scope_id
          required: false
          description: >-
            Scope target of the grant to revoke. Provide together with scope_type.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: groupId
          required: true
          description: Group ID
        - schema:
            type: string
          in: path
          name: roleId
          required: true
          description: Role ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/session-resource-access:
    servers: []
    get:
      operationId: listSessionResourceAccessByFilters
      summary: List aggregated session resource access
      tags:
        - Sessions
      description: >-
        Returns aggregated access records per session-resource pair. By default (rollup_children=true), includes access from descendant sessions. Set rollup_children=false to return only direct session access. At least one of user_id, session_id, or resource_id must be provided.
      parameters:
        - schema:
            type: string
          in: query
          name: user_id
          required: false
          description: Filter by user ID
        - schema:
            type: string
          in: query
          name: session_id
          required: false
          description: Filter by session ID
        - schema:
            type: string
          in: query
          name: resource_id
          required: false
          description: Filter by resource ID
        - schema:
            default: true
            type: boolean
          in: query
          name: rollup_children
          required: false
          description: >-
            Include resource access from descendant sessions. When true (default), aggregates access from the session and all its descendants. When false, returns only direct access for the session.
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_SessionResourceAccessList'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/sessions:
    servers: []
    get:
      operationId: listSessions
      summary: List sessions
      tags:
        - Sessions
      description: >-
        Returns sessions in the specified zone. By default, returns entry sessions (app user sessions with an initiator that are roots or direct children of a root user session). Use include_nested=true to include nested sessions. Can be filtered by session type, status, and user.
      parameters:
        - schema:
            type: string
            enum:
              - user
              - application
          in: query
          name: session_type
          required: false
        - schema:
            type: string
            enum:
              - 'true'
          in: query
          name: active
          required: false
        - schema:
            type: string
            enum:
              - active
              - expired
              - revoked
          in: query
          name: status
          required: false
        - schema:
            type: string
          in: query
          name: user_id
          required: false
          description: Filter by user ID
        - schema:
            type: string
            enum:
              - 'true'
          in: query
          name: include_nested
          required: false
          description: >-
            Include nested sessions. When false (default), only returns entry sessions (direct children of root user sessions). When true, returns all sessions with an initiator, including nested sessions.
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_Session'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/sessions/{id}:
    servers: []
    get:
      operationId: getSession
      summary: Get session
      tags:
        - Sessions
      description: Returns details of a specific session by session ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Session ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            An authenticated identity session. Sessions can be user sessions (representing end-user authentication) or application sessions (representing service-to-service authentication). User sessions support hierarchical relationships via parent_id, while application sessions are always standalone.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Session'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateSession
      summary: Update session
      tags:
        - Sessions
      description: Revokes an active session
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - status
              properties:
                status:
                  type: string
                  enum:
                    - revoked
        required: true
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Session ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            An authenticated identity session. Sessions can be user sessions (representing end-user authentication) or application sessions (representing service-to-service authentication). User sessions support hierarchical relationships via parent_id, while application sessions are always standalone.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Session'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteSession
      summary: Delete session
      tags:
        - Sessions
      description: >-
        Permanently deletes a session, effectively logging out the user or application
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: Session ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/user-agents:
    servers: []
    get:
      operationId: listUserAgents
      summary: List user agents
      tags:
        - User Agents
      description: >-
        Returns the user agents in the specified zone, cursor-paginated and ordered by name. User agents represent client software (browsers, desktop apps, CLI tools) registered via OAuth 2.0 Dynamic Client Registration. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of user agents — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested user agent that exists in the zone, in a single page. IDs not in the zone are silently omitted.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
          in: query
          name: expand[]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to user agents with this ID. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact identifier (OAuth client_id)
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[identifier]
          required: false
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_UserAgent'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/user-agents/{id}:
    servers: []
    get:
      operationId: getUserAgent
      summary: Get user agent
      tags:
        - User Agents
      description: Returns details of a specific user agent by user agent ID
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: User agent ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: >-
            A User Agent represents a user agent (browser, desktop app, CLI tool) that can initiate user sessions via OAuth 2.0 Dynamic Client Registration.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_UserAgent'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/users:
    servers: []
    get:
      operationId: listUsers
      summary: List users
      tags:
        - Users
      description: >-
        Returns a paginated list of users in the specified zone.


        Use cursor pagination via `after`/`before`. Sort: comma-separated field list; prefix with `-` for descending. Use `expand[]=total_count` to include the matching row count, `expand[]=session_count` to include per-user session counts, `expand[]=grant_count` to include per-user delegated-grant counts, `expand[]=role-assignments` to include each user's structured role grants (direct grants only by default, each tagged with `source`; use `role_source=all` to also include group-inherited), `expand[]=groups` to include each user's group memberships, `expand[]=credentials` to include each user's authentication credentials (each with its `provider_id`), and `expand[]=credentials.provider` to additionally inline the full identity provider on each federation credential. Filter by exact email via `filter[email]` and by exact identifier via `filter[identifier]`; restrict to members of a group via `filter[groups]` (repeatable, OR'd across values); restrict to users directly granted a role via `filter[role]` (role identifier, repeatable up to 100, OR'd across values; group-inherited grants do not match); pass `filter[external]=false` for only users managed in Keycard or `filter[external]=true` for only users provisioned by an external directory (omit to list both); match exactly on the user's `subject` and `issuer` via `filter[subject]` and `filter[issuer]` (each repeatable and OR'd across values; AND'd with each other); search via `query[email]` / `query[subject]` / `query[]` (substring match, OR'd across repeated values). `query[]` matches against email and the user's `subject`. Pass `filter[id]` (repeatable, max 100) to restrict results to a known set of users — mutually exclusive with `after`/`before` (returns 400 if combined). When `filter[id]` is set, `limit` is ignored and the response contains every requested user that exists in the zone, in a single page. IDs not in the zone are silently omitted.
      parameters:
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: after
          required: false
          description: Cursor for forward pagination
        - schema:
            minLength: 1
            maxLength: 255
            type: string
          in: query
          name: before
          required: false
          description: Cursor for backward pagination
        - schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
          in: query
          name: limit
          required: false
          description: Maximum number of items to return
        - schema:
            anyOf:
              - type: string
                enum:
                  - total_count
                  - session_count
                  - grant_count
                  - role-assignments
                  - groups
                  - credentials
                  - credentials.provider
              - type: array
                items:
                  type: string
                  enum:
                    - total_count
                    - session_count
                    - grant_count
                    - role-assignments
                    - groups
                    - credentials
                    - credentials.provider
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
            enum:
              - user
              - group
              - all
          in: query
          name: role_source
          required: false
          description: >-
            Selects which grants `expand[]=role-assignments` returns, tagging each with `source`: `user` (direct only, the default), `group` (group-inherited only), or `all` (both direct and group-inherited). Requires `expand[]=role-assignments`.
        - schema:
            anyOf:
              - format: email
                description: Filter by exact email address
                type: string
              - maxItems: 100
                type: array
                items:
                  format: email
                  type: string
          in: query
          name: filter[email]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict results to users with this publicId. Repeatable, max 100. Mutually exclusive with after/before.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[id]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact user identifier
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[identifier]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict to members of this group (by group ID). Repeatable; OR'd across values.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[groups]
          required: false
        - schema:
            anyOf:
              - description: >-
                  Restrict to users directly granted this role (by role identifier). Repeatable, max 100; OR'd across values. Group-inherited grants do not match.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[role]
          required: false
        - schema:
            type: boolean
          in: query
          name: filter[external]
          required: false
          description: >-
            Filter by source: `false` for users managed in Keycard, `true` for users provisioned by an external directory. Omit to list both.
        - schema:
            anyOf:
              - description: Filter by exact `subject`. Repeatable; OR'd across values.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[subject]
          required: false
        - schema:
            anyOf:
              - description: Filter by exact `issuer`. Repeatable; OR'd across values.
                type: string
              - maxItems: 100
                type: array
                items:
                  type: string
          in: query
          name: filter[issuer]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by email (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[email]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search by the user's `subject` (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[subject]
          required: false
        - schema:
            anyOf:
              - minLength: 1
                maxLength: 255
                description: Search across email and the user's `subject` (substring match)
                type: string
              - maxItems: 100
                type: array
                items:
                  minLength: 1
                  maxLength: 255
                  type: string
          in: query
          name: query[]
          required: false
        - schema:
            pattern: ^-?(created_at|email|authenticated_at)(,\s*-?(created_at|email|authenticated_at))*$
            type: string
          in: query
          name: sort
          required: false
          description: >-
            Comma-separated sort fields. Prefix with - for descending. Allowed: created_at, email, authenticated_at
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: Default Response
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                  - pagination
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/iam_User'
                  pagination:
                    $ref: '#/components/schemas/iam_Pagination'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/users/{id}:
    servers: []
    get:
      operationId: getUser
      summary: Get user
      tags:
        - Users
      description: >-
        Returns details of a specific user by user ID. Use `expand[]=role-assignments` for the user's structured role grants and `expand[]=groups` for the user's group memberships. Role grants are direct only by default, each tagged with `source`; use `role_source=all` to also include group-inherited.
      parameters:
        - schema:
            anyOf:
              - type: string
                enum:
                  - role-assignments
                  - groups
              - type: array
                items:
                  type: string
                  enum:
                    - role-assignments
                    - groups
          in: query
          name: expand[]
          required: false
        - schema:
            type: string
            enum:
              - user
              - group
              - all
          in: query
          name: role_source
          required: false
          description: >-
            Selects which grants `expand[]=role-assignments` returns, tagging each with `source`: `user` (direct only, the default), `group` (group-inherited only), or `all` (both direct and group-inherited). Requires `expand[]=role-assignments`.
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: User ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: An authenticated user entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_User'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    patch:
      operationId: updateUser
      summary: Update user
      tags:
        - Users
      description: Update a user
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/iam_UserUpdate'
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: User ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: An authenticated user entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_User'
        '400':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
    delete:
      operationId: deleteUser
      summary: Delete user
      tags:
        - Users
      description: Delete a user
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
        - schema:
            type: string
          in: path
          name: id
          required: true
          description: User ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '204':
          description: Default Response
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '409':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /zones/{zoneId}/users/me:
    servers: []
    get:
      operationId: getCurrentUser
      summary: Get current user
      tags:
        - Users
      description: >-
        Returns the currently authenticated user in the zone. Requires read access to the resolved user. Returns 404 when the caller has no user record in the zone.
      parameters:
        - schema:
            type: string
          in: path
          name: zoneId
          required: true
          description: Zone ID
      security:
        - bearerAuth: []
        - OAuth2: []
      responses:
        '200':
          description: An authenticated user entity
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_User'
        '403':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        '404':
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
        default:
          description: Error response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/iam_Error'
  /organizations:
    servers: []
    post:
      operationId: createOrganization
      parameters:
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: Organization details to create
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_CreateOrganizationRequest'
      responses:
        '201':
          description: Organization created successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Organization'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '409':
          description: Organization with label already exists
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organizations
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: listOrganizations
      description: List organizations for the current user
      parameters:
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
        - in: query
          name: after
          description: Cursor for forward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: before
          description: Cursor for backward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: limit
          description: Maximum number of organizations to return
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: List of organizations
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_OrganizationsList'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organizations
      security:
        - bearerAuth: []
        - OAuth2: []
  /organizations/{organization_id}:
    servers: []
    get:
      operationId: getOrganization
      description: Get organization by ID or label
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
      responses:
        '200':
          description: Organization details
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Organization'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organizations
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updateOrganization
      description: Update organization details
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: Organization update details
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_UpdateOrganizationRequest'
      responses:
        '200':
          description: Organization updated successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Organization'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '409':
          description: Organization with label already exists
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organizations
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: deleteOrganization
      summary: Delete organization by ID or label
      description: |
        Deletes the organization and all zones.
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      responses:
        '204':
          description: Organization deleted successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organizations
      security:
        - bearerAuth: []
        - OAuth2: []
  /service-account-token:
    servers: []
    post:
      operationId: postServiceAccountToken
      description: >
        Exchange service account credentials for an organization-scoped M2M token.


        Credentials may be provided via HTTP Basic Authentication (RFC 6749 Section 2.3.1,

        preferred) or as form body parameters. The server MUST NOT accept credentials in

        both locations simultaneously and will reject such requests with a 400 error.

      security: []
      parameters:
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: OAuth2 Client Credentials
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - grant_type
              properties:
                grant_type:
                  type: string
                  enum:
                    - client_credentials
                  description: OAuth 2.0 grant type (must be "client_credentials")
                client_id:
                  type: string
                  nullable: true
                  description: >-
                    Service account client ID. Required if not using HTTP Basic Authentication.
                client_secret:
                  type: string
                  nullable: true
                  description: >-
                    Service account client secret. Required if not using HTTP Basic Authentication.
      responses:
        '200':
          description: M2M token generated successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_TokenResponse'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Accounts
  /organizations/{organization_id}/invitations:
    servers: []
    post:
      operationId: createOrganizationInvitation
      description: Create an invitation to join an organization
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: Invitation details
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_CreateInvitationRequest'
      responses:
        '201':
          description: Invitation created successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Invitation'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '409':
          description: Pending invitation already exists for this email
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organization Invitations
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: listOrganizationInvitations
      description: List invitations for an organization
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
        - in: query
          name: after
          description: Cursor for forward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: before
          description: Cursor for backward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: limit
          description: Maximum number of invitations to return
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - in: query
          name: filter[status]
          description: >
            Return only invitations with these statuses. Repeat the parameter

            to match any of several statuses (`?filter[status]=pending&filter[status]=accepted`).

            Expired invitations are never listed, so `expired` matches nothing.

            When absent, no status filter is applied.

          required: false
          style: form
          explode: true
          schema:
            type: array
            minItems: 1
            maxItems: 4
            items:
              $ref: '#/components/schemas/org-management_InvitationStatus'
      responses:
        '200':
          description: List of organization invitations
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_InvitationsList'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organization Invitations
      security:
        - bearerAuth: []
        - OAuth2: []
  /organizations/{organization_id}/invitations/{invitation_id}:
    servers: []
    delete:
      operationId: deleteOrganizationInvitation
      description: Delete an invitation
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: invitation_id
          required: true
          description: Invitation ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      responses:
        '204':
          description: Invitation deleted
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organization Invitations
      security:
        - bearerAuth: []
        - OAuth2: []
  /organizations/{organization_id}/service-accounts:
    servers: []
    post:
      operationId: createServiceAccount
      description: Create a new service account for an organization
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: Service account details
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_CreateServiceAccountRequest'
      responses:
        '201':
          description: Service account created successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccount'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Accounts
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: listServiceAccounts
      description: List service accounts for an organization
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
        - in: query
          name: query[]
          description: >
            Search service accounts by name or description (case-insensitive substring match).

            When multiple values are provided, a service account matches if it matches any of them.

          required: false
          style: form
          explode: true
          schema:
            type: array
            maxItems: 10
            items:
              type: string
              minLength: 1
              maxLength: 255
        - in: query
          name: after
          description: Cursor for forward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: before
          description: Cursor for backward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: limit
          description: Maximum number of service accounts to return
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: List of service accounts
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccountsList'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Accounts
      security:
        - bearerAuth: []
        - OAuth2: []
  /organizations/{organization_id}/service-accounts/{service_account_id}:
    servers: []
    get:
      operationId: getServiceAccount
      description: Get a specific service account
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
      responses:
        '200':
          description: Service account details
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccount'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Accounts
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updateServiceAccount
      description: Update a service account
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: Service account update details
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_UpdateServiceAccountRequest'
      responses:
        '200':
          description: Service account updated successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccount'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Accounts
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: deleteServiceAccount
      description: Delete a service account
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      responses:
        '204':
          description: Service account deleted
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Accounts
      security:
        - bearerAuth: []
        - OAuth2: []
  /organizations/{organization_id}/service-accounts/{service_account_id}/credentials:
    servers: []
    post:
      operationId: createServiceAccountCredential
      description: Create a new credential for a service account
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: Credential creation details
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_CreateServiceAccountCredentialRequest'
      responses:
        '201':
          description: Credential created successfully (client_secret is only shown once)
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccountCredentialWithSecret'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Account Credentials
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: listServiceAccountCredentials
      description: List credentials for a service account
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
        - in: query
          name: query[]
          description: >
            Search credentials by name, client ID, or description (case-insensitive substring match).

            When multiple values are provided, a credential matches if it matches any of them.

          required: false
          style: form
          explode: true
          schema:
            type: array
            maxItems: 10
            items:
              type: string
              minLength: 1
              maxLength: 255
        - in: query
          name: after
          description: Cursor for forward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: before
          description: Cursor for backward pagination
          schema:
            $ref: '#/components/schemas/org-management_Cursor'
        - in: query
          name: limit
          description: Maximum number of credentials to return
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
      responses:
        '200':
          description: List of credentials (without secrets)
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccountCredentialsList'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Account Credentials
      security:
        - bearerAuth: []
        - OAuth2: []
  /organizations/{organization_id}/service-accounts/{service_account_id}/credentials/{credential_id}:
    servers: []
    get:
      operationId: getServiceAccountCredential
      description: Get a specific service account credential
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - in: path
          name: credential_id
          required: true
          description: Credential ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
      responses:
        '200':
          description: Credential details (without secret)
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccountCredential'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Account Credentials
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updateServiceAccountCredential
      description: Update a service account credential
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - in: path
          name: credential_id
          required: true
          description: Credential ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: Credential update details
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_UpdateServiceAccountCredentialRequest'
      responses:
        '200':
          description: Credential updated successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_ServiceAccountCredential'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Account Credentials
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: deleteServiceAccountCredential
      description: Delete a service account credential
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - in: path
          name: service_account_id
          required: true
          description: Service account ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - in: path
          name: credential_id
          required: true
          description: Credential ID
          schema:
            $ref: '#/components/schemas/org-management_ShortID'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      responses:
        '204':
          description: Credential deleted
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Service Account Credentials
      security:
        - bearerAuth: []
        - OAuth2: []
  /invitations/{token}:
    servers: []
    get:
      operationId: getInvitationByToken
      description: View invitation details by token without consuming the token
      security: []
      parameters:
        - in: path
          name: token
          required: true
          description: Invitation token
          schema:
            type: string
            minLength: 1
            maxLength: 500
            pattern: ^[A-Za-z0-9_.-]+$
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      responses:
        '200':
          description: Invitation details
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_InvitationDetails'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '410':
          description: Invitation has expired or already been consumed
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organization Invitations
  /invitations/{token}/accept:
    servers: []
    post:
      operationId: acceptInvitation
      description: Accept and consume an invitation token to join the organization
      parameters:
        - in: path
          name: token
          required: true
          description: Invitation token
          schema:
            type: string
            minLength: 1
            maxLength: 500
            pattern: ^[A-Za-z0-9_.-]+$
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      responses:
        '200':
          description: Invitation accepted successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_InvitationAcceptResult'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '403':
          description: Email mismatch or invitation cannot be accepted by current user
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '410':
          description: Invitation has expired or already been consumed
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - Organization Invitations
      security:
        - bearerAuth: []
        - OAuth2: []
  /organizations/{organization_id}/sso-connection:
    servers: []
    post:
      operationId: enableSSOConnection
      description: Enable SSO for organization
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: SSO connection configuration
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_SSOConnectionCreate'
      responses:
        '201':
          description: SSO connection created successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_SSOConnection'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          $ref: '#/components/responses/org-management_NotFoundError'
        '409':
          description: SSO is already enabled for this organization
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - SSO Connection
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: getSSOConnection
      description: Get SSO connection configuration for organization
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
        - $ref: '#/components/parameters/org-management_Expand'
      responses:
        '200':
          description: SSO connection details
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_SSOConnection'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          description: Organization not found or SSO not enabled
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - SSO Connection
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updateSSOConnection
      description: Update SSO connection configuration
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      requestBody:
        description: SSO connection update details
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/org-management_SSOConnectionUpdate'
      responses:
        '200':
          description: SSO connection updated successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_SSOConnection'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          description: Organization not found or SSO not enabled
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - SSO Connection
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: disableSSOConnection
      description: Disable SSO for organization
      parameters:
        - in: path
          name: organization_id
          required: true
          description: Organization ID or label
          schema:
            $ref: '#/components/schemas/org-management_OrganizationIdOrLabel'
        - $ref: '#/components/parameters/org-management_X-Client-Request-ID'
      responses:
        '204':
          description: SSO connection disabled successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
        '400':
          $ref: '#/components/responses/org-management_BadRequestError'
        '401':
          $ref: '#/components/responses/org-management_UnauthorizedError'
        '403':
          $ref: '#/components/responses/org-management_ForbiddenError'
        '404':
          description: Organization not found or SSO not enabled
          headers:
            X-Request-ID:
              $ref: '#/components/headers/org-management_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/org-management_Error'
        '429':
          $ref: '#/components/responses/org-management_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/org-management_InternalServerError'
        '503':
          $ref: '#/components/responses/org-management_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/org-management_InternalServerError'
      tags:
        - SSO Connection
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-schemas:
    servers: []
    get:
      operationId: listPolicySchemas
      summary: List policy schemas
      tags:
        - PolicySchemas
      x-authz:
        action: list
        resourceType: policy_schemas
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_Expand'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - $ref: '#/components/parameters/pdp_Sort'
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_SchemaFormat'
        - $ref: '#/components/parameters/pdp_IsDefault'
        - $ref: '#/components/parameters/pdp_FilterDefault'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of policy schemas
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySchemasList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-schemas/{version}:
    servers: []
    get:
      operationId: getPolicySchema
      summary: Get a policy schema by version
      tags:
        - PolicySchemas
      x-authz:
        action: read
        resource:
          param: version
          type: policy_schemas
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_SchemaVersionParam'
        - $ref: '#/components/parameters/pdp_SchemaFormat'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The requested policy schema
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_SchemaVersionWithZoneInfo'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: setDefaultPolicySchema
      summary: Set the default policy schema for a zone
      tags:
        - PolicySchemas
      x-authz:
        action: update
        resource:
          param: version
          type: policy_schemas
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_SchemaVersionParam'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_SetDefaultPolicySchemaRequest'
      responses:
        '200':
          description: The updated policy schema
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_SchemaVersionWithZoneInfo'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policies:
    servers: []
    get:
      operationId: listPolicies
      summary: List policies in a zone
      description: |
        Returns a paginated list of policies in the zone. Supports
        cursor-based pagination, sorting, full-text search, and
        composable filters.

        The `filter[id]` parameter restricts results to a known set
        of policy IDs (up to 100). It composes with other filters
        (`filter[owner_type]`, `query[]`, etc.) but **cannot** be
        combined with cursor pagination (`after` / `before`) — the
        server returns 400 if both are present. When `filter[id]` is
        used without an explicit `limit`, the limit defaults to the
        number of requested IDs so all results fit in a single page.
        IDs that don't exist or fall outside the zone are silently
        omitted.
      tags:
        - Policies
      x-authz:
        action: list
        resourceType: policies
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_Expand'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - $ref: '#/components/parameters/pdp_Sort'
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_QueryName'
        - $ref: '#/components/parameters/pdp_QueryDescription'
        - $ref: '#/components/parameters/pdp_QueryUnscoped'
        - $ref: '#/components/parameters/pdp_Query'
        - $ref: '#/components/parameters/pdp_FilterOwnerType'
        - $ref: '#/components/parameters/pdp_FilterID'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of policies
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PoliciesList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    post:
      operationId: createPolicy
      summary: Create a new policy
      tags:
        - Policies
      x-authz:
        action: create
        resourceType: policies
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_CreatePolicyRequest'
      responses:
        '201':
          description: The newly created policy
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Policy'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '409':
          description: Conflict - a policy with this name already exists
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policies/{policy_id}:
    servers: []
    get:
      operationId: getPolicy
      summary: Get a policy by ID
      tags:
        - Policies
      x-authz:
        action: read
        resource:
          param: policy_id
          type: policies
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_ExpandSingle'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The requested policy
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Policy'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updatePolicy
      summary: Update a policy
      tags:
        - Policies
      x-authz:
        action: update
        resource:
          param: policy_id
          type: policies
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_If-Match'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_UpdatePolicyRequest'
      responses:
        '200':
          description: The updated policy
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Policy'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: Conflict - name collision
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '412':
          description: >-
            Precondition Failed - resource has been modified since the provided ETag
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: archivePolicy
      summary: Archive a policy
      tags:
        - Policies
      x-authz:
        action: delete
        resource:
          param: policy_id
          type: policies
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The archived policy
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Policy'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policies/{policy_id}/versions:
    servers: []
    get:
      operationId: listPolicyVersions
      summary: List versions of a policy
      tags:
        - PolicyVersions
      x-authz:
        action: list
        resourceType: policy_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_Expand'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - $ref: '#/components/parameters/pdp_Sort'
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_PolicyFormat'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of policy versions
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyVersionsList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    post:
      operationId: createPolicyVersion
      summary: Create a new immutable policy version
      tags:
        - PolicyVersions
      x-authz:
        action: create
        resourceType: policy_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_CreatePolicyVersionRequest'
      responses:
        '201':
          description: The newly created policy version
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyVersion'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policies/{policy_id}/versions/{version_id}:
    servers: []
    get:
      operationId: getPolicyVersion
      summary: Get a specific policy version
      tags:
        - PolicyVersions
      x-authz:
        action: read
        resource:
          param: version_id
          type: policy_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_VersionId'
        - $ref: '#/components/parameters/pdp_PolicyFormat'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_ExpandSingle'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The requested policy version
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyVersion'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: archivePolicyVersion
      summary: Archive a policy version
      tags:
        - PolicyVersions
      x-authz:
        action: delete
        resource:
          param: version_id
          type: policy_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_VersionId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The archived policy version
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyVersion'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-validations:
    servers: []
    post:
      operationId: validatePolicyContent
      summary: Validate Cedar policy content against a schema
      tags:
        - PolicyValidations
      x-authz:
        action: evaluate
        resourceType: policy_validations
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_ValidatePolicyContentRequest'
      responses:
        '200':
          description: Validation result
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyValidationResult'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policies/{policy_id}/draft:
    servers: []
    get:
      operationId: getPolicyDraft
      summary: Get the draft for a policy
      tags:
        - PolicyDrafts
      x-authz:
        action: read
        resource:
          param: policy_id
          type: policy_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_PolicyFormat'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_ExpandSingle'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The policy draft
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyDraft'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    put:
      operationId: upsertPolicyDraft
      summary: Create or update a policy draft
      tags:
        - PolicyDrafts
      x-authz:
        action: create
        resource:
          param: policy_id
          type: policy_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - name: format
          in: query
          required: false
          description: >-
            Response format override. `json` returns cedar_json, `cedar` returns cedar_raw. When omitted, the response matches the input format.
          schema:
            type: string
            enum:
              - cedar
              - json
        - name: validate_cedar
          in: query
          required: false
          schema:
            type: boolean
            default: true
          description: Whether to validate cedar_json against the schema. Defaults to true.
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_UpsertPolicyDraftRequest'
      responses:
        '200':
          description: The upserted policy draft
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyDraft'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: Conflict - concurrency conflict
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: deletePolicyDraft
      summary: Delete a policy draft
      tags:
        - PolicyDrafts
      x-authz:
        action: delete
        resource:
          param: policy_id
          type: policy_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicyId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '204':
          description: Draft successfully deleted
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets:
    servers: []
    get:
      operationId: listPolicySets
      summary: List policy sets in a zone
      description: |
        Returns a paginated list of policy sets in the zone.

        `filter[target_type]` defaults to `zone`, hiding principal-scoped
        sets (e.g. per-user bundle sets) unless explicitly widened. The
        deprecated `filter[scope_type]` is honored as an equivalent and
        suppresses the default; supplying both with different value sets
        returns 400.
      tags:
        - PolicySets
      x-authz:
        action: list
        resourceType: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_Expand'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - name: sort
          in: query
          required: false
          description: |
            Field to sort by. `created_at` (default) sorts by creation date.
            `status` sorts active-first, then by creation date within each
            group. When `sort=status`, only descending order and forward
            pagination are supported; `order=asc` or `before` cursors
            return 400.
          schema:
            type: string
            enum:
              - created_at
              - status
            default: created_at
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_QueryName'
        - $ref: '#/components/parameters/pdp_QueryUnscoped'
        - $ref: '#/components/parameters/pdp_Query'
        - $ref: '#/components/parameters/pdp_FilterOwnerType'
        - $ref: '#/components/parameters/pdp_FilterScopeType'
        - $ref: '#/components/parameters/pdp_FilterTargetType'
        - $ref: '#/components/parameters/pdp_FilterActive'
        - $ref: '#/components/parameters/pdp_FilterActiveNew'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of policy sets
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetsList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    post:
      operationId: createPolicySet
      summary: Create a new policy set
      description: >
        Creates a policy set. Supply `manifest` to create its first

        version and any new policies in the same transaction. A failure rolls

        back every write. Without `manifest`, creates a versionless set and

        preserves the existing response body.


        Entries use manifest apply semantics with no predecessor: bare pins

        use each policy's latest version; supplied content reuses that version

        when its SHA and schema match. Omitted `schema_version` uses the zone

        default. This operation supports neither `dry_run` nor `If-Match`.

        Set `manifest.activate: true` to bind v1 to the zone's active slot in

        the same transaction. Requires `target_type: zone` (the default) and

        the `activate` permission on `policy_set_bindings`, in addition to

        the route's `create` permission. Omitted or false leaves the set unbound.


        The `ETag` header is the set revision, as on `GET`. The manifest digest

        is `policy_set_version.manifest_sha` and the `ETag` of `GET .../manifest`.


        Domain error codes: `policy_set_name_conflict`, `policy_name_conflict`,

        `policy_not_found`, `policy_archived`, `policy_version_not_found`,

        `version_archived`, `schema_version_mismatch`,

        `manifest_duplicate_policy`, `missing_cedar_content`, `invalid_cedar`,

        `schema_version_unsupported`, `activate_requires_zone_target`.

      tags:
        - PolicySets
      x-authz:
        action: create
        resourceType: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_CreatePolicySetRequest'
      responses:
        '201':
          description: The newly created policy set
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetWithBinding'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: >-
            A policy or policy set name conflicts, or a referenced policy is archived
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}:
    servers: []
    get:
      operationId: getPolicySet
      summary: Get a policy set by ID
      description: Returns the policy set with current binding information.
      tags:
        - PolicySets
      x-authz:
        action: read
        resource:
          param: policy_set_id
          type: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_ExpandSingle'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The requested policy set with binding info
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetWithBinding'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updatePolicySet
      summary: Update a policy set
      description: >-
        Update policy set metadata (name). Binding is managed by activating a policy set version or via the policy-bindings API.
      tags:
        - PolicySets
      x-authz:
        action: update
        resource:
          param: policy_set_id
          type: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_If-Match'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_UpdatePolicySetRequest'
      responses:
        '200':
          description: The updated policy set
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetWithBinding'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: Conflict - concurrency conflict or name collision
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '412':
          description: >-
            Precondition Failed - resource has been modified since the provided ETag
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: archivePolicySet
      summary: Archive a policy set
      tags:
        - PolicySets
      x-authz:
        action: delete
        resource:
          param: policy_set_id
          type: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_If-Match'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The archived policy set
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetWithBinding'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: >-
            Conflict - policy set is currently bound. Bind a replacement policy set to the slot (or delete the shadow binding), then archive.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '412':
          description: >-
            Precondition Failed - resource has been modified since the provided ETag
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}/versions:
    servers: []
    get:
      operationId: listPolicySetVersions
      summary: List versions of a policy set
      tags:
        - PolicySetVersions
      x-authz:
        action: list
        resourceType: policy_set_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_Expand'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - $ref: '#/components/parameters/pdp_Sort'
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of policy set versions
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetVersionsList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    post:
      operationId: createPolicySetVersion
      summary: Create a new immutable policy set version
      description: >-
        Validates the manifest, computes SHA, and creates an immutable version snapshot.
      tags:
        - PolicySetVersions
      x-authz:
        action: create
        resourceType: policy_set_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_CreatePolicySetVersionRequest'
      responses:
        '201':
          description: The newly created policy set version
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetVersion'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}/versions/{version_id}:
    servers: []
    get:
      operationId: getPolicySetVersion
      summary: Get a specific policy set version
      tags:
        - PolicySetVersions
      x-authz:
        action: read
        resource:
          param: version_id
          type: policy_set_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_VersionId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_ExpandSingle'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The requested policy set version
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetVersion'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updatePolicySetVersion
      summary: Activate a policy set version
      description: Set active=true to bind this version as the active zone policy set.
      tags:
        - PolicySetVersions
      x-authz:
        action: update
        resource:
          param: version_id
          type: policy_set_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_VersionId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_UpdatePolicySetVersionRequest'
      responses:
        '200':
          description: The policy set version, now active
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetVersion'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: archivePolicySetVersion
      summary: Archive a policy set version
      tags:
        - PolicySetVersions
      x-authz:
        action: delete
        resource:
          param: version_id
          type: policy_set_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_VersionId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The archived policy set version
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetVersion'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}/versions/{version_id}/policies:
    servers: []
    get:
      operationId: listPolicySetVersionPolicies
      summary: List policy versions in a policy set version
      description: >-
        Returns the policy versions referenced by this policy set version's manifest as a paginated list.
      tags:
        - PolicySetVersions
      x-authz:
        action: list
        resourceType: policy_set_versions
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_VersionId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_Expand'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - $ref: '#/components/parameters/pdp_Sort'
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_PolicyFormat'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of policy versions in this policy set version
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetVersionPoliciesList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}/draft:
    servers: []
    post:
      operationId: createPolicySetDraft
      summary: Create or resume a policy set draft
      description: >-
        Safe draft creation that never overwrites an existing draft. If a draft already exists for this policy set, it is returned as-is (200 OK). Three body modes control how a new draft is initialized: (1) empty body — hydrate from the latest non-archived version, (2) { base_version_id } — hydrate from a specific version, (3) full body with manifest and schema_version — create with explicit content. base_version_id and manifest are mutually exclusive; providing both is rejected.
      tags:
        - PolicySetDrafts
      x-authz:
        action: create
        resource:
          param: policy_set_id
          type: policy_set_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_CreatePolicySetDraftRequest'
      responses:
        '200':
          description: Existing draft resumed (unchanged)
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetDraft'
        '201':
          description: New draft created
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetDraft'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: getPolicySetDraft
      summary: Get the draft for a policy set
      tags:
        - PolicySetDrafts
      x-authz:
        action: read
        resource:
          param: policy_set_id
          type: policy_set_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_ExpandSingle'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The policy set draft
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetDraft'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    put:
      operationId: upsertPolicySetDraft
      summary: Create or replace a policy set draft
      description: >-
        Full replacement of the draft state. Creates the draft if it does not exist, replaces it if it does. Standard REST PUT idempotency — the caller provides the complete desired state.
      tags:
        - PolicySetDrafts
      x-authz:
        action: create
        resource:
          param: policy_set_id
          type: policy_set_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_UpsertPolicySetDraftRequest'
      responses:
        '200':
          description: The upserted policy set draft
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetDraft'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: Conflict - concurrency conflict
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: patchPolicySetDraft
      summary: Partially update a policy set draft
      description: >-
        Applies partial updates to an existing draft. Supports updating metadata fields (name, description, schema_version) and manifest operations (set, add, remove entries).
      tags:
        - PolicySetDrafts
      x-authz:
        action: update
        resource:
          param: policy_set_id
          type: policy_set_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_PatchPolicySetDraftRequest'
      responses:
        '200':
          description: The updated policy set draft
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetDraft'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: Conflict - concurrency conflict
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: deletePolicySetDraft
      summary: Delete a policy set draft
      tags:
        - PolicySetDrafts
      x-authz:
        action: delete
        resource:
          param: policy_set_id
          type: policy_set_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '204':
          description: Draft successfully deleted
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}/draft/policies:
    servers: []
    get:
      operationId: listPolicySetDraftPolicies
      summary: List policies in a policy set draft
      description: >-
        Returns the policy versions referenced by the draft's manifest as a paginated list. Mirrors the published `/policy-sets/{policy_set_id}/versions/{version_id}/policies` endpoint but sources entries from the policy set's mutable draft. Archived policy versions referenced by the manifest are still returned.
      tags:
        - PolicySetDrafts
      x-authz:
        action: read
        resource:
          param: policy_set_id
          type: policy_set_drafts
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - $ref: '#/components/parameters/pdp_Sort'
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_PolicyFormat'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of policy versions pinned by this draft's manifest
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetVersionPoliciesList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}/clones:
    servers: []
    post:
      operationId: clonePolicySet
      summary: Clone a policy set into a new customer-owned set
      description: |
        Creates a new customer-owned policy set whose first version reproduces
        the manifest of a source version: the source's latest non-archived
        version by default, or the one named by `source_version_id`. The set,
        any copied policies and their versions, the first policy set version,
        and its attestation are written in one transaction. Any failure leaves
        zero writes. The source is never modified.

        Platform-owned sets (for example the zone default
        `default-zone-policies`) cannot be updated or versioned by customers.
        Clone is how a customer forks one into a set they can edit with
        `PUT .../manifest`.

        `copy_policies` decides what is shared and what is duplicated
        (default `platform`):

        - `none`: every entry pins the same policy version as the source. No
          new policies are created.
        - `platform`: platform-owned pins are copied into new customer-owned
          policies; customer-owned pins are shared. The result is fully
          editable with minimal duplication.
        - `all`: every pin is copied.

        Copied policies get `owner_type: customer`, the source policy's
        description, and a first version whose `cedar_json`, `schema_version`
        and `sha` are copied verbatim from the pinned source version. There is
        no Cedar revalidation and no rewrite of the embedded static-policy
        keys; the evaluator namespaces them by policy version ID.

        A copied policy is named after its source, with the platform catalog
        prefix `default-` stripped for platform-owned sources
        (`default-user-grants` becomes `user-grants`). Customer-owned names
        are kept as-is. A derived name that collides with a non-archived
        policy in the zone gets the first free numeric suffix (`user-grants-2`,
        `user-grants-3`, ...). Names are resolved inside the transaction; a
        concurrent race still surfaces as `409 policy_name_conflict`.

        Manifest order is the source's, with shared and copied pins
        interleaved as they were. `schema_version` is the source version's.
        `target_type` defaults to the source set's and may be overridden.

        The `ETag` header is the digest of the first version's manifest, so
        clone, then conditional `PUT .../manifest`, needs no intermediate GET.

        Domain error codes: `policy_set_not_found`,
        `policy_set_version_not_found`, `policy_set_name_conflict`,
        `policy_name_conflict`, `set_archived`, `version_archived`,
        `schema_version_unsupported`.
      tags:
        - PolicySets
      x-authz:
        action: create
        resourceType: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_ClonePolicySetRequest'
      responses:
        '201':
          description: The new policy set, its first version, and the per-policy outcome
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              description: |
                Digest of the new set's first (and latest) manifest. Usable as
                `If-Match` on a follow-up `PUT .../manifest` without a re-GET.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_ClonePolicySetResult'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          description: |
            Source set not found (`policy_set_not_found`), or
            `source_version_id` names a version that does not exist on it
            (`policy_set_version_not_found`).
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '409':
          description: |
            `policy_set_name_conflict` (`name` already exists in the zone),
            `policy_name_conflict` (a derived policy name lost a race),
            `set_archived`, `version_archived` (the source version is
            archived, or it pins an archived policy version), or
            `schema_version_unsupported` (the source version's schema is
            archived; clone a newer source version).
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-sets/{policy_set_id}/manifest:
    servers: []
    get:
      operationId: getPolicySetManifest
      summary: Get the manifest of a policy set version
      description: |
        Returns the resolved manifest of the **latest non-archived version** by
        default. Pass `?version=` with a policy set version public ID to read a
        specific version's manifest (e.g. for rollback: GET an old manifest,
        PUT it back — which mints a new version at the tip with the old
        content; history is never re-pointed).

        There is deliberately no `?version=active` keyword: a binding slot is
        `(zone, target_type, target_id, mode)` and a set may have zero or
        several active bindings, so "the active version" is not a function of
        the set alone. Resolve the version ID first — from the enriched policy
        set representation (`active_version_id`) or `GET /policy-bindings` —
        then pass it here.

        The default (latest) read anchors the apply flow: the `ETag` response
        header is the JCS SHA-256 digest of the latest manifest and is the
        value to send as `If-Match` on `PUT`. **`ETag` is emitted only on the
        default latest read** — versioned reads return `manifest_sha` in the
        body but no `ETag`, so a stale token cannot be round-tripped as a
        precondition.

        A policy set with no versions yet returns `200` with empty `entries`,
        null `policy_set_version_id`/`version`/`schema_version`/`manifest_sha`,
        and the digest of the empty manifest as `ETag`, so even the first
        apply can be conditional.
      tags:
        - PolicySetManifest
      x-authz:
        action: read
        resource:
          param: policy_set_id
          type: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
        - name: version
          in: query
          required: false
          schema:
            type: string
          description: 'Policy set version public ID. Default: latest non-archived version.'
      responses:
        '200':
          description: The resolved manifest
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetManifestDetail'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          description: >-
            Policy set not found (`policy_set_not_found`), or `?version=` names a version that does not exist (`policy_set_version_not_found`).
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    put:
      operationId: applyPolicySetManifest
      summary: Apply the full desired state of a policy set
      description: >
        Declarative full-replace apply. `entries` is the complete desired

        content of the policy set: **any policy omitted from `entries` is

        dropped from the resulting version** (its rows are retained and a later

        apply may reference it again). Entry order is preserved for newly added

        policies; retained policies keep their current manifest order, so an

        unchanged apply is byte-identical and dedups to the existing version.


        Per entry, the server diffs by content SHA against the version pinned

        in the latest manifest: unchanged content under the same schema version

        reuses the pinned policy version; changed content mints a new policy

        version; `new_policy` entries mint a customer-owned policy with the

        requested name. All of this, plus the policy set version mint and the

        optional activation, happens in **one transaction** (row lock on the

        policy set). Cedar validation runs against the resolved schema before

        the transaction opens — an invalid policy rejects the whole apply with

        zero writes.


        **Schema resolution:** `schema_version` omitted → the latest version's

        schema if still writable, else the zone default. Provided →

        authoritative (`schema_version_unsupported` if unknown, unattested, or

        archived). All entries validate against the single resolved version

        (uniform-schema-per-version is retained); a pinned policy version

        created under a different schema is re-versioned even if its content is

        unchanged.


        **Activation:** `activate: true` requires a zone-targeted set and rebinds the

        `(zone, target_type=zone, mode=active)` slot to the resulting version

        in the same transaction. It requires `policy_set_bindings:activate`

        permission and preserves the previous binding in binding history.

        Unchanged content returns `created: false` and still activates the

        resulting version. An already active version keeps its binding unchanged.


        **Concurrency:** `If-Match` is optional (omitted = last-writer-wins).

        When provided it is compared, under the row lock, against the digest of

        the latest version's manifest; mismatch returns `412` (`etag_mismatch`)

        carrying the current `ETag`. The token is content-addressed, not a

        version identity: it guards "the content I read is still the content in

        place", so two versions with identical manifests are interchangeable for

        the precondition, and archiving the tip does not invalidate a token whose

        digest the new latest version still carries. Do not re-key it on

        `policy_set_version_id`.


        **Identity and reverts:** a desired state identical to the **latest**

        version is a no-op (`created: false`, latest returned, nothing minted).

        A desired state matching an **older** version mints a new version at

        the tip — history is linear, never forked. Rolling back deployment

        without a content edit is not an apply at all: bind the older version

        via `PUT /policy-bindings`.


        **Authorization:** the route gate is `update` on the policy set. When

        `activate: true`, the handler additionally requires the `activate`

        action on `policy_set_bindings`.


        Domain error codes: `policy_set_not_found`, `policy_not_found`,

        `policy_version_not_found`, `version_archived`,

        `schema_version_mismatch`, `manifest_duplicate_policy`,

        `missing_cedar_content`, `invalid_cedar`, `schema_version_unsupported`,

        `policy_name_conflict`, `policy_archived`, `set_archived`,

        `etag_mismatch`, `activate_requires_zone_target`, `shadow_equals_active`.

      tags:
        - PolicySetManifest
      x-authz:
        action: update
        resource:
          param: policy_set_id
          type: policy_sets
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_PolicySetId'
        - $ref: '#/components/parameters/pdp_If-Match'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
        - name: dry_run
          in: query
          required: false
          schema:
            type: boolean
            default: false
          description: >-
            Not yet implemented — `true` returns 501 until ACC-1002. When true, performs validation, schema resolution, and the content diff, and returns the would-be `changes` and `warnings` — but persists nothing. `policy_set_version` is omitted from the response and no ETag is returned.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_ApplyPolicySetManifestRequest'
      responses:
        '200':
          description: >-
            The apply result. Always `200` — the resulting version may be newly minted (`created: true`), deduped to an existing version, or a pure no-op (`created: false`); the body discriminates so clients never branch on status.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              description: >-
                Digest of the resulting (now latest) manifest — usable as If-Match for a follow-up apply without a re-GET. Omitted on dry_run.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_ApplyPolicySetManifestResult'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          description: >-
            Caller lacks the route permission, or `activate: true` and the caller lacks the `activate` permission on policy set bindings — the error names the missing permission.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '409':
          description: >-
            Conflict: `policy_name_conflict` (a `new_policy` name already exists in the zone), `policy_archived`, `set_archived`.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '412':
          description: >-
            Precondition failed (`etag_mismatch`): the latest manifest no longer matches `If-Match`. The current `ETag` is returned so the client can re-read, merge, and retry.
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
            ETag:
              $ref: '#/components/headers/pdp_ETag'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-evaluations:
    servers: []
    post:
      operationId: createPolicyEvaluation
      summary: Test Cedar policy evaluation against real entities
      description: >
        Stateless evaluation endpoint for testing Cedar policy evaluation against real entities before deployment. Supports evaluating a single policy, a full policy set, or raw Cedar text.

      tags:
        - PolicyEvaluations
      x-authz:
        action: evaluate
        resourceType: policy_evaluations
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_PolicyEvaluationRequest'
      responses:
        '200':
          description: The evaluation result
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicyEvaluationResponse'
        '400':
          description: >
            Bad Request - invalid input or validation error. Common causes: - Schema validation error (action/principal/resource doesn't exist in schema) - Entity not found (invalid principal_id, subject_id, or resource_id) - Policy source error (policy/policy set/version not found, draft doesn't exist) - Unsupported schema version - Invalid Cedar policy syntax (when using 'raw' source with validate=true)

          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_Error'
              examples:
                schema_validation_error:
                  summary: Action doesn't exist in schema
                  value:
                    status: 400
                    code: validation_error
                    message: policy evaluation validation error
                    request_id: 8fdccf3e-655c-918c-be90-5caf8efde53d
                    timestamp: '2026-03-31T10:02:00Z'
                    path: /zones/4yscgiw2iynj3hfeenuxa3q6gp/policy-evaluations
                    details:
                      - field: policy_source
                        message: >-
                          check 0: action `Keycard::Action::"invalid_action"` does not exist in the supplied schema
                        code: validation_error
                entity_not_found:
                  summary: Principal not found
                  value:
                    status: 400
                    code: bad_request
                    message: 'user not found: invalid_user_id'
                    request_id: 8fdccf3e-655c-918c-be90-5caf8efde53d
                    timestamp: '2026-03-31T10:02:00Z'
                    path: /zones/4yscgiw2iynj3hfeenuxa3q6gp/policy-evaluations
                    details:
                      - field: principal_id
                        message: 'user not found: invalid_user_id'
                        code: bad_request
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-evaluations/requests:
    servers: []
    get:
      operationId: listEvaluationRequests
      summary: List captured evaluation requests
      description: >
        Returns a paginated list of evaluation request entries captured from live credentials API traffic for the specified zone. Sorted by created_at descending (newest first). Use with the test evaluation endpoint for replay-based impact analysis.

      tags:
        - PolicyEvaluations
      x-authz:
        action: list
        resourceType: policy_evaluations
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_After'
        - $ref: '#/components/parameters/pdp_Before'
        - $ref: '#/components/parameters/pdp_Limit'
        - $ref: '#/components/parameters/pdp_ExpandNew'
        - $ref: '#/components/parameters/pdp_Sort'
        - $ref: '#/components/parameters/pdp_Order'
        - $ref: '#/components/parameters/pdp_QueryAction'
        - $ref: '#/components/parameters/pdp_FilterActiveDecision'
        - $ref: '#/components/parameters/pdp_FilterPrincipalType'
        - $ref: '#/components/parameters/pdp_FilterSubjectType'
        - $ref: '#/components/parameters/pdp_FilterAuthorityType'
        - $ref: '#/components/parameters/pdp_FilterHasShadow'
        - $ref: '#/components/parameters/pdp_FilterPrincipalId'
        - $ref: '#/components/parameters/pdp_FilterResourceId'
        - $ref: '#/components/parameters/pdp_FilterSubjectId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: A paginated list of evaluation requests
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_EvaluationRequestsList'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        '503':
          $ref: '#/components/responses/pdp_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-bindings:
    servers: []
    put:
      operationId: setPolicyBinding
      summary: Create or replace a policy set binding
      description: >
        Upserts a binding for a slot identified by (scope_type, scope_target_id, mode).

        If a binding already exists for the slot, it is replaced. The binding ID

        is stable per slot and survives replacements.

      tags:
        - PolicyBindings
      x-authz:
        action: create
        resourceType: policy_set_bindings
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/pdp_SetPolicySetBindingRequest'
      responses:
        '200':
          description: The binding was created or replaced
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetBinding'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: listPolicyBindings
      summary: List policy set bindings for a zone
      description: |
        Returns bindings for the zone, filtered by target and mode.

        `filter[target_type]` defaults to `zone` and `filter[mode]`
        defaults to `shadow` when omitted (preserving the endpoint's
        historical shadow-only listing); pass explicit values to widen.
        The deprecated bare `scope_type` and `mode` parameters are honored
        as equivalents and suppress the respective defaults; supplying a
        bare parameter and its `filter[...]` form with different values
        returns 400. With an effective target type set of exactly `zone`,
        `filter[target_id]` values other than the zone ID return 400.
      tags:
        - PolicyBindings
      x-authz:
        action: list
        resourceType: policy_set_bindings
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
        - name: scope_type
          in: query
          required: false
          deprecated: true
          schema:
            type: string
            enum:
              - zone
          description: |
            **Deprecated.** Use `filter[target_type]` instead. Still honored
            for backward compatibility but only accepts `zone`; other values
            return 400. Conflicts with `filter[target_type]` return 400.
        - name: mode
          in: query
          required: false
          deprecated: true
          schema:
            type: string
            enum:
              - shadow
          description: |
            **Deprecated.** Use `filter[mode]` instead. Still honored for
            backward compatibility but only accepts `shadow`; other values
            return 400. Conflicts with `filter[mode]` return 400.
        - $ref: '#/components/parameters/pdp_FilterTargetType'
        - $ref: '#/components/parameters/pdp_FilterTargetID'
        - $ref: '#/components/parameters/pdp_FilterMode'
      responses:
        '200':
          description: List of bindings
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                type: object
                required:
                  - items
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/pdp_PolicySetBinding'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-bindings/{binding_id}:
    servers: []
    get:
      operationId: getPolicyBinding
      summary: Get a policy set binding by ID
      description: Returns a specific binding by its stable identifier.
      tags:
        - PolicyBindings
      x-authz:
        action: read
        resource:
          param: binding_id
          type: policy_set_bindings
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_BindingId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '200':
          description: The binding
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetBinding'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
    delete:
      operationId: deletePolicyBinding
      summary: Delete a policy set binding
      description: Removes a binding by its identifier, stopping evaluation for that slot.
      tags:
        - PolicyBindings
      x-authz:
        action: delete
        resource:
          param: binding_id
          type: policy_set_bindings
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_BindingId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
      responses:
        '204':
          description: Binding deleted
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/policy-bindings/{binding_id}/metrics:
    servers: []
    get:
      operationId: getPolicyBindingMetrics
      summary: Get shadow evaluation metrics for a binding
      description: >
        Returns shadow evaluation metrics for a specific binding. Use query parameters to change scope:

        - `scope=zone` — zone-level aggregate across all pairings

        - `psv_id=<id>` — metrics for a specific policy set version (in any role),

          including per-pairing breakdown
      tags:
        - PolicyBindings
      x-authz:
        action: read
        resource:
          param: binding_id
          type: policy_set_bindings
        scope:
          zone:
            param: zone_id
      parameters:
        - $ref: '#/components/parameters/pdp_ZoneId'
        - $ref: '#/components/parameters/pdp_BindingId'
        - $ref: '#/components/parameters/pdp_X-API-Version'
        - $ref: '#/components/parameters/pdp_X-Client-Request-ID'
        - name: scope
          in: query
          required: false
          schema:
            type: string
            enum:
              - binding
              - zone
            default: binding
          description: |
            Metrics scope. `binding` (default) returns metrics for this binding.
            `zone` returns zone-level aggregate across all pairings.
        - name: policy_set_id
          in: query
          required: false
          schema:
            type: string
          description: Policy set to filter metrics for. Required when psv_id is provided.
        - name: psv_id
          in: query
          required: false
          schema:
            type: string
          description: >-
            Filter to a specific policy set version (in any role). When provided, response includes per-pairing breakdown. Requires policy_set_id.
        - name: since
          in: query
          required: false
          schema:
            type: string
            format: date-time
          description: Start of the time window (default 24h ago)
      responses:
        '200':
          description: Shadow evaluation metrics
          headers:
            X-Request-ID:
              $ref: '#/components/headers/pdp_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/pdp_PolicySetShadowMetricsSummary'
        '400':
          $ref: '#/components/responses/pdp_BadRequestError'
        '401':
          $ref: '#/components/responses/pdp_UnauthorizedError'
        '403':
          $ref: '#/components/responses/pdp_ForbiddenError'
        '404':
          $ref: '#/components/responses/pdp_NotFoundError'
        '429':
          $ref: '#/components/responses/pdp_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/pdp_InternalServerError'
        default:
          $ref: '#/components/responses/pdp_InternalServerError'
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/secrets:
    servers: []
    post:
      operationId: createZoneSecret
      x-authz:
        action: create
        resourceType: secrets
        scope:
          zone:
            param: zone_id
      parameters:
        - in: path
          name: zone_id
          required: true
          schema:
            $ref: '#/components/schemas/vault-api_ID'
        - $ref: '#/components/parameters/vault-api_X-Client-Request-ID'
      requestBody:
        description: A JSON object containing the secret's value that should be stored.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/vault-api_CreateZoneSecretRequest'
      responses:
        '201':
          description: Secret created successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/vault-api_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/vault-api_Secret'
        '400':
          $ref: '#/components/responses/vault-api_BadRequestError'
        '401':
          $ref: '#/components/responses/vault-api_UnauthorizedError'
        '403':
          $ref: '#/components/responses/vault-api_ForbiddenError'
        '429':
          $ref: '#/components/responses/vault-api_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/vault-api_InternalServerError'
        '503':
          $ref: '#/components/responses/vault-api_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/vault-api_InternalServerError'
      tags:
        - Secrets
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: listZoneSecrets
      x-authz:
        action: list
        resourceType: secrets
        scope:
          zone:
            param: zone_id
      parameters:
        - in: path
          name: zone_id
          required: true
          schema:
            $ref: '#/components/schemas/vault-api_ID'
        - in: query
          name: entity_id
          description: The entity to list all secrets for
          schema:
            type: string
        - in: query
          name: type
          description: The type of secrets to list. Required when owner_type is specified.
          schema:
            type: string
            enum:
              - token
              - password
        - in: query
          name: owner_type
          description: >
            Filter by secret ownership. Services can select either owner type;

            other principals can select only customer-owned secrets. If omitted,

            services see both owner types and other principals see customer-owned secrets.

            Requires type=token or type=password when specified.

          schema:
            $ref: '#/components/schemas/vault-api_SecretOwnerType'
        - $ref: '#/components/parameters/vault-api_X-Client-Request-ID'
      responses:
        '200':
          description: List available secrets without their decrypted values
          headers:
            X-Request-ID:
              $ref: '#/components/headers/vault-api_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/vault-api_SecretsList'
        '400':
          $ref: '#/components/responses/vault-api_BadRequestError'
        '401':
          $ref: '#/components/responses/vault-api_UnauthorizedError'
        '403':
          $ref: '#/components/responses/vault-api_ForbiddenError'
        '404':
          $ref: '#/components/responses/vault-api_NotFoundError'
        '429':
          $ref: '#/components/responses/vault-api_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/vault-api_InternalServerError'
        '503':
          $ref: '#/components/responses/vault-api_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/vault-api_InternalServerError'
      tags:
        - Secrets
      security:
        - bearerAuth: []
        - OAuth2: []
  /zones/{zone_id}/secrets/{id}:
    servers: []
    delete:
      operationId: deleteZoneSecret
      x-authz:
        action: delete
        resource:
          param: id
          type: secrets
        scope:
          zone:
            param: zone_id
      parameters:
        - in: path
          name: zone_id
          required: true
          schema:
            $ref: '#/components/schemas/vault-api_ID'
        - in: path
          name: id
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/vault-api_X-Client-Request-ID'
      responses:
        '204':
          description: Secret deleted successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/vault-api_X-Request-ID'
        '400':
          $ref: '#/components/responses/vault-api_BadRequestError'
        '401':
          $ref: '#/components/responses/vault-api_UnauthorizedError'
        '403':
          $ref: '#/components/responses/vault-api_ForbiddenError'
        '429':
          $ref: '#/components/responses/vault-api_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/vault-api_InternalServerError'
        '503':
          $ref: '#/components/responses/vault-api_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/vault-api_InternalServerError'
      tags:
        - Secrets
      security:
        - bearerAuth: []
        - OAuth2: []
    patch:
      operationId: updateZoneSecret
      x-authz:
        action: update
        resource:
          param: id
          type: secrets
        scope:
          zone:
            param: zone_id
      parameters:
        - in: path
          name: zone_id
          required: true
          schema:
            $ref: '#/components/schemas/vault-api_ID'
        - in: path
          name: id
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/vault-api_X-Client-Request-ID'
      requestBody:
        description: A JSON object containing the secret's value that should be stored.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/vault-api_UpdateSecretRequest'
      responses:
        '200':
          description: Secret updated successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/vault-api_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/vault-api_Secret'
        '400':
          $ref: '#/components/responses/vault-api_BadRequestError'
        '401':
          $ref: '#/components/responses/vault-api_UnauthorizedError'
        '403':
          $ref: '#/components/responses/vault-api_ForbiddenError'
        '429':
          $ref: '#/components/responses/vault-api_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/vault-api_InternalServerError'
        '503':
          $ref: '#/components/responses/vault-api_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/vault-api_InternalServerError'
      tags:
        - Secrets
      security:
        - bearerAuth: []
        - OAuth2: []
    get:
      operationId: getZoneSecretValue
      x-authz:
        action: read
        resource:
          param: id
          type: secrets
        scope:
          zone:
            param: zone_id
      parameters:
        - in: path
          name: zone_id
          required: true
          schema:
            $ref: '#/components/schemas/vault-api_ID'
        - in: path
          name: id
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/vault-api_X-Client-Request-ID'
      responses:
        '200':
          description: Secret value retrieved successfully
          headers:
            X-Request-ID:
              $ref: '#/components/headers/vault-api_X-Request-ID'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/vault-api_SecretValue'
        '400':
          $ref: '#/components/responses/vault-api_BadRequestError'
        '401':
          $ref: '#/components/responses/vault-api_UnauthorizedError'
        '403':
          $ref: '#/components/responses/vault-api_ForbiddenError'
        '404':
          $ref: '#/components/responses/vault-api_NotFoundError'
        '429':
          $ref: '#/components/responses/vault-api_RateLimitExceededError'
        '500':
          $ref: '#/components/responses/vault-api_InternalServerError'
        '503':
          $ref: '#/components/responses/vault-api_ServiceUnavailableError'
        default:
          $ref: '#/components/responses/vault-api_InternalServerError'
      tags:
        - Secrets
      security:
        - bearerAuth: []
        - OAuth2: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT Bearer Token Authentication
    OAuth2:
      type: oauth2
      description: OAuth2 Client Credentials Authentication
      flows:
        clientCredentials:
          tokenUrl: /service-account-token
          scopes: {}
  schemas:
    common_Error:
      type: object
      description: Represents an error that has occurred in the Keycard system.
      properties:
        status:
          type: integer
          description: HTTP Status Code
        code:
          $ref: '#/components/schemas/common_ErrorCode'
        message:
          type: string
          description: summary of the error
        request_id:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
        path:
          type: string
          format: url
        details:
          type: array
          items:
            $ref: '#/components/schemas/common_ErrorDetail'
      additionalProperties: false
      required:
        - status
        - code
        - message
        - request_id
        - timestamp
        - path
        - details
      x-go-type: httperrors.Error
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    common_ErrorDetail:
      type: object
      properties:
        field:
          type: string
          description: >-
            valid json path for request body. Omitted when the detail is not tied to a request field (e.g. domain error codes); clients should treat absent and empty the same.
        message:
          type: string
          description: error message for specific error
        code:
          anyOf:
            - $ref: '#/components/schemas/common_ErrorCode'
            - type: string
          description: >-
            Machine-readable code. Either a common `ErrorCode` value or a service-specific domain code (snake_case) documented by the service's own API spec. Clients should match on this instead of parsing `message`. Open set; unknown codes must be tolerated.
          example: version_currently_bound
      required:
        - message
        - code
      additionalProperties: false
      x-go-type: httperrors.ErrorDetail
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    common_ErrorCode:
      type: string
      enum:
        - validation_error
        - bad_request
        - unauthorized
        - forbidden
        - not_found
        - conflict
        - rate_limit_exceeded
        - internal_error
        - not_implemented
        - service_unavailable
      x-enum-varnames:
        - ValidationErrorCode
        - BadRequestErrorCode
        - UnauthorizedErrorCode
        - ForbiddenErrorCode
        - NotFoundErrorCode
        - ConflictErrorCode
        - RateLimitExceededErrorCode
        - InternalErrorCode
        - NotImplementedErrorCode
        - ServiceUnavailableErrorCode
      x-go-type: httperrors.ErrorCode
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    common_ID:
      type: string
      description: A globally unique opaque identifier
      minLength: 1
      x-go-type: types.ID
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_IdentityRef:
      type: object
      description: >-
        A reference to another entity including its ID and a href to fetch this entity.
      properties:
        id:
          $ref: '#/components/schemas/common_ID'
        href:
          type: string
          format: url
      required:
        - id
        - href
      additionalProperties: false
      x-go-type: types.IdentityRef
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Identifier:
      type: string
      description: >-
        An identifier representing either an opaque ID or address (labels separated by periods, e.g.: aws.s3)
      minLength: 1
      x-go-type: types.IdentifierString
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Name:
      type: string
      description: A name for the entity to be displayed in UI
      pattern: ^[a-zA-Z][a-zA-Z0-9\s,\.'\-pL\ \-_]{1,63}$
      x-go-type: types.Name
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Label:
      type: string
      description: A domain name segment for the entity, often derived from the name.
      pattern: ^([a-z0-9]+(-[a-z0-9]+)+)$
      maxLength: 63
      x-go-type: types.Label
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Address:
      type: string
      description: >-
        A domain address for the entity, derived from labels of parent entities (e.g. aws.s3)
      pattern: ^[a-z][a-z0-9\-]{2,64}(\.[a-z][a-z0-9\-]{2,64}){0,9}$
      x-go-type: types.Address
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Description:
      type: string
      description: A description of the entity
      maxLength: 128
      x-go-type: types.Description
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Tags:
      type: array
      description: An array of meta data to make searching for entities easier.
      items:
        type: string
        pattern: ^[a-z][a-z0-9\-\_\ \.]{1,63}$
        description: A tag
      maxItems: 10
      x-go-type: types.Tags
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Visibility:
      type: string
      description: >-
        The visibility of the entity and whether its publicly available, privately available to those who own it, or if its hidden entirely as a system resource.
      enum:
        - public
        - private
        - hidden
      x-go-type: types.Visibility
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_CreatedAt:
      type: string
      description: The time the entity was created in utc
      format: date-time
    common_UpdatedAt:
      type: string
      description: The time the entity was mostly recently updated in utc
      format: date-time
    common_IdentityType:
      type: string
      enum:
        - user
        - service_account
      x-go-type: types.IdentityType
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Domain:
      type: string
      format: hostname
      x-go-type: types.Domain
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Permission:
      type: string
      pattern: ^[a-zA-Z0-9_.:/+-]{3,128}$
      description: A valid permission or scope made available on a ResourceType
      x-go-type: types.Permission
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_RestrictedSchema:
      type: object
      description: RestrictedSchema for specify the schema of a dynamic type or field
      externalDocs:
        description: JSON Metaschema for RestrictedSchema
        url: https://catalog.keycard.sh/schemas/restricted-schema-01.json
      additionalProperties: true
      x-go-type: types.RestrictedSchema
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_URITemplate:
      type: string
      description: An RFC6570 Level-4 Compatible URI Template
      maxLength: 256
      externalDocs:
        description: RFC6570 Specification
        url: https://datatracker.ietf.org/doc/html/rfc6570#section-2
      example: '{scheme}://{user}:{password}@{hostname}:{port}/{/dbname}'
      x-go-type: types.URITemplate
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_StringTemplate:
      type: string
      description: >-
        A simple string template that only supports simple variable replacement (e.g. \"hey {world}\").
      example: hello {name}, how are you?
      maxLength: 256
      x-go-type: types.StringTemplate
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_VariableName:
      type: string
      pattern: ^[a-z][a-z0-9_]{0,31}$
      description: A string representing a variable name in a StringTemplate or URITemplate
      example: user_id
      x-go-type: types.VariableName
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_URL:
      type: string
      format: url
      description: RFC3986 compliant URL
      x-go-type: types.URL
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_PaginationCursor:
      type: string
      description: An opaque cursor used for paginating through a list of results
      minLength: 1
      maxLength: 255
      x-go-type: types.PaginationCursor
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_Pagination:
      type: object
      description: Cursor-based pagination metadata returned alongside a list of results
      properties:
        before_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/common_PaginationCursor'
        after_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/common_PaginationCursor'
        total_count:
          type: integer
          description: >-
            Total number of items across all pages. Only present when the request includes ?expand[]=total_count.
      required:
        - before_cursor
        - after_cursor
      additionalProperties: false
      x-go-type: types.Pagination
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    common_FilterValues:
      type: array
      description: |
        Value shape for `filter[<field>]` query parameters.

        Wire conventions:
          - Repeated parameter instances are OR-ed across values.
          - A single value containing comma-separated tokens is AND-ed across tokens.

        Examples:
          ?filter[status]=a&filter[status]=b       -> status in (a, b)
          ?filter[tag]=foo,bar                     -> tag contains foo AND bar
          ?filter[tag]=foo,bar&filter[tag]=baz     -> (foo AND bar) OR baz

        Field names and allowed values are endpoint-specific; services declare
        each filter[<field>] parameter per operation with an appropriate
        items.type/items.enum override.
      items:
        type: string
    common_QueryTerms:
      type: array
      description: |
        Value shape for `query[]` and `query[<field>]` search parameters.

        Wire conventions:
          - Case-insensitive substring match (ILIKE).
          - Repeated parameter instances are OR-ed across terms.
          - Comma splitting is NOT performed; literal commas in a search term
            are preserved as part of the term.

        Examples:
          ?query[name]=alpha&query[name]=beta      -> name ILIKE %alpha% OR name ILIKE %beta%
          ?query[]=alpha                           -> any searchable field ILIKE %alpha%

        Cross-field form is `query[]`; field-scoped form is `query[<field>]`.
        Field names are endpoint-specific; services declare each query parameter
        per operation.
      items:
        type: string
        minLength: 1
        maxLength: 255
    pdp-credentials_PdpError:
      type: object
      required:
        - error
        - error_description
      properties:
        error:
          type: string
          description: PDP error code
          enum:
            - invalid_request
            - invalid_token
            - entity_not_found
            - no_active_binding
            - evaluation_error
            - internal_error
        error_description:
          type: string
          description: Human-readable error description
        request_id:
          type: string
        entity_type:
          type: string
          description: Present when error is entity_not_found
        entity_id:
          type: string
          description: Present when error is entity_not_found
    pdp_EvaluationContext:
      type: object
      description: |
        Additional context for Cedar authorization evaluation. Fields here
        are mapped directly into the Cedar `context` record.
      properties:
        scopes:
          type: array
          items:
            type: string
          description: |
            OAuth scopes associated with the request. Mapped to `context.scopes`
            in the Cedar evaluation as a `Set<String>`.
        session_id:
          type: string
          description: |
            Session identifier for the current authorization context. Mapped to
            `context.session_id` in Cedar.
        claims:
          $ref: '#/components/schemas/pdp_EvaluationClaims'
      additionalProperties: false
    pdp_EvaluationClaims:
      type: object
      description: |
        Token claims for the actor, subject, and/or acting principal. Mapped to
        `context.actor_claims`, `context.subject_claims`, and
        `context.acting_principal_claims` in Cedar.
      properties:
        actor:
          $ref: '#/components/schemas/pdp_ClaimsData'
        subject:
          $ref: '#/components/schemas/pdp_ClaimsData'
        acting_principal:
          $ref: '#/components/schemas/pdp_ClaimsData'
      additionalProperties: false
    pdp_ClaimsData:
      type: object
      description: |
        Represents token claims passed into the Cedar context. Mapped to the
        Cedar `Keycard::Claims` type. Known fields (`email`, `groups`,
        `issuer_claims`) are typed; additional claims are passed through as
        untyped key-value pairs via `additionalProperties`.
      additionalProperties: true
      properties:
        email:
          type: string
          description: Email claim from the authentication token.
        groups:
          type: array
          items:
            type: string
          description: Group membership claims from the authentication token.
        issuer_claims:
          $ref: '#/components/schemas/pdp_IssuerClaims'
    pdp_IssuerClaims:
      type: object
      description: |
        Issuer-specific claims forwarded opaquely from STS (e.g. GHA OIDC
        assertion claims). Mapped to `context.actor_claims.issuer_claims`
        in Cedar. All fields are optional and issuer-dependent. See issuer
        documentation for available claim fields.
      additionalProperties: true
    pdp_EvaluationCheck:
      type: object
      description: |
        Result of a single Cedar sub-check within a compound evaluation. Each
        check's determining policies and their effect are attributed to that
        check's own decision, not the deny-wins aggregate.
      properties:
        role:
          type: string
          enum:
            - actor
            - subject
          description: |
            actor = the requesting principal's access (or its right to act for
            the subject in an on-behalf-of flow); subject = the impersonated /
            delegated principal's own access.
        decision:
          type: string
          enum:
            - allow
            - deny
        determining_policies:
          type: array
          items:
            $ref: '#/components/schemas/pdp_DeterminingPolicyDetail'
      additionalProperties: false
    pdp_DeterminingPolicyDetail:
      type: object
      description: |
        A policy that contributed to the decision, enriched with human-readable
        names and version. For an allow these are permit policies; for an
        explicit deny these are forbid policies. An implicit (fall-through)
        deny has none. On the management test-evaluate endpoint, names and
        policy-set version populate only when a minted policy version is being
        evaluated; raw text and draft sources stay structural.
      properties:
        policy_id:
          type: string
          description: Public ID of the policy.
        policy_name:
          type: string
          description: Human-readable policy name.
        rule_id:
          type: string
          description: |
            Cedar per-rule `@id` annotation that determined the decision
            (e.g. `limit-linear-scopes`). Falls back to the generated
            `policyN` key when the Cedar statement carries no `@id`.
        policy_version_id:
          type: string
          description: Public ID of the policy version that was evaluated.
        policy_set_id:
          type: string
          description: Public ID of the policy set the policy belongs to.
        policy_set_name:
          type: string
          description: Human-readable policy set name.
        policy_set_version:
          type: integer
          description: Version number of the policy set.
        effect:
          type: string
          enum:
            - permit
            - forbid
      additionalProperties: false
    pdp_DiagnosticEntry:
      type: object
      properties:
        policy_id:
          type: string
        message:
          type: string
      additionalProperties: false
    catalog_CatalogDependencyStatus:
      type: string
      enum:
        - attached
        - failed
      description: Whether attaching an application dependency succeeded.
    catalog_CatalogInstallDependency:
      type: object
      required:
        - resource_id
      properties:
        resource_id:
          type: string
          description: The svc-iam resource id to wire as a dependency.
      description: >-
        An existing in-zone resource to attach to a package install as a dependency.
    catalog_CatalogInstallDependencyResult:
      type: object
      required:
        - resource_id
        - status
      properties:
        resource_id:
          type: string
          description: The requested resource id.
        status:
          allOf:
            - $ref: '#/components/schemas/catalog_CatalogDependencyStatus'
          description: Whether the dependency was attached.
        error:
          type: string
          description: Error detail, present only when `status` is `failed`.
      description: The outcome of attaching one application dependency.
    catalog_CatalogInstallRequest:
      type: object
      properties:
        package_id:
          type: string
          description: >-
            Public ID of the package to install. Provide exactly one of package_id or slug.
        slug:
          type: string
          description: >-
            Stable slug of the package to install, resolved within the zone's visible

            catalog (most specific scope wins). Lets callers install a known package

            without discovering its per-zone package_id. Provide exactly one of

            package_id or slug; providing both is rejected.
        fields:
          type: object
          additionalProperties: {}
          description: Values for the package's form fields, keyed by field `name`.
        dependencies:
          type: array
          items:
            $ref: '#/components/schemas/catalog_CatalogInstallDependency'
          description: >-
            Existing in-zone resources to attach to the provisioned package as

            dependencies in the same call. Each is wired by resource id; a failure to

            attach one is reported per-item in the response `dependencies` without

            failing the install or the others.
      description: >-
        Request body for installing a package from the catalog. Exactly one of

        `package_id` or `slug` must be provided to identify the package; providing

        neither or both is rejected.
      oneOf:
        - required:
            - package_id
        - required:
            - slug
    catalog_CatalogInstallResponse:
      type: object
      properties:
        dependencies:
          type: array
          items:
            $ref: '#/components/schemas/catalog_CatalogInstallDependencyResult'
          description: >-
            Per-dependency outcomes for the request's `dependencies`, in request order.

            Absent when the install carried no dependencies.
      description: >-
        Response body for a catalog install. A synchronous install either succeeds or

        fails with an error; on success the provisioned entity's URL is returned in the

        `Location` header. `dependencies` carries the per-item attach outcomes when the

        request supplied any.
    catalog_CatalogPackage:
      type: object
      required:
        - id
        - slug
        - name
        - form
        - created_at
        - updated_at
      properties:
        id:
          type: string
        slug:
          type: string
          description: URL-friendly identifier.
        name:
          type: string
        description:
          type: string
        form:
          allOf:
            - $ref: '#/components/schemas/catalog_Form'
          description: The input required to install this package.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        icon_url:
          type: string
          description: Fully-qualified CDN link for the package icon.
        setup_guide:
          allOf:
            - $ref: '#/components/schemas/catalog_Keycard.Catalog.Vocabulary.markdown'
          description: Markdown text describing how to set up the subject.
        usage_guide:
          allOf:
            - $ref: '#/components/schemas/catalog_Keycard.Catalog.Vocabulary.markdown'
          description: Markdown text explaining how to use the subject.
        recommended:
          type: boolean
          description: Boolean flag indicating whether the subject is recommended.
        categories:
          type: array
          items:
            type: string
          description: Array of category labels.
        icon:
          type: string
          description: Icon basename used by the catalog UI grid.
        tags:
          type: array
          items:
            type: string
          description: UI-facing tags surfaced by the catalog detail page.
        long_description:
          allOf:
            - $ref: '#/components/schemas/catalog_Keycard.Catalog.Vocabulary.markdown'
          description: Markdown long description shown on the catalog detail page.
        tools:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              description:
                type: string
            required:
              - name
              - description
            additionalProperties:
              type: string
          description: >-
            List of tool descriptors surfaced by the package. The kind of tool is implied by the subject's domain (e.g., MCP packages describe MCP tools).
      additionalProperties: {}
      description: Catalog installable item.
    catalog_CatalogPackageList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/catalog_CatalogPackage'
        pagination:
          $ref: '#/components/schemas/catalog_Pagination'
    catalog_Form:
      type: object
      required:
        - fields
      properties:
        fields:
          type: array
          items:
            $ref: '#/components/schemas/catalog_FormField'
          description: Empty when the package can be installed without input.
      description: Describes the input a user must supply to install a package.
    catalog_FormField:
      type: object
      required:
        - type
        - label
        - name
        - required
      properties:
        type:
          allOf:
            - $ref: '#/components/schemas/catalog_FormFieldType'
          description: >-
            Input control type. `password` masks secret values; `tags` collects a

            list of strings submitted as a JSON array.
        label:
          type: string
          description: The name to display for the input.
        name:
          type: string
          description: The literal input name, matching the install input property.
        required:
          type: boolean
          description: Whether the input must be provided to install the package.
      description: |-
        A single form input, translated from one property of the package's
        install input schema.
    catalog_FormFieldType:
      type: string
      enum:
        - text
        - password
        - tags
      description: |-
        Input control type for a form field. `tags` is rendered for
        array-of-string inputs and submitted back as a JSON array of strings.
      x-enum-varnames:
        - Text
        - Password
        - FormFieldTypeTags
    catalog_JsonSchema:
      type: object
      properties:
        type:
          allOf:
            - $ref: '#/components/schemas/catalog_JsonSchemaType'
          description: The JSON Schema `type` keyword.
        title:
          type: string
          description: Human-readable title (annotation).
        description:
          type: string
          description: Human-readable description (annotation).
        default:
          description: Default value (annotation).
        const:
          description: Constant allowed value.
        enum:
          type: array
          items: {}
          description: Enumerated allowed values.
        writeOnly:
          type: boolean
          description: Write-only hint (passwords, secrets) — never returned on read.
        readOnly:
          type: boolean
          description: Read-only hint — server-populated, ignored on write.
        format:
          type: string
          description: Format hint (e.g., "uri", "uuid", "email", "date-time").
        properties:
          allOf:
            - $ref: '#/components/schemas/catalog_JsonSchemaProperties'
          description: Property schemas, keyed by property name.
        required:
          type: array
          items:
            type: string
          description: Names of required properties.
        additionalProperties:
          allOf:
            - $ref: '#/components/schemas/catalog_JsonSchema'
          description: Schema for properties not named in `properties`.
        items:
          allOf:
            - $ref: '#/components/schemas/catalog_JsonSchema'
          description: Schema for array items.
        minItems:
          type: integer
        maxItems:
          type: integer
        pattern:
          type: string
        minLength:
          type: integer
        maxLength:
          type: integer
        minimum:
          type: number
        maximum:
          type: number
      description: >-
        A subset of JSON Schema 2020-12 used to describe package input and output

        shapes.


        Supported keywords:

        - Structural: `type`, `properties`, `required`, `items`, `additionalProperties`

        - Annotations: `title`, `description`, `default`, `readOnly`, `writeOnly`

        - Constraints: `pattern`, `minLength`, `maxLength`, `minimum`, `maximum`,

        `minItems`, `maxItems`, `enum`, `const`, `format`


        Intentionally unsupported (reject at release time rather than silently ignore):

        - Schema combinators: `allOf`, `anyOf`, `oneOf`, `not`

        - References: `$ref`, `$dynamicRef`

        - `patternProperties`, `propertyNames`, `unevaluatedProperties`

        - Custom vocabularies and `$vocabulary`


        Dialect: JSON Schema 2020-12 (implied — authors do not include `$schema`).
    catalog_JsonSchemaProperties:
      type: object
      additionalProperties:
        $ref: '#/components/schemas/catalog_JsonSchema'
      description: Map of property name to a JSON Schema describing that property.
    catalog_JsonSchemaType:
      type: string
      enum:
        - object
        - array
        - string
        - integer
        - number
        - boolean
        - 'null'
      description: The `type` keyword in JSON Schema 2020-12.
    catalog_Keycard.Catalog.Vocabulary.markdown:
      type: string
      format: markdown
    catalog_PackageInputBinding:
      type: object
      properties:
        schema:
          allOf:
            - $ref: '#/components/schemas/catalog_JsonSchema'
          description: |-
            JSON Schema constraining install-level inputs for this package.
            Must be a subset of the package kind's inputs schema. Properties
            listed in `required` must be provided at install creation time.
        bindings:
          type: string
          description: |-
            CEL expression assembling the flat input map from static values
            and install-provided values (referenced via `pkg.inputs.X`).

            Scope:
            - `pkg.inputs` — install-supplied values conforming to `schema`.
      description: >-
        Input binding for a package.


        `schema` constrains install-level inputs. `bindings` is a CEL expression

        that assembles the flat input map — static values are CEL literals,

        install-provided values are `pkg.inputs.X` references. Evaluated at

        provisioning time to produce the `entities.inputs` map for entity bindings.
    catalog_PaginationCursor:
      type: string
      description: An opaque cursor used for paginating through a list of results
      minLength: 1
      maxLength: 255
      x-go-type: types.PaginationCursor
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    catalog_Pagination:
      type: object
      description: Cursor-based pagination metadata returned alongside a list of results
      properties:
        before_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/catalog_PaginationCursor'
        after_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/catalog_PaginationCursor'
        total_count:
          type: integer
          description: >-
            Total number of items across all pages. Only present when the request includes ?expand[]=total_count.
      required:
        - before_cursor
        - after_cursor
      additionalProperties: false
      x-go-type: types.Pagination
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    catalog_ActionRefreshResult:
      type: object
      required:
        - resource_id
        - tool_count
        - truncated
        - changed
      properties:
        resource_id:
          type: string
          description: The resource whose actions were recorded.
        tool_count:
          type: integer
          description: How many tools the walk observed.
        truncated:
          type: boolean
          description: >-
            True when the walk stopped before the server ran out of pages. What was

            seen is still recorded, and nothing is retired, since a tool missing from

            a partial walk has not been shown to be gone.
        changed:
          type: boolean
          description: Whether recording the observation altered the resource's actions.
      description: What a completed walk observed.
    catalog_ActionRefreshStartRequest:
      type: object
      properties:
        return_to:
          type: string
          description: >-
            Where to send the user's browser once the walk is done, so a caller

            that leaves the round trip to this service still gets its page back. Must

            match a specific allowed origin, which is typically the Keycard Console URL

            in the catalog's deployment. Omit it and the browser stops on a page from

            this service.
      description: Where to come back to once the user has authorized the walk.
    catalog_ActionRefreshStartResponse:
      type: object
      oneOf:
        - required:
            - authorization_url
        - required:
            - completed
            - tool_count
            - truncated
            - changed
      properties:
        completed:
          type: boolean
          description: >-
            True when the refresh is already done, because the zone still held the

            user's authorization for this server and no browser leg was needed. The

            counts are then present and `authorization_url` is absent.
        tool_count:
          type: integer
          minimum: 0
          description: How many tools the walk recorded, when it ran.
        truncated:
          type: boolean
          description: >-
            True when the walk reached its page limit before enumeration finished.

            Existing actions absent from that incomplete list are retained.
        changed:
          type: boolean
          description: True when observed tools were recorded in IAM.
        warning:
          type: string
          enum:
            - incomplete_list
            - cleanup_failed
            - missing_cutoff
            - empty_list
            - incomplete_refresh
          description: >-
            Present when the observation did not reconcile the complete tool list.

            Existing actions may remain. The response is

            completed and does not require browser authorization.
        authorization_url:
          type: string
          description: >-
            The URL the user's browser must visit. Present only when the zone holds

            no authorization for this user and this server yet.
      description: |-
        Either what a completed walk found, or where to send the user so a later
        refresh can answer without asking again.
    catalog_PackageKind:
      type: string
      description: A recognized catalog package kind.
      enum:
        - api-server
        - mcp-server-proxy
      x-enum-varnames:
        - PackageKindAPIServer
        - PackageKindMCPServerProxy
    catalog_QueryTerms:
      type: array
      description: |
        Value shape for `query[]` and `query[<field>]` search parameters.

        Wire conventions:
          - Case-insensitive substring match (ILIKE).
          - Repeated parameter instances are OR-ed across terms.
          - Comma splitting is NOT performed; literal commas in a search term
            are preserved as part of the term.

        Examples:
          ?query[name]=alpha&query[name]=beta      -> name ILIKE %alpha% OR name ILIKE %beta%
          ?query[]=alpha                           -> any searchable field ILIKE %alpha%

        Cross-field form is `query[]`; field-scoped form is `query[<field>]`.
        Field names are endpoint-specific; services declare each query parameter
        per operation.
      items:
        type: string
        minLength: 1
        maxLength: 255
    catalog_ErrorCode:
      type: string
      enum:
        - validation_error
        - bad_request
        - unauthorized
        - forbidden
        - not_found
        - conflict
        - rate_limit_exceeded
        - internal_error
        - not_implemented
        - service_unavailable
      x-enum-varnames:
        - ValidationErrorCode
        - BadRequestErrorCode
        - UnauthorizedErrorCode
        - ForbiddenErrorCode
        - NotFoundErrorCode
        - ConflictErrorCode
        - RateLimitExceededErrorCode
        - InternalErrorCode
        - NotImplementedErrorCode
        - ServiceUnavailableErrorCode
      x-go-type: httperrors.ErrorCode
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    catalog_ErrorDetail:
      type: object
      properties:
        field:
          type: string
          description: >-
            valid json path for request body. Omitted when the detail is not tied to a request field (e.g. domain error codes); clients should treat absent and empty the same.
        message:
          type: string
          description: error message for specific error
        code:
          anyOf:
            - $ref: '#/components/schemas/catalog_ErrorCode'
            - type: string
          description: >-
            Machine-readable code. Either a common `ErrorCode` value or a service-specific domain code (snake_case) documented by the service's own API spec. Clients should match on this instead of parsing `message`. Open set; unknown codes must be tolerated.
          example: version_currently_bound
      required:
        - message
        - code
      additionalProperties: false
      x-go-type: httperrors.ErrorDetail
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    catalog_Error:
      type: object
      description: Represents an error that has occurred in the Keycard system.
      properties:
        status:
          type: integer
          description: HTTP Status Code
        code:
          $ref: '#/components/schemas/catalog_ErrorCode'
        message:
          type: string
          description: summary of the error
        request_id:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
        path:
          type: string
          format: url
        details:
          type: array
          items:
            $ref: '#/components/schemas/catalog_ErrorDetail'
      additionalProperties: false
      required:
        - status
        - code
        - message
        - request_id
        - timestamp
        - path
        - details
      x-go-type: httperrors.Error
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    iam_PageInfo:
      title: Page Info
      description: Pagination information
      additionalProperties: false
      type: object
      required:
        - has_next_page
        - has_previous_page
      properties:
        has_next_page:
          description: Whether there are more items after the current page
          type: boolean
        has_previous_page:
          description: Whether there are items before the current page
          type: boolean
        start_cursor:
          nullable: true
          description: Cursor pointing to the first item in the current page
          type: string
        end_cursor:
          nullable: true
          description: Cursor pointing to the last item in the current page
          type: string
    iam_PaginationCursor:
      title: Pagination Cursor
      description: An opaque cursor used for paginating through a list of results
      minLength: 1
      maxLength: 255
      type: string
    iam_Pagination:
      title: Pagination
      description: Cursor-based pagination metadata
      additionalProperties: false
      type: object
      required:
        - after_cursor
        - before_cursor
      properties:
        after_cursor:
          type: string
          allOf:
            - $ref: '#/components/schemas/iam_PaginationCursor'
          nullable: true
          description: Cursor to fetch the next page of results
        before_cursor:
          type: string
          allOf:
            - $ref: '#/components/schemas/iam_PaginationCursor'
          nullable: true
          description: Cursor to fetch the previous page of results
        total_count:
          description: >-
            Total number of items matching the query. Only included when expand[]=total_count is requested.
          type: integer
    iam_Metadata:
      additionalProperties: false
      description: Entity metadata
      type: object
      properties:
        docs_url:
          format: uri
          maxLength: 2048
          description: Documentation URL
          type: string
        icon_url:
          format: uri
          maxLength: 2048
          description: Icon URL
          type: string
    iam_MetadataUpdate:
      nullable: true
      additionalProperties: false
      description: Entity metadata (set to null or {} to remove metadata)
      type: object
      properties:
        docs_url:
          format: uri
          maxLength: 2048
          nullable: true
          description: Documentation URL (set to null to unset)
          type: string
        icon_url:
          format: uri
          maxLength: 2048
          nullable: true
          description: Icon URL (set to null to unset)
          type: string
    iam_Permissions:
      title: Permissions
      description: >-
        Permissions granted to the authenticated principal. Only populated when expand[]=permissions query parameter is provided. Keys are resource types, values are objects mapping action names to boolean values.
      type: object
      additionalProperties:
        type: object
        additionalProperties:
          type: boolean
      example:
        zones:
          read: true
          update: true
          delete: false
          create: false
        applications:
          read: true
          list: true
          create: false
    iam_ZoneCimd:
      title: Zone CIMD Configuration
      description: Client ID Metadata Document auto-provisioning configuration
      type: object
      required:
        - enabled
        - allowed_client_ids
      properties:
        enabled:
          description: >-
            Whether CIMD auto-provisioning is enabled for unregistered URL-based clients
          default: false
          type: boolean
        allowed_client_ids:
          description: >-
            Allowlist for CIMD client_id URLs. Each entry is an exact URL, a wildcard origin with a single * replacing one subdomain label (e.g. https://*.example.com matches https://app.example.com but not https://a.b.example.com), or the literal * to allow any client. Only one * is permitted per entry.
          default: []
          type: array
          items:
            type: string
    iam_ZoneOAuth2Protocol:
      title: Zone OAuth 2.0 Protocol
      description: OAuth 2.0 protocol configuration for a zone
      type: object
      required:
        - issuer
        - authorization_server_metadata
        - authorization_endpoint
        - token_endpoint
        - redirect_uri
        - registration_endpoint
        - jwks_uri
        - pkce_required
        - dcr_enabled
        - cimd
      properties:
        issuer:
          format: uri
          description: OAuth 2.0 issuer identifier
          type: string
        authorization_server_metadata:
          format: uri
          description: >-
            OAuth 2.0 Authorization Server Metadata endpoint (.well-known/oauth-authorization-server)
          type: string
        authorization_endpoint:
          format: uri
          description: OAuth 2.0 authorization endpoint
          type: string
        token_endpoint:
          format: uri
          description: OAuth 2.0 token endpoint
          type: string
        redirect_uri:
          format: uri
          description: OAuth 2.0 redirect URI for this zone
          type: string
        registration_endpoint:
          format: uri
          description: OAuth 2.0 Dynamic Client Registration endpoint
          type: string
        jwks_uri:
          format: uri
          description: JSON Web Key Set endpoint
          type: string
        pkce_required:
          description: Whether PKCE is required for authorization code flows
          type: boolean
        dcr_enabled:
          description: Whether Dynamic Client Registration is enabled
          type: boolean
        cimd:
          $ref: '#/components/schemas/iam_ZoneCimd'
    iam_ZoneOpenIDProtocol:
      title: Zone OpenID Connect Protocol
      description: OpenID Connect protocol configuration for a zone
      type: object
      required:
        - provider_configuration
        - userinfo_endpoint
      properties:
        provider_configuration:
          format: uri
          description: >-
            OpenID Connect Provider Configuration endpoint (.well-known/openid-configuration)
          type: string
        userinfo_endpoint:
          format: uri
          description: OpenID Connect UserInfo endpoint
          type: string
    iam_ZoneProtocol:
      title: Zone Protocol
      description: Protocol configuration for a zone
      type: object
      required:
        - oauth2
        - openid
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ZoneOAuth2Protocol'
        openid:
          $ref: '#/components/schemas/iam_ZoneOpenIDProtocol'
    iam_ZoneOAuth2ProtocolCreate:
      title: Zone OAuth 2.0 Protocol Create
      description: OAuth 2.0 protocol configuration for zone creation
      type: object
      properties:
        pkce_required:
          description: Whether PKCE is required for authorization code flows
          default: true
          type: boolean
        dcr_enabled:
          description: Whether Dynamic Client Registration is enabled
          default: true
          type: boolean
        cimd:
          $ref: '#/components/schemas/iam_ZoneCimd'
    iam_ZoneProtocolCreate:
      title: Zone Protocol Create
      description: Protocol configuration for zone creation
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ZoneOAuth2ProtocolCreate'
    iam_ZoneOAuth2ProtocolUpdate:
      title: Zone OAuth 2.0 Protocol Update
      description: OAuth 2.0 protocol configuration update for a zone (partial update)
      type: object
      properties:
        pkce_required:
          nullable: true
          description: Whether PKCE is required for authorization code flows
          type: boolean
        dcr_enabled:
          nullable: true
          description: Whether Dynamic Client Registration is enabled
          type: boolean
        cimd:
          $ref: '#/components/schemas/iam_ZoneCimd'
    iam_ZoneProtocolUpdate:
      title: Zone Protocol Update
      description: Protocol configuration update for a zone (partial update)
      nullable: true
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ZoneOAuth2ProtocolUpdate'
    iam_EncryptionKeyAwsKmsConfig:
      title: AWS KMS Encryption Key Configuration
      description: >-
        AWS KMS configuration for zone encryption. When not specified, the default Keycard Cloud encryption key will be used.
      type: object
      required:
        - type
        - arn
      properties:
        type:
          type: string
          enum:
            - aws
        arn:
          minLength: 1
          description: AWS KMS Key ARN for encrypting the zone's data
          type: string
    iam_EncryptionKeyAwsKmsConfigUpdate:
      title: AWS KMS Encryption Key Configuration Update
      description: >-
        AWS KMS configuration for zone encryption update (set to null to remove customer-managed key and revert to default)
      nullable: true
      type: object
      required:
        - type
        - arn
      properties:
        type:
          type: string
          enum:
            - aws
        arn:
          minLength: 1
          description: AWS KMS Key ARN for encrypting the zone's data
          type: string
    iam_ProviderOAuth2Protocol:
      title: Provider OAuth 2.0 Protocol
      description: OAuth 2.0 protocol configuration
      nullable: true
      type: object
      required:
        - issuer
      properties:
        issuer:
          format: uri
          description: OIDC issuer URL used for discovery and token validation.
          type: string
        authorization_endpoint:
          format: uri
          nullable: true
          type: string
        token_endpoint:
          format: uri
          nullable: true
          type: string
        registration_endpoint:
          format: uri
          nullable: true
          type: string
        jwks_uri:
          format: uri
          nullable: true
          type: string
        code_challenge_methods_supported:
          nullable: true
          type: array
          items:
            type: string
        scopes_supported:
          nullable: true
          type: array
          items:
            type: string
        authorization_resource_enabled:
          nullable: true
          description: Whether to include the resource parameter in authorization requests.
          type: boolean
        authorization_resource_parameter:
          nullable: true
          description: >-
            The resource parameter value to include in authorization requests. Defaults to "resource" when authorization_resource_enabled is true.
          type: string
        scope_parameter:
          nullable: true
          description: >-
            The query parameter name for scopes in authorization requests. Defaults to "scope". Slack v2 uses "user_scope".
          type: string
        scope_separator:
          nullable: true
          description: >-
            The separator character for scope values. Defaults to " " (space). Slack v2 uses ",".
          type: string
        token_response_access_token_pointer:
          nullable: true
          description: >-
            Dot-separated path to the access token in the token response body. Defaults to "access_token". Slack v2 uses "authed_user.access_token".
          type: string
        authorization_parameters:
          nullable: true
          description: >-
            Custom query parameters appended to authorization redirect URLs. Use for non-standard providers (e.g. Google prompt=consent, access_type=offline).
          type: object
          additionalProperties:
            type: string
    iam_ProviderOpenIDProtocol:
      title: Provider OpenID Connect Protocol
      description: OpenID Connect protocol configuration
      nullable: true
      type: object
      properties:
        userinfo_endpoint:
          format: uri
          nullable: true
          type: string
        user_identifier_claim:
          nullable: true
          description: >-
            Name of a top-level string claim in this provider's ID Token to use as the user identifier on user creation. When not set, the user's Keycard ID is used.
          type: string
        scopes:
          nullable: true
          description: >-
            Additional OIDC scopes to request from this provider during authentication (e.g. "groups"). Merged with the default scopes (openid, profile, email).
          type: array
          items:
            type: string
        single_logout_enabled:
          nullable: true
          description: >-
            When true, logging out of the zone propagates the logout to this provider's end_session_endpoint (RP-initiated logout). Defaults to false.
          type: boolean
    iam_ProviderProtocol:
      title: Provider Protocol
      description: Protocol-specific configuration
      nullable: true
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ProviderOAuth2Protocol'
        openid:
          $ref: '#/components/schemas/iam_ProviderOpenIDProtocol'
    iam_ProviderOAuth2ProtocolCreate:
      title: Provider OAuth 2.0 Protocol Create
      description: OAuth 2.0 protocol configuration for provider creation
      type: object
      properties:
        issuer:
          format: uri
          description: >-
            OIDC issuer URL for discovery and token validation. When omitted, the provider identifier is used as the issuer. New clients should always set this explicitly.
          type: string
        authorization_endpoint:
          format: uri
          type: string
        token_endpoint:
          format: uri
          type: string
        registration_endpoint:
          format: uri
          type: string
        jwks_uri:
          format: uri
          type: string
        code_challenge_methods_supported:
          type: array
          items:
            type: string
        scopes_supported:
          type: array
          items:
            type: string
        authorization_resource_enabled:
          description: Whether to include the resource parameter in authorization requests.
          type: boolean
        authorization_resource_parameter:
          description: >-
            The resource parameter value to include in authorization requests. Defaults to "resource" when authorization_resource_enabled is true.
          type: string
        scope_parameter:
          description: >-
            The query parameter name for scopes in authorization requests. Defaults to "scope". Slack v2 uses "user_scope".
          type: string
        scope_separator:
          description: >-
            The separator character for scope values. Defaults to " " (space). Slack v2 uses ",".
          type: string
        token_response_access_token_pointer:
          description: >-
            Dot-separated path to the access token in the token response body. Defaults to "access_token". Slack v2 uses "authed_user.access_token".
          type: string
        authorization_parameters:
          description: >-
            Custom query parameters appended to authorization redirect URLs. Use for non-standard providers (e.g. Google prompt=consent, access_type=offline).
          type: object
          additionalProperties:
            type: string
    iam_ProviderOpenIDProtocolCreate:
      title: Provider OpenID Connect Protocol Create
      description: OpenID Connect protocol configuration for provider creation
      type: object
      properties:
        userinfo_endpoint:
          format: uri
          type: string
        user_identifier_claim:
          description: >-
            Name of a top-level string claim in this provider's ID Token to use as the user identifier on user creation. When not set, the user's Keycard ID is used.
          type: string
        scopes:
          description: >-
            Additional OIDC scopes to request from this provider during authentication (e.g. "groups"). Merged with the default scopes (openid, profile, email).
          type: array
          items:
            type: string
        single_logout_enabled:
          description: >-
            When true, logging out of the zone propagates the logout to this provider's end_session_endpoint (RP-initiated logout). Defaults to false.
          type: boolean
    iam_ProviderProtocolCreate:
      title: Provider Protocol Create
      description: Protocol-specific configuration for provider creation
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ProviderOAuth2ProtocolCreate'
        openid:
          $ref: '#/components/schemas/iam_ProviderOpenIDProtocolCreate'
    iam_ProviderOAuth2ProtocolUpdate:
      title: Provider OAuth 2.0 Protocol Update
      description: >-
        OAuth 2.0 protocol configuration. Set to null to remove all OAuth2 config.
      nullable: true
      type: object
      properties:
        issuer:
          format: uri
          description: >-
            OIDC issuer URL for discovery and token validation. Cannot be set to null.
          type: string
        authorization_endpoint:
          format: uri
          nullable: true
          type: string
        token_endpoint:
          format: uri
          nullable: true
          type: string
        registration_endpoint:
          format: uri
          nullable: true
          type: string
        jwks_uri:
          format: uri
          nullable: true
          type: string
        code_challenge_methods_supported:
          nullable: true
          type: array
          items:
            type: string
        scopes_supported:
          nullable: true
          type: array
          items:
            type: string
        authorization_resource_enabled:
          nullable: true
          description: >-
            Whether to include the resource parameter in authorization requests. Set to null to unset.
          type: boolean
        authorization_resource_parameter:
          nullable: true
          description: >-
            The resource parameter value to include in authorization requests. Defaults to "resource" when authorization_resource_enabled is true. Set to null to unset.
          type: string
        scope_parameter:
          nullable: true
          description: >-
            The query parameter name for scopes in authorization requests. Defaults to "scope". Set to null to unset.
          type: string
        scope_separator:
          nullable: true
          description: >-
            The separator character for scope values. Defaults to " " (space). Set to null to unset.
          type: string
        token_response_access_token_pointer:
          nullable: true
          description: >-
            Dot-separated path to the access token in the token response body. Defaults to "access_token". Set to null to unset.
          type: string
        authorization_parameters:
          nullable: true
          description: >-
            Custom query parameters appended to authorization redirect URLs. Set to null to unset.
          type: object
          additionalProperties:
            type: string
    iam_ProviderOpenIDProtocolUpdate:
      title: Provider OpenID Connect Protocol Update
      description: >-
        OpenID Connect protocol configuration. Set to null to remove all OpenID config.
      nullable: true
      type: object
      properties:
        userinfo_endpoint:
          format: uri
          nullable: true
          type: string
        user_identifier_claim:
          nullable: true
          description: >-
            Name of a top-level string claim in this provider's ID Token to use as the user identifier on user creation. Set to null to revert to default. Changing this value does not affect existing users.
          type: string
        scopes:
          nullable: true
          description: >-
            Additional OIDC scopes to request from this provider during authentication (e.g. "groups"). Merged with the default scopes (openid, profile, email). Set to null to clear.
          type: array
          items:
            type: string
        single_logout_enabled:
          nullable: true
          description: >-
            When true, logging out of the zone propagates the logout to this provider's end_session_endpoint (RP-initiated logout). Defaults to false.
          type: boolean
    iam_ProviderProtocolUpdate:
      title: Provider Protocol Update
      description: Protocol-specific configuration. Set to null to remove all protocols.
      nullable: true
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ProviderOAuth2ProtocolUpdate'
        openid:
          $ref: '#/components/schemas/iam_ProviderOpenIDProtocolUpdate'
    iam_ApplicationOAuth2Protocol:
      title: Application OAuth 2.0 Protocol
      description: OAuth 2.0 protocol configuration
      nullable: true
      additionalProperties: false
      type: object
      properties:
        redirect_uris:
          nullable: true
          description: OAuth 2.0 redirect URIs for this application
          x-audit: true
          type: array
          items:
            format: uri
            type: string
        post_logout_redirect_uris:
          nullable: true
          description: OAuth 2.0 post-logout redirect URIs for this application
          x-audit: true
          type: array
          items:
            format: uri
            type: string
    iam_ApplicationProtocol:
      title: Application Protocol
      description: Protocol-specific configuration
      nullable: true
      additionalProperties: false
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ApplicationOAuth2Protocol'
    iam_ApplicationOAuth2ProtocolCreate:
      title: Application OAuth 2.0 Protocol Create
      description: OAuth 2.0 protocol configuration for application creation
      additionalProperties: false
      type: object
      properties:
        redirect_uris:
          description: OAuth 2.0 redirect URIs for this application
          type: array
          items:
            format: uri
            type: string
        post_logout_redirect_uris:
          description: OAuth 2.0 post-logout redirect URIs for this application
          type: array
          items:
            format: uri
            type: string
    iam_ApplicationProtocolCreate:
      title: Application Protocol Create
      description: Protocol-specific configuration for application creation
      additionalProperties: false
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ApplicationOAuth2ProtocolCreate'
    iam_ApplicationOAuth2ProtocolUpdate:
      title: Application OAuth 2.0 Protocol Update
      description: OAuth 2.0 protocol configuration for application update
      nullable: true
      additionalProperties: false
      type: object
      properties:
        redirect_uris:
          nullable: true
          description: >-
            OAuth 2.0 redirect URIs for this application (set to null or [] to unset)
          type: array
          items:
            format: uri
            type: string
        post_logout_redirect_uris:
          nullable: true
          description: >-
            OAuth 2.0 post-logout redirect URIs for this application (set to null or [] to unset)
          type: array
          items:
            format: uri
            type: string
    iam_ApplicationProtocolUpdate:
      title: Application Protocol Update
      description: Protocol-specific configuration for application update
      nullable: true
      additionalProperties: false
      type: object
      properties:
        oauth2:
          $ref: '#/components/schemas/iam_ApplicationOAuth2ProtocolUpdate'
    iam_ApplicationCredentialCreateToken:
      title: Application Credential Create Token
      description: Schema for creating a token application credential
      type: object
      required:
        - application_id
        - type
        - provider_id
      properties:
        application_id:
          description: ID of the application this credential belongs to
          type: string
        type:
          type: string
          enum:
            - token
        provider_id:
          description: ID of the provider issuing tokens this credential verifies
          type: string
        subject:
          description: >-
            Subject identifier for the token. When omitted, any token from the provider is accepted without checking application-specific claims.
          type: string
    iam_ApplicationCredentialCreatePassword:
      title: Application Credential Create Password
      description: Schema for creating a password application credential
      type: object
      required:
        - application_id
        - type
      properties:
        application_id:
          description: ID of the application this credential belongs to
          type: string
        type:
          type: string
          enum:
            - password
        identifier:
          description: >-
            Username for password credential, also used as OAuth 2.0 client ID (auto-generated if not provided)
          type: string
    iam_ApplicationCredentialCreatePublicKey:
      title: Application Credential Create Public Key
      description: Schema for creating a public key application credential
      type: object
      required:
        - application_id
        - type
        - jwks_uri
      properties:
        application_id:
          description: ID of the application this credential belongs to
          type: string
        type:
          type: string
          enum:
            - public-key
        jwks_uri:
          format: uri
          description: JWKS URI to retrieve public keys from
          type: string
        identifier:
          description: >-
            Client ID for public key credential, also used as OAuth 2.0 client ID (auto-generated if not provided)
          type: string
    iam_ApplicationCredentialCreateUrl:
      title: Application Credential Create URL
      description: Schema for creating a URL application credential
      type: object
      required:
        - application_id
        - type
        - identifier
      properties:
        application_id:
          description: ID of the application this credential belongs to
          type: string
        type:
          type: string
          enum:
            - url
        identifier:
          format: uri
          description: URL of the credential (must be a valid URL)
          type: string
    iam_ApplicationCredentialCreatePublic:
      title: Application Credential Create Public
      description: Schema for creating a public application credential
      type: object
      required:
        - application_id
        - type
      properties:
        application_id:
          description: ID of the application this credential belongs to
          type: string
        type:
          type: string
          enum:
            - public
        identifier:
          description: >-
            Identifier for public credential, also used as OAuth 2.0 client ID (auto-generated if not provided)
          type: string
    iam_Error:
      title: Error
      description: Error response
      type: object
      required:
        - message
        - code
        - status
      properties:
        message:
          type: string
        code:
          type: string
        status:
          type: number
    iam_Provider:
      title: Provider
      description: >-
        A Provider is a system that supplies access to Resources and allows actors (Users or Applications) to authenticate.
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - slug
        - name
        - identifier
        - owner_type
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the provider
          type: string
        organization_id:
          description: Organization that owns this provider
          type: string
        zone_id:
          description: Zone this provider belongs to
          type: string
        slug:
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          minLength: 1
          maxLength: 63
          description: URL-safe identifier, unique within the zone
          type: string
        name:
          minLength: 1
          maxLength: 255
          description: Human-readable name
          x-audit: true
          type: string
        description:
          maxLength: 2048
          nullable: true
          description: Human-readable description
          x-audit: true
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          description: User specified identifier, unique within the zone
          x-audit: true
          type: string
        type:
          type: string
          enum:
            - external
            - keycard-vault
            - keycard-sts
        client_id:
          nullable: true
          description: OAuth 2.0 client identifier
          type: string
        client_secret_set:
          description: Indicates whether a client secret is configured
          type: boolean
        protocols:
          nullable: true
          description: Protocol-specific configuration
          type: object
          properties:
            oauth2:
              $ref: '#/components/schemas/iam_ProviderOAuth2Protocol'
            openid:
              $ref: '#/components/schemas/iam_ProviderOpenIDProtocol'
        metadata:
          nullable: true
          description: Provider metadata
          type: object
          properties:
            icon_url:
              format: uri
              maxLength: 2048
              description: Icon URL
              type: string
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >-
            Who owns this provider. Platform-owned providers cannot be modified via API.
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_ProviderCreate:
      title: Provider Create
      description: Schema for creating a new provider
      type: object
      required:
        - name
        - identifier
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: >-
            User specified identifier, unique within the zone. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        client_id:
          description: OAuth 2.0 client identifier
          type: string
        client_secret:
          description: OAuth 2.0 client secret (will be encrypted and stored securely)
          type: string
        protocols:
          $ref: '#/components/schemas/iam_ProviderProtocolCreate'
        metadata:
          description: Provider metadata
          type: object
          properties:
            icon_url:
              format: uri
              maxLength: 2048
              description: Icon URL
              type: string
    iam_ProviderUpdate:
      title: Provider Update
      description: Schema for updating an existing provider
      type: object
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: >-
            User specified identifier, unique within the zone. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        client_id:
          nullable: true
          description: OAuth 2.0 client identifier. Set to null to remove.
          type: string
        client_secret:
          nullable: true
          description: >-
            OAuth 2.0 client secret (will be encrypted and stored securely). Set to null to remove.
          type: string
        protocols:
          $ref: '#/components/schemas/iam_ProviderProtocolUpdate'
        metadata:
          nullable: true
          description: Provider metadata. Set to null to remove all metadata.
          type: object
          properties:
            icon_url:
              format: uri
              maxLength: 2048
              nullable: true
              description: Icon URL (set to null to unset)
              type: string
    iam_ProviderValidationCheckName:
      type: string
      enum:
        - issuer_reachability
        - metadata_retrieval
        - endpoint_consistency
        - authorization_endpoint_reachability
        - credential_exchange
      title: Provider Validation Check Name
      description: Identifier of an individual provider validation check
    iam_ProviderValidationCheckStatus:
      type: string
      enum:
        - pass
        - fail
        - skipped_with_reason
        - not_applicable
      title: Provider Validation Check Status
      description: >-
        Outcome of a single check. `pass`/`fail` mean the check ran. `skipped_with_reason` means it could not run because a prerequisite is missing on our side (e.g. no credential stored). `not_applicable` means the check does not apply to this provider class (e.g. a login-flow-only provider that does not advertise the `client_credentials` grant) — render as a neutral state, distinct from a failure. Neither `skipped_with_reason` nor `not_applicable` fails the overall run.
    iam_ProviderValidationOverallStatus:
      type: string
      enum:
        - pass
        - fail
      title: Provider Validation Overall Status
      description: >-
        Overall outcome. `fail` when any individual check failed; skipped checks do not fail the run.
    iam_ProviderValidationCheck:
      title: Provider Validation Check
      description: Result of a single provider validation check
      type: object
      required:
        - check
        - status
      properties:
        check:
          $ref: '#/components/schemas/iam_ProviderValidationCheckName'
        status:
          $ref: '#/components/schemas/iam_ProviderValidationCheckStatus'
        detail:
          description: >-
            Human-readable explanation, present on `fail`, `skipped_with_reason`, and `not_applicable`.
          type: string
    iam_ProviderValidationResult:
      title: Provider Validation Result
      description: >-
        Result of running the provider OIDC connection checks on demand. Not persisted.
      type: object
      required:
        - provider_id
        - status
        - checks
        - validated_at
      properties:
        provider_id:
          description: Provider that was validated
          type: string
        status:
          $ref: '#/components/schemas/iam_ProviderValidationOverallStatus'
        checks:
          description: Per-check results, in execution order
          type: array
          items:
            $ref: '#/components/schemas/iam_ProviderValidationCheck'
        validated_at:
          format: date-time
          description: When the validation run completed
          type: string
    iam_Resource:
      title: Resource
      description: >-
        A Resource is a system that exposes protected information or functionality. It requires authentication of the requesting actor, which may be a user or application, before allowing access.
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - slug
        - identifier
        - name
        - application_type
        - prefix
        - owner_type
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the resource
          type: string
        organization_id:
          description: Organization that owns this resource
          type: string
        zone_id:
          description: Zone this resource belongs to
          type: string
        slug:
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          minLength: 1
          maxLength: 63
          description: URL-safe identifier, unique within the zone
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          description: User specified identifier, unique within the zone
          x-audit: true
          type: string
        name:
          minLength: 1
          maxLength: 255
          description: Human-readable name
          x-audit: true
          type: string
        description:
          maxLength: 2048
          nullable: true
          description: Human-readable description
          x-audit: true
          type: string
        scopes:
          nullable: true
          description: Scopes supported by the resource
          x-audit: true
          type: array
          items:
            type: string
        credential_provider_id:
          description: ID of the credential provider for this resource
          type: string
        credential_provider:
          allOf:
            - $ref: '#/components/schemas/iam_Provider'
          deprecated: true
          description: >-
            Deprecated: Nested provider object. Use credential_provider_id to fetch provider separately. When this resource appears nested in another API response, this field will be undefined.
        application_id:
          description: ID of the application that provides this resource
          type: string
        application:
          allOf:
            - $ref: '#/components/schemas/iam_Application'
          deprecated: true
          description: >-
            Deprecated: Nested application object. Use application_id to fetch application separately. When this resource appears nested in another API response, this field will be undefined.
        application_type:
          type: string
          enum:
            - native
            - web
          description: >-
            The expected type of client for this credential. Native clients must use localhost URLs for redirect_uris or URIs with custom schemes. Web clients must use https URLs and must not use localhost as the hostname.
          x-audit: true
        prefix:
          description: >-
            When true, the resource identifier is treated as a URI prefix, protecting all URLs that share the identifier as a prefix at path/query/fragment boundaries. Protocol and hostname must match exactly. When multiple prefix resources satisfy an identifier query, the resource with the longest prefix is matched.
          x-audit: true
          type: boolean
        credential_lifetime_seconds:
          type: integer
          nullable: true
          minimum: 60
          maximum: 86400
          description: >-
            Credential lifetime override in seconds. When set, overrides the default credential lifetime for this resource. When absent, the default from the provider or zone is used.
          x-audit: true
        when_accessing:
          description: >-
            List of resource IDs that, when accessed, make this dependency available. Only present when this resource is returned as a dependency.
          type: array
          items:
            type: string
        metadata:
          allOf:
            - $ref: '#/components/schemas/iam_Metadata'
          x-audit: true
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >-
            Who owns this resource. Platform-owned resources cannot be modified via API.
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_ResourceCreate:
      title: Resource Create
      description: Schema for creating a new resource
      type: object
      required:
        - name
        - identifier
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: >-
            User specified identifier, unique within the zone. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        scopes:
          description: Scopes supported by the resource
          type: array
          items:
            minLength: 1
            type: string
        credential_provider_id:
          description: ID of the credential provider to associate with the resource
          type: string
        application_id:
          description: ID of the application that provides this resource
          type: string
        application_type:
          type: string
          enum:
            - native
            - web
          description: >-
            The expected type of client for this credential. Native clients must use localhost URLs for redirect_uris or URIs with custom schemes. Web clients must use https URLs and must not use localhost as the hostname.
        prefix:
          default: false
          description: >-
            When true, the resource identifier is treated as a URI prefix and protects all URLs that share the identifier as a prefix. Defaults to false: resources only match by exact identifier unless explicitly enabled.
          type: boolean
        credential_lifetime_seconds:
          minimum: 60
          maximum: 86400
          description: >-
            Credential lifetime override in seconds. When set, overrides the default credential lifetime for this resource.
          type: integer
        metadata:
          $ref: '#/components/schemas/iam_Metadata'
    iam_ResourceUpdate:
      title: Resource Update
      description: >-
        Schema for updating an existing resource (partial update).


        **Warning:** Changing the `identifier` field may break existing integrations and dependencies.
      type: object
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        scopes:
          nullable: true
          description: Scopes supported by the resource (set to null to unset)
          type: array
          items:
            minLength: 1
            type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: >-
            User specified identifier, unique within the zone. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        credential_provider_id:
          nullable: true
          description: >-
            ID of the credential provider to associate with the resource (set to null to unset)
          type: string
        application_id:
          nullable: true
          description: >-
            ID of the application that provides this resource (set to null to unset)
          type: string
        application_type:
          type: string
          enum:
            - native
            - web
          description: >-
            The expected type of client for this credential. Native clients must use localhost URLs for redirect_uris or URIs with custom schemes. Web clients must use https URLs and must not use localhost as the hostname.
        prefix:
          description: >-
            When true, the resource identifier is treated as a URI prefix, protecting all URLs that share the identifier as a prefix.
          type: boolean
        credential_lifetime_seconds:
          nullable: true
          minimum: 60
          maximum: 86400
          description: >-
            Credential lifetime override in seconds. Set to null to clear the override and use the default.
          type: integer
        metadata:
          $ref: '#/components/schemas/iam_MetadataUpdate'
    iam_ResourceTrait:
      type: string
      enum:
        - external
        - proxy
        - mcp-server
      title: Resource Trait
      description: >-
        Traits ascribe a role to a resource. `external` marks a resource whose identifier is a network locator hosted outside Keycard (access to which Keycard may protect), as opposed to a Keycard-hosted resource, a resource provided by a Keycard application, or a URN placeholder for a secret. `proxy` marks the Keycard-hosted proxy that fronts an `external` resource; together they mark the two sides of a proxied MCP. `mcp-server` marks a resource that speaks the MCP protocol at its endpoint (carried by both sides).
    iam_Application:
      title: Application
      description: >-
        An Application is a software system with an associated identity that can access Resources. It may act on its own behalf (machine-to-machine) or on behalf of a user (delegated access).
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - slug
        - identifier
        - name
        - dependencies_count
        - owner_type
        - consent
        - initiate_login_uri
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the application
          type: string
        organization_id:
          description: Organization that owns this application
          type: string
        zone_id:
          description: Zone this application belongs to
          type: string
        slug:
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          minLength: 1
          maxLength: 63
          description: URL-safe identifier, unique within the zone
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          description: User specified identifier, unique within the zone
          x-audit: true
          type: string
        name:
          minLength: 1
          maxLength: 255
          description: Human-readable name
          x-audit: true
          type: string
        description:
          maxLength: 2048
          nullable: true
          description: Human-readable description
          x-audit: true
          type: string
        metadata:
          $ref: '#/components/schemas/iam_Metadata'
        protocols:
          nullable: true
          additionalProperties: false
          description: Protocol-specific configuration
          x-audit: true
          type: object
          properties:
            oauth2:
              $ref: '#/components/schemas/iam_ApplicationOAuth2Protocol'
        dependencies_count:
          description: Number of resource dependencies
          type: integer
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >-
            Who owns this application. Platform-owned applications cannot be modified via API.
        consent:
          type: string
          enum:
            - implicit
            - required
          description: >-
            Consent mode for the application. 'implicit' means consent is automatically granted, 'required' means explicit user consent is needed.
          default: required
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_ApplicationCreate:
      title: Application Create
      description: Schema for creating a new application
      type: object
      required:
        - name
        - identifier
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: >-
            User specified identifier, unique within the zone. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        dependencies:
          description: Dependencies of the application
          type: array
          items:
            type: object
            required:
              - id
            properties:
              id:
                description: Resource identifier
                type: string
              type:
                type: string
        metadata:
          $ref: '#/components/schemas/iam_Metadata'
        protocols:
          $ref: '#/components/schemas/iam_ApplicationProtocolCreate'
        consent:
          type: string
          enum:
            - implicit
            - required
          description: Consent mode for the application. Defaults to 'required'.
          default: required
    iam_ApplicationUpdate:
      title: Application Update
      description: Schema for updating an existing application
      type: object
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: >-
            User specified identifier, unique within the zone. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        metadata:
          $ref: '#/components/schemas/iam_MetadataUpdate'
        protocols:
          $ref: '#/components/schemas/iam_ApplicationProtocolUpdate'
        consent:
          type: string
          enum:
            - implicit
            - required
          description: >-
            Consent mode for the application. 'implicit' means consent is automatically granted, 'required' means explicit user consent is needed.
    iam_ApplicationTrait:
      type: string
      enum:
        - gateway
        - mcp-provider
        - unified-gateway
        - mcp-server
      title: Application Trait
      description: >-
        Traits ascribe behaviors and characteristics to an application, which may activate trait-specific user experiences, workflows, or other system behaviors
    iam_UserAgent:
      title: User Agent
      description: >-
        A User Agent represents a user agent (browser, desktop app, CLI tool) that can initiate user sessions via OAuth 2.0 Dynamic Client Registration.
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - slug
        - identifier
        - name
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the user agent
          type: string
        organization_id:
          description: Organization that owns this user agent
          type: string
        zone_id:
          description: Zone this user agent belongs to
          type: string
        slug:
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          minLength: 1
          maxLength: 63
          description: URL-safe identifier, unique within the zone
          type: string
        identifier:
          description: >-
            User agent identifier (serves as OAuth client_id). Format: ua:{sha256_hash}
          x-audit: true
          type: string
        name:
          minLength: 1
          maxLength: 255
          description: Human-readable name
          x-audit: true
          type: string
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_ExternalSyncToken:
      title: External Sync Token
      description: >-
        Token an identity provider uses to provision users and groups into a zone over SCIM. The token value is returned once, when the token is created, and is never returned again.
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - provider_id
        - last_used_at
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the token
          x-audit: true
          type: string
        organization_id:
          description: Organization that owns this token
          type: string
        zone_id:
          description: Zone this token provisions users into
          type: string
        provider_id:
          description: Identity provider this token provisions users for
          x-audit: true
          type: string
        last_used_at:
          type: string
          format: date-time
          nullable: true
          description: When the token was last used. `null` if it has never been used.
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_ExternalSyncTokenCreateResponse:
      title: External Sync Token Create Response
      description: >-
        A new external sync token, including the token value. The value is returned only in this response.
      allOf:
        - $ref: '#/components/schemas/iam_ExternalSyncToken'
        - type: object
          required:
            - token
          properties:
            token:
              description: >-
                The token value to configure in the identity provider. Returned only when the token is created.
              type: string
    iam_ApplicationCredentialBaseFields:
      title: Application Credential Base Fields
      description: Common fields shared by all application credential types
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - slug
        - application_id
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the credential
          type: string
        organization_id:
          description: Organization that owns this credential
          type: string
        zone_id:
          description: Zone this credential belongs to
          type: string
        slug:
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          minLength: 1
          maxLength: 63
          description: URL-safe identifier, unique within the zone
          type: string
        application_id:
          description: ID of the application this credential belongs to
          x-audit: true
          type: string
        application:
          allOf:
            - $ref: '#/components/schemas/iam_Application'
          deprecated: true
          description: >-
            Deprecated: Nested application object. Use application_id to fetch application separately. When this credential appears nested in another API response, this field will be undefined.
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_ApplicationCredentialToken:
      title: Application Credential Token
      description: Token-based application credential
      allOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialBaseFields'
        - type: object
          required:
            - type
            - provider_id
            - identifier
          properties:
            type:
              x-audit: true
              type: string
              enum:
                - token
            provider_id:
              description: ID of the provider issuing tokens verified by this credential
              type: string
            provider:
              allOf:
                - $ref: '#/components/schemas/iam_Provider'
              deprecated: true
              description: >-
                Deprecated: Nested provider object. Use provider_id to fetch provider separately. When this credential appears nested in another API response, this field will be undefined.
            identifier:
              description: >-
                Identifier for this credential. For token type, this equals the subject value, or '*' when subject is not specified.
              x-audit: true
              type: string
            subject:
              nullable: true
              description: >-
                Subject identifier for the token. When null or omitted, any token from the provider is accepted without checking application-specific claims.
              type: string
    iam_ApplicationCredentialPassword:
      title: Application Credential Password
      description: Password-based application credential
      allOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialBaseFields'
        - type: object
          required:
            - type
            - identifier
          properties:
            type:
              x-audit: true
              type: string
              enum:
                - password
            identifier:
              description: >-
                Username for password credential, also used as OAuth 2.0 client ID
              x-audit: true
              type: string
            password:
              description: >-
                Password for credential (only returned on creation, store securely), also used as OAuth 2.0 client secret
              type: string
    iam_ApplicationCredentialPublicKey:
      title: Application Credential Public Key
      description: Public key-based application credential
      allOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialBaseFields'
        - type: object
          required:
            - type
            - identifier
            - jwks_uri
          properties:
            type:
              x-audit: true
              type: string
              enum:
                - public-key
            identifier:
              description: >-
                Client ID for public key credential, also used as OAuth 2.0 client ID
              x-audit: true
              type: string
            jwks_uri:
              format: uri
              description: JWKS URI to retrieve public keys from
              type: string
    iam_ApplicationCredentialUrl:
      title: Application Credential URL
      description: URL-based application credential
      allOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialBaseFields'
        - type: object
          required:
            - type
            - identifier
          properties:
            type:
              x-audit: true
              type: string
              enum:
                - url
            identifier:
              format: uri
              description: URL of the credential (must be a valid URL)
              x-audit: true
              type: string
    iam_ApplicationCredentialPublic:
      title: Application Credential Public
      description: Public credential (no secret storage)
      allOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialBaseFields'
        - type: object
          required:
            - type
            - identifier
          properties:
            type:
              x-audit: true
              type: string
              enum:
                - public
            identifier:
              description: >-
                Identifier for public credential, also used as OAuth 2.0 client ID
              x-audit: true
              type: string
    iam_ApplicationCredential:
      title: Application Credential
      description: Credentials for accessing external services from applications
      anyOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialToken'
        - $ref: '#/components/schemas/iam_ApplicationCredentialPassword'
        - $ref: '#/components/schemas/iam_ApplicationCredentialPublicKey'
        - $ref: '#/components/schemas/iam_ApplicationCredentialUrl'
        - $ref: '#/components/schemas/iam_ApplicationCredentialPublic'
    iam_ApplicationCredentialCreate:
      title: Application Credential Create
      description: Schema for creating a new application credential
      anyOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialCreateToken'
        - $ref: '#/components/schemas/iam_ApplicationCredentialCreatePassword'
        - $ref: '#/components/schemas/iam_ApplicationCredentialCreatePublicKey'
        - $ref: '#/components/schemas/iam_ApplicationCredentialCreateUrl'
        - $ref: '#/components/schemas/iam_ApplicationCredentialCreatePublic'
    iam_ApplicationCredentialCreateResponse:
      title: Application Credential Create Response
      description: Response for creating a new application credential
      anyOf:
        - $ref: '#/components/schemas/iam_ApplicationCredentialToken'
        - $ref: '#/components/schemas/iam_ApplicationCredentialPassword'
        - $ref: '#/components/schemas/iam_ApplicationCredentialPublicKey'
        - $ref: '#/components/schemas/iam_ApplicationCredentialUrl'
        - $ref: '#/components/schemas/iam_ApplicationCredentialPublic'
    iam_TokenCredentialUpdate:
      title: Token Credential Update
      description: Schema for updating a token credential
      type: object
      properties:
        type:
          type: string
          enum:
            - token
        subject:
          nullable: true
          description: >-
            Subject identifier for the token. Set to null to unset, which allows any token from the provider to be accepted without checking application-specific claims.
          type: string
    iam_PasswordCredentialUpdate:
      title: Password Credential Update
      description: Schema for updating a password credential
      type: object
      properties:
        type:
          type: string
          enum:
            - password
    iam_PublicKeyCredentialUpdate:
      title: Public Key Credential Update
      description: Schema for updating a public key credential
      type: object
      properties:
        type:
          type: string
          enum:
            - public-key
    iam_UrlCredentialUpdate:
      title: URL Credential Update
      description: Schema for updating a URL credential
      type: object
      properties:
        type:
          type: string
          enum:
            - url
        identifier:
          format: uri
          description: URL of the credential (must be a valid URL)
          type: string
    iam_PublicCredentialUpdate:
      title: Public Credential Update
      description: Schema for updating a public credential
      type: object
      properties:
        type:
          type: string
          enum:
            - public
        identifier:
          description: Identifier for public credential, also used as OAuth 2.0 client ID
          type: string
    iam_ApplicationCredentialUpdate:
      title: Application Credential Update
      description: Schema for updating an existing application credential
      anyOf:
        - $ref: '#/components/schemas/iam_TokenCredentialUpdate'
        - $ref: '#/components/schemas/iam_PasswordCredentialUpdate'
        - $ref: '#/components/schemas/iam_PublicKeyCredentialUpdate'
        - $ref: '#/components/schemas/iam_UrlCredentialUpdate'
        - $ref: '#/components/schemas/iam_PublicCredentialUpdate'
    iam_Zone:
      title: Zone
      description: A zone for organizing resources within an organization
      type: object
      required:
        - id
        - organization_id
        - slug
        - name
        - password_login_enabled
        - password_tenant
        - default_application_id
        - external_sync_enabled
        - protocols
        - owner_type
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the zone
          type: string
        organization_id:
          description: Organization that owns this zone
          type: string
        slug:
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
          minLength: 1
          maxLength: 63
          description: URL-safe identifier, unique within the zone
          type: string
        name:
          minLength: 1
          maxLength: 255
          description: Human-readable name
          x-audit: true
          type: string
        description:
          maxLength: 2048
          nullable: true
          description: Human-readable description
          x-audit: true
          type: string
        user_identity_provider_id:
          description: Provider ID configured for user login
          type: string
        external_sync_enabled:
          description: >-
            Whether external directory sync (SCIM) is enabled for this zone. Required to create external sync tokens.
          type: boolean
        protocols:
          description: Protocol configuration for a zone
          type: object
          required:
            - oauth2
            - openid
          properties:
            oauth2:
              $ref: '#/components/schemas/iam_ZoneOAuth2Protocol'
            openid:
              $ref: '#/components/schemas/iam_ZoneOpenIDProtocol'
        encryption_key:
          $ref: '#/components/schemas/iam_EncryptionKeyAwsKmsConfig'
        default_mcp_gateway_application_id:
          description: Application ID configured as the default MCP Gateway for the zone
          type: string
        default_resource_id:
          description: Resource ID configured as the default resource for the zone
          type: string
        permissions:
          $ref: '#/components/schemas/iam_Permissions'
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: Who owns this zone. Platform-owned zones cannot be modified via API.
          readOnly: true
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_ZoneCreate:
      title: Zone Create
      description: Schema for creating a new zone
      type: object
      required:
        - name
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        organization_id:
          description: >-
            Target organization ID. Required for platform principals (whose tokens carry no organization claim); for organization-scoped principals it is optional and must match the authenticated organization if supplied.
          type: string
        protocols:
          $ref: '#/components/schemas/iam_ZoneProtocolCreate'
        encryption_key:
          $ref: '#/components/schemas/iam_EncryptionKeyAwsKmsConfig'
        default_mcp_gateway_application:
          description: Assign a default MCP Gateway application to the zone
          default: true
          type: boolean
    iam_ZoneUpdate:
      title: Zone Update
      description: Schema for updating an existing zone (partial update)
      type: object
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: >-
            Human-readable name. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        description:
          maxLength: 2048
          nullable: true
          format: safe-text
          description: >-
            Human-readable description. Must not contain HTML tags (e.g. `<script>`, `<div>`) or control characters.
          type: string
        external_sync_enabled:
          description: >-
            Turns external directory sync (SCIM) on or off for this zone. Required to create external sync tokens.
          type: boolean
        user_identity_provider_id:
          nullable: true
          description: Provider ID to configure for user login (set to null to unset)
          type: string
        protocols:
          $ref: '#/components/schemas/iam_ZoneProtocolUpdate'
        encryption_key:
          $ref: '#/components/schemas/iam_EncryptionKeyAwsKmsConfigUpdate'
        default_mcp_gateway_application_id:
          nullable: true
          description: >-
            Application ID configured as the default MCP Gateway for the zone (set to null to unset)
          type: string
        default_resource_id:
          nullable: true
          description: >-
            Resource ID to configure as the default resource for the zone (set to null to unset)
          type: string
    iam_RoleIdentifier:
      title: Role Identifier
      pattern: ^[a-z0-9]+(?:[-_][a-z0-9]+)*$
      minLength: 1
      maxLength: 255
      description: >-
        Role identifier: a lowercase slug (letters and digits separated by single hyphens or underscores), unique per owner type within a zone. Role identifiers surface in policy evaluation, so the slug restriction keeps them unambiguous in policy text.
      type: string
    iam_Group:
      title: Group
      description: >-
        A zone-scoped group of users, assignable to roles and usable in policies. Roles assigned to a group are inherited by its members. `external` is false for groups managed in Keycard and true for groups synced from an external directory.
      type: object
      required:
        - id
        - zone_id
        - organization_id
        - identifier
        - name
        - external
        - external_issuer
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the group
          type: string
        zone_id:
          description: Zone this group belongs to
          type: string
        organization_id:
          description: Organization this group belongs to
          type: string
        identifier:
          description: >-
            User-specified identifier, unique within the zone. Automatically assigned for groups from an external directory.
          x-audit: true
          type: string
        name:
          description: Human-readable group name
          x-audit: true
          type: string
        external:
          description: >-
            Whether the group is synced from an external directory over SCIM. When true the group is directory-owned and its membership is read-only while the zone has `external_sync_enabled` set.
          x-audit: true
          type: boolean
        external_issuer:
          type: string
          nullable: true
          description: >-
            Issuer of the external directory the group was synced from. `null` for groups managed in Keycard. Read-only: set by external sync, never by the caller.
          x-audit: true
        member_count:
          description: >-
            Number of users in the group. Included only when requested via `expand[]=member_count` (group get or list).
          type: integer
        roles:
          description: >-
            Identifiers of the roles assigned to the group; members inherit them. Deduped across scopes. Included only when requested via `expand[]=roles` (group get or list).
          type: array
          items:
            type: string
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_GroupCreate:
      title: Group Create
      additionalProperties: false
      description: >-
        Schema for creating a group in Keycard. Groups synced from an external directory are created by that directory, not through this endpoint.
      type: object
      required:
        - name
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: Human-readable group name
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: >-
            User-specified identifier, unique within the zone. Derived from the name when omitted (a suffix is appended if it collides).
          type: string
    iam_GroupUpdate:
      title: Group Update
      additionalProperties: false
      description: Schema for updating a group.
      type: object
      properties:
        name:
          minLength: 1
          maxLength: 255
          format: safe-text
          description: Human-readable group name
          type: string
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: User-specified identifier, unique within the zone.
          type: string
    iam_GroupMemberCreate:
      title: Group Member Create
      additionalProperties: false
      description: Schema for adding a user to a group
      type: object
      required:
        - user_id
      properties:
        user_id:
          description: ID of the user to add to the group
          type: string
    iam_Role:
      title: Role
      description: A role that can be assigned to users within a zone.
      type: object
      required:
        - id
        - zone_id
        - identifier
        - owner_type
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the role
          type: string
        zone_id:
          description: Zone this role belongs to
          type: string
        identifier:
          $ref: '#/components/schemas/iam_RoleIdentifier'
        description:
          maxLength: 1000
          nullable: true
          description: Human-readable description
          type: string
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >-
            Who owns this role. Platform-owned roles are managed by Keycard and cannot be modified or deleted via the API; customer-owned roles are user-created.
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_RoleCreate:
      title: Role Create
      description: Schema for creating a new role
      type: object
      required:
        - identifier
      properties:
        identifier:
          $ref: '#/components/schemas/iam_RoleIdentifier'
        description:
          maxLength: 1000
          description: Human-readable description
          type: string
    iam_RoleUpdate:
      title: Role Update
      description: Schema for updating an existing role. The role identifier is immutable.
      type: object
      properties:
        description:
          maxLength: 1000
          nullable: true
          description: Human-readable description (set to null to unset)
          type: string
    iam_RoleAssignment:
      title: Role Assignment
      description: Represents a role assigned to a principal within a zone
      type: object
      required:
        - id
        - zone_id
        - principal_type
        - principal_id
        - role_id
        - role_identifier
        - role_owner_type
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the role assignment
          type: string
        zone_id:
          description: Zone this assignment belongs to
          type: string
        principal_type:
          description: >-
            The kind of principal the role is assigned to: `user`, `application`, or `group`. A role assigned to a `group` is inherited by that group's members.
          type: string
        principal_id:
          description: >-
            ID of the principal the role is assigned to (a user, application, or group ID).
          type: string
        role_id:
          description: ID of the assigned role
          type: string
        role_identifier:
          $ref: '#/components/schemas/iam_RoleIdentifier'
        role_owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >-
            Owner type of the assigned role. Disambiguates roles that share an identifier across owner types.
        scope_type:
          nullable: true
          description: >-
            The kind of resource this grant is scoped to (e.g. `zone`). Null when the assignment is unscoped (applies to the owning zone itself).
          type: string
        scope_id:
          nullable: true
          description: The ID of the scoped resource. Null when the assignment is unscoped.
          type: string
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_RoleAssignmentScopeGroup:
      title: Role Assignment Scope Group
      description: A principal's role assignments on one requested scope.
      type: object
      required:
        - scope_type
        - scope_id
        - assignments
      properties:
        scope_type:
          type: string
          nullable: true
          description: >-
            The requested `scope_type` this group answers for. `null` for the unscoped group (grants that apply to the zone itself).
        scope_id:
          type: string
          nullable: true
          description: >-
            The requested scope ID this group answers for. `null` for the unscoped group.
        assignments:
          description: >-
            Every role assignment the principal holds on this scope; empty when it holds none.
          type: array
          items:
            $ref: '#/components/schemas/iam_RoleAssignment'
    iam_RoleAssignmentScopeGroupList:
      title: Role Assignment Scope Group List
      description: >-
        Role assignments keyed by requested scope. Not paginated: the number of groups equals the number of scopes named in the request.
      type: object
      required:
        - items
      properties:
        items:
          description: >-
            One group per requested scope, in request order (the unscoped group first when `unscoped=true`).
          type: array
          items:
            $ref: '#/components/schemas/iam_RoleAssignmentScopeGroup'
    iam_RoleAssignmentCreate:
      title: Role Assignment Create
      additionalProperties: false
      description: >-
        Schema for assigning a role to a principal. Provide exactly one of role_id or role_identifier. When role_identifier is used, owner_type is required to disambiguate roles that share an identifier across owner types; owner_type must be omitted when role_id is used.
      type: object
      properties:
        role_id:
          description: >-
            ID of the role to assign. Provide exactly one of role_id or role_identifier; owner_type must be omitted when role_id is used.
          type: string
        role_identifier:
          allOf:
            - $ref: '#/components/schemas/iam_RoleIdentifier'
          description: >-
            Opaque identifier of the role to assign. Provide exactly one of role_id or role_identifier; owner_type is required when role_identifier is used.
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >-
            Owner type of the role to assign. Required with role_identifier (an identifier is unique only per owner type); must be omitted with role_id.
        scope_type:
          minLength: 1
          description: >-
            The kind of resource to scope the grant to (e.g. `zone`). Provide together with scope_id, or omit both for an unscoped assignment (applies to the owning zone itself). Only platform roles on the org zone may carry a scope.
          type: string
        scope_id:
          minLength: 1
          description: >-
            The ID of the resource to scope the grant to. Provide together with scope_type, or omit both for an unscoped assignment. When scope_type is `zone`, this must reference a different zone in the same organization.
          type: string
    iam_UserRoleAssignment:
      title: User Role Assignment
      description: A role granted to a user within a zone.
      type: object
      required:
        - role_id
        - role_identifier
        - role_owner_type
        - scope
        - source
      properties:
        role_id:
          description: ID of the assigned role
          type: string
        role_identifier:
          $ref: '#/components/schemas/iam_RoleIdentifier'
        role_owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >-
            Owner type of the granted role. Disambiguates roles that share an identifier across owner types.
        scope:
          type: object
          nullable: true
          properties:
            type:
              type: string
              description: The kind of resource this grant is scoped to (e.g. `zone`).
            id:
              type: string
              description: The ID of the scoped resource.
          required:
            - type
            - id
          description: >-
            The resource this grant is scoped to, or null when the grant is unscoped (applies to the owning zone itself).
        source:
          type: string
          enum:
            - user
            - group
          description: >-
            The principal that holds this grant: `user` when assigned directly to the user, or `group` when inherited through group membership.
        group_id:
          description: >-
            ID of the group this grant is inherited from. Present only when `source` is `group`.
          type: string
    iam_UserGroup:
      title: User Group
      description: A group a user belongs to within a zone.
      type: object
      required:
        - id
        - identifier
        - name
        - external
        - external_issuer
      properties:
        id:
          description: Unique identifier of the group
          type: string
        identifier:
          description: Zone-unique slug that policy rules match on.
          type: string
        name:
          description: Human-readable group name
          type: string
        external:
          description: >-
            Whether the group is synced from an external directory. When true the group is directory-owned and its membership is read-only; when false it is managed in Keycard.
          type: boolean
        external_issuer:
          type: string
          nullable: true
          description: >-
            Issuer of the external directory the group was synced from. `null` for groups managed in Keycard. Read-only: set by external sync, never by the caller.
    iam_UserCredentialBaseFields:
      title: User Credential Base Fields
      description: Common fields shared by all user credential types
      type: object
      required:
        - created_at
        - updated_at
      properties:
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
    iam_UserCredentialFederation:
      title: User Credential Federation
      description: >-
        Federation credential: the user authenticates through an identity provider.
      allOf:
        - $ref: '#/components/schemas/iam_UserCredentialBaseFields'
        - type: object
          required:
            - type
            - provider_id
          properties:
            type:
              type: string
              enum:
                - federation
            subject:
              description: Subject identifier from the identity provider.
              type: string
            issuer:
              description: Issuer identifier of the identity provider.
              type: string
            provider_id:
              type: string
              nullable: true
              description: >-
                ID of the identity provider backing this credential. `null` when the source provider has been deleted.
            provider:
              allOf:
                - $ref: '#/components/schemas/iam_Provider'
              description: >-
                The identity provider backing this credential. Populated only when `expand[]=credentials.provider` is set and the credential references an existing provider.
    iam_UserCredentialPassword:
      title: User Credential Password
      description: >-
        Password credential: the user authenticates with email and password. The email lives on the user.
      allOf:
        - $ref: '#/components/schemas/iam_UserCredentialBaseFields'
        - type: object
          required:
            - type
          properties:
            type:
              type: string
              enum:
                - password
    iam_UserCredential:
      title: User Credential
      description: An authentication credential belonging to a user.
      anyOf:
        - $ref: '#/components/schemas/iam_UserCredentialFederation'
        - $ref: '#/components/schemas/iam_UserCredentialPassword'
    iam_User:
      title: User
      description: An authenticated user entity
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - identifier
        - email
        - email_verified
        - status
        - external
        - created_at
        - updated_at
      properties:
        id:
          description: Unique identifier of the user
          type: string
        organization_id:
          description: Organization that owns this user
          type: string
        zone_id:
          description: Zone this user belongs to
          type: string
        identifier:
          description: >-
            Zone-scoped user identifier. Defaults to the user's Keycard ID. When the provider has user_identifier_claim configured, the value is set from that claim at user creation time.
          x-audit: true
          type: string
        subject:
          description: Subject identifier from the identity provider
          x-audit: true
          type: string
        issuer:
          description: Issuer identifier of the identity provider
          x-audit: true
          type: string
        email:
          format: email
          description: Email address of the user
          x-audit: true
          type: string
        email_verified:
          description: Whether the email address has been verified
          type: boolean
        status:
          type: string
          enum:
            - active
            - disabled
          description: Status of the user. Disabled users cannot authenticate.
          x-audit: true
        external:
          description: >-
            Whether the user is synced from an external directory over SCIM. When true the user is directory-owned: `status` cannot be changed and the user cannot be deleted through this API while the zone has `external_sync_enabled` set.
          x-audit: true
          type: boolean
        provider_id:
          description: >-
            Reference to the identity provider. This field is undefined when the source identity provider is deleted but the user is not deleted.
          type: string
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
        authenticated_at:
          description: Date when the user was last authenticated
          type: string
        session_count:
          minimum: 0
          description: >-
            Session count for this user. Populated only when `expand[]=session_count` is set on the listing endpoint.
          type: integer
        grant_count:
          minimum: 0
          description: >-
            Delegated-grant count for this user. Populated only when `expand[]=grant_count` is set on the listing endpoint.
          type: integer
        role_assignments:
          description: >-
            Role grants for this user within the zone. Populated only when `expand[]=role-assignments` is set on the listing endpoint.
          type: array
          items:
            $ref: '#/components/schemas/iam_UserRoleAssignment'
        groups:
          description: >-
            Groups this user belongs to within the zone. Populated only when `expand[]=groups` is set on the listing endpoint.
          type: array
          items:
            $ref: '#/components/schemas/iam_UserGroup'
        credentials:
          description: >-
            Authentication credentials for this user, each carrying its identity provider for federation credentials. Populated only when `expand[]=credentials` is set on the listing endpoint.
          type: array
          items:
            $ref: '#/components/schemas/iam_UserCredential'
    iam_GroupMember:
      title: Group Member
      description: A user's membership in a group
      type: object
      required:
        - user_id
        - created_at
      properties:
        user_id:
          description: ID of the user
          x-audit: true
          type: string
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        user:
          allOf:
            - $ref: '#/components/schemas/iam_User'
          description: The user. Included only when requested via `expand[]=user`.
    iam_UserUpdate:
      title: User Update
      description: Schema for updating an existing user
      type: object
      properties:
        identifier:
          minLength: 1
          maxLength: 2048
          format: safe-text
          description: Zone-scoped user identifier
          type: string
        status:
          type: string
          enum:
            - active
            - disabled
          description: >-
            Status of the user. Set to `disabled` to prevent the user from authenticating and revoke their active sessions, or `active` to re-enable.
    iam_UserSessionType:
      title: User Session Type
      description: User session type-specific fields
      type: object
      required:
        - session_type
        - user_id
      properties:
        session_type:
          type: string
          enum:
            - user
        user_id:
          description: User ID
          x-audit: true
          type: string
        application_id:
          description: Application ID that initiated this session
          x-audit: true
          type: string
        user_agent_id:
          description: User agent ID (browser/client) that initiated this session
          type: string
        user:
          allOf:
            - $ref: '#/components/schemas/iam_User'
          deprecated: true
          description: >-
            Deprecated: Nested user object. Use user_id to fetch user separately. This nested object does not contain further nested relations.
        application:
          allOf:
            - $ref: '#/components/schemas/iam_Application'
          deprecated: true
          description: >-
            Deprecated: Nested application object. Use application_id to fetch application separately. This nested object does not contain further nested relations.
        user_agent:
          allOf:
            - $ref: '#/components/schemas/iam_UserAgent'
          deprecated: true
          description: >-
            Deprecated: Nested user agent object. Use user_agent_id to fetch user agent separately. This nested object does not contain further nested relations.
        provider_id:
          description: Provider ID
          x-audit: true
          type: string
        subject:
          description: Subject claim from IdP
          x-audit: true
          type: string
        issuer:
          format: uri
          description: Issuer URL from IdP
          x-audit: true
          type: string
        parent_id:
          description: >-
            Parent session ID for hierarchical sessions (user sessions only). When null, this is a web session - a top-level session initiated directly by a user. When set, this is a child session derived from the parent, used for token refresh or delegation. Application sessions cannot have parents.
          x-audit: true
          type: string
    iam_ApplicationSessionType:
      title: Application Session Type
      description: Application session type-specific fields
      type: object
      required:
        - session_type
        - application_id
        - provider_id
        - subject
        - issuer
      properties:
        session_type:
          type: string
          enum:
            - application
        application_id:
          description: Application ID that initiated this session
          x-audit: true
          type: string
        application:
          allOf:
            - $ref: '#/components/schemas/iam_Application'
          deprecated: true
          description: >-
            Deprecated: Nested application object. Use application_id to fetch application separately. This nested object does not contain further nested relations.
        provider_id:
          description: Provider ID
          x-audit: true
          type: string
        subject:
          description: Subject claim from IdP
          x-audit: true
          type: string
        issuer:
          format: uri
          description: Issuer URL from IdP
          x-audit: true
          type: string
    iam_Session:
      title: Session
      description: >-
        An authenticated identity session. Sessions can be user sessions (representing end-user authentication) or application sessions (representing service-to-service authentication). User sessions support hierarchical relationships via parent_id, while application sessions are always standalone.
      allOf:
        - type: object
          required:
            - id
            - organization_id
            - zone_id
            - created_at
            - updated_at
            - expires_at
            - metadata
          properties:
            id:
              description: Session ID
              type: string
            organization_id:
              description: Organization that owns this session
              type: string
            zone_id:
              description: Zone this session belongs to
              type: string
            created_at:
              format: date-time
              description: Entity creation timestamp
              type: string
            authenticated_at:
              format: date-time
              description: Date when the session was authenticated
              type: string
            updated_at:
              format: date-time
              description: Entity update timestamp
              type: string
            expires_at:
              format: date-time
              description: Date when session expires
              x-audit: true
              type: string
            session_data:
              description: >-
                Session claims data (ID token claims for users, application claims for applications)
              type: object
              additionalProperties: {}
            metadata:
              description: Session metadata
              type: object
              required:
                - name
              properties:
                name:
                  description: Name of the initiating application or user agent
                  type: string
            status:
              type: string
              enum:
                - active
                - expired
                - revoked
              x-audit: true
            active:
              deprecated: true
              description: >-
                Whether the session is currently active (deprecated - use status instead)
              type: boolean
        - anyOf:
            - $ref: '#/components/schemas/iam_UserSessionType'
            - $ref: '#/components/schemas/iam_ApplicationSessionType'
    iam_DelegatedGrant:
      title: Delegated Grant
      description: >-
        User authorization for a resource to be accessed on their behalf. The grant links the user, resource, and the provider that issued the grant.
      type: object
      required:
        - id
        - organization_id
        - zone_id
        - user_id
        - resource_id
        - provider_id
        - scopes
        - created_at
        - updated_at
        - expires_at
        - status
        - refresh_token_set
      properties:
        id:
          description: Unique identifier of the delegated grant
          type: string
        organization_id:
          description: Organization that owns this grant
          type: string
        zone_id:
          description: Zone this grant belongs to
          type: string
        user_id:
          description: Reference to the user granting permission
          x-audit: true
          type: string
        resource_id:
          description: ID of resource receiving grant
          x-audit: true
          type: string
        provider_id:
          description: ID of the provider that issued this grant
          x-audit: true
          type: string
        scopes:
          description: Granted OAuth scopes
          x-audit: true
          type: array
          items:
            type: string
        created_at:
          format: date-time
          description: Entity creation timestamp
          type: string
        updated_at:
          format: date-time
          description: Entity update timestamp
          type: string
        expires_at:
          format: date-time
          description: Date when grant expires
          x-audit: true
          type: string
        status:
          type: string
          enum:
            - active
            - expired
            - revoked
          x-audit: true
        refreshed_at:
          format: date-time
          description: >-
            Timestamp when this grant's tokens were last refreshed. Omitted if grant was never refreshed.
          type: string
        refresh_token_set:
          description: >-
            Indicates whether a refresh token is stored for this grant. Grants with refresh tokens can be refreshed even after access token expiration.
          type: boolean
        active:
          deprecated: true
          description: >-
            Whether the grant is currently active (deprecated - use status instead)
          type: boolean
        resource:
          allOf:
            - $ref: '#/components/schemas/iam_Resource'
          deprecated: true
          description: >-
            Deprecated: Nested resource object. Use resource_id to fetch resource separately. This nested object does not contain further nested relations.
        user:
          allOf:
            - $ref: '#/components/schemas/iam_User'
          deprecated: true
          description: >-
            Deprecated: Nested user object. Use user_id to fetch user separately. This nested object does not contain further nested relations.
        provider:
          allOf:
            - $ref: '#/components/schemas/iam_Provider'
          deprecated: true
          description: >-
            Deprecated: Nested provider object. Use provider_id to fetch provider separately. This nested object does not contain further nested relations.
    iam_SessionResourceAccess:
      title: Session Resource Access
      description: Aggregated record of session-resource access events
      type: object
      required:
        - session_id
        - resource_id
        - organization_id
        - total_access_count
        - first_accessed_at
        - last_accessed_at
      properties:
        session_id:
          description: Session ID
          type: string
        resource_id:
          description: Resource ID
          type: string
        organization_id:
          description: Organization ID
          type: string
        total_access_count:
          description: Total number of access events for this session-resource pair
          type: integer
        first_accessed_at:
          format: date-time
          description: When access first occurred
          type: string
        last_accessed_at:
          format: date-time
          description: When access most recently occurred
          type: string
    iam_SessionResourceAccessList:
      title: Session Resource Access List
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/iam_SessionResourceAccess'
        pagination:
          $ref: '#/components/schemas/iam_Pagination'
    org-management_OrganizationStatus:
      type: string
      description: Status of organization membership
      enum:
        - active
        - disabled
      x-enum-varnames:
        - Active
        - Disabled
    org-management_InvitationStatus:
      type: string
      description: Status of an invitation
      enum:
        - pending
        - accepted
        - expired
        - revoked
      x-enum-varnames:
        - Pending
        - Accepted
        - Expired
        - Revoked
    org-management_OrganizationIdOrLabel:
      type: string
      description: Organization ID or label identifier
      minLength: 1
      maxLength: 255
    org-management_ShortID:
      type: string
      description: |
        Identifier for API resources. A 26-char nanoid (URL/DNS safe).
      minLength: 1
      maxLength: 255
      example: ab3def8hij2klm9opq5rst7uvw
    org-management_Cursor:
      type: string
      description: Pagination cursor for navigating through results
      minLength: 1
      maxLength: 255
    org-management_PageInfo:
      type: object
      description: Pagination information using cursor-based pagination
      required:
        - has_next_page
        - has_prev_page
      properties:
        has_next_page:
          type: boolean
          description: Whether there are more items after the current page
        has_prev_page:
          type: boolean
          description: Whether there are more items before the current page
        start_cursor:
          $ref: '#/components/schemas/org-management_Cursor'
          description: Cursor pointing to the first item in the current page
        end_cursor:
          $ref: '#/components/schemas/org-management_Cursor'
          description: Cursor pointing to the last item in the current page
      additionalProperties: false
    org-management_CreateOrganizationRequest:
      type: object
      properties:
        name:
          $ref: '#/components/schemas/org-management_Name'
          description: Organization name
      additionalProperties: false
    org-management_UpdateOrganizationRequest:
      type: object
      properties:
        name:
          $ref: '#/components/schemas/org-management_Name'
          description: Organization name
      additionalProperties: false
    org-management_SyncOrganizationRoleRequest:
      type: object
      required:
        - role
      properties:
        role:
          $ref: '#/components/schemas/org-management_OrganizationRole'
          description: Org role to apply to the user
        groups:
          type: array
          items:
            $ref: '#/components/schemas/org-management_ShortID'
          description: |
            Full set of group public IDs the user currently belongs to in this
            organization. Optional for backward compatibility: when omitted the
            user's group memberships are left untouched; when present (including
            an empty array) it is authoritative and the user's group memberships
            for this organization are replaced to exactly this set.
      additionalProperties: false
    org-management_SyncOrganizationGroupRequest:
      type: object
      properties:
        role:
          $ref: '#/components/schemas/org-management_OrganizationRole'
          description: |
            Org role the group grants its members. Omit to record the group
            without granting any org role.
      additionalProperties: false
    org-management_OrganizationGroup:
      type: object
      required:
        - id
      properties:
        id:
          $ref: '#/components/schemas/org-management_ShortID'
        role:
          $ref: '#/components/schemas/org-management_OrganizationRole'
          description: Org role the group grants its members, if any.
      additionalProperties: false
    org-management_Permissions:
      type: object
      description: >
        Permissions granted to the authenticated principal for this resource.

        Only populated when the 'expand[]=permissions' query parameter is provided.

        Keys are resource types (e.g., "organizations"), values are objects mapping

        permission names to boolean values indicating if the permission is granted.

      additionalProperties:
        type: object
        additionalProperties:
          type: boolean
      example:
        organizations:
          read: true
          update: true
        users:
          read: true
          list: true
    org-management_Organization:
      type: object
      required:
        - id
        - name
        - label
        - sso_enabled
        - zone_id
        - created_at
        - updated_at
      properties:
        id:
          $ref: '#/components/schemas/org-management_ShortID'
        name:
          $ref: '#/components/schemas/org-management_Name'
        label:
          $ref: '#/components/schemas/org-management_Label'
          readOnly: true
        sso_enabled:
          type: boolean
          description: Whether SSO is enabled for this organization
          readOnly: true
        zone_id:
          type: string
          description: |
            Identifier of the zone containing this organization's users and
            their permissions and roles in the organization.
          readOnly: true
        created_at:
          $ref: '#/components/schemas/org-management_CreatedAt'
        updated_at:
          $ref: '#/components/schemas/org-management_UpdatedAt'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_OrganizationsList:
      type: object
      required:
        - items
        - page_info
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/org-management_Organization'
        page_info:
          allOf:
            - $ref: '#/components/schemas/org-management_PageInfo'
          deprecated: true
          description: Deprecated — use `pagination` (the cross-service envelope) instead.
        pagination:
          $ref: '#/components/schemas/org-management_Pagination'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_OrganizationRole:
      type: string
      enum:
        - org_admin
        - org_member
        - org_viewer
      description: User's role in the organization
    org-management_OrganizationUser:
      type: object
      required:
        - id
        - role
        - status
        - source
        - created_at
        - updated_at
      properties:
        id:
          $ref: '#/components/schemas/org-management_ShortID'
          description: The keycard account ID
        email:
          type: string
          format: email
          description: User email address
        role:
          $ref: '#/components/schemas/org-management_OrganizationRole'
        source:
          type: string
          format: uri
          description: Identity provider issuer
        status:
          $ref: '#/components/schemas/org-management_OrganizationStatus'
        created_at:
          $ref: '#/components/schemas/org-management_CreatedAt'
        updated_at:
          $ref: '#/components/schemas/org-management_UpdatedAt'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_CreateInvitationRequest:
      type: object
      required:
        - email
        - role
      properties:
        email:
          type: string
          format: email
          description: Email address to invite
        role:
          $ref: '#/components/schemas/org-management_OrganizationRole'
          description: Role to assign when invitation is accepted
      additionalProperties: false
    org-management_Invitation:
      type: object
      required:
        - id
        - email
        - organization_id
        - created_at
        - updated_at
        - created_by
        - role
        - status
        - expires_at
      properties:
        id:
          $ref: '#/components/schemas/org-management_ShortID'
        email:
          type: string
          format: email
          description: Email address for the invitation
        organization_id:
          $ref: '#/components/schemas/org-management_ShortID'
        created_at:
          $ref: '#/components/schemas/org-management_CreatedAt'
        updated_at:
          $ref: '#/components/schemas/org-management_UpdatedAt'
        created_by:
          $ref: '#/components/schemas/org-management_ShortID'
          description: ID of the user who created the invitation
        role:
          $ref: '#/components/schemas/org-management_OrganizationRole'
          description: Role that will be assigned when invitation is accepted
        status:
          $ref: '#/components/schemas/org-management_InvitationStatus'
        expires_at:
          type: string
          format: date-time
          description: When the invitation expires
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_InvitationDetails:
      type: object
      description: Public invitation details viewable by token
      required:
        - email
        - organization_name
        - created_by_name
        - role
        - expires_at
        - status
      properties:
        email:
          type: string
          format: email
          description: Email address for the invitation
        organization_name:
          $ref: '#/components/schemas/org-management_Name'
          description: Name of the organization being invited to
        created_by_name:
          $ref: '#/components/schemas/org-management_Name'
          description: Name of the user who sent the invitation
        role:
          $ref: '#/components/schemas/org-management_OrganizationRole'
          description: Role that will be assigned when invitation is accepted
        expires_at:
          type: string
          format: date-time
          description: When the invitation expires
        status:
          $ref: '#/components/schemas/org-management_InvitationStatus'
      additionalProperties: false
    org-management_InvitationAcceptResult:
      type: object
      description: Result of accepting an invitation
      required:
        - success
        - organization_id
        - organization_name
      properties:
        success:
          type: boolean
          description: Whether the invitation was successfully accepted
        organization_id:
          $ref: '#/components/schemas/org-management_ShortID'
          description: ID of the organization joined
        organization_name:
          $ref: '#/components/schemas/org-management_Name'
          description: Name of the organization joined
        user_id:
          $ref: '#/components/schemas/org-management_ShortID'
          description: ID of the user who accepted the invitation
      additionalProperties: false
    org-management_InvitationsList:
      type: object
      required:
        - items
        - page_info
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/org-management_Invitation'
        page_info:
          $ref: '#/components/schemas/org-management_PageInfo'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_TokenResponse:
      type: object
      description: OAuth2-style token response for M2M tokens
      required:
        - access_token
        - token_type
      properties:
        access_token:
          type: string
          description: The M2M access token
        token_type:
          type: string
          description: Token type (always "Bearer")
          example: Bearer
        expires_in:
          type: integer
          description: Token expiration time in seconds
          example: 3600
      additionalProperties: false
    org-management_CreateServiceAccountRequest:
      type: object
      required:
        - name
      properties:
        name:
          $ref: '#/components/schemas/org-management_Name'
          description: Service account name
        description:
          type: string
          description: Optional description of the service account
          maxLength: 500
      additionalProperties: false
    org-management_UpdateServiceAccountRequest:
      type: object
      properties:
        name:
          $ref: '#/components/schemas/org-management_Name'
          description: Service account name
        description:
          type: string
          description: Optional description of the service account
          maxLength: 500
      additionalProperties: false
    org-management_ServiceAccount:
      type: object
      required:
        - id
        - name
        - created_at
        - updated_at
      properties:
        id:
          $ref: '#/components/schemas/org-management_ShortID'
        name:
          $ref: '#/components/schemas/org-management_Name'
        description:
          type: string
          description: Optional description of the service account
        created_at:
          $ref: '#/components/schemas/org-management_CreatedAt'
        updated_at:
          $ref: '#/components/schemas/org-management_UpdatedAt'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_ServiceAccountsList:
      type: object
      required:
        - items
        - page_info
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/org-management_ServiceAccount'
        page_info:
          allOf:
            - $ref: '#/components/schemas/org-management_PageInfo'
          deprecated: true
          description: Deprecated — use `pagination` (the cross-service envelope) instead.
        pagination:
          $ref: '#/components/schemas/org-management_Pagination'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_CreateServiceAccountCredentialRequest:
      type: object
      required:
        - name
      properties:
        name:
          $ref: '#/components/schemas/org-management_Name'
          description: Credential name
        description:
          type: string
          description: Optional description of the credential
          maxLength: 500
      additionalProperties: false
    org-management_UpdateServiceAccountCredentialRequest:
      type: object
      properties:
        name:
          $ref: '#/components/schemas/org-management_Name'
          description: Credential name
        description:
          type: string
          description: Optional description of the credential
          maxLength: 500
      additionalProperties: false
    org-management_ServiceAccountCredential:
      type: object
      description: Service account credential (without secret)
      required:
        - id
        - name
        - client_id
        - created_at
      properties:
        id:
          $ref: '#/components/schemas/org-management_ShortID'
        name:
          $ref: '#/components/schemas/org-management_Name'
        client_id:
          type: string
          description: The client ID for authentication
          example: A1b2C3d4E5f6G7h8I9j0K
        description:
          type: string
          description: Optional description of the credential
        created_at:
          $ref: '#/components/schemas/org-management_CreatedAt'
        last_used_at:
          type: string
          format: date-time
          description: When the credential was last used
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_ServiceAccountCredentialWithSecret:
      type: object
      description: >-
        Service account credential with plaintext secret (only returned on creation)
      required:
        - id
        - name
        - client_id
        - client_secret
        - created_at
      properties:
        id:
          $ref: '#/components/schemas/org-management_ShortID'
        name:
          $ref: '#/components/schemas/org-management_Name'
        client_id:
          type: string
          description: The client ID for authentication
          example: A1b2C3d4E5f6G7h8I9j0K
        client_secret:
          type: string
          description: The client secret
          example: a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V2w3X4y5Z6A7B8c9D0e1F2
        description:
          type: string
          description: Optional description of the credential
        created_at:
          $ref: '#/components/schemas/org-management_CreatedAt'
      additionalProperties: false
    org-management_ServiceAccountCredentialsList:
      type: object
      required:
        - items
        - page_info
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/org-management_ServiceAccountCredential'
        page_info:
          allOf:
            - $ref: '#/components/schemas/org-management_PageInfo'
          deprecated: true
          description: Deprecated — use `pagination` (the cross-service envelope) instead.
        pagination:
          $ref: '#/components/schemas/org-management_Pagination'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_AWSKeyPolicy:
      type: object
      description: AWS KMS key policy for use with customer-managed KMS encryption keys
      required:
        - policy
      properties:
        policy:
          type: string
          description: JSON-encoded key policy that can be used for AWS KMS keys
          example: >-
            {"Statement":[{"Sid":"Enable IAM User Permissions","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::111122223333:root"},"Action":"kms:*","Resource":"*"}]}
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_SSOConnectionProtocolOAuth2:
      type: object
      description: OAuth 2.0 protocol configuration for SSO connection
      nullable: true
      properties:
        authorization_endpoint:
          type: string
          format: uri
          nullable: true
          description: OAuth 2.0 authorization endpoint
        token_endpoint:
          type: string
          format: uri
          nullable: true
          description: OAuth 2.0 token endpoint
        registration_endpoint:
          type: string
          format: uri
          nullable: true
          description: OAuth 2.0 registration endpoint
        jwks_uri:
          type: string
          format: uri
          nullable: true
          description: JSON Web Key Set endpoint
        code_challenge_methods_supported:
          type: array
          nullable: true
          items:
            type: string
          description: Supported PKCE code challenge methods
        scopes_supported:
          type: array
          nullable: true
          items:
            type: string
          description: Supported OAuth 2.0 scopes
        authorization_parameters:
          type: object
          nullable: true
          additionalProperties:
            type: string
          description: >-
            Custom query parameters appended to authorization redirect URLs. Use for non-standard providers (e.g. Google prompt=consent, access_type=offline).
      additionalProperties: false
    org-management_SSOConnectionProtocolOpenID:
      type: object
      description: OpenID Connect protocol configuration for SSO connection
      nullable: true
      properties:
        userinfo_endpoint:
          type: string
          format: uri
          nullable: true
          description: OpenID Connect UserInfo endpoint
        user_identifier_claim:
          type: string
          nullable: true
          description: >-
            Name of a top-level string claim in the provider's ID Token to use as the user identifier on user creation. When not set, the user's Keycard ID is used.
        scopes:
          type: array
          nullable: true
          items:
            type: string
          description: >-
            Additional OIDC scopes to request from this provider during authentication (e.g. "groups"). Merged with the default scopes (openid, profile, email).
      additionalProperties: false
    org-management_SSOConnectionProtocol:
      type: object
      description: Protocol configuration for SSO connection
      nullable: true
      properties:
        oauth2:
          $ref: '#/components/schemas/org-management_SSOConnectionProtocolOAuth2'
        openid:
          $ref: '#/components/schemas/org-management_SSOConnectionProtocolOpenID'
      additionalProperties: false
    org-management_SSOConnectionProtocolOAuth2Update:
      type: object
      description: >-
        OAuth 2.0 protocol configuration for an SSO connection update. Each field is tri-state, omit to leave unchanged, send null to clear, send a value to set.
      nullable: true
      properties:
        authorization_endpoint:
          type: string
          format: uri
          nullable: true
          description: OAuth 2.0 authorization endpoint. Set to null to clear.
          x-go-type: nullable.Nullable[string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        token_endpoint:
          type: string
          format: uri
          nullable: true
          description: OAuth 2.0 token endpoint. Set to null to clear.
          x-go-type: nullable.Nullable[string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        registration_endpoint:
          type: string
          format: uri
          nullable: true
          description: OAuth 2.0 registration endpoint. Set to null to clear.
          x-go-type: nullable.Nullable[string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        jwks_uri:
          type: string
          format: uri
          nullable: true
          description: JSON Web Key Set endpoint. Set to null to clear.
          x-go-type: nullable.Nullable[string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        code_challenge_methods_supported:
          type: array
          nullable: true
          items:
            type: string
          description: Supported PKCE code challenge methods. Set to null to clear.
          x-go-type: nullable.Nullable[[]string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        scopes_supported:
          type: array
          nullable: true
          items:
            type: string
          description: Supported OAuth 2.0 scopes. Set to null to clear.
          x-go-type: nullable.Nullable[[]string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        authorization_parameters:
          type: object
          nullable: true
          additionalProperties:
            type: string
          description: >-
            Custom query parameters appended to authorization redirect URLs. Use for non-standard providers (e.g. Google prompt=consent, access_type=offline). Set to null to clear.
          x-go-type: nullable.Nullable[map[string]string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
      additionalProperties: false
    org-management_SSOConnectionProtocolOpenIDUpdate:
      type: object
      description: >-
        OpenID Connect protocol configuration for an SSO connection update. Each field is tri-state, omit to leave unchanged, send null to clear, send a value to set.
      nullable: true
      properties:
        userinfo_endpoint:
          type: string
          format: uri
          nullable: true
          description: OpenID Connect UserInfo endpoint. Set to null to clear.
          x-go-type: nullable.Nullable[string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        user_identifier_claim:
          type: string
          nullable: true
          description: >-
            Name of a top-level string claim in the provider's ID Token to use as the user identifier on user creation. Set to null to clear.
          x-go-type: nullable.Nullable[string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
        scopes:
          type: array
          nullable: true
          items:
            type: string
          description: >-
            Additional OIDC scopes to request from this provider during authentication (e.g. "groups"). Merged with the default scopes (openid, profile, email). Set to null to clear.
          x-go-type: nullable.Nullable[[]string]
          x-go-type-skip-optional-pointer: true
          x-go-type-import:
            path: github.com/oapi-codegen/nullable
          x-omitempty: true
      additionalProperties: false
    org-management_SSOConnectionProtocolUpdate:
      type: object
      description: >-
        Protocol configuration for an SSO connection update. Omit a protocol to leave it unchanged.
      nullable: true
      properties:
        oauth2:
          $ref: '#/components/schemas/org-management_SSOConnectionProtocolOAuth2Update'
        openid:
          $ref: '#/components/schemas/org-management_SSOConnectionProtocolOpenIDUpdate'
      additionalProperties: false
    org-management_SSOConnection:
      type: object
      description: SSO connection configuration for an organization
      required:
        - id
        - identifier
        - client_id
        - client_secret_set
        - created_at
        - updated_at
      properties:
        id:
          type: string
          description: Unique identifier for the SSO connection
        identifier:
          type: string
          minLength: 1
          maxLength: 2048
          description: SSO provider identifier (e.g., issuer URL)
        client_id:
          type: string
          nullable: true
          description: OAuth 2.0 client ID
        client_secret_set:
          type: boolean
          description: Whether a client secret is configured
        protocols:
          $ref: '#/components/schemas/org-management_SSOConnectionProtocol'
        created_at:
          $ref: '#/components/schemas/org-management_CreatedAt'
        updated_at:
          $ref: '#/components/schemas/org-management_UpdatedAt'
        permissions:
          $ref: '#/components/schemas/org-management_Permissions'
      additionalProperties: false
    org-management_SSOConnectionCreate:
      type: object
      description: Schema for creating an SSO connection
      required:
        - identifier
        - client_id
      properties:
        identifier:
          type: string
          minLength: 1
          maxLength: 2048
          description: SSO provider identifier (e.g., issuer URL)
        client_id:
          type: string
          description: OAuth 2.0 client ID
        client_secret:
          type: string
          description: OAuth 2.0 client secret (optional, will be encrypted if provided)
        protocols:
          $ref: '#/components/schemas/org-management_SSOConnectionProtocol'
      additionalProperties: false
    org-management_SSOConnectionUpdate:
      type: object
      description: Schema for updating an SSO connection
      properties:
        identifier:
          type: string
          minLength: 1
          maxLength: 2048
          description: SSO provider identifier (e.g., issuer URL)
        client_id:
          type: string
          description: OAuth 2.0 client ID (set to null to remove)
        client_secret:
          type: string
          description: OAuth 2.0 client secret (set to null to remove)
        protocols:
          $ref: '#/components/schemas/org-management_SSOConnectionProtocolUpdate'
      additionalProperties: false
    org-management_ErrorCode:
      type: string
      enum:
        - validation_error
        - bad_request
        - unauthorized
        - forbidden
        - not_found
        - conflict
        - rate_limit_exceeded
        - internal_error
        - not_implemented
        - service_unavailable
      x-enum-varnames:
        - ValidationErrorCode
        - BadRequestErrorCode
        - UnauthorizedErrorCode
        - ForbiddenErrorCode
        - NotFoundErrorCode
        - ConflictErrorCode
        - RateLimitExceededErrorCode
        - InternalErrorCode
        - NotImplementedErrorCode
        - ServiceUnavailableErrorCode
      x-go-type: httperrors.ErrorCode
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    org-management_ErrorDetail:
      type: object
      properties:
        field:
          type: string
          description: >-
            valid json path for request body. Omitted when the detail is not tied to a request field (e.g. domain error codes); clients should treat absent and empty the same.
        message:
          type: string
          description: error message for specific error
        code:
          anyOf:
            - $ref: '#/components/schemas/org-management_ErrorCode'
            - type: string
          description: >-
            Machine-readable code. Either a common `ErrorCode` value or a service-specific domain code (snake_case) documented by the service's own API spec. Clients should match on this instead of parsing `message`. Open set; unknown codes must be tolerated.
          example: version_currently_bound
      required:
        - message
        - code
      additionalProperties: false
      x-go-type: httperrors.ErrorDetail
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    org-management_Error:
      type: object
      description: Represents an error that has occurred in the Keycard system.
      properties:
        status:
          type: integer
          description: HTTP Status Code
        code:
          $ref: '#/components/schemas/org-management_ErrorCode'
        message:
          type: string
          description: summary of the error
        request_id:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
        path:
          type: string
          format: url
        details:
          type: array
          items:
            $ref: '#/components/schemas/org-management_ErrorDetail'
      additionalProperties: false
      required:
        - status
        - code
        - message
        - request_id
        - timestamp
        - path
        - details
      x-go-type: httperrors.Error
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    org-management_Name:
      type: string
      description: A name for the entity to be displayed in UI
      pattern: ^[a-zA-Z][a-zA-Z0-9\s,\.'\-pL\ \-_]{1,63}$
      x-go-type: types.Name
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    org-management_Label:
      type: string
      description: A domain name segment for the entity, often derived from the name.
      pattern: ^([a-z0-9]+(-[a-z0-9]+)+)$
      maxLength: 63
      x-go-type: types.Label
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    org-management_CreatedAt:
      type: string
      description: The time the entity was created in utc
      format: date-time
    org-management_UpdatedAt:
      type: string
      description: The time the entity was mostly recently updated in utc
      format: date-time
    org-management_PaginationCursor:
      type: string
      description: An opaque cursor used for paginating through a list of results
      minLength: 1
      maxLength: 255
      x-go-type: types.PaginationCursor
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    org-management_Pagination:
      type: object
      description: Cursor-based pagination metadata returned alongside a list of results
      properties:
        before_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/org-management_PaginationCursor'
        after_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/org-management_PaginationCursor'
        total_count:
          type: integer
          description: >-
            Total number of items across all pages. Only present when the request includes ?expand[]=total_count.
      required:
        - before_cursor
        - after_cursor
      additionalProperties: false
      x-go-type: types.Pagination
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    pdp_ExpandField:
      type: string
      enum:
        - total_count
        - user
      x-enum-varnames:
        - ExpandFieldTotalCount
        - ExpandFieldUser
      description: >-
        Opt-in response field requested via `expand[]` on list endpoints. `total_count` adds `pagination.total_count`; `user` adds a `*_user` object beside every `created_by`, `updated_by` and `archived_by` field that resolves to an organization user.
    pdp_ExpandSingleField:
      type: string
      enum:
        - user
      x-enum-varnames:
        - ExpandSingleFieldUser
      description: >-
        Opt-in response field requested via `expand[]` on single-resource reads. `user` behaves as described on `ExpandField`.
    pdp_User:
      type: object
      description: >-
        The organization user behind a `created_by`, `updated_by` or `archived_by` value. Returned only when `expand[]=user` is requested.
      required:
        - id
        - zone_id
        - email
      properties:
        id:
          type: string
          description: >-
            Public ID of the user in the organization's platform zone. This is not the same value as the `*_by` field it expands; use it to link to `/zones/{zone_id}/users/{id}`.
        zone_id:
          type: string
          description: Public ID of the organization's platform zone the user belongs to.
        email:
          type: string
          nullable: true
          description: The user's email address, or null when not known.
      additionalProperties: false
    pdp_Policy:
      type: object
      required:
        - id
        - zone_id
        - name
        - created_at
        - updated_at
        - created_by
        - owner_type
      properties:
        id:
          type: string
        zone_id:
          type: string
        name:
          type: string
        description:
          type: string
          nullable: true
        archived_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        created_by:
          type: string
        created_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `created_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        updated_by:
          type: string
          nullable: true
        updated_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `updated_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        latest_version_id:
          type: string
          nullable: true
        latest_version:
          type: integer
          nullable: true
          description: Human-readable version number of the latest version (e.g., 1, 2, 3)
        latest_schema_version:
          type: string
          nullable: true
          description: |
            Schema version the latest version was validated against (e.g.,
            "2026-02-24"). Null when the policy has no published versions.
            Denormalized from `PolicyVersion.schema_version` for the policy
            referenced by `latest_version_id`.
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: |
            Who manages this policy:
            - `"platform"` — managed by the Keycard platform (system policies).
            - `"customer"` — managed by the tenant (custom policies).
      additionalProperties: false
    pdp_PolicyVersion:
      type: object
      required:
        - id
        - policy_id
        - zone_id
        - version
        - schema_version
        - sha
        - created_at
        - created_by
        - owner_type
      properties:
        id:
          type: string
        policy_id:
          type: string
        zone_id:
          type: string
        version:
          type: integer
        schema_version:
          type: string
          description: Schema version this policy was validated against when created.
        cedar_json:
          type: object
          nullable: true
          x-go-type: json.RawMessage
          description: |
            Cedar policy in JSON representation. Populated by default
            and when `format=json` is passed; null when `format=cedar`
            narrows the response to the text representation only.
            Serialized verbatim from the stored Cedar so the order of
            `staticPolicies` matches the source policy order (ACC-613).
        cedar_raw:
          type: string
          nullable: true
          description: |
            Cedar policy in human-readable syntax. Populated by default
            and when `format=cedar` is passed; null when `format=json`
            narrows the response to the JSON representation only.
        sha:
          type: string
          description: Hex-encoded content hash
        archived_at:
          type: string
          format: date-time
          nullable: true
        archived_by:
          type: string
          nullable: true
        archived_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `archived_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        created_at:
          type: string
          format: date-time
        created_by:
          type: string
        created_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `created_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >
            Who manages this policy version:

            - `"platform"` — managed by the Keycard platform (system policy versions).

            - `"customer"` — managed by the tenant (custom policy versions).

      additionalProperties: false
    pdp_PolicyDraft:
      type: object
      required:
        - policy_id
        - schema_version
        - created_at
        - updated_at
        - updated_by
      properties:
        policy_id:
          type: string
        cedar_json:
          type: object
          nullable: true
          x-go-type: json.RawMessage
          description: |
            Cedar policy in JSON representation. Populated by default
            and when `format=json` is passed; null when `format=cedar`
            narrows the response to the text representation only.
            Serialized verbatim from the converted Cedar so the order of
            `staticPolicies` matches the source policy order (ACC-613).
        cedar_raw:
          type: string
          nullable: true
          description: |
            Cedar policy in human-readable syntax. Populated by default
            and when `format=cedar` is passed; null when `format=json`
            narrows the response to the JSON representation only.
        schema_version:
          type: string
        base_version_id:
          type: string
          nullable: true
          description: >-
            ID of the policy version this draft was hydrated from. Null when the draft was created without an existing version.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        updated_by:
          type: string
        updated_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `updated_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
      additionalProperties: false
    pdp_SchemaVersion:
      type: object
      description: |
        A versioned Cedar schema that defines the entity model, actions, and
        context shape used for policy evaluation. The schema contains the valid
        entity types (User, Application, Resource), their attributes, and the
        allowed attribute values. See the Credentials API spec for a full
        reference of entity attributes and valid values.
      required:
        - version
        - status
        - created_at
        - updated_at
      properties:
        version:
          type: string
        status:
          type: string
          enum:
            - active
            - deprecated
            - archived
          description: >
            Controls what can be done with this schema version:

            - `"active"` - new policy versions can be created and validated against it.

            - `"deprecated"` - superseded by a newer version but still accepts new policy versions.

            - `"archived"` - closed to new policy versions. Existing policy set versions pinned to this schema still evaluate normally.

        cedar_schema:
          type: string
          nullable: true
          description: Cedar schema in human-readable syntax. Populated when format=cedar.
        cedar_schema_json:
          type: object
          nullable: true
          description: Cedar schema as JSON object. Populated when format=json (default).
        deprecated_at:
          type: string
          format: date-time
          nullable: true
        archived_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      additionalProperties: false
    pdp_SchemaVersionWithZoneInfo:
      allOf:
        - $ref: '#/components/schemas/pdp_SchemaVersion'
        - type: object
          required:
            - is_default
          properties:
            is_default:
              type: boolean
              description: >-
                Whether this is the zone's default schema. Clients use this to pre-select which schema to write policies against. Has no effect on evaluation.
    pdp_PolicySet:
      type: object
      required:
        - id
        - zone_id
        - name
        - target_type
        - scope_type
        - created_at
        - updated_at
        - created_by
        - owner_type
      properties:
        id:
          type: string
        zone_id:
          type: string
        name:
          type: string
        scope_type:
          type: string
          enum:
            - zone
            - resource
            - user
            - session
          deprecated: true
          description: |
            **Deprecated.** Use `target_type` instead. Carries the same value.
        target_type:
          type: string
          enum:
            - zone
            - user
          description: |
            What this policy set targets:
            - `"zone"` — applies to all requests in the zone.
            - `"user"` — scoped to a specific user.

            `resource` and `session` are reserved; legacy sets with those
            scopes carry them in the deprecated `scope_type` field.
        latest_version_id:
          type: string
          nullable: true
        latest_version:
          type: integer
          nullable: true
          description: Human-readable version number of the latest version (e.g., 1, 2, 3)
        archived_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        created_by:
          type: string
        created_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `created_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        updated_by:
          type: string
          nullable: true
        updated_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `updated_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: |
            Who manages this policy set:
            - `"platform"` — managed by the Keycard platform (system policies).
            - `"customer"` — managed by the tenant (custom policies).
      additionalProperties: false
    pdp_PolicySetWithBinding:
      allOf:
        - $ref: '#/components/schemas/pdp_PolicySet'
        - type: object
          properties:
            scope_target_id:
              type: string
              nullable: true
              deprecated: true
              description: |
                **Deprecated.** Use `target_id` instead. Carries the
                active binding's target; null when unbound.
            target_id:
              type: string
              nullable: true
              description: |
                Target entity ID. Equals `zone_id` for zone-targeted sets;
                the principal identifier for principal-scoped sets. Null
                only for legacy non-zone sets that predate target tracking.
            mode:
              type: string
              enum:
                - active
                - shadow
              nullable: true
            active:
              type: boolean
              description: Whether this policy set is currently bound to a scope
            active_version_id:
              type: string
              nullable: true
              description: Public ID of the currently active (bound) version
            active_version:
              type: integer
              nullable: true
              description: >-
                Human-readable version number of the active version (e.g., 1, 2, 3)
            shadow_version_id:
              type: string
              nullable: true
              description: Public ID of the shadow (observed) version, if any
            shadow_version:
              type: integer
              nullable: true
              description: Human-readable version number of the shadow version
            policy_set_version:
              allOf:
                - $ref: '#/components/schemas/pdp_PolicySetVersion'
              description: First version, present only when created with a manifest.
            changes:
              type: array
              description: Per-policy outcomes, present only when created with a manifest.
              items:
                $ref: '#/components/schemas/pdp_ApplyChange'
            warnings:
              type: array
              description: Non-fatal findings, present only when non-empty on create.
              items:
                $ref: '#/components/schemas/pdp_ApplyWarning'
            binding:
              allOf:
                - $ref: '#/components/schemas/pdp_PolicySetBinding'
              description: >-
                Active zone binding, present when created with `manifest.activate` set to true.
    pdp_Attestation:
      type: object
      description: >
        JWS Flattened JSON Serialization (RFC 7515 §7.2.2) of a policy set attestation. The protected header carries the signing algorithm and key identifier; the payload is a base64url-encoded AttestationStatement canonicalized per RFC 8785 (JCS). Verify using the zone JWKS endpoint (RFC 7517). Currently signed with RS256; future zone key types (e.g. EdDSA) will be indicated by the "alg" header — no envelope changes required.

      required:
        - payload
        - protected
        - signature
      properties:
        payload:
          type: string
          description: >
            Base64url-encoded AttestationStatement (RFC 7515 §3). Decode to inspect attestation content. The RFC 8785 canonical form of the decoded JSON is the JWS Signing Input alongside the protected header.

        protected:
          type: string
          description: >
            Base64url-encoded JWS protected header (RFC 7515 §4). Contains at minimum "alg" (signing algorithm — currently RS256, will migrate to EdDSA) and "kid" (signing key identifier resolvable via the zone JWKS endpoint).

        signature:
          type: string
          description: >
            Base64url-encoded digital signature computed over the JWS Signing Input (ASCII(protected) || '.' || payload) per RFC 7515 §5.1.

      additionalProperties: false
    pdp_AttestationStatement:
      type: object
      description: >
        Decoded content of an Attestation JWS payload. Describes the exact policy set version composition at attestation time. This schema defines what consumers see after base64url-decoding the Attestation.payload field.

      required:
        - v
        - type
        - zone_id
        - policy_set_id
        - policy_set_version
        - manifest_sha
        - status
        - attested_at
        - attested_by
        - key_id
      properties:
        v:
          type: integer
          description: Statement schema version
          enum:
            - 1
        type:
          type: string
          description: Statement type discriminator
          enum:
            - policy_set_attestation
        zone_id:
          type: string
        policy_set_id:
          type: string
        policy_set_version:
          type: integer
        manifest_sha:
          type: string
          description: >
            SHA-256 of the policy set version manifest. Verifiers MUST check this matches the policy_set_version.manifest_sha to detect attestation/version mismatches.

        status:
          type: string
          description: >
            Event that produced this attestation. "created" is the initial attestation at version creation; "re_signed" is a re-attestation after key rotation (same content, new signature).

          enum:
            - created
            - re_signed
        attested_at:
          type: string
          format: date-time
        attested_by:
          type: string
        key_id:
          type: string
          description: >
            Key ID of the signing key used to produce the attestation signature. Matches the "kid" in the JWS protected header.

      additionalProperties: false
    pdp_PolicySetManifest:
      type: object
      required:
        - entries
      properties:
        entries:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicySetManifestEntry'
      additionalProperties: false
    pdp_PolicySetManifestEntry:
      type: object
      required:
        - policy_id
        - policy_version_id
      properties:
        policy_id:
          type: string
        policy_version_id:
          type: string
        sha:
          type: string
          description: SHA-256 of the policy version content, populated by the server
      additionalProperties: false
    pdp_InlinePolicySetManifest:
      type: object
      description: >
        Inline policy-set manifest used by the `manifest` variant of PolicySource. Mirrors the shape of a stored policy set version's manifest so a policy set under construction (no stored id/version) can be tested without being saved first. The `sha` field on each entry is ignored on input and recomputed server-side.

      required:
        - entries
        - schema_version
      properties:
        entries:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/pdp_PolicySetManifestEntry'
        schema_version:
          type: string
          description: Cedar schema version the entries are validated against.
      additionalProperties: false
    pdp_PolicySetManifestDetail:
      type: object
      description: >-
        Readback shape of a policy set version's manifest, richer than the write shape: each entry carries the resolved policy version ID and content SHA.
      required:
        - policy_set_id
        - entries
      properties:
        policy_set_id:
          type: string
        policy_set_version_id:
          type: string
          nullable: true
          description: Null only for a policy set with no versions yet.
        version:
          type: integer
          nullable: true
          description: Monotonic version number. Null when no versions exist yet.
        schema_version:
          type: string
          nullable: true
          description: Null when no versions exist yet.
        manifest_sha:
          type: string
          nullable: true
          description: >-
            JCS SHA-256 digest of the stored manifest of the returned version. Null when no versions exist yet. On the default latest read this is the same value the `ETag` header carries.
        entries:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicySetManifestEntry'
      additionalProperties: false
    pdp_ApplyPolicySetManifestRequest:
      type: object
      description: The full desired state of the policy set's content. Omitted = dropped.
      required:
        - entries
      properties:
        schema_version:
          type: string
          description: >-
            Cedar schema version to validate and pin the resulting version against. Omitted: the server resolves it (latest version's schema if still writable, else the zone default).
        activate:
          type: boolean
          default: false
          description: >-
            Also rebind the zone/active slot to the resulting version in the same transaction. Requires the `activate` permission on policy set bindings. Targets only the zone/active slot; other slots go through PUT /policy-bindings.
        entries:
          type: array
          description: >-
            Complete desired content. Order is preserved for newly added policies; retained policies keep their current manifest order (so an unchanged apply reproduces the identical manifest and dedups).
          items:
            $ref: '#/components/schemas/pdp_ApplyManifestEntry'
      additionalProperties: false
    pdp_ApplyManifestEntry:
      oneOf:
        - $ref: '#/components/schemas/pdp_ExistingPolicyEntry'
        - $ref: '#/components/schemas/pdp_NewPolicyEntry'
    pdp_ExistingPolicyEntry:
      type: object
      description: >-
        Reference to an existing (non-archived) policy in the zone — not limited to policies already in this set.

        With `cedar_raw`/`cedar_json` (mutually exclusive): the server diffs by content SHA; unchanged content under the resolved schema reuses the pinned policy version, changed content mints a new one.

        Without content ("pin as-is"): reuses the version pinned in the latest manifest, or the policy's latest version when the policy is newly added to this set. Bare pins are re-versioned when the resolved schema differs from the pinned version's schema.

        With `policy_version_id`: pins exactly that existing version and mints nothing. Mutually exclusive with `cedar_raw`/`cedar_json` (a version is content; 400 when both are supplied). The version must belong to `policy_id`, must not be archived (`version_archived`), and must have been validated against the resolved schema (`schema_version_mismatch`; no re-versioning). Reported as `repinned` when the set already pins a different version of the policy, otherwise `reused`.

        Platform-owned policies accept bare pins and `policy_version_id` (customers cannot mint versions of those).
      required:
        - policy_id
      properties:
        policy_id:
          type: string
          description: Public ID of an existing policy in the zone.
        policy_version_id:
          type: string
          description: >-
            Public ID of an existing version of `policy_id` to pin. Mutually exclusive with cedar_raw and cedar_json.
        cedar_raw:
          type: string
          description: Cedar policy text. Mutually exclusive with cedar_json.
        cedar_json:
          type: object
          description: Cedar policy JSON. Mutually exclusive with cedar_raw.
      additionalProperties: false
    pdp_NewPolicyEntry:
      type: object
      description: >-
        Mints a new customer-owned policy with the requested name (409 `policy_name_conflict` on collision) plus its first version from the supplied content. Exactly one of `cedar_raw`/`cedar_json` is required.
      required:
        - new_policy
      properties:
        new_policy:
          type: object
          required:
            - name
          properties:
            name:
              type: string
            description:
              type: string
          additionalProperties: false
        cedar_raw:
          type: string
          description: Cedar policy text. Mutually exclusive with cedar_json.
        cedar_json:
          type: object
          description: Cedar policy JSON. Mutually exclusive with cedar_raw.
      additionalProperties: false
    pdp_ApplyPolicySetManifestResult:
      type: object
      required:
        - created
        - changes
      properties:
        policy_set_version:
          allOf:
            - $ref: '#/components/schemas/pdp_PolicySetVersion'
          description: The resulting version. Omitted on dry_run.
        created:
          type: boolean
          description: >-
            True when the server mints a new policy set version. False when the content matches the latest version, even when activate changes the active binding. Reverts to older content mint a new version at the tip and return true.
        changes:
          type: array
          description: Per-policy outcome of the diff.
          items:
            $ref: '#/components/schemas/pdp_ApplyChange'
        warnings:
          type: array
          description: >-
            Non-fatal findings — e.g. Cedar actions unknown to the resolved schema. Present only when non-empty.
          items:
            $ref: '#/components/schemas/pdp_ApplyWarning'
        binding:
          allOf:
            - $ref: '#/components/schemas/pdp_PolicySetBinding'
          description: Present when activate was true.
      additionalProperties: false
    pdp_ApplyChange:
      type: object
      required:
        - policy_id
        - name
        - action
      properties:
        policy_id:
          type: string
        name:
          type: string
          description: >-
            The policy's name. Lets a caller correlate a `created_policy` row with its `new_policy` request entry without a re-list.
        action:
          type: string
          enum:
            - created_policy
            - created_version
            - reused
            - repinned
            - dropped
          description: >-
            `repinned`: an explicit `policy_version_id` replaced a different version the set already pinned for that policy; no version minted.
        policy_version_id:
          type: string
          description: Absent when action is dropped.
      additionalProperties: false
    pdp_ApplyWarning:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine-readable warning code, e.g. unknown_actions.
        message:
          type: string
      additionalProperties: false
    pdp_ClonePolicySetRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          description: >-
            Name of the new policy set. 409 `policy_set_name_conflict` on collision.
        target_type:
          type: string
          enum:
            - zone
            - user
          description: Defaults to the source set's target type.
        source_version_id:
          type: string
          description: |
            Policy set version public ID on the source set. Defaults to the
            source's latest non-archived version.
        copy_policies:
          type: string
          enum:
            - none
            - platform
            - all
          default: platform
          description: |
            Which pinned policies are duplicated as new customer-owned policies.
            `none` shares every pin; `platform` copies platform-owned pins and
            shares customer-owned ones; `all` copies every pin.
      additionalProperties: false
    pdp_ClonePolicySetResult:
      type: object
      required:
        - policy_set
        - policy_set_version
        - policies
      properties:
        policy_set:
          allOf:
            - $ref: '#/components/schemas/pdp_PolicySetWithBinding'
          description: >-
            The new set. `latest_version_id` is the first version; it is unbound.
        policy_set_version:
          allOf:
            - $ref: '#/components/schemas/pdp_PolicySetVersion'
          description: The new set's first version, with manifest and attestation.
        policies:
          type: array
          description: One row per manifest entry, in manifest order.
          items:
            $ref: '#/components/schemas/pdp_ClonedPolicyEntry'
      additionalProperties: false
    pdp_ClonedPolicyEntry:
      type: object
      required:
        - source_policy_id
        - policy_id
        - policy_version_id
        - name
        - action
      properties:
        source_policy_id:
          type: string
          description: Public ID of the policy pinned by the source version.
        policy_id:
          type: string
          description: >-
            Public ID of the policy pinned by the clone. Equals `source_policy_id` when `shared`.
        policy_version_id:
          type: string
          description: >-
            Public ID of the pinned policy version. Equals the source's when `shared`.
        name:
          type: string
          description: The pinned policy's name (the derived name when `copied`).
        action:
          type: string
          enum:
            - shared
            - copied
      additionalProperties: false
    pdp_PolicySetVersion:
      type: object
      required:
        - id
        - policy_set_id
        - version
        - schema_version
        - manifest
        - manifest_sha
        - created_at
        - created_by
        - owner_type
      properties:
        id:
          type: string
        policy_set_id:
          type: string
        version:
          type: integer
        schema_version:
          type: string
          description: >
            Schema version pinned to this policy set version. Determines the Cedar

            schema used for evaluation when activated.

        manifest:
          $ref: '#/components/schemas/pdp_PolicySetManifest'
        manifest_sha:
          type: string
          description: Hex-encoded SHA-256 of the canonicalized manifest
        attestation:
          type: object
          nullable: true
          allOf:
            - $ref: '#/components/schemas/pdp_AttestationStatement'
        active:
          type: boolean
          description: >-
            Whether this policy set version is currently bound with mode='active'. Always populated in responses; clients must treat absence as unknown rather than inferring 'not bound'.
        archived_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            Timestamp when the version was archived. Non-null only for archived versions; null or absent means not archived.
        archived_by:
          type: string
          nullable: true
          description: >-
            Identifier of the actor that archived the version. Null or absent means not archived.
        archived_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `archived_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        created_at:
          type: string
          format: date-time
        created_by:
          type: string
        created_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `created_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        owner_type:
          type: string
          enum:
            - platform
            - customer
          description: >
            Who manages this policy set version:

            - `"platform"` — managed by the Keycard platform (system policy set versions).

            - `"customer"` — managed by the tenant (custom policy set versions).

      additionalProperties: false
    pdp_PolicySetDraft:
      type: object
      required:
        - policy_set_id
        - manifest
        - schema_version
        - created_at
        - updated_at
        - updated_by
      properties:
        policy_set_id:
          type: string
        manifest:
          $ref: '#/components/schemas/pdp_PolicySetManifest'
        schema_version:
          type: string
        name:
          type: string
          nullable: true
        description:
          type: string
          nullable: true
        base_version_id:
          type: string
          nullable: true
          description: >-
            ID of the policy set version this draft was hydrated from. Null when the draft was created without an existing version.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        updated_by:
          type: string
        updated_by_user:
          allOf:
            - $ref: '#/components/schemas/pdp_User'
          description: >-
            The organization user behind `updated_by`. Present only when `expand[]=user` is requested and the value resolves to a user; absent for system actors and unresolvable values.
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicySetDraftManifestWarning'
          description: >-
            Warnings about manifest entries that would prevent creating a version from this draft. Present only when there are warnings; omitted when empty.
      additionalProperties: false
    pdp_PolicySetDraftManifestWarning:
      type: object
      required:
        - policy_id
        - policy_version_id
        - type
        - message
      properties:
        policy_id:
          type: string
        policy_version_id:
          type: string
        type:
          $ref: '#/components/schemas/pdp_ManifestWarningType'
        message:
          type: string
          description: >-
            Human-readable description of the warning, e.g. 'validated against schema "2026-02-24", draft targets "2026-03-16"' or 'policy version is archived'.
        detail:
          allOf:
            - $ref: '#/components/schemas/pdp_ManifestWarningDetail'
          description: >-
            Structured detail payload. Present for warning types that carry additional context (e.g. schema_version_mismatch includes the two schema versions). Omitted when the type alone is sufficient (e.g. policy_version_archived).
      additionalProperties: false
    pdp_ManifestWarningType:
      type: string
      enum:
        - policy_version_archived
        - schema_version_mismatch
    pdp_ManifestWarningDetail:
      type: object
      description: >-
        Additional structured context for a manifest warning. The shape depends on the warning type.
      properties:
        policy_schema_version:
          type: string
          description: >-
            Schema version the policy version was validated against. Present only for schema_version_mismatch warnings.
        draft_schema_version:
          type: string
          description: >-
            Schema version the draft targets. Present only for schema_version_mismatch warnings.
      additionalProperties: false
    pdp_PoliciesList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/pdp_Policy'
        pagination:
          $ref: '#/components/schemas/pdp_Pagination'
      additionalProperties: false
    pdp_PolicyVersionsList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicyVersion'
        pagination:
          $ref: '#/components/schemas/pdp_Pagination'
      additionalProperties: false
    pdp_PolicySchemasList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/pdp_SchemaVersionWithZoneInfo'
        pagination:
          $ref: '#/components/schemas/pdp_Pagination'
      additionalProperties: false
    pdp_PolicySetsList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicySetWithBinding'
        pagination:
          $ref: '#/components/schemas/pdp_Pagination'
      additionalProperties: false
    pdp_PolicySetVersionsList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicySetVersion'
        pagination:
          $ref: '#/components/schemas/pdp_Pagination'
      additionalProperties: false
    pdp_PolicySetVersionPoliciesList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicyVersion'
        pagination:
          $ref: '#/components/schemas/pdp_Pagination'
      additionalProperties: false
    pdp_EvaluationRequestsList:
      type: object
      required:
        - items
        - pagination
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/pdp_EvaluationRequestItem'
        pagination:
          $ref: '#/components/schemas/pdp_Pagination'
      additionalProperties: false
    pdp_EvaluationRequestItem:
      type: object
      required:
        - id
        - request_id
        - principal_type
        - principal_id
        - action
        - resource_id
        - active_psv_id
        - active_schema_version
        - active_decision
        - active_duration_ms
        - created_at
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for this evaluation request entry.
        request_id:
          type: string
          description: Correlation ID from the original credentials API request.
        principal_type:
          type: string
          enum:
            - user
            - application
        principal_id:
          type: string
        action:
          type: string
        resource_id:
          type: string
        subject_type:
          type: string
          nullable: true
          enum:
            - user
            - application
        subject_id:
          type: string
          nullable: true
        authority_type:
          type: string
          nullable: true
          enum:
            - delegation
            - impersonation
        acting_principal_id:
          type: string
          nullable: true
          description: |
            The verified RFC 8693 acting principal (nominated via actor_token)
            from the original check, when one was present.
        context:
          $ref: '#/components/schemas/pdp_EvaluationContext'
        active_psv_id:
          type: string
          format: uuid
          description: ID of the active policy set version used for evaluation.
        active_schema_version:
          type: string
          description: Cedar schema version of the active policy set version.
        active_decision:
          type: string
          enum:
            - allow
            - deny
        active_duration_ms:
          type: integer
          description: Evaluation duration in milliseconds.
        shadow_psv_id:
          type: string
          format: uuid
          nullable: true
          description: ID of the shadow policy set version, if a shadow binding existed.
        created_at:
          type: string
          format: date-time
      additionalProperties: false
    pdp_CreatePolicyRequest:
      type: object
      required:
        - name
      properties:
        name:
          type: string
        description:
          type: string
      additionalProperties: false
    pdp_UpdatePolicyRequest:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
      additionalProperties: false
    pdp_CreatePolicyVersionRequest:
      type: object
      required:
        - schema_version
      properties:
        cedar_json:
          type: object
          nullable: true
          description: >-
            Cedar policy in JSON representation. Mutually exclusive with cedar_raw.
        cedar_raw:
          type: string
          nullable: true
          description: >-
            Cedar policy in human-readable Cedar syntax. Mutually exclusive with cedar_json.
        schema_version:
          type: string
          description: >-
            Schema version to validate this policy against. Must not be archived.
      additionalProperties: false
    pdp_UpsertPolicyDraftRequest:
      type: object
      required:
        - schema_version
      properties:
        cedar_json:
          type: object
          nullable: true
          description: >-
            Cedar policy in JSON representation. Mutually exclusive with cedar_raw.
        cedar_raw:
          type: string
          nullable: true
          description: >-
            Cedar policy in human-readable Cedar syntax. Mutually exclusive with cedar_json.
        schema_version:
          type: string
      additionalProperties: false
    pdp_SetDefaultPolicySchemaRequest:
      type: object
      additionalProperties: false
    pdp_CreatePolicySetRequest:
      type: object
      required:
        - name
      description: |
        At most one of `target_type` or the deprecated `scope_type` may be
        provided; supplying both with different values returns 400. Defaults
        to `zone`.
      properties:
        name:
          type: string
        scope_type:
          type: string
          enum:
            - zone
          deprecated: true
          description: |
            **Deprecated.** Use `target_type` instead. Only `zone` is
            accepted; use `target_type` for `user` targets.
        target_type:
          type: string
          enum:
            - zone
            - user
          description: |
            What this policy set targets:
            - `"zone"` — applies to all requests in the zone.
            - `"user"` — can be bound to a specific user.
        manifest:
          $ref: '#/components/schemas/pdp_CreatePolicySetManifest'
      additionalProperties: false
    pdp_CreatePolicySetManifest:
      type: object
      description: Content for the first version, created atomically with the set.
      required:
        - entries
      properties:
        activate:
          type: boolean
          default: false
          description: >-
            Bind the first version to the zone's active slot in the same transaction. Requires a zone-targeted set and the activate permission on policy_set_bindings.
        entries:
          type: array
          minItems: 1
          description: Initial manifest entries, in request order.
          items:
            $ref: '#/components/schemas/pdp_ApplyManifestEntry'
        schema_version:
          type: string
          description: Schema to validate and pin v1 against. Defaults to the zone default.
      additionalProperties: false
    pdp_UpdatePolicySetRequest:
      type: object
      properties:
        name:
          type: string
      additionalProperties: false
    pdp_UpdatePolicySetVersionRequest:
      type: object
      required:
        - active
      properties:
        active:
          type: boolean
          enum:
            - true
          description: Must be true. Binds this version as the active zone policy set.
      additionalProperties: false
    pdp_CreatePolicySetVersionRequest:
      type: object
      required:
        - manifest
        - schema_version
      properties:
        manifest:
          $ref: '#/components/schemas/pdp_PolicySetManifest'
        schema_version:
          type: string
          description: Schema version to pin to this policy set version.
      additionalProperties: false
    pdp_CreatePolicySetDraftRequest:
      type: object
      description: >-
        Optional body for POST draft creation. Three modes: (1) empty/omitted — hydrate from latest version, (2) only base_version_id — hydrate from that version, (3) manifest provided — use explicit content. base_version_id and manifest are mutually exclusive; providing both is rejected.
      properties:
        base_version_id:
          type: string
          description: >-
            ID of a policy set version to hydrate from. Mutually exclusive with manifest — the server rejects requests containing both fields.
        manifest:
          $ref: '#/components/schemas/pdp_PolicySetManifest'
        schema_version:
          type: string
        name:
          type: string
        description:
          type: string
      additionalProperties: false
    pdp_UpsertPolicySetDraftRequest:
      type: object
      required:
        - manifest
        - schema_version
      properties:
        manifest:
          $ref: '#/components/schemas/pdp_PolicySetManifest'
        schema_version:
          type: string
        name:
          type: string
        description:
          type: string
      additionalProperties: false
    pdp_PatchPolicySetDraftRequest:
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        schema_version:
          type: string
        manifest_operations:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicySetDraftManifestOperation'
      additionalProperties: false
    pdp_ValidatePolicyContentRequest:
      type: object
      required:
        - schema_version
      properties:
        cedar_json:
          type: object
          nullable: true
          description: >-
            Cedar policy in JSON representation. Mutually exclusive with cedar_raw.
        cedar_raw:
          type: string
          nullable: true
          description: >-
            Cedar policy in human-readable Cedar syntax. Mutually exclusive with cedar_json.
        schema_version:
          type: string
          description: Schema version to validate against. Must not be archived.
      additionalProperties: false
    pdp_PolicyValidationResult:
      type: object
      required:
        - valid
        - schema_version
        - errors
        - warnings
      properties:
        valid:
          type: boolean
          description: True if the policy passes schema validation with no errors.
        schema_version:
          type: string
          description: Schema version validated against (echo back).
        errors:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicyValidationDiagnostic'
          description: Validation errors. Empty array when valid.
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/pdp_PolicyValidationDiagnostic'
          description: >-
            Validation warnings. May be non-empty even when valid is true. References to actions absent from the schema are reported here as per-occurrence warnings with code `unknown_action` (partitioned out of errors: they do not make valid false).
      additionalProperties: false
    pdp_PolicyValidationDiagnostic:
      type: object
      required:
        - message
      properties:
        message:
          type: string
          description: Human-readable description of the validation issue.
        severity:
          type: string
          enum:
            - error
            - warning
          x-enum-varnames:
            - SeverityError
            - SeverityWarning
          description: >-
            Severity of the diagnostic. Optional and additive; older clients that only read `message` can ignore it. Diagnostics under `errors` are `error`; those under `warnings` are `warning`.
        range:
          $ref: '#/components/schemas/pdp_SourceRange'
        code:
          type: string
          description: >-
            Machine-readable kind of the diagnostic (e.g. `unknown_action`, `parse_error`). Optional and additive; absent when the finding has no specific code.
        help:
          type: string
          description: >-
            Optional advisory text, rendered by clients as secondary text below the primary message.
        data:
          type: object
          additionalProperties:
            type: string
          description: >-
            Optional structured details keyed by the diagnostic `code`, so consumers need not parse `message`. For `unknown_action`: `{"action_uid": "..."}`.
      additionalProperties: false
    pdp_SourceRange:
      type: object
      required:
        - start
        - end
      description: >-
        Half-open source range [start, end) locating a diagnostic in the submitted policy text. Optional: present only when the engine can map the finding to a span. Populated for parse/syntax errors and for semantic findings when the policy was submitted as `cedar_raw`; absent for whole-policy semantic findings (no single span) and for policies submitted as `cedar_json` (the JSON AST carries no source locations).
      properties:
        start:
          $ref: '#/components/schemas/pdp_SourcePosition'
        end:
          $ref: '#/components/schemas/pdp_SourcePosition'
      additionalProperties: false
    pdp_SourcePosition:
      type: object
      required:
        - line
        - column
        - offset
      description: A position in the submitted policy text.
      properties:
        line:
          type: integer
          format: int32
          minimum: 1
          description: 1-based line number.
        column:
          type: integer
          format: int32
          minimum: 1
          description: 1-based column number (counts Unicode scalar values).
        offset:
          type: integer
          format: int32
          minimum: 0
          description: 0-based byte offset into the UTF-8 policy text.
      additionalProperties: false
    pdp_PolicySetDraftManifestOperation:
      type: object
      required:
        - op
        - policy_id
      properties:
        op:
          type: string
          enum:
            - set
            - add
            - remove
          description: >-
            set: Replace policy_version_id for an existing entry matching policy_id. add: Append a new entry with the given policy_id and policy_version_id. remove: Remove the entry matching policy_id.
        policy_id:
          type: string
        policy_version_id:
          type: string
          description: Required for set and add operations. Ignored for remove.
      additionalProperties: false
    pdp_PolicyEvaluationRequest:
      type: object
      required:
        - principal_type
        - principal_id
        - action
        - resource_id
        - policy_source
      properties:
        principal_type:
          type: string
          enum:
            - user
            - application
        principal_id:
          type: string
          description: Public ID of the user or application.
        action:
          type: string
          description: >-
            Cedar action to evaluate (e.g. `any`). The engine namespaces actions automatically as `Keycard::Action::"<name>"`.
        resource_id:
          type: string
          description: Public ID of the resource.
        subject_type:
          type: string
          enum:
            - user
            - application
        subject_id:
          type: string
          description: Public ID of the subject (required when subject_type is set).
        authority_type:
          type: string
          nullable: true
          enum:
            - delegation
            - impersonation
          description: |
            Discriminator for the subject authority model. Determines how the
            subject relationship is expressed in the Cedar context:
            - `"delegation"` — sets `context.on_behalf = true` on the actor
              check. The actor is acting on behalf of the subject.
            - `"impersonation"` — sets `context.impersonate = true` on the
              actor check. The actor is impersonating the subject.
            When null and a subject is present, defaults to `"delegation"` for
            backward compatibility.
        acting_principal_id:
          type: string
          description: |
            ID of the acting application from a verified RFC 8693 `actor_token`,
            as sent on `/policy/check`. Resolved with the same entity lookup as
            an application `principal_id` and exposed to Cedar as
            `context.acting_principal.application` on both checks. Lets a
            captured evaluation request be replayed faithfully.
        context:
          $ref: '#/components/schemas/pdp_EvaluationContext'
        policy_source:
          $ref: '#/components/schemas/pdp_PolicySource'
      additionalProperties: false
    pdp_PolicySource:
      type: object
      description: >
        Specifies which policies to evaluate. Exactly one of policy, policy_set, raw, or manifest must be provided.

      properties:
        policy:
          $ref: '#/components/schemas/pdp_PolicyRef'
        policy_set:
          $ref: '#/components/schemas/pdp_PolicySetRef'
        raw:
          $ref: '#/components/schemas/pdp_RawPolicyInput'
        manifest:
          $ref: '#/components/schemas/pdp_InlinePolicySetManifest'
      additionalProperties: false
    pdp_PolicyRef:
      type: object
      required:
        - policy_id
      properties:
        policy_id:
          type: string
          description: Public ID of the policy.
        version_id:
          type: string
          description: >
            Public ID of a specific policy version. When omitted, the draft is used. If no draft exists, returns 400.

        schema_version:
          type: string
          description: >
            Cedar schema version override (date string, e.g. "2026-03-16"). When omitted, uses the schema_version recorded on the resolved policy version or draft.

      additionalProperties: false
    pdp_PolicySetRef:
      type: object
      required:
        - policy_set_id
      properties:
        policy_set_id:
          type: string
          description: Public ID of the policy set.
        version_id:
          type: string
          description: >
            Public ID of a specific policy set version. When omitted, the draft is used. If no draft exists, returns 400.

      additionalProperties: false
    pdp_RawPolicyInput:
      type: object
      required:
        - cedar
        - schema_version
      properties:
        cedar:
          type: string
          description: >
            Raw Cedar policy text. Can contain one or more policy statements. Converted to JSON before evaluation.

        schema_version:
          type: string
          description: Cedar schema version to evaluate against.
        validate:
          type: boolean
          default: true
          description: >
            When true, validate the converted policy against the schema before evaluation. Validation errors are returned as 400 with details. Set to false to skip validation and attempt evaluation directly.

      additionalProperties: false
    pdp_PolicyEvaluationResponse:
      type: object
      required:
        - decision
        - evaluated_at
      properties:
        decision:
          type: string
          enum:
            - allow
            - deny
        evaluation_status:
          type: string
          enum:
            - complete
            - partial
        determining_policies:
          type: array
          description: |
            Raw Cedar policy IDs that determined the decision, of the form
            "<policy_version_id>::<cedar_key>", unioned across sub-checks. See
            `checks` for the resolved, human-readable form with per-check
            attribution.
          items:
            type: string
        checks:
          type: array
          description: |
            Per-sub-check results, each with the policies that determined it.
            A simple request has one actor check; an on-behalf-of /
            impersonation request has a subject check and an actor check. The
            overall decision is deny-wins across these. Determining-policy names
            and policy-set version populate only when evaluating a minted policy
            set/version; raw text and drafts are structural.
          items:
            $ref: '#/components/schemas/pdp_EvaluationCheck'
        reason:
          type: string
          description: |
            Human-readable explanation of the decision, suitable for presenting
            to end users.
        diagnostics:
          type: array
          items:
            $ref: '#/components/schemas/pdp_DiagnosticEntry'
        evaluated_at:
          type: string
          format: date-time
        entity_snapshot:
          $ref: '#/components/schemas/pdp_EntitySnapshot'
      additionalProperties: false
    pdp_EntitySnapshot:
      type: object
      properties:
        principal:
          oneOf:
            - $ref: '#/components/schemas/pdp_UserSnapshot'
            - $ref: '#/components/schemas/pdp_ApplicationSnapshot'
        resource:
          $ref: '#/components/schemas/pdp_ResourceSnapshot'
        subject:
          oneOf:
            - $ref: '#/components/schemas/pdp_UserSnapshot'
            - $ref: '#/components/schemas/pdp_ApplicationSnapshot'
          description: Present when subject_type/subject_id were provided.
        context:
          type: object
          description: The assembled Cedar context record.
      additionalProperties: false
    pdp_UserSnapshot:
      type: object
      description: >
        Subset of the IAM User entity relevant to Cedar evaluation. All fields match the IAM management API User schema.

      required:
        - type
        - id
        - email
      properties:
        type:
          type: string
          enum:
            - user
        id:
          type: string
          description: User public ID (same as IAM management API).
        email:
          type: string
        email_verified:
          type: boolean
      additionalProperties: false
    pdp_ApplicationSnapshot:
      type: object
      description: >
        Subset of the IAM Application entity relevant to Cedar evaluation. All fields match the IAM management API Application schema.

      required:
        - type
        - id
        - name
        - registration_method
      properties:
        type:
          type: string
          enum:
            - application
        id:
          type: string
          description: Application public ID (same as IAM management API).
        name:
          type: string
        registration_method:
          type: string
          enum:
            - managed
            - dcr
        credential_type:
          type: string
          description: Present only when resolved via credential lookup.
        dependencies:
          type: array
          items:
            $ref: '#/components/schemas/pdp_ResourceSnapshot'
          description: Resources this application depends on.
      additionalProperties: false
    pdp_ResourceSnapshot:
      type: object
      description: >
        Subset of the IAM Resource entity relevant to Cedar evaluation. All fields match the IAM management API Resource schema.

      required:
        - id
        - identifier
        - name
      properties:
        id:
          type: string
          description: Resource public ID (same as IAM management API).
        identifier:
          type: string
        name:
          type: string
        scopes:
          type: array
          items:
            type: string
      additionalProperties: false
    pdp_PolicySetBinding:
      type: object
      required:
        - id
        - scope_type
        - scope_target_id
        - target_type
        - target_id
        - mode
        - policy_set_id
        - policy_set_version_id
        - created_at
      properties:
        id:
          type: string
          description: Binding identifier (stable per slot)
        scope_type:
          type: string
          enum:
            - zone
          deprecated: true
          description: |
            **Deprecated.** Use `target_type` instead. Carries the same value.
        scope_target_id:
          type: string
          deprecated: true
          description: |
            **Deprecated.** Use `target_id` instead. Carries the same value.
        target_type:
          type: string
          enum:
            - zone
            - user
          description: What this binding targets
        target_id:
          type: string
          description: Target entity ID. Equals zone_id for zone-targeted bindings.
        mode:
          type: string
          enum:
            - active
            - shadow
          description: Binding mode
        policy_set_id:
          type: string
          description: Public ID of the bound policy set
        policy_set_version_id:
          type: string
          description: Public ID of the bound policy set version
        created_at:
          type: string
          format: date-time
      additionalProperties: false
    pdp_SetPolicySetBindingRequest:
      type: object
      required:
        - mode
        - policy_set_id
        - policy_set_version_id
      description: |
        Exactly one of `target_type` or the deprecated `scope_type` must be
        provided; supplying both with different values returns 400. The same
        applies to `target_id` / `scope_target_id`.
      properties:
        scope_type:
          type: string
          enum:
            - zone
          deprecated: true
          description: |
            **Deprecated.** Use `target_type` instead.
        scope_target_id:
          type: string
          deprecated: true
          description: |
            **Deprecated.** Use `target_id` instead.
        target_type:
          type: string
          enum:
            - zone
          description: >-
            What the binding targets. Only `zone` is supported for direct binding writes.
        target_id:
          type: string
          description: Defaults to zone_id for zone targets. Required for other targets.
        mode:
          type: string
          enum:
            - shadow
          description: Binding mode
        policy_set_id:
          type: string
          description: Public ID of the policy set to bind
        policy_set_version_id:
          type: string
          description: Public ID of the policy set version to bind
      additionalProperties: false
    pdp_PolicySetShadowMetricsSummary:
      type: object
      required:
        - total_evaluations
        - agree_count
        - shadow_allow_active_deny_count
        - shadow_deny_active_allow_count
        - since
      properties:
        total_evaluations:
          type: integer
        agree_count:
          type: integer
        shadow_allow_active_deny_count:
          type: integer
        shadow_deny_active_allow_count:
          type: integer
        agreement_rate:
          type: number
          format: float
          description: >-
            Fraction of evaluations where active and shadow decisions agreed (0.0–1.0)
        avg_shadow_duration_ms:
          type: integer
        stddev_shadow_duration_ms:
          type: integer
        since:
          type: string
          format: date-time
        pairings:
          type: array
          description: Per-pairing breakdown. Present when querying by PSV.
          items:
            $ref: '#/components/schemas/pdp_PolicySetShadowPairingSummary'
      additionalProperties: false
    pdp_PolicySetShadowPairingSummary:
      type: object
      required:
        - active_psv_id
        - shadow_psv_id
        - total
        - agree_count
        - first_eval
        - last_eval
      properties:
        active_psv_id:
          type: string
        shadow_psv_id:
          type: string
        total:
          type: integer
        agree_count:
          type: integer
        first_eval:
          type: string
          format: date-time
        last_eval:
          type: string
          format: date-time
      additionalProperties: false
    pdp_PaginationCursor:
      type: string
      description: An opaque cursor used for paginating through a list of results
      minLength: 1
      maxLength: 255
      x-go-type: types.PaginationCursor
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    pdp_ErrorCode:
      type: string
      enum:
        - validation_error
        - bad_request
        - unauthorized
        - forbidden
        - not_found
        - conflict
        - rate_limit_exceeded
        - internal_error
        - not_implemented
        - service_unavailable
      x-enum-varnames:
        - ValidationErrorCode
        - BadRequestErrorCode
        - UnauthorizedErrorCode
        - ForbiddenErrorCode
        - NotFoundErrorCode
        - ConflictErrorCode
        - RateLimitExceededErrorCode
        - InternalErrorCode
        - NotImplementedErrorCode
        - ServiceUnavailableErrorCode
      x-go-type: httperrors.ErrorCode
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    pdp_ErrorDetail:
      type: object
      properties:
        field:
          type: string
          description: >-
            valid json path for request body. Omitted when the detail is not tied to a request field (e.g. domain error codes); clients should treat absent and empty the same.
        message:
          type: string
          description: error message for specific error
        code:
          anyOf:
            - $ref: '#/components/schemas/pdp_ErrorCode'
            - type: string
          description: >-
            Machine-readable code. Either a common `ErrorCode` value or a service-specific domain code (snake_case) documented by the service's own API spec. Clients should match on this instead of parsing `message`. Open set; unknown codes must be tolerated.
          example: version_currently_bound
      required:
        - message
        - code
      additionalProperties: false
      x-go-type: httperrors.ErrorDetail
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    pdp_Error:
      type: object
      description: Represents an error that has occurred in the Keycard system.
      properties:
        status:
          type: integer
          description: HTTP Status Code
        code:
          $ref: '#/components/schemas/pdp_ErrorCode'
        message:
          type: string
          description: summary of the error
        request_id:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
        path:
          type: string
          format: url
        details:
          type: array
          items:
            $ref: '#/components/schemas/pdp_ErrorDetail'
      additionalProperties: false
      required:
        - status
        - code
        - message
        - request_id
        - timestamp
        - path
        - details
      x-go-type: httperrors.Error
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    pdp_Pagination:
      type: object
      description: Cursor-based pagination metadata returned alongside a list of results
      properties:
        before_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/pdp_PaginationCursor'
        after_cursor:
          type: string
          nullable: true
          allOf:
            - $ref: '#/components/schemas/pdp_PaginationCursor'
        total_count:
          type: integer
          description: >-
            Total number of items across all pages. Only present when the request includes ?expand[]=total_count.
      required:
        - before_cursor
        - after_cursor
      additionalProperties: false
      x-go-type: types.Pagination
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    pdp_QueryTerms:
      type: array
      description: |
        Value shape for `query[]` and `query[<field>]` search parameters.

        Wire conventions:
          - Case-insensitive substring match (ILIKE).
          - Repeated parameter instances are OR-ed across terms.
          - Comma splitting is NOT performed; literal commas in a search term
            are preserved as part of the term.

        Examples:
          ?query[name]=alpha&query[name]=beta      -> name ILIKE %alpha% OR name ILIKE %beta%
          ?query[]=alpha                           -> any searchable field ILIKE %alpha%

        Cross-field form is `query[]`; field-scoped form is `query[<field>]`.
        Field names are endpoint-specific; services declare each query parameter
        per operation.
      items:
        type: string
        minLength: 1
        maxLength: 255
    pdp_FilterValues:
      type: array
      description: |
        Value shape for `filter[<field>]` query parameters.

        Wire conventions:
          - Repeated parameter instances are OR-ed across values.
          - A single value containing comma-separated tokens is AND-ed across tokens.

        Examples:
          ?filter[status]=a&filter[status]=b       -> status in (a, b)
          ?filter[tag]=foo,bar                     -> tag contains foo AND bar
          ?filter[tag]=foo,bar&filter[tag]=baz     -> (foo AND bar) OR baz

        Field names and allowed values are endpoint-specific; services declare
        each filter[<field>] parameter per operation with an appropriate
        items.type/items.enum override.
      items:
        type: string
    vault-api_Metadata:
      description: >-
        A JSON object containing arbitrary metadata. Metadata will not be encrypted.
      type: object
      maxProperties: 100
    vault-api_RegisterZoneRequest:
      additionalProperties: false
      type: object
      properties:
        organization_id:
          description: |
            Organization that will own the zone. Optional during the S2S auth
            migration: when omitted, vault resolves org from the gateway header,
            then authz scope. Internal service principals never fall back to
            the JWT claim; users and service accounts may still use the claim
            as a last resort. Will become required once callers always send it.
          allOf:
            - $ref: '#/components/schemas/vault-api_ID'
        encryption_key:
          oneOf:
            - $ref: '#/components/schemas/vault-api_AwsKmsConfig'
          discriminator:
            propertyName: type
            mapping:
              aws: '#/components/schemas/vault-api_AwsKmsConfig'
    vault-api_AwsKmsConfig:
      additionalProperties: false
      type: object
      required:
        - type
        - arn
      properties:
        type:
          type: string
          enum:
            - aws
        arn:
          type: string
          description: >
            AWS KMS Key ARN for encrypting the zone's Data Encryption Key.

            Only full key ARNs in the format arn:aws:kms:region:account-id:key/KEY-ID (with UUID-style key ID) are accepted.

            This format is required for cross-account KMS key access.


            Rejected formats that will cause kms_invalid_arn errors:

            - Key aliases: arn:aws:kms:region:account-id:alias/NAME

            - Bare key IDs: 12345678-1234-1234-1234-123456789012

          example: arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
    vault-api_Zone:
      additionalProperties: false
      type: object
      required:
        - id
      properties:
        id:
          $ref: '#/components/schemas/vault-api_ID'
        keys:
          type: array
          items:
            $ref: '#/components/schemas/vault-api_Key'
    vault-api_Key:
      additionalProperties: false
      type: object
      required:
        - id
        - use
        - spec
        - public_key
      properties:
        id:
          type: string
        use:
          type: string
          description: The key use that is used to create the key.
          enum:
            - SIGN_VERIFY
        spec:
          type: string
          description: The key specification that is used to create the key.
          enum:
            - RSA_2048
        public_key:
          $ref: '#/components/schemas/vault-api_PublicKey'
    vault-api_PublicKey:
      additionalProperties: false
      type: object
      required:
        - modulus
        - exponent
      properties:
        modulus:
          type: string
        exponent:
          type: string
    vault-api_JWKS:
      description: JSON Web Key Set format (RFC 7517)
      additionalProperties: false
      type: object
      required:
        - keys
      properties:
        keys:
          type: array
          items:
            $ref: '#/components/schemas/vault-api_JWK'
    vault-api_JWK:
      description: JSON Web Key (RFC 7517)
      additionalProperties: false
      type: object
      required:
        - kty
        - use
        - kid
        - alg
        - 'n'
        - e
      properties:
        kty:
          type: string
          description: Key Type
          enum:
            - RSA
        use:
          type: string
          description: Public Key Use
          enum:
            - sig
        kid:
          type: string
          description: Key ID
        alg:
          type: string
          description: Algorithm
          enum:
            - RS256
        'n':
          type: string
          description: Modulus (base64url encoded)
        e:
          type: string
          description: Exponent (base64url encoded)
    vault-api_UpdateSecretRequest:
      additionalProperties: false
      type: object
      properties:
        name:
          $ref: '#/components/schemas/vault-api_Name'
        description:
          $ref: '#/components/schemas/vault-api_Description'
        metadata:
          $ref: '#/components/schemas/vault-api_Metadata'
        data:
          oneOf:
            - $ref: '#/components/schemas/vault-api_SecretTokenFields'
            - $ref: '#/components/schemas/vault-api_SecretPasswordFields'
          discriminator:
            propertyName: type
            mapping:
              token: '#/components/schemas/vault-api_SecretTokenFields'
              password: '#/components/schemas/vault-api_SecretPasswordFields'
    vault-api_CreateZoneSecretRequest:
      additionalProperties: false
      type: object
      required:
        - name
        - entity_id
        - data
      properties:
        name:
          $ref: '#/components/schemas/vault-api_Name'
        description:
          $ref: '#/components/schemas/vault-api_Description'
        metadata:
          $ref: '#/components/schemas/vault-api_Metadata'
        entity_id:
          $ref: '#/components/schemas/vault-api_ID'
        zone_id:
          $ref: '#/components/schemas/vault-api_ID'
        data:
          oneOf:
            - $ref: '#/components/schemas/vault-api_SecretTokenFields'
            - $ref: '#/components/schemas/vault-api_SecretPasswordFields'
          discriminator:
            propertyName: type
            mapping:
              token: '#/components/schemas/vault-api_SecretTokenFields'
              password: '#/components/schemas/vault-api_SecretPasswordFields'
    vault-api_SecretTokenFields:
      additionalProperties: false
      type: object
      required:
        - token
        - type
      properties:
        type:
          type: string
          enum:
            - token
        token:
          type: string
    vault-api_SecretPasswordFields:
      additionalProperties: false
      type: object
      required:
        - username
        - password
        - type
      properties:
        type:
          type: string
          enum:
            - password
        username:
          type: string
        password:
          type: string
    vault-api_SecretsList:
      additionalProperties: false
      type: array
      items:
        $ref: '#/components/schemas/vault-api_Secret'
    vault-api_SecretVersion:
      type: integer
      minimum: 1
    vault-api_SecretOwnerType:
      type: string
      description: >-
        Platform secrets are managed by internal services; customer secrets are managed by customers.
      enum:
        - platform
        - customer
    vault-api_Secret:
      additionalProperties: false
      type: object
      required:
        - id
        - name
        - entity_id
        - zone_id
        - version
        - type
        - created_at
        - updated_at
      properties:
        id:
          $ref: '#/components/schemas/vault-api_ID'
        entity_id:
          $ref: '#/components/schemas/vault-api_ID'
        zone_id:
          $ref: '#/components/schemas/vault-api_ID'
        version:
          $ref: '#/components/schemas/vault-api_SecretVersion'
        type:
          type: string
          enum:
            - token
            - password
        name:
          $ref: '#/components/schemas/vault-api_Name'
        description:
          $ref: '#/components/schemas/vault-api_Description'
        metadata:
          $ref: '#/components/schemas/vault-api_Metadata'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    vault-api_SecretValue:
      type: object
      required:
        - id
        - name
        - entity_id
        - zone_id
        - version
        - created_at
        - updated_at
        - data
      properties:
        id:
          $ref: '#/components/schemas/vault-api_ID'
        entity_id:
          $ref: '#/components/schemas/vault-api_ID'
        zone_id:
          $ref: '#/components/schemas/vault-api_ID'
        version:
          $ref: '#/components/schemas/vault-api_SecretVersion'
        name:
          $ref: '#/components/schemas/vault-api_Name'
        description:
          $ref: '#/components/schemas/vault-api_Description'
        metadata:
          $ref: '#/components/schemas/vault-api_Metadata'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        data:
          oneOf:
            - $ref: '#/components/schemas/vault-api_SecretTokenFields'
            - $ref: '#/components/schemas/vault-api_SecretPasswordFields'
          discriminator:
            propertyName: type
            mapping:
              token: '#/components/schemas/vault-api_SecretTokenFields'
              password: '#/components/schemas/vault-api_SecretPasswordFields'
    vault-api_SignMessageRequest:
      additionalProperties: false
      type: object
      required:
        - message
        - algorithm
        - key_id
      properties:
        key_id:
          type: string
          description: The ID of the private key to sign the message with
        message:
          type: string
          description: Base64-encoded message to sign
        algorithm:
          type: string
          description: The signing algorithm to use
          enum:
            - RSASSA_PKCS1_V1_5_SHA_256
    vault-api_SignedMessage:
      additionalProperties: false
      type: object
      required:
        - signature
        - key_id
        - algorithm
      properties:
        signature:
          type: string
          description: Base64-encoded signature of the message
        key_id:
          type: string
          description: The ID of the key used to sign the message
        algorithm:
          type: string
          description: The signing algorithm that was used
          enum:
            - RSASSA_PKCS1_V1_5_SHA_256
    vault-api_ID:
      type: string
      description: A globally unique opaque identifier
      minLength: 1
      x-go-type: types.ID
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    vault-api_ErrorCode:
      type: string
      enum:
        - validation_error
        - bad_request
        - unauthorized
        - forbidden
        - not_found
        - conflict
        - rate_limit_exceeded
        - internal_error
        - not_implemented
        - service_unavailable
      x-enum-varnames:
        - ValidationErrorCode
        - BadRequestErrorCode
        - UnauthorizedErrorCode
        - ForbiddenErrorCode
        - NotFoundErrorCode
        - ConflictErrorCode
        - RateLimitExceededErrorCode
        - InternalErrorCode
        - NotImplementedErrorCode
        - ServiceUnavailableErrorCode
      x-go-type: httperrors.ErrorCode
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    vault-api_ErrorDetail:
      type: object
      properties:
        field:
          type: string
          description: >-
            valid json path for request body. Omitted when the detail is not tied to a request field (e.g. domain error codes); clients should treat absent and empty the same.
        message:
          type: string
          description: error message for specific error
        code:
          anyOf:
            - $ref: '#/components/schemas/vault-api_ErrorCode'
            - type: string
          description: >-
            Machine-readable code. Either a common `ErrorCode` value or a service-specific domain code (snake_case) documented by the service's own API spec. Clients should match on this instead of parsing `message`. Open set; unknown codes must be tolerated.
          example: version_currently_bound
      required:
        - message
        - code
      additionalProperties: false
      x-go-type: httperrors.ErrorDetail
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    vault-api_Error:
      type: object
      description: Represents an error that has occurred in the Keycard system.
      properties:
        status:
          type: integer
          description: HTTP Status Code
        code:
          $ref: '#/components/schemas/vault-api_ErrorCode'
        message:
          type: string
          description: summary of the error
        request_id:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time
        path:
          type: string
          format: url
        details:
          type: array
          items:
            $ref: '#/components/schemas/vault-api_ErrorDetail'
      additionalProperties: false
      required:
        - status
        - code
        - message
        - request_id
        - timestamp
        - path
        - details
      x-go-type: httperrors.Error
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/httperrors
        name: httperrors
    vault-api_Name:
      type: string
      description: A name for the entity to be displayed in UI
      pattern: ^[a-zA-Z][a-zA-Z0-9\s,\.'\-pL\ \-_]{1,63}$
      x-go-type: types.Name
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
    vault-api_Description:
      type: string
      description: A description of the entity
      maxLength: 128
      x-go-type: types.Description
      x-go-type-import:
        path: github.com/keycardlabs/pkg-oapi-common/golang/types
        name: types
  headers:
    common_X-Request-ID:
      description: >-
        A v7 UUID that is unique for this request, id originating from a server and used by downstream servers
      schema:
        type: string
        format: uuid
    catalog_X-Request-ID:
      description: >-
        A v7 UUID that is unique for this request, id originating from a server and used by downstream servers
      schema:
        type: string
        format: uuid
    org-management_X-Request-ID:
      description: >-
        A v7 UUID that is unique for this request, id originating from a server and used by downstream servers
      schema:
        type: string
        format: uuid
    pdp_ETag:
      description: >-
        Entity tag for optimistic concurrency control. Pass this value back in the If-Match header on subsequent updates.
      schema:
        type: string
    pdp_X-Request-ID:
      description: >-
        A v7 UUID that is unique for this request, id originating from a server and used by downstream servers
      schema:
        type: string
        format: uuid
    vault-api_X-Request-ID:
      description: >-
        A v7 UUID that is unique for this request, id originating from a server and used by downstream servers
      schema:
        type: string
        format: uuid
  parameters:
    common_X-Client-Request-ID:
      name: X-Client-Request-ID
      in: header
      description: >-
        Unique request identifier specified by the originating caller and passed along by proxies.
      required: false
      schema:
        type: string
        format: uuid
        x-go-type: uuid.UUID
        x-go-type-import:
          path: github.com/google/uuid
          name: uuid
    common_After:
      name: after
      in: query
      required: false
      description: >-
        Cursor for forward pagination. Returned in `Pagination.after_cursor`. Mutually exclusive with `before`.
      schema:
        $ref: '#/components/schemas/common_PaginationCursor'
    common_Before:
      name: before
      in: query
      required: false
      description: >-
        Cursor for backward pagination. Returned in `Pagination.before_cursor`. Mutually exclusive with `after`.
      schema:
        $ref: '#/components/schemas/common_PaginationCursor'
    common_Limit:
      name: limit
      in: query
      required: false
      description: Maximum number of items to return per page.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    catalog_ZoneId:
      name: zone_id
      in: path
      required: true
      schema:
        type: string
    catalog_OrgId:
      name: org_id
      in: path
      required: true
      description: The organization the zone belongs to.
      schema:
        type: string
    catalog_ResourceId:
      name: resource_id
      in: path
      required: true
      schema:
        type: string
    catalog_PackageId:
      name: package_id
      in: path
      required: true
      schema:
        type: string
        pattern: ^([a-z]+:)?[a-z0-9]+(-[a-z0-9]+)*$
        minLength: 1
        maxLength: 70
    catalog_PackageKindFilter:
      name: filters[kind]
      in: query
      description: >-
        Filter packages by kind. Supply one kind or a comma-separated list to match any of them (`?filters[kind]=api-server,mcp-server-proxy`). When absent, no kind filter is applied.
      required: false
      style: form
      explode: false
      schema:
        type: array
        items:
          $ref: '#/components/schemas/catalog_PackageKind'
    catalog_PackageRecommendedFilter:
      name: filters[recommended]
      in: query
      description: >-
        Filter packages by their `recommended` flag. Supply `true` or `false`. When the parameter is present with no value (`?filters[recommended]`), it is treated as `true`. When the parameter is absent, no recommendation filter is applied.
      required: false
      allowEmptyValue: true
      schema:
        type: boolean
    catalog_PackageIncludeUnpublishedFilter:
      name: include_unpublished
      in: query
      description: When true, include unpublished packages alongside published ones.
      required: false
      schema:
        type: boolean
    catalog_PackageQueryFilter:
      name: query[]
      in: query
      description: >-
        Full-text search over package name and description. Each term is a case-insensitive substring match (ILIKE); repeat the parameter to OR multiple terms (`?query[]=foo&query[]=bar` matches packages whose name or description contains `foo` or `bar`). The matched name and description are resolved from the latest released version, falling back to the draft.
      required: false
      schema:
        allOf:
          - $ref: '#/components/schemas/catalog_QueryTerms'
        maxItems: 10
    catalog_After:
      name: after
      in: query
      required: false
      description: >-
        Cursor for forward pagination. Returned in `Pagination.after_cursor`. Mutually exclusive with `before`.
      schema:
        $ref: '#/components/schemas/catalog_PaginationCursor'
    catalog_Before:
      name: before
      in: query
      required: false
      description: >-
        Cursor for backward pagination. Returned in `Pagination.before_cursor`. Mutually exclusive with `after`.
      schema:
        $ref: '#/components/schemas/catalog_PaginationCursor'
    catalog_Limit:
      name: limit
      in: query
      required: false
      description: Maximum number of items to return per page.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    catalog_X-Client-Request-ID:
      name: X-Client-Request-ID
      in: header
      description: >-
        Unique request identifier specified by the originating caller and passed along by proxies.
      required: false
      schema:
        type: string
        format: uuid
        x-go-type: uuid.UUID
        x-go-type-import:
          path: github.com/google/uuid
          name: uuid
    org-management_Expand:
      name: expand[]
      in: query
      description: >
        Fields to expand in the response. Supports "permissions" to include the permissions

        field with the caller's permissions for the resource. For the service account and

        service account credential list operations, "total_count" populates

        pagination.total_count with the number of items matching the same filters as the list

        (excluding cursor and limit). Other operations ignore expand values they do not use.

      required: false
      schema:
        x-go-type: '[]string'
        anyOf:
          - type: string
            enum:
              - permissions
              - total_count
          - type: array
            items:
              type: string
              enum:
                - permissions
                - total_count
      style: form
      explode: true
    org-management_X-Client-Request-ID:
      name: X-Client-Request-ID
      in: header
      description: >-
        Unique request identifier specified by the originating caller and passed along by proxies.
      required: false
      schema:
        type: string
        format: uuid
        x-go-type: uuid.UUID
        x-go-type-import:
          path: github.com/google/uuid
          name: uuid
    pdp_ZoneId:
      name: zone_id
      in: path
      required: true
      description: The zone identifier
      schema:
        type: string
    pdp_PolicyId:
      name: policy_id
      in: path
      required: true
      description: The policy identifier
      schema:
        type: string
    pdp_VersionId:
      name: version_id
      in: path
      required: true
      description: The policy version identifier
      schema:
        type: string
    pdp_PolicySetId:
      name: policy_set_id
      in: path
      required: true
      description: The policy set identifier
      schema:
        type: string
    pdp_BindingId:
      name: binding_id
      in: path
      required: true
      description: The binding identifier
      schema:
        type: string
    pdp_SchemaVersionParam:
      name: version
      in: path
      required: true
      description: The schema version string
      schema:
        type: string
    pdp_Expand:
      name: expand
      in: query
      required: false
      deprecated: true
      description: |
        **Deprecated.** Use `expand[]` instead.

        Opt-in to additional response fields. Still honored for backward
        compatibility; supplying both `expand` and `expand[]` with disagreeing
        values returns `400 Bad Request`.
      schema:
        type: array
        items:
          $ref: '#/components/schemas/pdp_ExpandField'
      style: form
      explode: false
    pdp_ExpandNew:
      name: expand[]
      in: query
      required: false
      description: >-
        Opt-in to additional response fields (`total_count`, `user`). Repeatable; matches the `expand[]` convention used across the Keycard API.
      x-go-name: ExpandBracketed
      schema:
        type: array
        items:
          $ref: '#/components/schemas/pdp_ExpandField'
      style: form
      explode: true
    pdp_ExpandSingle:
      name: expand[]
      in: query
      required: false
      description: >-
        Opt-in to additional response fields on a single resource (`user`). Repeatable.
      x-go-name: ExpandSingle
      schema:
        type: array
        items:
          $ref: '#/components/schemas/pdp_ExpandSingleField'
      style: form
      explode: true
    pdp_Sort:
      name: sort
      in: query
      required: false
      description: Field to sort by.
      schema:
        type: string
        enum:
          - created_at
        default: created_at
    pdp_Order:
      name: order
      in: query
      required: false
      description: Sort direction. Default is desc (newest first).
      schema:
        type: string
        enum:
          - asc
          - desc
        default: desc
    pdp_SchemaFormat:
      name: format
      in: query
      required: false
      description: >-
        Schema representation format. `cedar` returns human-readable Cedar syntax in `cedar_schema`, `json` returns Cedar JSON schema object in `cedar_schema_json`.
      schema:
        type: string
        enum:
          - cedar
          - json
        default: json
    pdp_PolicyFormat:
      name: format
      in: query
      required: false
      description: |
        Narrows which Cedar representation the response includes. When
        omitted, both `cedar_json` and `cedar_raw` are populated. Pass
        `json` to receive only `cedar_json`, or `cedar` to receive only
        `cedar_raw`. Callers that don't care about payload size can skip
        this parameter.
      schema:
        type: string
        enum:
          - cedar
          - json
    pdp_FilterActive:
      name: active
      in: query
      required: false
      deprecated: true
      description: >
        **Deprecated.** Use `filter[active]` instead.


        Filter by active binding status. When `true`, returns only policy sets with an active binding. When `false`, returns only policy sets without one. Omit to return all.


        Still honored for backward compatibility. Supplying both `active` and `filter[active]` with conflicting values returns `400 Bad Request`.

      schema:
        type: boolean
    pdp_FilterActiveNew:
      name: filter[active]
      in: query
      required: false
      description: >-
        Filter by active binding status. When `true`, returns only policy sets with an active binding. When `false`, returns only policy sets without one. Omit to return all.
      schema:
        type: boolean
    pdp_FilterOwnerType:
      name: filter[owner_type]
      in: query
      required: false
      description: |
        Filter on `owner_type`. Repeatable; repeated instances OR across values
        (e.g. `?filter[owner_type]=platform&filter[owner_type]=customer` matches
        either). See `FilterValues` in the shared spec for the full wire
        convention.

        Allowed values: `platform`, `customer`. Unknown values return 400 with
        the list of allowed values. Comma-separated single values
        (e.g. `?filter[owner_type]=platform,customer`) are rejected with a 400
        pointing at the repeated-parameter OR form.

        Note: the allowed-value enum is enforced in the handler (not as an
        OpenAPI `items.enum`) so the server can return a targeted error for
        the comma-AND form instead of a generic "not in allowed values"
        response.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterID:
      name: filter[id]
      in: query
      required: false
      description: |
        Filter by policy ID. Repeatable; multiple values are OR-ed
        (e.g. `?filter[id]=p1&filter[id]=p2`). Capped at 100 IDs per
        request — over-cap returns 400.

        Cannot be combined with cursor pagination (`after` or
        `before`). The server returns 400 if both are present.

        Composes with other filters (`filter[owner_type]`, `query[]`,
        etc.). When no explicit `limit` is provided, it defaults to
        the number of requested IDs so all results fit in a single
        page.

        IDs that don't exist or fall outside the zone scope are
        silently omitted; callers diff against the request set if they
        care about missing IDs.
      style: form
      explode: true
      schema:
        type: array
        items:
          type: string
        maxItems: 100
    pdp_FilterScopeType:
      name: filter[scope_type]
      in: query
      required: false
      deprecated: true
      description: |
        **Deprecated.** Use `filter[target_type]` instead.

        Filter on `scope_type` (policy sets only). Repeatable; repeated
        instances OR across values. See `FilterValues` in the shared spec
        for the full wire convention.

        Allowed values: `zone` only. Use `filter[target_type]` to select
        `user` (or future) targets. Unknown values return 400 with the list
        of allowed values. Comma-separated single values are rejected with a
        400 pointing at the repeated-parameter OR form.

        Still honored for backward compatibility and suppresses the
        `filter[target_type]` zone default. Supplying both this and
        `filter[target_type]` with different value sets returns
        `400 Bad Request`.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterTargetType:
      name: filter[target_type]
      in: query
      required: false
      description: |
        Filter on `target_type`. Repeatable; repeated instances OR across
        values. See `FilterValues` in the shared spec for the full wire
        convention.

        Allowed values: `zone`, `user` (`resource` and `session` are
        reserved and not yet accepted). Unknown values return 400 with the
        list of allowed values. Comma-separated single values are rejected
        with a 400 pointing at the repeated-parameter OR form.

        **Defaults to `zone`** when omitted (and no deprecated equivalent
        parameter is supplied), so listings exclude principal-scoped
        elements unless explicitly widened. On `listPolicies` the default
        is skipped when `filter[id]` is present, so by-ID fetches resolve
        regardless of target.

        Note: the allowed-value enum is enforced in the handler (not as an
        OpenAPI `items.enum`) so the server can return a targeted error for
        the comma-AND form instead of a generic "not in allowed values"
        response.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterTargetID:
      name: filter[target_id]
      in: query
      required: false
      description: |
        Filter on `target_id`. Repeatable; repeated instances OR across
        values. See `FilterValues` in the shared spec for the full wire
        convention.

        Zone-targeted elements carry the zone ID as their `target_id`. When
        the effective `filter[target_type]` set is exactly `zone` (including
        via its default), any `filter[target_id]` value other than the path
        `zone_id` returns `400 Bad Request`.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterMode:
      name: filter[mode]
      in: query
      required: false
      description: |
        Filter on binding `mode`. Repeatable; repeated instances OR across
        values. See `FilterValues` in the shared spec for the full wire
        convention.

        Allowed values: `active`, `shadow`. Unknown values return 400 with
        the list of allowed values. Comma-separated single values are
        rejected with a 400 pointing at the repeated-parameter OR form.

        **Defaults to `shadow`** when omitted (and the deprecated bare
        `mode` parameter is absent), preserving the endpoint's historical
        shadow-only listing. Pass `filter[mode]=active` (or both values) to
        widen.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterActiveDecision:
      name: filter[active_decision]
      in: query
      required: false
      description: |
        Filter on `active_decision`. Repeatable; repeated instances OR across
        values. See `FilterValues` in the shared spec for the full wire
        convention.

        Allowed values: `allow`, `deny`. Unknown values return 400 with the
        list of allowed values. Comma-separated single values are rejected
        with a 400 pointing at the repeated-parameter OR form.

        Note: the allowed-value enum is enforced in the handler (not as an
        OpenAPI `items.enum`) so the server can return a targeted error for
        the comma-AND form instead of a generic "not in allowed values"
        response.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterPrincipalType:
      name: filter[principal_type]
      in: query
      required: false
      description: |
        Filter on `principal_type`. Repeatable; repeated instances OR across
        values. See `FilterValues` in the shared spec for the full wire
        convention.

        Allowed values: `user`, `application`. Unknown values return 400
        with the list of allowed values. Comma-separated single values are
        rejected with a 400 pointing at the repeated-parameter OR form.

        Note: the allowed-value enum is enforced in the handler (not as an
        OpenAPI `items.enum`) so the server can return a targeted error for
        the comma-AND form.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterSubjectType:
      name: filter[subject_type]
      in: query
      required: false
      description: |
        Filter on `subject_type`. Repeatable; repeated instances OR across
        values. See `FilterValues` in the shared spec for the full wire
        convention. Rows with `NULL` subject_type are excluded when this
        filter is present.

        Allowed values: `user`, `application`. Unknown values return 400
        with the list of allowed values. Comma-separated single values are
        rejected with a 400 pointing at the repeated-parameter OR form.

        Note: the allowed-value enum is enforced in the handler.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterAuthorityType:
      name: filter[authority_type]
      in: query
      required: false
      description: |
        Filter on `authority_type`. Repeatable; repeated instances OR across
        values. See `FilterValues` in the shared spec for the full wire
        convention. Rows with `NULL` authority_type are excluded when this
        filter is present.

        Allowed values: `delegation`, `impersonation`. Unknown values return
        400 with the list of allowed values. Comma-separated single values
        are rejected with a 400 pointing at the repeated-parameter OR form.

        Note: the allowed-value enum is enforced in the handler.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterHasShadow:
      name: filter[has_shadow]
      in: query
      required: false
      description: |
        Filter by shadow-evaluation presence. When `true`, returns only
        requests that had a shadow policy set version (`shadow_psv_id IS NOT
        NULL`). When `false`, returns only requests without one. Omit to
        return all.
      schema:
        type: boolean
    pdp_FilterPrincipalId:
      name: filter[principal_id]
      in: query
      required: false
      description: |
        Filter on `principal_id` by exact match. Repeatable; repeated
        instances OR across values. See `FilterValues` in the shared spec for
        the full wire convention. Comma-separated single values are rejected
        with a 400 pointing at the repeated-parameter OR form.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterResourceId:
      name: filter[resource_id]
      in: query
      required: false
      description: |
        Filter on `resource_id` by exact match. Repeatable; repeated
        instances OR across values. See `FilterValues` in the shared spec for
        the full wire convention. Comma-separated single values are rejected
        with a 400 pointing at the repeated-parameter OR form.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_FilterSubjectId:
      name: filter[subject_id]
      in: query
      required: false
      description: |
        Filter on `subject_id` by exact match. Repeatable; repeated instances
        OR across values. Rows with `NULL` subject_id are excluded when this
        filter is present. See `FilterValues` in the shared spec for the full
        wire convention.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_FilterValues'
    pdp_QueryName:
      name: query[name]
      in: query
      required: false
      description: >-
        Case-insensitive substring search on `name`. Repeatable; if multiple terms are supplied they are OR-ed (any matching term returns the row).
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_QueryTerms'
    pdp_QueryDescription:
      name: query[description]
      in: query
      required: false
      description: >-
        Case-insensitive substring search on `description` (policies only). Repeatable; if multiple terms are supplied they are OR-ed.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_QueryTerms'
    pdp_Query:
      name: query
      in: query
      required: false
      deprecated: true
      description: >
        **Deprecated.** Use `query[]` instead.


        Identical semantics to `query[]`: case-insensitive substring search across all searchable fields of the resource, repeatable and OR-ed across terms. Still honored for backward compatibility — generated SDK clients serialize the unscoped search parameter without brackets (the OpenAPI name `query[]` is normalized to `query` at generation time). Supplying both `query` and `query[]` with disagreeing values returns `400 Bad Request`.

      x-go-name: QueryDeprecated
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_QueryTerms'
    pdp_QueryUnscoped:
      name: query[]
      in: query
      required: false
      description: >
        Case-insensitive substring search across all searchable fields of the resource. For policies that is `name` and `description`; for policy sets that is `name`. Repeatable; if multiple terms are supplied they are OR-ed.

      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_QueryTerms'
    pdp_QueryAction:
      name: query[action]
      in: query
      required: false
      description: >-
        Case-insensitive substring search on `action`. Repeatable; if multiple terms are supplied they are OR-ed.
      style: form
      explode: true
      schema:
        $ref: '#/components/schemas/pdp_QueryTerms'
    pdp_IsDefault:
      name: is_default
      in: query
      required: false
      deprecated: true
      description: >
        **Deprecated.** Use `filter[default]` instead.


        Filter schemas by default status. When `true`, returns only the zone's default schema. When `false`, returns only non-default schemas. Omit to return all schemas.


        Still honored for backward compatibility. Supplying both `is_default` and `filter[default]` with conflicting values returns `400 Bad Request`.

      schema:
        type: boolean
    pdp_FilterDefault:
      name: filter[default]
      in: query
      required: false
      description: >-
        Filter schemas by default status. When `true`, returns only the zone's default schema. When `false`, returns only non-default schemas. Omit to return all schemas.
      schema:
        type: boolean
    pdp_If-Match:
      name: If-Match
      in: header
      required: false
      description: >-
        ETag value from a previous GET/POST/PATCH response. When provided, the update only succeeds if the resource has not been modified; otherwise 412 Precondition Failed is returned.
      schema:
        type: string
    pdp_X-API-Version:
      name: X-API-Version
      in: header
      required: false
      description: API version header (date-based, e.g. 2026-02-01)
      schema:
        type: string
    pdp_After:
      name: after
      in: query
      required: false
      description: >-
        Cursor for forward pagination. Returned in `Pagination.after_cursor`. Mutually exclusive with `before`.
      schema:
        $ref: '#/components/schemas/pdp_PaginationCursor'
    pdp_Before:
      name: before
      in: query
      required: false
      description: >-
        Cursor for backward pagination. Returned in `Pagination.before_cursor`. Mutually exclusive with `after`.
      schema:
        $ref: '#/components/schemas/pdp_PaginationCursor'
    pdp_Limit:
      name: limit
      in: query
      required: false
      description: Maximum number of items to return per page.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
    pdp_X-Client-Request-ID:
      name: X-Client-Request-ID
      in: header
      description: >-
        Unique request identifier specified by the originating caller and passed along by proxies.
      required: false
      schema:
        type: string
        format: uuid
        x-go-type: uuid.UUID
        x-go-type-import:
          path: github.com/google/uuid
          name: uuid
    vault-api_X-Client-Request-ID:
      name: X-Client-Request-ID
      in: header
      description: >-
        Unique request identifier specified by the originating caller and passed along by proxies.
      required: false
      schema:
        type: string
        format: uuid
        x-go-type: uuid.UUID
        x-go-type-import:
          path: github.com/google/uuid
          name: uuid
  responses:
    common_BadRequestError:
      description: bad request error response when caller supplied invalid input data
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    common_UnauthorizedError:
      description: unauthorized error response when caller session is not authenticated
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    common_ForbiddenError:
      description: >-
        forbidden error response when caller does not have permissions to a resource
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    common_NotFoundError:
      description: >-
        not found error response when caller does not have permission to see a resource or the resource does not exist
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    common_ConflictError:
      description: >-
        conflict error response when a request can not be completed due to a conflict with the current state of the resource
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    common_RateLimitExceededError:
      description: >-
        rate limit exceeded error response when caller has exhausted api limits for the given time period
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    common_InternalServerError:
      description: >-
        internal server error response when server encountered error of its own creation
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    common_ServiceUnavailableError:
      description: >-
        service unavailable error when server you're attempting to reach is not available
      headers:
        X-Request-ID:
          $ref: '#/components/headers/common_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/common_Error'
    catalog_CatalogPackageListResponse:
      description: Paginated list of catalog packages
      headers:
        X-Request-ID:
          $ref: '#/components/headers/catalog_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/catalog_CatalogPackageList'
    catalog_CatalogPackageResponse:
      description: Single catalog package
      headers:
        X-Request-ID:
          $ref: '#/components/headers/catalog_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/catalog_CatalogPackage'
    catalog_BadRequestError:
      description: bad request error response when caller supplied invalid input data
      headers:
        X-Request-ID:
          $ref: '#/components/headers/catalog_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/catalog_Error'
    catalog_UnauthorizedError:
      description: unauthorized error response when caller session is not authenticated
      headers:
        X-Request-ID:
          $ref: '#/components/headers/catalog_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/catalog_Error'
    catalog_ForbiddenError:
      description: >-
        forbidden error response when caller does not have permissions to a resource
      headers:
        X-Request-ID:
          $ref: '#/components/headers/catalog_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/catalog_Error'
    catalog_InternalServerError:
      description: >-
        internal server error response when server encountered error of its own creation
      headers:
        X-Request-ID:
          $ref: '#/components/headers/catalog_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/catalog_Error'
    catalog_NotFoundError:
      description: >-
        not found error response when caller does not have permission to see a resource or the resource does not exist
      headers:
        X-Request-ID:
          $ref: '#/components/headers/catalog_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/catalog_Error'
    org-management_InternalServerError:
      description: >-
        internal server error response when server encountered error of its own creation
      headers:
        X-Request-ID:
          $ref: '#/components/headers/org-management_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/org-management_Error'
    org-management_BadRequestError:
      description: bad request error response when caller supplied invalid input data
      headers:
        X-Request-ID:
          $ref: '#/components/headers/org-management_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/org-management_Error'
    org-management_UnauthorizedError:
      description: unauthorized error response when caller session is not authenticated
      headers:
        X-Request-ID:
          $ref: '#/components/headers/org-management_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/org-management_Error'
    org-management_ForbiddenError:
      description: >-
        forbidden error response when caller does not have permissions to a resource
      headers:
        X-Request-ID:
          $ref: '#/components/headers/org-management_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/org-management_Error'
    org-management_RateLimitExceededError:
      description: >-
        rate limit exceeded error response when caller has exhausted api limits for the given time period
      headers:
        X-Request-ID:
          $ref: '#/components/headers/org-management_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/org-management_Error'
    org-management_ServiceUnavailableError:
      description: >-
        service unavailable error when server you're attempting to reach is not available
      headers:
        X-Request-ID:
          $ref: '#/components/headers/org-management_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/org-management_Error'
    org-management_NotFoundError:
      description: >-
        not found error response when caller does not have permission to see a resource or the resource does not exist
      headers:
        X-Request-ID:
          $ref: '#/components/headers/org-management_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/org-management_Error'
    pdp_InternalServerError:
      description: >-
        internal server error response when server encountered error of its own creation
      headers:
        X-Request-ID:
          $ref: '#/components/headers/pdp_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/pdp_Error'
    pdp_BadRequestError:
      description: bad request error response when caller supplied invalid input data
      headers:
        X-Request-ID:
          $ref: '#/components/headers/pdp_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/pdp_Error'
    pdp_UnauthorizedError:
      description: unauthorized error response when caller session is not authenticated
      headers:
        X-Request-ID:
          $ref: '#/components/headers/pdp_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/pdp_Error'
    pdp_ForbiddenError:
      description: >-
        forbidden error response when caller does not have permissions to a resource
      headers:
        X-Request-ID:
          $ref: '#/components/headers/pdp_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/pdp_Error'
    pdp_NotFoundError:
      description: >-
        not found error response when caller does not have permission to see a resource or the resource does not exist
      headers:
        X-Request-ID:
          $ref: '#/components/headers/pdp_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/pdp_Error'
    pdp_RateLimitExceededError:
      description: >-
        rate limit exceeded error response when caller has exhausted api limits for the given time period
      headers:
        X-Request-ID:
          $ref: '#/components/headers/pdp_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/pdp_Error'
    pdp_ServiceUnavailableError:
      description: >-
        service unavailable error when server you're attempting to reach is not available
      headers:
        X-Request-ID:
          $ref: '#/components/headers/pdp_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/pdp_Error'
    vault-api_InternalServerError:
      description: >-
        internal server error response when server encountered error of its own creation
      headers:
        X-Request-ID:
          $ref: '#/components/headers/vault-api_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/vault-api_Error'
    vault-api_BadRequestError:
      description: bad request error response when caller supplied invalid input data
      headers:
        X-Request-ID:
          $ref: '#/components/headers/vault-api_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/vault-api_Error'
    vault-api_UnauthorizedError:
      description: unauthorized error response when caller session is not authenticated
      headers:
        X-Request-ID:
          $ref: '#/components/headers/vault-api_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/vault-api_Error'
    vault-api_ForbiddenError:
      description: >-
        forbidden error response when caller does not have permissions to a resource
      headers:
        X-Request-ID:
          $ref: '#/components/headers/vault-api_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/vault-api_Error'
    vault-api_NotFoundError:
      description: >-
        not found error response when caller does not have permission to see a resource or the resource does not exist
      headers:
        X-Request-ID:
          $ref: '#/components/headers/vault-api_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/vault-api_Error'
    vault-api_RateLimitExceededError:
      description: >-
        rate limit exceeded error response when caller has exhausted api limits for the given time period
      headers:
        X-Request-ID:
          $ref: '#/components/headers/vault-api_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/vault-api_Error'
    vault-api_ServiceUnavailableError:
      description: >-
        service unavailable error when server you're attempting to reach is not available
      headers:
        X-Request-ID:
          $ref: '#/components/headers/vault-api_X-Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/vault-api_Error'
