openapi: 3.0.0
info:
  title: Admin API
  description: Admin API for the DNG
  version: 3.3.1
paths:
  /api/web-applications:
    get:
      description: Get Web Applications with pagination.
      operationId: get_web_applications
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        200:
          description: Successful response to get Web Applications.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/WebApplication"
                  metadata:
                    $ref: "#/components/schemas/Metadata"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Create a Web Application.
      operationId: create_web_application
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebApplication"
      responses:
        200:
          description: Successful response to creating a Web Application.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/WebApplication"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/web-applications/{appKey}:
    parameters:
      - $ref: "#/components/parameters/appKey"
    get:
      description: Get a Web Application
      operationId: get_web_application
      responses:
        200:
          description: Successful response to get Web Application.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/WebApplication"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Update a Web Application.
      operationId: update_web_application
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WebApplication"
      responses:
        200:
          description: Successful response to updating a Web Application.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/WebApplication"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    delete:
      description: Delete a Web Application.
      operationId: delete_web_application
      responses:
        200:
          description: Successful response to deleting a Web Application.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/ssh-servers:
    get:
      description: Get all SSH Servers with pagination.
      operationId: get_ssh_servers
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        200:
          description: Successful response to get SSH Servers.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/SSHServer"
                  metadata:
                    $ref: "#/components/schemas/Metadata"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Create an SSH Server.
      operationId: create_ssh_server
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SSHServer"
      responses:
        200:
          description: Successful response to adding an SSH Server.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/SSHServer"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/ssh-servers/{appKey}:
    parameters:
      - $ref: "#/components/parameters/appKey"
    get:
      description: Get an SSH Server.
      operationId: get_ssh_server
      responses:
        200:
          description: Successful response to get an SSH Server.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/SSHServer"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Update an SSH Server.
      operationId: update_ssh_server
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SSHServer"
      responses:
        200:
          description: Successful response to updating an SSH Server.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/SSHServer"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    delete:
      description: Delete an SSH Server.
      operationId: delete_ssh_server
      responses:
        200:
          description: Successful response to deleting an SSH Server.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/application-relays:
    get:
      description: Get all the current application relays with pagination.
      operationId: get_application_relays
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        200:
          description: Successful response to get application relays.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/ApplicationRelay"
                  metadata:
                    $ref: "#/components/schemas/Metadata"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Create an Application Relay.
      operationId: create_application_relay
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ApplicationRelay"
      responses:
        200:
          description: Successful response to creating an Application Relay
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/ApplicationRelay"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/application-relays/{appKey}:
    parameters:
      - $ref : "#/components/parameters/appKey"
    get:
      description: Get a Application Relay
      operationId: get_application_relay
      responses:
        200:
          description: Successful response to getting an Application Relay.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/ApplicationRelay"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Update an Application Relay.
      operationId: update_application_relay
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ApplicationRelay"
      responses:
        200:
          description: Successful response to updating an Application Relay.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/ApplicationRelay"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    delete:
      description: Delete an Application Relay.
      operationId: delete_application_relay
      responses:
        200:
          description: Successful response to deleting an Application Relay.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/subdomains:
    get:
      description: Get all External to Internal Subdomain Translations with pagination.
      operationId: get_subdomains
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        200:
          description: Successful response to get Subdomains.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/Subdomain"
                  metadata:
                    $ref: "#/components/schemas/Metadata"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Set External to Internal Subdomain Translations.
      operationId: set_subdomains
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/Subdomain"
      responses:
        200:
          description: Successful response to setting External to Internal Subdomain Translations.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/Subdomain"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/primary-authentication:
    get:
      description: Get Primary Authentication Configuration.
      operationId: get_primary_authentication
      responses:
        200:
          description: Successful response to get Primary Authentication Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/PrimaryAuthentication"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Set Primary Authentication Configuration.
      operationId: set_primary_authentication
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PrimaryAuthentication"
      responses:
        200:
          description: Successful response to setting Primary Authentication Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/PrimaryAuthentication"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/network-gateway:
    get:
      description: Get Network Gateway Configuration.
      operationId: get_network_gateway
      responses:
        200:
          description: Successful response to get Network Gateway Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/NetworkGateway"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Set Network Gateway Configuration.
      operationId: set_network_gateway
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/NetworkGateway"
      responses:
        200:
          description: Successful response to setting Network Gateway Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/NetworkGateway"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/feature-flags:
    get:
      description: Get Feature Flags Configuration.
      operationId: get_feature_flags
      responses:
        200:
          description: Successful response to get Feature Flags Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/FeatureFlags"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Set Feature Flags Configuration.
      operationId: set_feature_flags
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FeatureFlags"
      responses:
        200:
          description: Successful response to setting Feature Flags Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/FeatureFlags"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/sessions/{username}:
    parameters:
      - $ref: "#/components/parameters/username"
    delete:
      description: Delete user sessions.
      operationId: delete_user_sessions
      responses:
        200:
          description: Successful response to deleting user sessions.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/sessions:
    get:
      description: Get all users sessions.
      operationId: get_users_sessions
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        200:
          description: Successful response to all the user sessions DNG has.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/UserSession"
                  metadata:
                    $ref: "#/components/schemas/Metadata"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"
          
    delete:
      description: Delete all users sessions.
      operationId: delete_users_sessions
      responses:
        200:
          description: Successful response to deleting all the user sessions DNG has.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
        404:
          $ref: "#/components/responses/NotFoundResponse"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"


  /api/duo-admin-api:
    get:
      description: Get Duo Admin API Configuration.
      operationId: get_duo_admin_api
      responses:
        200:
          description: Successful response to get Duo Admin API Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/DuoAdminApi"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Set Duo Admin API Configuration.
      operationId: set_duo_admin_api
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DuoAdminApi"
      responses:
        200:
          description: Successful response to setting Duo Admin API Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    $ref: "#/components/schemas/DuoAdminApi"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/groups:
    get:
      description: Get all Groups with pagination.
      operationId: get_groups
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        200:
          description: Successful response to get Groups.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/Group"
                  metadata:
                    $ref: "#/components/schemas/Metadata"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Set Groups Configuration
      operationId: set_groups
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/Group"
      responses:
        200:
          description: Successful response to setting Groups Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/Group"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

  /api/roles:
    get:
      description: Get all Roles with pagination.
      operationId: get_roles
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        200:
          description: Successful response to get Roles.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/Role"
                  metadata:
                    $ref: "#/components/schemas/Metadata"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

    post:
      description: Set Roles Configuration
      operationId: set_roles
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: "#/components/schemas/Role"
      responses:
        200:
          description: Successful response to setting Roles Configuration.
          content:
            application/json:
              schema:
                type: object
                properties:
                  stat:
                    $ref: "#/components/schemas/Stat"
                  response:
                    type: array
                    items:
                      $ref: "#/components/schemas/Role"
        400:
          $ref: "#/components/responses/BadRequestResponse"
        401:
          $ref: "#/components/responses/UnauthorizedResponse"
        405:
          $ref: "#/components/responses/MethodNotAllowedResponse"

components:
  schemas:
    Stat:
      type: string
      description: Response status
      enum:
        - OK
        - FAIL

    Metadata:
      type: object
      properties:
        total_objects:
          type: integer
        next_offset:
          type: integer
        prev_offset:
          type: integer

    WebApplication:
      type: object
      properties:
        external_hostname:
          type: string
          description: Web application external hostname, should have a corresponding CNAME DNS record
        external_port:
          type: integer
          description: Port to host Web Application
          default: 443
        allowlist_prefixes:
          type: array
          description: List of path prefixes that do not require authentication
          items:
            type: string
          example:
            - /api
        allowlist_suffixes:
          type: array
          description: List of path suffixes that do not require authentication
          items:
            type: string
          example:
            - .jpg
        allowlist_ips:
          type: array
          description: List of IP addresses that do not require authentication
          items:
            type: string
          example:
            - 192.168.0.5
        session_duration:
          type: integer
          description: User session duration length in seconds
          default: 480
        external_ssl_cert:
          $ref: "#/components/schemas/ExternalSSLCert"
        internal_hostname:
          type: string
          description: Internal application hostname
        internal_port:
          type: string
          description: Internal application port
        internal_use_ssl:
          type: boolean
          description: Use SSL for internal application
          default: false
        internal_trusted_cert:
          type: string
          description: Trusted certificate for internal server
          default: ""
        use_internal_name_for_host_header:
          type: boolean
          description: Set the internal hostname as the host header
          default: false
        use_internal_name_for_sni:
          type: boolean
          description: Use the internal hostname for SNI
          default: false
        add_x_forwarded_host:
          type: boolean
          description: Add the x-forwarded-for-host header
          default: false
        add_x_forwarded_proto:
          type: boolean
          description: Add the x-forwarded-for-proto header
          default: false
        upstream_response_timeout:
          type: integer
          description: Upstream response timeout in seconds
          default: 180
        client_max_body_size:
          type: integer
          description: Maximum body size client can upload in MB
          default: 128
        max_header_size:
          type: integer
          description: Maximum header size client can upload in KB
          default: 8
        proxy_buffer_size:
          type: integer
          description: Maximum proxy buffer size in KB for upstream response headers and websocket data streams
          default: 64
        duo_2fa:
          $ref: "#/components/schemas/Duo2FA"

      required:
        - external_hostname
        - external_ssl_cert
        - internal_hostname
        - duo_2fa

    SSHServer:
      type: object
      properties:
        external_hostname:
          type: string
          description: SSH Server hostname, should have a corresponding CNAME DNS record
        external_ssl_cert:
          description: Application Relay hostname, should have a corresponding CNAME DNS record
          $ref: "#/components/schemas/ExternalSSLCert"
        internal_servers:
          type: array
          description: List of internal servers for Application Relay to match
          items:
            $ref: "#/components/schemas/SSHInternalServer"

      required:
        - external_hostname
        - external_ssl_cert
        - internal_servers

    ApplicationRelay:
      type: object
      properties:
        application_type:
          type: string
          default: rdp
        external_hostname:
          type: string
          description: Application Relay hostname, should have a corresponding CNAME DNS record
          format: hostname
        external_ssl_cert:
          description: External Relay Certificate
          $ref: "#/components/schemas/ExternalSSLCert"
        internal_servers:
          type: array
          description: List of internal servers for Application Relay to match
          items:
            $ref: "#/components/schemas/ApplicationRelayInternalServer"

      required:
        - external_hostname
        - external_ssl_cert
        - internal_servers

    ApplicationRelayInternalServer:
      type: object
      properties:
        host_pattern:
          type: string
          description: Internal host pattern to match for an Application Relay
          example: ssh-server.example.com, *.example.com, 192.168.0.2, 192.168.0.1/16, 192.168.0.5-192.168.0.10
        ports:
          type: string
          description: Internal ports to match for an Application Relay
          example: 22,3389,50-60,55,80

      required:
        - host_pattern
        - ports

    SSHInternalServer:
      type: object
      properties:
        host_pattern:
          type: string
          description: Internal host pattern to match for an SSH server
          example: ssh-server.example.com, *.example.com, 192.168.0.2, 192.168.0.1/16, 192.168.0.5-192.168.0.10
        ports:
          type: string
          description: Internal ports to match for an SSH server
          example: 22,3389,50-60,55,80

      required:
        - host_pattern
        - ports

    ExternalSSLCert:
      type: object
      properties:
        source:
          type: string
          description: source of the certificate
          enum: [own, letsencrypt, selfsigned]
        cert:
          type: string
          description: PEM encoded certificate, required if source is set to own
          format: pem
        key:
          type: string
          description: PEM encoded key, required if source is set to own
          format: pem

      required:
        - source

    Duo2FA:
      type: object
      properties:
        ikey:
          type: string
          minLength: 20
          maxLength: 20
          example: DIVH5KOADK1SZ2DYBTQA
        skey:
          type: string
          minLength: 40
          maxLength: 40
          example: hxxrO2NzoDr3fZaiho3hx64UrDl6No8hlc9HnJGy
        apihost:
          type: string
          format: hostname
          example: api-791b28e0.duosecurity.com

      required:
        - ikey
        - skey
        - apihost

    Group:
      properties:
        name:
          type: string
          description: Name of the group
          example: "Engineering"
        duo_group_id:
          type: string
          description: Unique identifier for the group in Duo Admin API
          example: "DIEYR5Z71XNBWAJFBKBM"

      required:
        - name
        - duo_group_id  


    Role:
      type: object
      properties:
        name:
          type: string
          description: Name of the role
          example: "financial"
        session_duration:
          type: integer
          description: Session duration in minutes for users assigned to this role
          example: 60
        internal_servers:
          type: array
          description: List of internal servers that this role can access
          items:
            $ref: "#/components/schemas/ApplicationRelayInternalServer"
        groups:
          type: array
          description: List of group names that are assigned to this role
          items:
            type: string
          example:
            - contractors
            - fulltime

      required:
        - name
        - session_duration
        - internal_servers
        - groups

    NetworkGateway:
      properties:
        hostname:
          type: string
          description: Primary hostname for the DNG.
          format: hostname
        admin_email:
          type: string
          description: Admin email for use with Lets Encrypt.
          format: email
        load_balancer_cidrs_ips:
          type: array
          description: List of Load Balancer CIDRs to trust forwarded for IP headers or proxy protocol.
          items:
            type: string
        load_balancer_proxy_protocol:
          type: boolean
          description: Whether to use proxy protocol, must have specified load balancer CIDRs.
          default: false
        ssl_cert:
          description: Primary hostname SSL certificate
          $ref: "#/components/schemas/ExternalSSLCert"
        password:
          type: string
          description: Password for the DNG Admin UI
          format: password
        enable_ui:
          type: boolean
          description: Whether to enable the DNG Admin UI. If True, requires a password to be set
          default: true

      required:
        - hostname
        - admin_email
        - ssl_cert

    Subdomain:
      properties:
        external_subdomain:
          type: string
          description: External subdomain to map to internal subdomain, should have a corresponding NS DNS record.
          format: hostname
          example: rdp.example.com
        internal_subdomain:
          type: string
          description: Internal subdomain to map to external subdomain.
          format: hostname
          example: example.local

      required:
        - external_subdomain
        - internal_subdomain

    PrimaryAuthentication:
      properties:
        entity_id:
          type: string
          description: Global unique name for the SAML entity.
          example: https://sso-abc1def2.sso.duosecurity.com/saml2/sp/DIABC123678901234567/metadata
        single_signon_url:
          type: string
          description: URL to use when performing authentication
          example: https://sso-abc1def2.sso.duosecurity.com/saml2/sp/DIABC123678901234567/sso
        single_logout_url:
          type: string
          description: URL to use when logging out.
          example: https://sso-abc1def2.sso.duosecurity.com/saml2/sp/DIABC123678901234567/slo
        signing_cert:
          type: string
          description: PEM encoded SAML signing certificate.
          format: pem
        enforced_email_domain:
          type: string
          format: hostname
          description: Only accept authentication from given email domain.
        username_attribute:
          type: string
          description: Use an alternate username attribute other than NameID.

      required:
        - entity_id
        - single_signon_url
        - single_logout_url
        - signing_cert

    FeatureFlags:
      properties:
        api:
          type: boolean
          description: Whether to enable Duo Network Gateway API or not
          default: false

    UserSession:
      type: object
      properties:
        name:
          type: string
          description: Username for the session
      required:
        - name

    DuoAdminApi:
      type: object
      description: Configuration details for the Duo Admin API.
      properties:
        ikey:
          type: string
          description: Integration key for Duo Admin API.
          example: 'DIEYR5Z71XNBWAJFBKBM'
        skey:
          type: string
          description: Secret key for Duo Admin API. This should be kept confidential and never exposed via GET requests.
          example: '0g1d6RM9DOVHaN6TsuOsj53NYgYWBfhjOZJK0Eqx'
        apihost:
          type: string
          format: hostname
          description: API hostname for Duo Admin API.
          example: 'api-791b28e0.duosecurity.com'
      required:
        - ikey
        - skey
        - apihost

  responses:
    NotFoundResponse:
      description: Could not find resource.
      content:
        application/json:
          schema:
            type: object
            properties:
              stat:
                $ref: "#/components/schemas/Stat"
              code:
                type: integer
                description: More specific error code.
              message:
                type: string
                description: Description of failure.
              message_detail:
                type: string
                description: Additional information if applicable.

    BadRequestResponse:
      description: Client has sent a bad request.
      content:
        application/json:
          schema:
            type: object
            properties:
              stat:
                $ref: "#/components/schemas/Stat"
              code:
                type: integer
                description: More specific error code.
              message:
                type: string
                description: Description of failure.
              message_detail:
                type: string
                description: Additional information if applicable.

    UnauthorizedResponse:
      description: Client did not present a valid client certificate
      content:
        application/json:
          schema:
            type: object
            properties:
              stat:
                $ref: "#/components/schemas/Stat"
              code:
                type: integer
                description: More specific error code.
              message:
                type: string
                description: Description of failure.
              message_detail:
                type: string
                description: Additional information if applicable.

    MethodNotAllowedResponse:
      description: Request HTTP verb is not valid for this endpoint.
      content:
        application/json:
          schema:
            type: object
            properties:
              stat:
                $ref: "#/components/schemas/Stat"
              code:
                type: integer
                description: More specific error code.
              message:
                type: string
                description: Description of failure.
              message_detail:
                type: string
                description: Additional information if applicable.

  parameters:
    Offset:
      description: Paging offset
      in: query
      name: offset
      schema:
        type: integer
        minimum: 0
        default: 0
      required: false

    Limit:
      description: Paging limit
      in: query
      name: limit
      schema:
        type: integer
        minimum: 0
        default: 10
        maximum: 100
      required: false

    appKey:
      in: path
      name: appKey
      required: true
      schema:
        type: string
      description: Unique Application Key.

    username:
      in: path
      name: username
      required: true
      schema:
        type: string
      description: The username of the logged in user.
