> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Issue a Service Credential

> Single-tenant only. Issues the credential a Lerian service signs in with: `source` is the service the credential speaks for, recorded as its `sourceService` claim, and `target` the service it calls. Both must appear in `GET /v1/applications/available`.

Only a person may call this. An application token is refused even when it may create applications.

The application is displayed as `{target}-service`. For target `plugin-identity` it joins no permission: it only authenticates the service's own permission declaration. For any other target it is listed on the target's service lane, `{target}-service-m2m-permission`, which carries the roles the target declares in `m2m.service_roles`; it never joins the client lane `{target}-m2m-permission`.

⚠️ The response carries the `clientSecret` IN FULL, and no other Identity API response returns it.

Revoke it with `DELETE /v1/applications/{id}`, which also removes it from the service lane. Each issue is a new credential, so to rotate one: issue the new one, deploy it, then revoke the old one.

Failures:
- `400` — `source` or `target` is missing, or `IDE-0012` when either is not in the catalog.
- `403` — the caller is an application, not a person (`401` where M2M inversion is off).
- `409 IDE-1065` — the generated application name is taken. Nothing was created; retry it.
- `422` — the target has no service lane yet: it declares no `m2m.service_roles`, or it has not published its declaration. Nothing was created.
- `501` — multi-tenant deployment: the tenant manager issues service credentials there.
- `503 IDE-0064` / `IDE-0065` — another write to the same service lane held it past the wait, or the service that coordinates those writes did not answer. Nothing was created; retry it.
- `503 IDE-0066` — the identity provider is unavailable (unreachable, too slow to answer, or failing). Nothing about the request was wrong; retry it later.



## OpenAPI

````yaml /en/openapi/v3-current/AM-identity.yaml post /v1/applications/service-credentials
openapi: 3.1.0
info:
  contact:
    name: Lerian Studio
    url: https://lerian.studio
  description: OpenAPI 3.1 surface for the Access Manager identity component.
  license:
    name: Lerian Studio General License
  title: Plugin Access Manager — Identity API
  version: v1
servers:
  - url: https://identity.sandbox.lerian.net
security: []
tags:
  - description: >-
      M2M-only: each plugin declares its own permissions, roles and M2M
      contract, and the server reconciles them.
    name: Declarations
  - description: >-
      A tenant administrator's customers. Each partner holds what its
      credentials may DO (permissions, per product) and WHERE they may do it
      (scope, per product and dimension); an M2M application attached to one is
      confined to that intersection. Administrator-only: authorized on the
      "partners" resource, and every route resolves the owning organization from
      the caller's token.
    name: Partners
paths:
  /v1/applications/service-credentials:
    post:
      tags:
        - Applications
      summary: Issue a Service Credential
      description: >-
        Single-tenant only. Issues the credential a Lerian service signs in
        with: `source` is the service the credential speaks for, recorded as its
        `sourceService` claim, and `target` the service it calls. Both must
        appear in `GET /v1/applications/available`.


        Only a person may call this. An application token is refused even when
        it may create applications.


        The application is displayed as `{target}-service`. For target
        `plugin-identity` it joins no permission: it only authenticates the
        service's own permission declaration. For any other target it is listed
        on the target's service lane, `{target}-service-m2m-permission`, which
        carries the roles the target declares in `m2m.service_roles`; it never
        joins the client lane `{target}-m2m-permission`.


        ⚠️ The response carries the `clientSecret` IN FULL, and no other
        Identity API response returns it.


        Revoke it with `DELETE /v1/applications/{id}`, which also removes it
        from the service lane. Each issue is a new credential, so to rotate one:
        issue the new one, deploy it, then revoke the old one.


        Failures:

        - `400` — `source` or `target` is missing, or `IDE-0012` when either is
        not in the catalog.

        - `403` — the caller is an application, not a person (`401` where M2M
        inversion is off).

        - `409 IDE-1065` — the generated application name is taken. Nothing was
        created; retry it.

        - `422` — the target has no service lane yet: it declares no
        `m2m.service_roles`, or it has not published its declaration. Nothing
        was created.

        - `501` — multi-tenant deployment: the tenant manager issues service
        credentials there.

        - `503 IDE-0064` / `IDE-0065` — another write to the same service lane
        held it past the wait, or the service that coordinates those writes did
        not answer. Nothing was created; retry it.

        - `503 IDE-0066` — the identity provider is unavailable (unreachable,
        too slow to answer, or failing). Nothing about the request was wrong;
        retry it later.
      operationId: issueServiceCredential
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ServiceCredentialInput'
              description: The service credential to issue.
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApplicationResponse'
          description: Created
        '400':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Bad Request
        '401':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Unauthorized
        '403':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Forbidden
        '409':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Conflict
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Unprocessable Entity
        '500':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Internal Server Error
        '501':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Not Implemented
        '503':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPError'
          description: Service Unavailable
      security:
        - BearerAuth: []
components:
  schemas:
    ServiceCredentialInput:
      additionalProperties: false
      properties:
        source:
          description: >-
            The Lerian service that signs in with this credential; it becomes
            the sourceService claim. Must match GET /v1/applications/available.
          examples:
            - jd-courier
          type: string
        target:
          description: >-
            The service this credential calls. Must match GET
            /v1/applications/available.
          examples:
            - plugin-identity
          type: string
      required:
        - source
        - target
      type: object
    ApplicationResponse:
      additionalProperties: false
      properties:
        clientId:
          type: string
        clientSecret:
          description: >-
            Returned only by the create call. Absent from every Identity API
            read.
          type: string
        createdAt:
          examples:
            - '2021-09-01T00:00:00Z'
          type: string
        description:
          examples:
            - Midaz Used By Application X
          type: string
        id:
          examples:
            - 00000000-0000-0000-0000-000000000000
          type: string
        name:
          examples:
            - Midaz
          type: string
        partnerId:
          examples:
            - 00000000-0000-0000-0000-000000000000
          type: string
      type: object
    HTTPError:
      additionalProperties: false
      properties:
        code:
          type: string
        entityType:
          type: string
        err: {}
        message:
          type: string
        title:
          type: string
      type: object
  securitySchemes:
    BearerAuth:
      bearerFormat: JWT
      description: JWT bearer token issued by the identity provider.
      scheme: bearer
      type: http

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.