swagger: '2.0'
info:
  description: >-
    This API provides operations to manage your access to customer IoT data, namely

      1. The operations return a Technical Token, which gives access to the tenant's IoT data
      2. The operations return a Impersonated User Token, if respective payload is provided.
      3. Provides list of allowed users to an application hosted by Developer/Operator tenant

        ## Limitations

      - The service may decide to throttle API requests temporarily returning a 429 status code.

  version: 4.0.0
  x-visibility: 'external'
  title: Technical Token Manager API

produces:
  - application/json
consumes:
  - application/json

host: api.eu1.siemens.app
schemes:
  - https
basePath: /technicaltokenmanager-1000001700/v3

tags:
  - name: Token Operations
    description: >-
      Operations to get technical tokens.
  - name: User Tenant Operations
    description: >-
      Operations to get provisioned user tenants.

securityDefinitions:
  token_basicauth:
    type: "basic"
    description: The Authorization header value is a combination of your application's secret credentials, the user name / ID and password / values. Combine the two values, separating them with a colon, and Base64 encode the combined values. These credentials should be available in Environment variables of CF-space where application is deployed.Credentials - MDSP_KEY_STORE_CLIENT_ID MDSP_KEY_STORE_CLIENT_SECRET. Example "Basic ZGlvcDEtaGVybW..."
  userTenants:
    type: "oauth2"
    authorizationUrl: "http://UAA_DOMAIN//oauth/token"
    tokenUrl: "http://UAA_DOMAIN/oauth/token"
    flow: "accessCode"
    scopes:
      km.usr: "Permission to fetch user tenant records those have access to the app"

paths:
  /oauth/token:
    post:
      security:
      - token_basicauth: []
      - {}
      operationId: getToken
      tags:
        - Token Operations
      summary: Issues technical token to access customer IoT data.
      description: |
        Returns a technical user access token for the user tenant ID specified in the request body.

        The operation can be used by operator and developer tenants. Custom authentication is required, as described in detail at paramter X-SPACE-AUTH-KEY. Instead of X-SPACE-AUTH-KEY header, the Authorization header can also be used.

        The request information can be specified as a part of the body or as query parameters. Mixed forms are not allowed - You cannot specify some parameters in the query parameters and the remaining as a part of the request body.

        - When a developer tenant has hosted an app and a token has to be issued for the developer tenant, then the values of 'userTenant' and hostTenant' should both be equal to the developer tenant ID in the request payload or in the query parameters.
        - When an operator tenant has hosted an app and a token has to be issued for the operator tenant, then the values of 'userTenant' and hostTenant' should both be equal to the operator tenant ID in the request payload or in the query parameters.
        - When an operator tenant has hosted an app and provisioned it to another tenant and a token is to be issued for the provisioned tenant, then the value of the 'hostTenant' should be equal to operator tenant ID and the value of 'userTenant' should be equal to the provisioned tenant's ID in the request payload or in the query parameters.
        - In case of impersonated user token, along with appname, appVersion, host and user two more paramaters are required in request body. 'caller_context_type' and 'caller_context'. The value of 'caller_context_type' should be equal to 'access_token'. The value of 'caller_context' should be a valid access token based upon caller_context_type.
        - Note : 'caller_context_type' and 'caller_context' are optional paramter to issue technical token to access customer IoT data, but these are required to generate impersonated user token.
        - The 'user-impersonation' feature is made available in Jan 2023.
        - Note : User impersonated token can not be generated for existing app credentials created before Jan 2023. For apps in Developer Cockpit, the app credentials needs to be revoked and regenerated so that User impersonated token feature can be availed on same app version. For apps in Operator Cockpit, new version of app (with app credentials) needs to be created via Developer Cockpit and version upgrade needs to be performed in Operator Cockpit. This app credentials of the upgraded app version will have user impersonated token feature.


      parameters:
        - in: header
          name: X-SPACE-AUTH-KEY
          type: string
          description: |
            Is used as authentication information for this operation. The value of this header must be constructed according to basic authentication as

                  Basic Base64("clientID:clientSecret")

              where Base64(.) must be replaced by the Base64 encoded string of its argument string, including the separator colon. For self-hosted applications, clientID and clientSecret are flashed on the screen when registering the application, for Cloud Foundry based applications clientID and clientSecret can be obtained from the environment variables of a MindSphere CloudFoundry application, where the relation from environment variable to client credentials is given by

                  MDSP_KEY_STORE_CLIENT_ID     --> clientID
                  MDSP_KEY_STORE_CLIENT_SECRET --> clientSecret
              <br>**Instead of specifying the header name as 'X-SPACE-AUTH-KEY', you can use 'Authorization' header as well. Note that the Authorization header has the same value as X-SPACE-AUTH-KEY.**
        - name: body
          in: body
          description: Contains appname, appVersion, host and user for which token is required. <br>**Specify the body with all the four parameters only if the query parameters 'appName', 'appVersion', 'hostTenant' and 'userTenant' are not specified.<br/> Mixed forms are not allowed - You cannot specify some parameters in the query parameters and the remaining as a part of the body. <br>'caller_context' and 'caller_context_type' are optioanl but to aquire impersonated user token, In addtion to above four paramaetrs, 'caller_context' and 'caller_context_type' must be specified as a part of the payload.<br/>**
          schema:
            $ref: '#/definitions/Identification'
        - in: query
          name: appName
          type: string
          description: Specifies app name for which the token is being fetched.
        - in: query
          name: appVersion
          type: string
          description: Specifies app version of the app for which the token is being fetched.
        - in: query
          name: hostTenant
          type: string
          description: The host tenant is the tenant which deploys and administers the app. Specifies the tenant ID of the host tenant of the app for which the token is being fetched.
        - in: query
          name: userTenant
          type: string
          description: The user tenant is the tenant which consumes the app. Specifies the tenant ID of the user tenant of the app for which the token is being fetched.
        - in: query
          name: caller_context
          type: string
          description: This is optional parameter, which is required only in case of user impersonation. A valid combination of caller_context and caller_context_type must be provided to get an user impersonated token. 
        - in: query
          name: caller_context_type
          type: string
          description: This is optional parameter, which is required only in case of user impersonation. This is mandatory parameter along with caller_context. Sepcifies the type of context. Accepted  value is 'access_token'
      responses:
        '200':
          description: returns a valid Technical Token.
          schema:
            $ref: '#/definitions/AccessTokenResponse'
        '400':
          description: |
            Bad request. Possible reasons:<br/>
            - Authentication information is not provided in 'Authorization' header or 'X-SPACE-AUTH-KEY' header.
            - All four parameters: 'appName', 'appVersion', 'hostTenant' and 'userTenant' are not specified as a part of the query parameters
            - All four attributes: 'appName', 'appVersion', 'hostTenant' and 'userTenant' are not specified as a part of the request payload
            - Provided tenant {tenantId} for which token is requested is in DELETED status.
            - Provided tenant {tenantId} for which token is requested is in INACTIVE status whose deletion is already in progress.
        'default':
          description: Other error with any status code and response body format.




  /oauthTokens:
    post:
      operationId: getOauthTokens
      tags:
        - Token Operations
      summary: Issues multiple technical tokens to access customer IoT data.
      description: |
        Returns a technical user access token for each user tenant ID specified in the request body. A maximum of 2 access tokens can be requested in one call.

        The operation can be used by operator and developer tenants. Custom authentication is required, as described in detail at paramter X-SPACE-AUTH-KEY.

        - When a developer tenant has hosted an app and a token has to be issued for the developer tenant, then the values of 'userTenant' and hostTenant' should both be equal to the developer tenant ID in the request payload.
        - When an operator tenant has hosted an app and a token has to be issued for the operator tenant, then the values of 'userTenant' and hostTenant' should both be equal to the operator tenant ID in the request payload.
        - When an operator tenant has hosted an app and provisioned it to another tenant and a token is to be issued for the provisioned tenant, then the value of the 'hostTenant' should be equal to operator tenant ID and the value of 'userTenant' should be equal to the provisioned tenant's ID in the reqeust payload.

      parameters:
        - in: header
          name: X-SPACE-AUTH-KEY
          type: string
          required: true
          description: |
            Is used as authentication information for this operation. The value of this header must be constructed according to basic authentication as

                  Basic Base64("clientID:clientSecret")

              where Base64(.) must be replaced by the Base64 encoded string of its argument string, including the separator colon. clientID and clientSecret can be obtained from the environment variables of a MindSphere CloudFoundry application, where the relation from environment variable to client credentials is given by

                  MDSP_KEY_STORE_CLIENT_ID     --> clientID
                  MDSP_KEY_STORE_CLIENT_SECRET --> clientSecret
        - name: body
          in: body
          required: true
          schema:
            $ref: '#/definitions/TokensPayload'
      responses:
        '200':
          description: OK-
          schema:
            $ref: '#/definitions/TokensResponse'
        '400':
          description: |
            Bad request. Possible reasons:
            - The number of user tenant IDs are more than 2 (mdsp.core.keymanager.invalidRequestBody)</br>
            - Only the host tenant ID is mentioned(mdsp.core.keymanager.invalidRequestBody)</br>
            - There are no user tenant IDs provided(mdsp.core.keymanager.invalidRequestBody)</br>
            - Host tenant ID is empty(mdsp.core.keymanager.invalidRequestBody)</br>
            - Invalid tenant ID is specified in user tenant IDs or host tenant ID field(mdsp.core.keymanager.invalidRequestBody)
          schema:
            $ref: '#/definitions/Errors'
        'default':
          description: Other error with any status code and response body format.

  /userTenants:
    get:
      operationId: getUserTenantsByHost
      tags:
        - User Tenant Operations
      security:
      - userTenants:
        - "km.usr"
      summary: Provides list of user tenants provisioned to an application.
      description: |
        Provides a list of user tenant IDs of the user tenants being provisioned to an application. A user tenant is a customer or user of an application. Up to 500 user tenant IDs are returned. The operation can be used by operator and developer tenants. This endpoint needs an Authorization header with bearer token. Token for developer or host tenant can be obtained by calling "/oauth/token" or "/oauthTokens" endpoint and using the tenand ID of the developer tenant or the host tenant as the value for both 'userTenant' and 'hostTenant' attributes in the request payload.
      parameters:
        - $ref: '#/parameters/page'
        - $ref: '#/parameters/size'
      responses:
        '200':
          description: OK
          schema:
            $ref: '#/definitions/UserTenantResponse'
        '400':
          description: |
            Bad request. Possible reasons: </br>
            - Invalid Host Token(mdsp.core.keymanager.invalidHostTokenFormat)</br>
            - Unidentified User(mdsp.core.keymanager.unidentifiedUser)</br>
            - Page Size specified is more than maximum supported page size(mdsp.core.keymanager.pageSizeForUserTenantsExceeded).
          schema:
            $ref: '#/definitions/Errors'
        'default':
          description: Other error with any status code and response body format.

definitions:
    Identification:
      type: object
      properties:
        appName:
          type: string
          description: Name of the application from Operator/Developer Cockpit
          example: "testapplication"
        appVersion:
          type: string
          description: Version of the application as given in Operation/Developer Cockpit.
          example: "1.0.0"
        hostTenant:
          type: string
          description: Tenant ID of the developer/operator tenant hosting the application.
          example: "testhosttenant1"
        userTenant:
          type: string
          description: Tenant ID of the tenant owning the data to be accessed with the Technical Token.
          example: "testusertenant1"
        caller_context:
          type: string
          description: access_token
          format: access_token
        caller_context_type:
          type: string
          description: Type of caller context should be 'access_token'
          example: "access_token"


    AccessTokenResponse:
      type: object
      properties:
        access_token:
          type: string
          example: "eyJhbGciOi..."
          description: JWT bearer access Technical Token to access IoT data.
        token_type:
          type: string
          example: "bearer"
          description: "Type of the token provided by the API."
        timestamp:
          type: number
          example: "1559120938825"
        expires_in:
          type: integer
          format: int64
          description: "Number of seconds before this token expires from the time of issuance."
          example: 1799
        scope:
          type: string
          example: "cst.r uts.su im.usr.r em.rep.r tm.st.r tm.t.r agm.r iam-action.client_credentials.tenant-impersonation uts.ri asm.r atm.r uts.rc uaa.offline_token emds.ent.r asm.rep.r iam-action.client_credentials.user-impersonation mdsp:core:Admin3rdPartyTechUser"
        jti:
          type: string
          description: The jti (JWT ID) claim provides a unique identifier for the JWT.The jti claim can be used to prevent the JWT from being replayed. The jti value is a case-sensitive string.
          example: 'b019ceb63513456c88f2d67c0e92d35b'

    TokensPayload:
      type: object
      required:
      - appName
      - appVersion
      - hostTenantId
      - userTenantIds
      properties:
        appName:
          type: string
          description: Name of the application from Operator/Developer Cockpit
          example: "testapplication"
        appVersion:
          type: string
          description: Version of the application as given in Operation/Developer Cockpit.
          example: "1.0.0"
        hostTenantId:
          type: string
          description: Tenant ID of the developer/operator tenant hosting the application.
          example: "testhosttenant1"
        userTenantIds:
          description: List of Tenant IDs of the tenants owning the data to be accessed with the Technical Token.
          type: array
          maxItems: 2
          items:
              type: string
          example: [ "usertenanta", "usertenantb" ]

    TokensResponse:
      type: "object"
      properties:
        oauthTokens:
          type: array
          items:
            type: object
            properties:
              userTenantId:
                type: string
                description: Tenant ID of the tenant owning the data to be accessed with the Technical Token.
                example: "testusertenant1"
              token:
                $ref: '#/definitions/AccessTokenResponse'


    UserTenantResponse:
      type: "object"
      properties:
        page:
          $ref: '#/definitions/Page'
        userTenants:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                description: Tenant IDs provisioned by Developer/Operator tenant.
                example: testusertenant1

    Page:
      type: object
      properties:
        size:
          type: integer
        totalElements:
          type: integer
        totalPages:
          type: integer
        number:
          type: integer

    Errors:
      type: object
      description: Error response body model.
      properties:
        errors:
          type: array
          description: "Concrete error codes and messages are defined at operation error response descriptions in this API specification."
          items:
            type: object
            properties:
              code:
                type: string
                description: "Unique error code. Every code is bound to one (parametrized) message."
                format: "mdsp.core.<service/app>.<errorid>"
                example: "mdsp.core.keymanager.invalidAppNameFormat"
              logref:
                type: string
                description: "Logging correlation ID for debugging purposes."
                example: "0bff7e7a-cd25-4576-9908-4180ef086174"
              message:
                type: string
                description: "Human readable error message in English."
                example: "Example error message with parameter value 100"
parameters:
  page:
    name: page
    in: query
    type: integer
    default: 0
    description: Specifies the requested page index
  size:
    name: size
    in: query
    type: integer
    default: 500 & Max 500
    description: Specifies the number of elements in a page. Maximum value for size is 100