# Copyright (c) Abstract Machines
# SPDX-License-Identifier: Apache-2.0

openapi: 3.0.1
info:
  title: SuperMQ Certs service
  description: |
    HTTP API for Certs service
    Some useful links:
    - [The SuperMQ repository](https://github.com/absmach/supermq)
  contact:
    email: info@abstractmachines.fr
  license:
    name: Apache 2.0
    url: https://github.com/absmach/supermq/blob/main/LICENSE
  version: 0.18.0

servers:
  - url: http://localhost:9019
  - url: https://localhost:9019

tags:
  - name: certs
    description: Everything about your Certs
    externalDocs:
      description: Find out more about certs
      url: https://docs.supermq.abstractmachines.fr/

paths:
  /{domainID}/certs:
    post:
      operationId: createCert
      summary: Creates a certificate for client
      description: Creates a certificate for client
      tags:
        - certs
      parameters:
        - $ref: "auth.yaml#/components/parameters/DomainID"
      requestBody:
        $ref: "#/components/requestBodies/CertReq"
      responses:
        "201":
          description: Created
        "400":
          description: Failed due to malformed JSON.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "415":
          description: Missing or invalid content type.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /{domainID}/certs/{certID}:
    get:
      operationId: getCert
      summary: Retrieves a certificate
      description: |
        Retrieves a certificate for a given cert ID.
      tags:
        - certs
      parameters:
        - $ref: "auth.yaml#/components/parameters/DomainID"
        - $ref: "#/components/parameters/CertID"
      responses:
        "200":
          $ref: "#/components/responses/CertRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: |
            Failed to retrieve corresponding certificate.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /{domainID}/certs/{clientID}/revoke-all:
    post:
      operationId: revokeAllCerts
      summary: Revokes all certificates for a given client ID
      description: |
        Revokes all certificates for a given client ID.
      tags:
        - certs
      parameters:
        - $ref: "auth.yaml#/components/parameters/DomainID"
        - $ref: "#/components/parameters/ClientID"
      responses:
        "200":
          $ref: "#/components/responses/RevokeRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: |
            Failed to revoke corresponding certificate.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /{domainID}/certs/{certID}/revoke:
    post:
      operationId: revokeCertBySerial
      summary: Revokes a certificate by serial number
      description: |
        Revokes a certificate for a given certificate serial number.
      tags:
        - certs
      parameters:
        - $ref: "auth.yaml#/components/parameters/DomainID"
        - $ref: "#/components/parameters/CertID"
      responses:
        "200":
          $ref: "#/components/responses/RevokeRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: |
            Failed to revoke corresponding certificate.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /{domainID}/serials/{clientID}:
    get:
      operationId: getSerials
      summary: Retrieves certificates' serial IDs
      description: |
        Retrieves a list of certificates' serial IDs for a given client ID.
      tags:
        - certs
      parameters:
        - $ref: "auth.yaml#/components/parameters/DomainID"
        - $ref: "#/components/parameters/ClientID"
      responses:
        "200":
          $ref: "#/components/responses/SerialsPageRes"
        "400":
          description: Failed due to malformed query parameters.
        "401":
          description: Missing or invalid access token provided.
        "403":
          description: Failed to perform authorization over the entity.
        "404":
          description: |
            Failed to retrieve corresponding certificates.
        "422":
          description: Database can't process request.
        "500":
          $ref: "#/components/responses/ServiceError"

  /health:
    get:
      summary: Retrieves service health check info.
      tags:
        - health
      security: []
      responses:
        "200":
          $ref: "#/components/responses/HealthRes"
        "500":
          $ref: "#/components/responses/ServiceError"

components:
  parameters:
    ClientID:
      name: clientID
      description: Client ID
      in: path
      schema:
        type: string
        format: uuid
      required: true
    CertID:
      name: certID
      description: Serial of certificate
      in: path
      schema:
        type: string
        example: "7c:a9:91:e7:13:e9:5c:6b:1d:16:cf:76:20:82:f3:01:c3:d5:a6:66"
      required: true

  schemas:
    Cert:
      type: object
      properties:
        client_id:
          type: string
          format: uuid
          description: Corresponding SuperMQ Client ID.
        client_cert:
          type: string
          description: Client Certificate.
        client_key:
          type: string
          description: Key for the client_cert.
        issuing_ca:
          type: string
          description: CA Certificate that is used to issue client certs, usually intermediate.
        serial:
          type: string
          description: Certificate serial
        expire:
          type: string
          description: Certificate expiry date
    Serial:
      type: object
      properties:
        serial:
          type: string
          description: Certificate serial
    CertsPage:
      type: object
      properties:
        certs:
          type: array
          minItems: 0
          uniqueItems: true
          items:
            $ref: "#/components/schemas/Cert"
        total:
          type: integer
          description: Total number of items.
        offset:
          type: integer
          description: Number of items to skip during retrieval.
        limit:
          type: integer
          description: Maximum number of items to return in one page.
    SerialsPage:
      type: object
      properties:
        serials:
          type: array
          description: Certificate serials IDs.
          minItems: 0
          uniqueItems: true
          items:
            type: string
        total:
          type: integer
          description: Total number of items.
        offset:
          type: integer
          description: Number of items to skip during retrieval.
        limit:
          type: integer
          description: Maximum number of items to return in one page.
    Revoke:
      type: object
      properties:
        revocation_time:
          type: string
          description: Certificate revocation time

  requestBodies:
    CertReq:
      description: |
        Issues a certificate that is required for mTLS. To create a certificate for a client
        provide a client id, data identifying particular client will be embedded into the Certificate.
        x509 and ECC certificates are supported when using when Openbao is used as PKI.
      content:
        application/json:
          schema:
            type: object
            required:
              - client_id
              - ttl
            properties:
              client_id:
                type: string
                format: uuid
              ttl:
                type: string
                example: "10h"

  responses:
    ServiceError:
      description: Unexpected server-side error occurred.
    CertRes:
      description: Certificate data.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Cert"
      links:
        serial:
          operationId: getSerials
          parameters:
            clientID: $response.body#/client_id
        delete:
          operationId: revokeCertBySerial
          parameters:
            certID: $response.body#/serial
    CertsPageRes:
      description: Certificates page.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/CertsPage"
    SerialsPageRes:
      description: Serials page.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/SerialsPage"
    RevokeRes:
      description: Certificate revoked.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Revoke"
    HealthRes:
      description: Service Health Check.
      content:
        application/health+json:
          schema:
            $ref: "./schemas/health_info.yaml"

  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        * Users access: "Authorization: Bearer <user_token>"

security:
  - bearerAuth: []
