components:
  schemas:
    Error:
      properties:
        error:
          example: unauthenticated
          type: string
        requestId:
          example: e7c61d23-0b1a-4d3e-8a0b-18d4f1d7e2c3
          type: string
        violations:
          items:
            $ref: '#/components/schemas/Violation'
          type: array
          uniqueItems: false
      required:
      - error
      type: object
    InfoResponse:
      properties:
        name:
          example: prod-gateway
          type: string
        namespace:
          example: llm-gateway
          type: string
      required:
      - name
      - namespace
      type: object
    McpServerCatalog:
      properties:
        items:
          items:
            $ref: '#/components/schemas/McpServerEntry'
          type: array
          uniqueItems: false
      required:
      - items
      type: object
    McpServerEntry:
      properties:
        description:
          type: string
        name:
          maxLength: 253
          type: string
        ready:
          type: boolean
      required:
      - name
      type: object
    MeResponse:
      properties:
        email:
          example: admin@example.com
          format: email
          type: string
        groups:
          items:
            type: string
          type: array
          uniqueItems: false
        roles:
          items:
            type: string
          type: array
          uniqueItems: false
        subject:
          example: github|42
          type: string
      required:
      - groups
      - roles
      - subject
      type: object
    OpenAIModel:
      properties:
        context_window:
          example: 200000
          type: integer
        created:
          example: 1690000000
          type: integer
        display_name:
          type: string
        id:
          example: openai/gpt-4o-mini
          type: string
        object:
          example: model
          type: string
        owned_by:
          example: openai
          type: string
      required:
      - created
      - id
      - object
      - owned_by
      type: object
    OpenAIModelList:
      properties:
        data:
          items:
            $ref: '#/components/schemas/OpenAIModel'
          type: array
          uniqueItems: false
        object:
          example: list
          type: string
      required:
      - data
      - object
      type: object
    Violation:
      properties:
        field:
          example: /spec/auth/workloadIssuers/0/allowedSubjects
          type: string
        message:
          example: must contain at least one entry
          type: string
      required:
      - field
      - message
      type: object
  securitySchemes:
    BearerAuth:
      description: Bearer JWT validated against the AIGateway's OIDC provider.
      in: header
      name: Authorization
      type: apiKey
externalDocs:
  description: ""
  url: ""
info:
  contact:
    name: Stacklok LLM Gateway
    url: https://github.com/stacklok/stacklok-llm-gateway
  description: |-
    Gateway-scoped HTTP API backing caller introspection and model/MCP catalogs.
    Endpoints read the owning `AIGateway` and, for `/v1/me`, the
    authenticated caller's identity directly from the apiserver.
    No parallel store.

    ## Scope

    Each API server instance is bound to exactly one Kubernetes namespace
    (configured via operator flag) and the `AIGateway` it serves lives in
    that namespace. The namespace is therefore **not** in the URL path;
    multi-namespace deployments run multiple API instances.

    ## Authentication and authorization

    All requests require a bearer JWT validated against the OIDC provider
    configured on the target `AIGateway` (`spec.auth.oidc`). `/v1/me` also
    returns roles resolved from `AIGateway.spec.auth.authz.roles`.
  license:
    name: Apache-2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  title: Stacklok LLM Gateway Management API
  version: 0.1.0
openapi: 3.1.0
paths:
  /v1/info:
    get:
      description: |-
        Returns the AIGateway name and namespace this api-key-service
        serves. Sourced from the operator-injected GATEWAY_NAME /
        GATEWAY_NAMESPACE — authoritative and unambiguous.
      operationId: getInfo
      parameters:
      - description: Correlation ID; echoed on responses and included in audit records.
        in: header
        name: X-Request-Id
        schema:
          type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InfoResponse'
          description: OK
          headers:
            X-Request-Id:
              description: Echoed correlation ID.
              schema:
                type: string
        "401":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Missing or invalid JWT.
        x-required-role: authenticated
      security:
      - BearerAuth: []
      summary: Return the owning gateway's identity.
      tags:
      - Catalog
  /v1/mcp-servers:
    get:
      description: |-
        Forward-compatible; always returns an empty `items` array in
        Phase 8. Enforcement lands in a later phase.
      operationId: listMcpServers
      parameters:
      - description: Correlation ID; echoed on responses and included in audit records.
        in: header
        name: X-Request-Id
        schema:
          type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/McpServerCatalog'
          description: OK
          headers:
            X-Request-Id:
              description: Echoed correlation ID.
              schema:
                type: string
        "401":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Missing or invalid JWT.
        "429":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Rate limit exceeded.
        "503":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Kubernetes API unavailable.
        x-required-role: authenticated
      security:
      - BearerAuth: []
      summary: List all MCP servers visible to the gateway.
      tags:
      - Catalog
  /v1/me:
    get:
      description: Returns subject, groups, and resolved management roles.
      operationId: getMe
      parameters:
      - description: Correlation ID; echoed on responses and included in audit records.
        in: header
        name: X-Request-Id
        schema:
          type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MeResponse'
          description: OK
          headers:
            X-Request-Id:
              description: Echoed correlation ID.
              schema:
                type: string
        "401":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Missing or invalid JWT.
        x-required-role: authenticated
      security:
      - BearerAuth: []
      summary: Return the caller's identity and resolved management roles.
      tags:
      - Introspection
  /v1/models:
    get:
      description: |-
        Derived from the owning AIGateway's `spec.routes[].match.model`,
        then filtered to the caller's effective model access as the
        Directory decides it — so this surface and the data-plane
        GET /v1/models intercept always agree about what the caller
        may call. Deduplicated and sorted by model id, OpenAI-shaped
        (`object:"list"`, `data[]`) to match that intercept.

        `?scope=all` returns the complete configured catalog instead,
        unfiltered, for an Admin authoring a Model Set — who must be
        able to grant models their own access does not include. It
        requires the deployment's admin role.
      operationId: listModels
      parameters:
      - description: Correlation ID; echoed on responses and included in audit records.
        in: header
        name: X-Request-Id
        schema:
          type: string
      - description: Set to `all` for the complete configured catalog, unfiltered.
          Requires the admin role.
        in: query
        name: scope
        schema:
          enum:
          - all
          type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OpenAIModelList'
          description: OK
          headers:
            X-Request-Id:
              description: Echoed correlation ID.
              schema:
                type: string
        "400":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Multiple AIGateways found, or an unsupported scope value.
        "401":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Missing or invalid JWT.
        "403":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Authenticated but bound to a namespace the caller cannot query,
            or asked for scope=all without the admin role.
        "404":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: No AIGateway configured in the namespace.
        "429":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Rate limit exceeded.
        "503":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
          description: Kubernetes API unavailable, or model access could not be decided.
            Never answered with an unfiltered catalog.
        x-required-role: authenticated
      security:
      - BearerAuth: []
      summary: List the models the calling user may use.
      tags:
      - Catalog
servers:
- url: management.invalid/
