# Integration Steps

### Prerequisites

- The legal entity has completed onboarding in the DOME ecosystem.
- The LEAR has obtained a valid **LEARCredentialMachine** through the Issuer service.
- DID method supported: `did:key`.
- The client’s private key is securely stored (e.g., in an HSM or vault).
- Access to developer documentation and environment URLs.

---

### Step 1 – Generating key pair: did:key + private key

You will need a `did:key` / private-key pair. It can be obtained through different methods. One option we can propose is to use our [Issue](https://issuer.dome-marketplace.eu/home)r: when issuing a [LEARCredentialMachine](https://knowledgebase.dome-marketplace.eu/books/dome-credential-issuer-user-guide/page/lear-credential-machine-issuance), a key pair is generated for the client. The corresponding `did:key` is set as the `mandatee.id` in the credential (which you can check in the [details page](https://knowledgebase.dome-marketplace.eu/books/dome-credential-issuer-user-guide/page/credentials-management) after issuing it --no need to activate it). The private key must be kept securely on your side and is never shared.

---

### Step 2 – Client configuration

**Client type:** Confidential.

- Obtain and store the assigned `client_id,` which should be the did:key generated in the previous step.
- Ensure the `redirect_uri` is pre-registered and uses HTTPS.
- Implement JWT-based client authentication (`client_secret_jwt`). You client will need a `request_uri` where a signed JWT token must be exposed (see the authorization request step).

**Outcome:**  
The confidential client is fully configured to authenticate using signed JWTs and perform the Authorization Code Flow.

### Step 3 – Registering to the Verifier (Trusted Services List)

The relying party must be registered in the [Trusted Services List](https://github.com/DOME-Marketplace/trust-framework). The data must match with your client's configuration (see step 2).

<table id="bkmrk-field-description-cl"><tbody><tr><td>**Field**

</td><td>**Description**

</td></tr><tr><td>clientId

</td><td>Should be a did:key that identifies your client.

</td></tr><tr><td>url

</td><td>The base URL of your service or application.

</td></tr><tr><td>redirectUris

</td><td>Must include all the URLs where you expect to receive authentication responses.

</td></tr><tr><td>scopes

</td><td>Currently, only openid\_learcredential is accepted. This scope allows your service to request the necessary credentials.

</td></tr><tr><td>clientAuthenticationMethods

</td><td>Must be set to \["client\_secret\_jwt"\]

</td></tr><tr><td>authorizationGrantTypes

</td><td>Must be set to \["authorization\_code"\] and \["refresh\_token"\] if needed.

</td></tr><tr><td>postLogoutRedirectUris

</td><td>Include URLs where users should be redirected after they log out from your service.

</td></tr><tr><td>requireAuthorizationConsent

</td><td>Set to false.

</td></tr><tr><td>requireProofKey

</td><td>Set to false.

</td></tr><tr><td>jwkSetUrl

</td><td>Since you're using a did:key for your clientId, you do not need to provide your own jwkSetUrl: the verifier can derive your JWKS directly from the did:key. Just add this string: “&lt;verifier-url&gt;/oidc/did/&lt;your-did-key&gt;”.

</td></tr><tr><td>tokenEndpointAuthenticationSigningAlgorithm

</td><td>Must be set to ES256, as this is the only supported algorithm.

</td></tr></tbody></table>

[![image.png](https://knowledgebase.dome-marketplace.eu/uploads/images/gallery/2026-03/scaled-1680-/usVimage.png)](https://knowledgebase.dome-marketplace.eu/uploads/images/gallery/2026-03/usVimage.png)


---

### Step 4 – Authorization request

The confidential client starts the authorization process by redirecting the user to the **Authorization Endpoint** with these parameters :

- `client_id`: has to match the one in your client's configuration
- `redirect_uri`: has to match the one in your client's configuration
- `response_type=code`
- `scope =` `openid learcredential`
- `state` : random string
- `nonce`: random string (this will be added in the ID token, so it is recommended if you rely on the ID token)
- `request_uri`: see the explanation below\*

**Non-normative example:**

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-get-%2Fauthorize%3F-resp"><div class="sticky top-9"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div align="left" dir="ltr" id="bkmrk-%7B-%C2%A0-%C2%A0-%22%40context%22%3A-%5B%22"><table><colgroup><col></col></colgroup><tbody><tr><td>GET /authorize?

response\_type=code

&amp;client\_id=did:key:wejkdew87fwhef9833f4

&amp;request\_uri=https%3A%2F%2Fapp.client.com%2Frequest.jwt%2F3Gr...AdM

&amp;state=af0ifjsldkj

&amp;nonce=n-0S6\_WzA2Mj

&amp;scope=openid%20learcredential

Host: authserver.example.org

</td></tr></tbody></table>

</div></div></div></div><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-the-authorization-se-1"></div>\*The `request_uri`. must expose an **Authorization Request Object**., which is an JWT and must include these parameters. These parameters must match the ones of your client's configuration (and the ones included in the request as well):

- `client_id`
- `scope`
- `redirect_uri`

 The Authorization Server retrieves this JWT, validates its signature against the client’s registered `jwkSetUrl`(that is, against the public key derived from you did:key), and proceeds with the flow.

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-outcome%3Athe-authoriz"><div class="sticky top-9">  
</div><div class="sticky top-9">**Outcome:**  
The Authorization Server successfully validates the signed request and displays the login and consent screen to the user.</div><div class="sticky top-9">  
</div></div>### Step 5 – Authorization response

After the user successfully authenticates and authorizes access, the Authorization Server redirects back to the client’s `redirect_uri` with an authorization code.

**Non-normative example:**

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-http%2F1.1-302-found-l"><div class="overflow-y-auto p-4" dir="ltr"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-post-%2Foauth%2Ftoken-ht"><div class="sticky top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div class="sticky top-9"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div align="left" dir="ltr" id="bkmrk-http%2F1.1-302-found-l-1"><table><colgroup><col></col></colgroup><tbody><tr><td>HTTP/1.1 302 FOUND

Location: https://app.client.com/cb?

code=SplxlOBeZQQYbYS6WxSbIA

&amp;state=af0ifjsldkj

</td></tr></tbody></table>

</div></div></div></div><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-te"></div></div></div></div></div></div><div class="overflow-y-auto p-4" dir="ltr">**Outcome:**  
The confidential client receives the authorization code and verifies that the `state` matches its original request to prevent CSRF attacks.</div></div>
### Step 6 – Token request

The client exchanges the authorization code for tokens by calling the **Token Endpoint**.  
In this step, the client authenticates using `client_secret_jwt`, sending a signed JWT in the `client_assertion` parameter.

**Non-normative example:**

Non-normative example of a Token Request:

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-post-%2Foauth%2Ftoken-ht-1"><div class="overflow-y-auto p-4" dir="ltr"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-post-%2Foauth%2Ftoken-ht-2"><div class="sticky top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div class="sticky top-9"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div align="left" dir="ltr" id="bkmrk-post-%2Foauth%2Ftoken-ht-3"><table><colgroup><col></col></colgroup><tbody><tr><td>POST /oauth/token HTTP/1.1

Host: authserver.example.com

Content-Type: application/x-www-form-urlencoded

grant\_type=authorization\_code

&amp;code=SplxlOBeZQQYbYS6WxSbIA

&amp;redirect\_uri=https%3A%2F%2Fapp.client.com%2Fcb

&amp;state=af0ifjsldkj

&amp;client\_assertion\_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer  
&amp;client\_assertion=eyJhbGciOiJFUzI1N...

</td></tr></tbody></table>

</div></div></div></div><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk--5"></div></div></div></div></div></div><div class="overflow-y-auto p-4" dir="ltr">  
</div></div>**Outcome:**  
The Authorization Server validates:

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-the-client_secret_jw"><div class="overflow-y-auto p-4" dir="ltr">- The `client_assertion` signature.
- The authorization code and redirect URI.  
    If valid, it issues access, ID, and refresh tokens.

  
</div></div>### Step 7 – Token response

**Non-normative example:**

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-http%2F1.1-200-ok-cont"><div class="overflow-y-auto p-4" dir="ltr"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-http%2F1.1-200-ok-cont-1"><div class="sticky top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div class="sticky top-9"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div align="left" dir="ltr" id="bkmrk-http%2F1.1-200-ok-cont-2"><table><colgroup><col></col></colgroup><tbody><tr><td>HTTP/1.1 200 OK

Content-Type: application/json

Cache-Control: no-store

Pragma: no-cache

{

 "access\_token": "eyJhbGciOiJFQ0RILUVTIiwiZ...qtAlx1oFIUpQQ",

 "token\_type": "Bearer",

 "expires\_in": 3600,

 "refresh\_token": "8xLOxBtZp8",

 "id\_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...p-QV30"

}

</td></tr></tbody></table>

</div></div></div></div><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk--6"></div></div></div></div></div></div><div class="overflow-y-auto p-4" dir="ltr">  
</div></div>**Outcome:**

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-access_token-grants-"><div class="overflow-y-auto p-4" dir="ltr">- `access_token` grants access to protected APIs.
- `id_token` identifies the authenticated subject.
- `refresh_token` allows new tokens to be obtained without user interaction.

</div></div>### Step 8 – Use access token

The confidential client uses the `access_token` to call Verifier-protected APIs:

<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-authorization%3A-beare"><div class="overflow-y-auto p-4" dir="ltr"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div class="overflow-y-auto p-4" dir="ltr"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary" id="bkmrk-authorization%3A-beare-1"><div class="sticky top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div class="sticky top-9"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"><div align="left" dir="ltr" id="bkmrk-authorization%3A-beare-2"><table><colgroup><col></col></colgroup><tbody><tr><td>Authorization: Bearer eyJhbGciOiJFQ0RILUVTIiwiZ...</td></tr></tbody></table>

</div></div></div></div></div></div></div></div></div></div></div></div>