openapi: "3.0.0"
info:
  title: Nuts Auth Service API spec
  version: 1.0.0
servers:
  - url: http://localhost:1323
paths:
  /internal/auth/v1/signature/session:
    post:
      operationId: createSignSession
      summary: Create a signing session for a supported means.
      description: |
        Create a signing session for a supported means.

        error returns:
        * 400 - one of the parameters has the wrong format
      tags:
        - contract
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SignSessionRequest"
      responses:
        201:
          description: When the signing session was successfully created.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignSessionResponse"
        default:
          $ref: '../common/error_response.yaml'

  /internal/auth/v1/signature/session/{sessionID}:
    get:
      operationId: getSignSessionStatus
      summary: Get the current status of a signing session
      description: |
        Get the current status of a signing session

        error returns:
        * 404 - session could not be found
        * 500 - internal server error
      tags:
        - contract
      parameters:
        - name: sessionID
          in: path
          required: true
          schema:
            type: string
      responses:
        200:
          description: When the session is found. Contains the current session status.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignSessionStatusResponse"
        default:
          $ref: '../common/error_response.yaml'

  /internal/auth/v1/signature/verify:
    put:
      operationId: verifySignature
      summary: Verify a signature in the form of a verifiable presentation
      description: |
        Verify a signature in the form of a verifiable presentation

        error returns:
        * 400 - one of the parameters has the wrong format
        * 500 - internal server error
      tags:
        - contract
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SignatureVerificationRequest"
      responses:
        200:
          description: "When the verification could be performed. The response contains the verification result. Note: This status code does not indicate the validity of the signature."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SignatureVerificationResponse"
        default:
          $ref: '../common/error_response.yaml'

  /public/auth/v1/contract/{contractType}:
    get:
      operationId: getContractByType
      summary: Get a contract by type and version
      description: |
        Get contract by type and version

        error returns:
        * 404 - contract does not exists
      tags:
        - contract
      parameters:
        - name: contractType
          in: path
          required: true
          schema:
            type: string
        - name: version
          description: The version of this contract. If omitted, the most recent version will be returned
          required: false
          in: query
          schema:
            type: string
        - name: language
          in: query
          required: false
          schema:
            type: string
            default: nl
      responses:
        '200':
          description: Returns the contract of this type, version, and language
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Contract"
        default:
          $ref: '../common/error_response.yaml'

  /internal/auth/v1/contract/drawup:
    put:
      operationId: drawUpContract
      summary: Draw up a contract using a specified contract template, language and version
      description: |
        Draw up a contract using a specified contract template, language and version

        error returns:
        * 400 - one of the parameters has the wrong format
        * 404 - combination of template, language, and version not found
      tags:
        - contract
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DrawUpContractRequest"
      responses:
        200:
          description: When the contract was drawn up successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ContractResponse"
        default:
          $ref: '../common/error_response.yaml'

  /internal/auth/v1/jwt-grant:
    post:
      operationId: createJwtGrant
      summary: Create a JWT Grant
      description: |
        Create a JWT Grant which can be used in the createAccessToken request in the assertion field

        error returns:
        * 400 - one of the parameters has the wrong format
      tags:
        - auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateJwtGrantRequest"
      responses:
        '200':
          description: Successful request. Responds with JWT encoded Bearer Token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JwtGrantResponse"
        default:
          $ref: '../common/error_response.yaml'

  /internal/auth/v1/request-access-token:
    post:
      operationId: requestAccessToken
      summary: Request an access token from the authorizer
      description: |
        Create a JWT Grant and use it as authorization grant to get an access token from the authorizer.

        error returns:
        * 400 - one of the parameters has the wrong format
        * 503 - the authorizer could not be reached or returned an error
      tags:
        - auth
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RequestAccessTokenRequest"
      responses:
        '200':
          description: Successful request. Responds with an access token.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccessTokenResponse"
        default:
          $ref: '../common/error_response.yaml'

  /n2n/auth/v1/accesstoken:
    post:
      operationId: createAccessToken
      summary: Create an access token using a JWT as authorization grant
      description: |
        Create an access token using a JWT as authorization grant.
        This endpoint must be available to other nodes for other applications to request access tokens.
        It requires a two-way TLS connection according to the network agreement.

        error returns:
        * Follows the oauth framework error response: RFC6749
      tags:
        - auth
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: "#/components/schemas/CreateAccessTokenRequest"
      responses:
        '200':
          description: The posted JWT is valid. Responds with access token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccessTokenResponse"
        '400':
          description: The posted JWT is invalid.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AccessTokenRequestFailedResponse"

  /internal/auth/v1/accesstoken/verify:
    head:
      operationId: verifyAccessToken
      summary: Verifies the provided access token
      description: |
        Verifies the access token given in the Authorization header (as bearer token). If it's a valid access token issued by this server, it'll return a 200 status code.

        error returns:
        * 403 - Token cannot be verified. Note that the contents of the access token are not returned. The introspection API is for that.
      tags:
        - auth
      parameters:
        - name: Authorization
          in: header
          required: true
          schema:
            type: string
      responses:
        '200':
          description: The access token is valid. It has been signed by this server.
        '403':
          description: The given access token is invalid or couldn't be verified.

  /internal/auth/v1/accesstoken/introspect:
    post:
      operationId: introspectAccessToken
      summary: Introspection endpoint to retrieve information from an Access Token as described by RFC7662
      tags:
        - auth
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required:
                - token
              properties:
                token:
                  type: string
                  description: JWT access token
      responses:
        '200':
          description: | 
            An Introspection response as described in RFC7662 section 2.2. The Irma, Dummy and Employee identity means all return 'username', 'initials',  'prefix', 'family_name' and 'assurance_level'.
            'username' should be used as unique identifier for the user.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenIntrospectionResponse"

components:
  schemas:
    VerifiableCredential:
      $ref: '../common/ssi_types.yaml#/components/schemas/VerifiableCredential'
    #
    # Everything related to sessions and signing
    #
    SignSessionRequest:
      required:
        - means
        - payload
        - params
      properties:
        means:
          type: string
          enum: [ irma, employeeid, dummy ]
          example: irma
        params:
          type: object
          description: Params are passed to the means. Should be documented in the means documentation.
        payload:
          type: string
          description: Base64 encoded payload what needs to be signed.
    SignSessionResponse:
      required:
        - sessionID
        - sessionPtr
        - means
      properties:
        sessionID:
          description: Unique identifier of this sign session.
          type: string
        sessionPtr:
          description: A pointer to a sign session. This is an opaque value which only has meaning in the context of the signing means. Can be an URL, base64 encoded image of a QRCode etc.
          type: object
        means:
          description: The means this session uses to sign.
          type: string
          enum: [ irma, employeeid, dummy ]
          example: irma
    SignSessionStatusResponse:
      required:
        - status
      properties:
        status:
          description: Status indicates the status of the signing process. Values depend on the implementation of the signing means.
          type: string
        verifiablePresentation:
          $ref: "#/components/schemas/VerifiablePresentation"
    VerifiablePresentation:
      $ref: '../common/ssi_types.yaml#/components/schemas/VerifiablePresentation'
    SignatureVerificationRequest:
      type: object
      required:
        - VerifiablePresentation
      properties:
        VerifiablePresentation:
          $ref: "#/components/schemas/VerifiablePresentation"
        checkTime:
          description: Moment in time to check the validity of the signature. If omitted, the current time is used.
          type: string
          example: "2019-06-24T14:32:00+02:00"
    SignatureVerificationResponse:
      description: Contains the signature verification result.
      type: object
      required:
        - validity
      properties:
        validity:
          type: boolean
          description: Indicates the validity of the signature.
        vpType:
          description: Type of Verifiable credential.
          example: NutsDelegation
          type: string
        issuerAttributes:
          description: Key vale pairs containing the attributes of the issuer.
          type: object
          example:
            uziNr: 9000382
            firstName: Henk
            lastName: de Vries
        credentials:
          description: Key value pairs containing claims and their values.
          type: object
          example:
            organization: Zorgcentrum de Oosterlanden
            validFrom: 2020-12-16T10:57:00
            validTo: 2020-12-16T12:57:00
    #
    # Everything related to Contracts
    #
    ContractType:
      type: string
      description: Type of which contract to sign.
      example: "BehandelaarLogin"
    ContractLanguage:
      type: string
      description: Language of the contract in all caps.
      example: "NL"
    ContractVersion:
      type: string
      description: Version of the contract.
      example: "v1"
    LegalEntity:
      type: string
      description: DID of the organization as registered in the Nuts registry.
      example: "did:nuts:EwVMYK2ugaMvRHUbGFBhuyF423JuNQbtpes35eHhkQic"
    Contract:
      required:
        - type
        - version
        - language
      properties:
        type:
          $ref: "#/components/schemas/ContractType"
        language:
          $ref: "#/components/schemas/ContractLanguage"
        version:
          $ref: "#/components/schemas/ContractVersion"
        signer_attributes:
          example:
          type: array
          items:
            type: string
        template:
          type: string
          example: ik verklaar dat ${acting_party} namens mij request mag maken
        template_attributes:
          type: array
          items:
            type: string
          example: [ "irma-demo.MijnOverheid.ageLower.over12",
                     "irma-demo.MijnOverheid.fullName"
          ]
    ContractSigningRequest:
      required:
        - type
        - version
        - language
        - legalEntity
      properties:
        type:
          $ref: "#/components/schemas/ContractType"
        language:
          $ref: "#/components/schemas/ContractLanguage"
        version:
          $ref: "#/components/schemas/ContractVersion"
        legalEntity:
          $ref: "#/components/schemas/LegalEntity"
        valid_from:
          type: string
          description: "ValidFrom describes the time from which this contract should be considered valid"
          example: "2019-06-24T14:32:00+02:00"
        valid_to:
          type: string
          description: "ValidTo describes the time until this contract should be considered valid"
          example: "2019-12-24T14:32:00+02:00"
    ContractResponse:
      required:
        - message
        - type
        - version
        - language
      properties:
        message:
          type: string
          description: The contract message.
          example: I hereby declare that Pro Gen - Italia should be make requests in my name
        type:
          $ref: "#/components/schemas/ContractType"
        language:
          $ref: "#/components/schemas/ContractLanguage"
        version:
          $ref: "#/components/schemas/ContractVersion"
    DrawUpContractRequest:
      required:
        - type
        - version
        - language
        - legalEntity
      properties:
        type:
          $ref: "#/components/schemas/ContractType"
        language:
          $ref: "#/components/schemas/ContractLanguage"
        version:
          $ref: "#/components/schemas/ContractVersion"
        legalEntity:
          $ref: "#/components/schemas/LegalEntity"
        validFrom:
          type: string
          description: validFrom describes the time from which this contract should be considered valid. Current time is used when omitted.
          example: "2019-06-24T14:32:00+02:00"
        validDuration:
          type: string
          description: "The duration this contract is valid, starting from validFrom or current time if validFrom is omitted. Uses this node default when omitted. Valid time units are: 's', 'm', 'h'"
          example: "2h"
        organizationCredential:
          $ref: '#/components/schemas/VerifiableCredential'
    #
    # Everything related to JWT Grants
    #
    CreateJwtGrantRequest:
      description: Request for a JWT Grant. The grant can be used during a Access Token Request in the assertion field
      required:
        - authorizer
        - requester
        - service
        - credentials
      properties:
        authorizer:
          type: string
        requester:
          type: string
        identity:
          $ref: "#/components/schemas/VerifiablePresentation"
        service:
          type: string
          description: The service for which this access token can be used. The right oauth endpoint is selected based on the service.
          example: nuts-patient-transfer
        credentials:
          type: array
          items:
            $ref: '#/components/schemas/VerifiableCredential'
    JwtGrantResponse:
      description: Response with a JWT Grant. It contains a JWT, signed with the private key of the requestor software vendor.
      required:
        - bearer_token
        - authorization_server_endpoint
      properties:
        bearer_token:
          type: string
        authorization_server_endpoint:
          description: The URL that corresponds to the oauth endpoint of the selected service.
          type: string

    #
    # Everything related to Access Tokens
    #
    RequestAccessTokenRequest:
      description: Request for a JWT Grant and use it as authorization grant to get the access token from the authorizer
      required:
        - authorizer
        - requester
        - service
        - credentials
      properties:
        authorizer:
          type: string
        requester:
          type: string
        identity:
          $ref: '#/components/schemas/VerifiablePresentation'
        service:
          type: string
          description: The service for which this access token can be used. The right oauth endpoint is selected based on the service.
          example: nuts-patient-transfer
        credentials:
          description: Verifiable Credentials to be included in the access token. If no VCs are to be included in the access token, the array can be left empty.
          type: array
          items:
            $ref: '#/components/schemas/VerifiableCredential'
    CreateAccessTokenRequest:
      description: Request as described in RFC7523 section 2.1
      required:
        - grant_type
        - assertion
      properties:
        grant_type:
          type: string
          description: always must contain the value "urn:ietf:params:oauth:grant-type:jwt-bearer"
          example: urn:ietf:params:oauth:grant-type:jwt-bearer
        assertion:
          type: string
          description: Base64 encoded JWT following rfc7523 and the Nuts documentation
          example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ1cm46b2lkOjIuMTYuODQwLjEuMTEzODgzLjIuNC42LjE6NDgwMDAwMDAiLCJzdWIiOiJ1cm46b2lkOjIuMTYuODQwLjEuMTEzODgzLjIuNC42LjE6MTI0ODEyNDgiLCJzaWQiOiJ1cm46b2lkOjIuMTYuODQwLjEuMTEzODgzLjIuNC42LjM6OTk5OTk5MCIsImF1ZCI6Imh0dHBzOi8vdGFyZ2V0X3Rva2VuX2VuZHBvaW50IiwidXNpIjoiYmFzZTY0IGVuY29kZWQgc2lnbmF0dXJlIiwiZXhwIjoxNTc4MTEwNDgxLCJpYXQiOjE1Nzg5MTA0ODEsImp0aSI6IjEyMy00NTYtNzg5In0.76XtU81IyR3Ak_2fgrYsuLcvxndf0eedT1mFPa-rPXk"
    AccessTokenResponse:
      description: Successful response as described in rfc6749 section 5.1
      required:
        - access_token
        - token_type
        - expires_in
      properties:
        access_token:
          description: |
            The access token issued by the authorization server.
            Could be a signed JWT or a random number. It should not have a meaning to the client.
          type: string
          example:
            "12345"
        token_type:
          description: The type of the token issued
          type: string
          example: "nuts_session_token"
        expires_in:
          type: integer
          description: The lifetime in seconds of the access token.
          example: 900
    AccessTokenRequestFailedResponse:
      description: Error response when access token request fails as described in rfc6749 section 5.2
      required:
        - error
        - error_description
      properties:
        error:
          type: string
          enum: [ invalid_request, invalid_grant, unsupported_grant_type ]
        error_description:
          description: >
            Human-readable ASCII text providing
            additional information, used to assist the client developer in
            understanding the error that occurred.
          type: string
    TokenIntrospectionRequest:
      description: Token introspection request as described in RFC7662 section 2.1
      required:
        - token
      properties:
        token:
          type: string
          example:
            eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhaWQiOiJ1cm46b2lkOjIuMTYuODQwLjEuMTEzODgzLjIuNC42LjE6MDAwMDAwMDAiLCJleHAiOjE1ODE0MTI2NjcsImlhdCI6MTU4MTQxMTc2NywiaXNzIjoidXJuOm9pZDoyLjE2Ljg0MC4xLjExMzg4My4yLjQuNi4xOjAwMDAwMDAxIiwic2lkIjoidXJuOm9pZDoyLjE2Ljg0MC4xLjExMzg4My4yLjQuNi4zOjk5OTk5OTk5MCIsInN1YiI6IiJ9.OhniTJcPS45nhJVqXfxsngG5eYS_0BvqFg-96zaWFO90I_5_N9Eg_k7NmIF5eNZ9Xutl1aqSxlSp80EX07Gmk8uzZO9PEReo0YZxnNQV-Zeq1njCMmfdwusmiczFlwcBi5Bl1xYGmLrxP7NcAoljmDgMgmLH0xaKfP4VVim6snPkPHqBdSzAgSrrc-cgVDLl-9V2obPB1HiVsFMYfbHEIb4MPsnPRnSGavYHTxt34mHbRsS8BvoBy3v6VNYaewLr6yz-_Zstrnr4I_wxtYbSiPJUeVQHcD-a9Ck53BdjspnhVHZ4IFVvuNrpflVaB1A7P3A2xZ7G_a8gF_SHMynYSA
    TokenIntrospectionResponse:
      description: Token introspection response as described in RFC7662 section 2.2
      required:
        - active
      properties:
        active:
          type: boolean
          description: |
            True if the token is active, false if the token is expired, malformed etc.
        service:
          type: string
        iss:
          type: string
          description: |
            The subject (not a Nuts subject) contains the DID of the authorizer.
          example: did:nuts:EwVMYK2ugaMvRHUbGFBhuyF423JuNQbtpes35eHhkQic
        sub:
          type: string
          description: |
            The subject is always the acting party, thus the care organization requesting access to data.
          example: did:nuts:EwVMYK2ugaMvRHUbGFBhuyF423JuNQbtpes35eHhkQic
        aud:
          type: string
          description: |
            As per rfc7523 https://tools.ietf.org/html/rfc7523>, the aud must be the
            token endpoint. This can be taken from the Nuts registry.
          example: "https://target_token_endpoint"
        vcs:
          type: array
          items:
            type: string
            description: credential ID as string
        resolvedVCs:
          type: array
          items:
            $ref: '#/components/schemas/VerifiableCredential'
          description: credentials resolved from `vcs` (VC IDs). It contains only those VCs that could be resolved.
        osi:
          type: string
          description: encoded ops signature. (TBD)
        exp:
          type: integer
        iat:
          type: integer
        family_name:
          type: string
          description: Surname(s) or last name(s) of the End-User.
          example: Bruijn
        prefix:
          type: string
          description: Surname prefix
          example: de
        initials:
          type: string
          description: Initials of the End-User.
          example: I.
        email:
          type: string
          description: End-User's preferred e-mail address. Should be a personal email and can be used to uniquely identify a user. Just like the email used for an account.
          example: w.debruijn@example.org
        username:
          type: string
          description: Identifier uniquely identifying the End-User's account in the issuing system.
        assurance_level:
          type: string
          description: Assurance level of the identity of the End-User.
          format: enum
          enum: [low, substantial, high]
        user_role:
          type: string
          description: Role of the End-User.
  securitySchemes:
    jwtBearerAuth:
      type: http
      scheme: bearer

security:
  - {}
  - jwtBearerAuth: []