openapi: 3.1.0
info:
  title: DTZ Identity
  version: 2.1.6
  description: a generated client for the DTZ Identity API
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
  contact:
    name: Jens Walter
    email: jens@apimeister.com
servers:
- url: https://identity.dtz.rocks/api/2021-02-21
paths:
  /auth/apikey:
    post:
      summary: authenticate with apikey
      operationId: authenticateApikey
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ApikeyRequest'
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        "401":
          description: not authenticated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "503":
          description: authentication backend temporarily unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /signup:
    post:
      summary: create a new identity with the given email as account email, also create an authentication with the given credentials to allow a login, creates a default context
      operationId: userSignup
      security: []
      requestBody:
        description: signup
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupRequest'
        required: true
      responses:
        "200":
          description: user created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        "409":
          description: account already registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "400":
          description: invalid email
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "500":
          description: server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /signup_with_redirect:
    post:
      summary: create a new identity and redirect to oauth authorize instead of returning a token
      description: |
        Creates a new identity and its user authentication, provisions a default context, and then responds like a successful OAuth authorization request.

        Instead of returning a token, the server immediately generates an authorization `code` bound to the newly created identity and default context and returns a JSON payload with a `location` field pointing to `https://dtz.rocks?code=...`.

        The code can be exchanged via `/oauth/token` to retrieve an access token for the default context.
      operationId: userSignupWithRedirect
      security: []
      requestBody:
        description: signup
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignupRequest'
        required: true
      responses:
        "200":
          description: returns JSON containing a `location` with an OAuth authorization code (default context)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OauthCodeResponse'
        "409":
          description: account already registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "400":
          description: invalid email
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "500":
          description: server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /authentication:
    get:
      summary: list user authentications
      operationId: listAuthentication
      responses:
        "200":
          description: list of authentication
          content:
            application/json:
              schema:
                type: object
                properties:
                  identityId:
                    type: string
                    format: IdentityId
                  userAuth:
                    type: array
                    items:
                      type: object
                      properties:
                        userName:
                          type: string
                        defaultContextId:
                          type: string
                          format: ContextId
                      required:
                        - userName
                  apiKeyAuth:
                    type: array
                    items:
                      type: object
                      properties:
                        apiKey:
                          type: string
                        defaultContextId:
                          type: string
                          format: ContextId
                        alias:
                          type: string
                        createdAt:
                          type: string
                          format: date-time
                        lastUsedAt:
                          type: string
                          format: date-time
                  oauthAuth:
                    type: array

    post:
      summary: update the user authentication, aka change you password or default context
      operationId: changeAuthentication
      requestBody:
        description: update an existing authentication
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                oldPassword:
                  type: string
                newPassword:
                  type: string
                defaultContextId:
                  type: string
                  format: ContextId
              required:
                - email
      responses:
        "200":
          description: success
  /context:
    get:
      summary: get a list of contexts that the user has access to
      operationId: listAvailableContexts
      responses:
        "200":
          description: all context ids
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    contextId:
                      type: string
                      format: ContextId
  /context/{context_id}:
    delete:
      summary: delete all roles attached to this context
      operationId: deleteContextRoles
      parameters:
        - in: path
          name: context_id
          schema:
            type: string
            pattern: 'context-[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}'
            examples:
              - sample_id:
                value: context-01909cb6-225b-7f11-8779-c401fbee19ff
          required: true
          description: context_id
      responses:
        "200":
          description: status
  /context/{context_id}/new:
    post:
      summary: create identity requirements for a new context
      operationId: newContext
      parameters:
        - in: path
          name: context_id
          schema:
            type: string
            format: ContextId
          required: true
          description: context_id
      requestBody:
        description: context creation request
        content:
          application/json:
            schema:
              type: object
              properties:
                identity_id:
                  type: string
                  format: IdentityId
                service_principal_id:
                  type: string
                  format: IdentityId
      responses:
        "200":
          description: status
  /identity:
    get:
      summary: get a list of all available identities
      operationId: listIdentity
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  currentIdentity:
                    type: string
                  identities:
                    type: array
                    items:
                      type: object
                      properties:
                        identityId:
                          type: string
                        email:
                          type: string
                        description:
                          type: string
    post:
      summary: creates a new identity
      operationId: newIdentity
      requestBody:
        description: create identity request
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                description:
                  type: string
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  identityId:
                    type: string
                  email:
                    type: string
                  description:
                    type: string
  /identity/assume:
    post: 
      summary: assume identity
      operationId: assumeIdentity
      requestBody:
        description: assume different identity
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                identityId:
                  type: string
                  format: IdentityId
                contextId:
                  type: string
                  format: ContextId
                  description: target context the token is issued for. The request fails if the caller is not authorized to assume the identity, the identity does not exist, the context does not exist, or the identity has no access to the context.
      responses:
        "200":
          description: success
          content: 
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        "401":
          description: Invalid input
          content: 
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /identity/check:
    post: 
      summary: checks whether an identity exists
      operationId: checkIdentity
      requestBody:
        description: checking for existing identity
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                identityId:
                  type: string
                  format: IdentityId
      responses:
        "200":
          description: success
          content: 
            application/json:
              schema:
                type: object
                properties:
                  exists:
                    type: boolean
        "401":
          description: Invalid input
          content: 
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /me:
    get:
      summary: get account stats
      operationId: getAccountStats
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  roles:
                    type: array
                    items:
                      type: object
                      properties:
                        contextId:
                          type: string
                          format: ContextId
                        count:
                          type: number
                  identityCount: 
                    type: number
                  authenticationCount:
                    type: number
  /me/email:
    get:
      summary: Get account email
      operationId: getAccountEmail
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  email:
                    type: string
        "404":
          description: Email not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /me/identity:
    delete:
      summary: delete current identity
      operationId: deleteIdentity
      responses:
        "200":
          description: success
  /me/identity/apikey:
    post:
      summary: create api key
      operationId: createApiKey
      requestBody:
        description: api key creation
        content:
          application/json:
            schema:
              type: object
              properties:
                contextId:
                  type: string
                  format: ContextId
                alias:
                  type: string
              required:
              - contextId
        required: true
      responses:
        "200":
          description: success
          content:
            text/plain:
              schema:
                type: string
              examples:
                text:
                  summary: api key
                  value: apikey-00000000-0000-0000-0000-000000000000
  /me/identity/apikey/{apikey}:
    delete:
      summary: delete api key
      operationId: deleteApiKey
      parameters:
        - in: path
          name: apikey
          schema:
            type: string
            format: ApikeyId
          required: true
          description: api key
      responses:
        "200":
          description: success
    patch:
      summary: update the api key alias
      operationId: updateApiKeyAlias
      parameters:
        - in: path
          name: apikey
          schema:
            type: string
            format: ApikeyId
          required: true
          description: api key
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                alias:
                  type: string
      responses:
        "200":
          description: success
  /me/roles/{roleId}:
    post:
      summary: assign an existing concrete role to the current identity
      operationId: assignConcreteRole
      parameters:
        - in: path
          name: roleId
          schema:
            type: string
            format: RoleId
          required: true
          description: role id
      responses:
        "200":
          description: success
    delete:
      summary: remove assignment of a concrete role from current identity
      operationId: unassignConcreteRole
      parameters:
        - in: path
          name: roleId
          schema:
            type: string
            format: RoleId
          required: true
          description: role id
      responses:
        "200":
          description: success
        "404":
          description: role not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /token/auth:
    post:
      summary: user login
      operationId: userLogin
      security: []
      requestBody:
        description: login
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthRequest'
        required: true
      responses:
        "200":
          description: success
          content: 
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        "401":
          description: Invalid input
          content: 
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /token/refresh:
    post:
      summary: token refresh, this operation is also used to switch context
      description: this operation either returns a new token or a new token for a different context. Switching to an unknown context or a context unavailable to the current identity fails.
      operationId: tokenRefresh
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangeContextRequest'
        required: true
      responses:
        "200":
          description: success
          content: 
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        "400":
          description: unknown context
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /roles:
    get:
      summary: get roles which are abstract - not assigned to any context or identity
      operationId: getAbstractRoles
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  roles:
                    type: array
                    items:
                      $ref: '#/components/schemas/AbstractRole'
  /roles/context/{contextId}:
    get:
      summary: get roles for a certain context id
      operationId: getConcreteRolesForContext
      parameters:
        - in: path
          name: contextId
          schema:
            type: string
            format: ContextId
          required: true
          description: context id
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  roles:
                    type: array
                    items:
                      $ref: '#/components/schemas/ContextRole'
    post:
      summary: create role from abstract role (template)
      operationId: createConcreteRoleForContext
      parameters:
        - in: path
          name: contextId
          schema:
            type: string
            format: ContextId
          required: true
          description: context id
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                roleId:
                  type: string
                  format: RoleId
              required:
              - roleId
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContextRole'  
  /roles/identity/{identityId}:
    get:
      summary: get roles for a certain identity id
      operationId: getConcreteRolesForIdentity
      parameters:
        - in: path
          name: identityId
          schema:
            type: string
            format: IdentityId
          required: true
          description: identity id
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  roles:
                    type: array
                    items:
                      $ref: '#/components/schemas/IdentityRole'
  /roles/{roleId}/identity:
    get:
      summary: get all indentities which have this role assigned to
      operationId: getRoleAssignment
      parameters:
        - in: path
          name: roleId
          schema:
            type: string
            format: RoleId
          required: true
          description: role id
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RoleAssignmentEntry'
        "401":
          description: unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "500":
          description: server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /roles/{roleId}/identity/{identityId}:
    delete:
      summary: revoke a context role assignment from an identity
      operationId: revokeRoleAssignment
      parameters:
        - in: path
          name: roleId
          schema:
            type: string
            format: RoleId
          required: true
          description: role id
        - in: path
          name: identityId
          schema:
            type: string
            format: IdentityId
          required: true
          description: identity id
      responses:
        "204":
          description: role assignment revoked
        "401":
          description: unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "404":
          description: role assignment not found in the current context
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "500":
          description: server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /roles/{roleId}/share:
    post:
      summary: sharing a role with another identity
      operationId: shareConcreteRole
      parameters:
        - in: path
          name: roleId
          schema:
            type: string
            format: RoleId
          required: true
          description: role id
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                identityId:
                  type: string
                  format: IdentityId
        required: true
      responses:
        "200":
          description: success
        "401":
          description: unauthorized
        "400":
          description: bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /oauth/authorize:
    get:
      summary: oauth authorize
      operationId: oauthAuthorize
      x-dtz-include-headers: true
      parameters: 
        - in: query
          name: response_type
          schema:
            type: string
          required: true
        - in: query
          name: client_id
          schema:
            type: string
          required: true
        - in: query
          name: redirect_uri
          schema:
            type: string
          required: true
        - in: query
          name: scope
          schema:
            type: string
          required: true
        - in: query
          name: state
          schema:
            type: string
        - in: query
          name: nonce
          schema:
            type: string
      responses:
        "302":
          description: success
          headers:
            Location:
              schema:
                type: string
              description: redirect uri
        "307":
          description: temporary redirect to login when unauthenticated
          headers:
            Location:
              schema:
                type: string
              description: login url
        "401":
          description: unauthorized
    post:
      summary: oauth authorize
      operationId: oauthAuthorizePost
      x-dtz-include-headers: true
      parameters: 
        - in: query
          name: response_type
          schema:
            type: string
          required: true
        - in: query
          name: client_id
          schema:
            type: string
          required: true
        - in: query
          name: redirect_uri
          schema:
            type: string
          required: true
        - in: query
          name: scope
          schema:
            type: string
          required: true
        - in: query
          name: state
          schema:
            type: string
        - in: query
          name: nonce
          schema:
            type: string
      responses:
        "302":
          description: success
          headers:
            Location:
              schema:
                type: string
              description: redirect uri
        "307":
          description: temporary redirect to login when unauthenticated
          headers:
            Location:
              schema:
                type: string
              description: login url
        "401":
          description: unauthorized
  /oauth/token:
    post:
      summary: oauth token request
      description: oauth token request
      operationId: oauthToken
      security: []
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/OauthTokenRequest'
        required: true
      responses:
        "200":
          description: success
          content: 
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        "400":
          description: invalid token format
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "401":
          description: unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        "500":
          description: internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /oauth/userinfo:
    get:
      summary: get user information from oauth token
      description: returns the decoded JWT token content containing user information
      operationId: oauthUserinfo
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                description: Decoded JWT token content
                additionalProperties: true
        "401":
          description: unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /oauth/register:
    post:
      summary: register oauth client
      description: register a new oauth client application
      operationId: oauthRegister
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                redirect_uris:
                  type: array
                  items:
                    type: string
                  description: List of allowed redirect URIs
                client_name:
                  type: string
                  description: Optional client application name
                logo_uri:
                  type: string
                  description: Optional logo URI for the client
              required:
                - redirect_uris
        required: true
      responses:
        "200":
          description: success
          content:
            application/json:
              schema:
                type: object
                properties:
                  client_id:
                    type: string
                    description: The registered client ID
                  client_secret:
                    type: string
                    description: Optional client secret (if generated)
                  client_id_issued_at:
                    type: string
                    format: date-time
                    description: When the client ID was issued
                  client_secret_expires_at:
                    type: string
                    format: date-time
                    description: When the client secret expires (if applicable)      
components:
  schemas:
    OauthCodeResponse:
      type: object
      properties:
        code:
          type: string
          description: OAuth authorization code
    ApikeyRequest:
      type: object
      properties:
        apiKey:
          type: string
        contextId:
          type: string
          format: ContextId
      required:
      - apiKey
    ErrorResponse:
      type: object
      properties:
        msg:
          type: string
    SignupRequest:
      type: object
      properties:
        email:
          type: string
        password:
          type: string
      required:
        - email
        - password
    AuthRequest:
      type: object
      properties:
        username:
          type: string
        password:
          type: string
        scopes:
          type: array
          items:
            type: string
      required:
        - username
        - password
    ChangeContextRequest:
      type: object
      properties:
        contextId:
          type: string
          format: ContextId
    TokenResponse:
      type: object
      properties:
        access_token:
          type: string
        scope:
          type: string
        token_type:
          type: string
        expires_in:
          type: number
      required:
      - access_token
      - token_type
      - expires_in
    AbstractRole:
      type: object
      properties:
        roleId:
          type: string
          format: RoleId
        roleAlias:
          type: string
        roleScope:
          type: string
      required:
      - roleId
      - roleScope
    ContextRole:
      type: object
      properties:
        roleId:
          type: string
          format: RoleId
        abstractRoleId:
          type: string
          format: RoleId
        roleAlias:
          type: string
        roleScope:
          type: string
        assignedToUser:
          type: boolean
      required:
        - roleId
        - roleAlias
        - roleScope
    IdentityRole:
      type: object
      properties:
        roleId:
          type: string
          format: RoleId
        abstractRoleId:
          type: string
          format: RoleId
        roleAlias:
          type: string
        roleScope:
          type: string
        assignedToUser:
          type: boolean
      required:
        - roleId
        - roleAlias
        - roleScope
    Role:
      type: object
      properties:
        roleId:
          type: string
          format: RoleId
        roleAlias:
          type: string
        roleScope:
          type: string
        contextId:
          type: string
          format: ContextId
        assignedToUser:
          type: boolean
      required:
        - roleId
        - roleAlias
        - roleScope
    RoleAssignmentEntry:
      type: object
      properties:
        identityId:
          type: string
          format: IdentityId
        email:
          type: string
      required:
        - identityId
    OauthTokenRequest:
      type: object
      properties:
        grant_type:
          type: string
        client_id:
          type: string
        client_secret:
          type: string
        redirect_uri:
          type: string
        code:
          type: string
      required:
      - grant_type
      - client_id
      - client_secret
      - redirect_uri
      - code
  securitySchemes:
    dtz_oauth:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: https://identity.dtz.rocks/api/2021-02-21/oauth/authorize
          tokenUrl: https://identity.dtz.rocks/api/2021-02-21/oauth/token
          scopes: {}
    dtz_apikey:
      type: apiKey
      in: header
      name: X-API-KEY
    dtz-cookie:
      type: apiKey
      in: cookie
      name: dtz-auth
security:
  - dtz_apikey: []
  - dtz_oauth: []
  - dtz-cookie: []