Skip to main content

Integration Steps

Prerequisites


Step 1 – MachineGenerating 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 Issuer: when issuing a LEARCredentialMachine, a key pair is generated for the client. The corresponding did:key is set as the mandatee.id in the credential issuance(which

Theyou LEARcan ofcheck in the organizationdetails issuespage aafter LEARCredentialMachineissuing it --no need to theactivate backendit). service (the confidential client).

  • The credential is a Verifiable Credential (VC) in JWT format.

  • It is bound to the machine’s DID, derived from its public key.

  • The private key must be kept securely storedon your side and is never shared.

Outcome:
The machine (confidential client) holds a valid LEARCredentialMachine and its associated DID key pair.


Step 2 – Client configuration

Client type: Confidential.

  • Obtain

    Registerand store the clientassigned client_id, which should be the did:key generated in the Verifier’sprevious Authorization Server.

  • Provide the jwks_uri exposing the public keys used for signing JWTs.

    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. The data must match with your client's configuration (see step 2).

Field

Description

clientId

Should be a did:key that identifies your client.

url

The base URL of your service or application.

redirectUris

Must include all the URLs where you expect to receive authentication responses.

scopes

Currently, only openid_learcredential is accepted. This scope allows your service to request the necessary credentials.

clientAuthenticationMethods

Must be set to ["client_secret_jwt"]

authorizationGrantTypes

Must be set to ["authorization_code"] and ["refresh_token"] if needed.

postLogoutRedirectUris

Include URLs where users should be redirected after they log out from your service.

requireAuthorizationConsent

Set to false.

requireProofKey

Set to false.

jwkSetUrl

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: “<verifier-url>/oidc/did/<your-did-key>”. 

tokenEndpointAuthenticationSigningAlgorithm

Must be set to ES256, as this is the only supported algorithm.

image.png


Step 34 – Authorization request

The confidential client starts the authorization process by redirecting the user to the Authorization Endpoint with athese signedparameters Authorization:

Request
    Object.
    This
  • object

    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 arecommended JWTif containingyou allrely authorizationon parameters,the hostedID attoken)

    a
  • request_uri.

    :

    The Authorization Server retrieves this JWT, validates its signature againstsee the client’sexplanation registeredbelow*

  • jwks_uri, and proceeds with the flow.

Non-normative example:

GET /authorize?

response_type=code

&client_id=did:key:wejkdew87fwhef9833f4

&request_uri=https%3A%2F%2Fapp.client.com%2Frequest.jwt%2F3Gr...AdM

&state=af0ifjsldkj

&nonce=n-0S6_WzA2Mj

&scope=openid%20learcredential

Host: authserver.example.org

*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 executesretrieves thethis request_uriJWT, tovalidates retrieveits thesignature data of the Authorization Request Object.
This object is a JWT signed withagainst the client’s privateregistered key.
ThejwkSetUrl(that Authorizationis, Server validates the JWT usingagainst the public key registeredderived underfrom you did:key), and proceeds with the client’sflow.

jwks_uri.

Outcome:
The Authorization Server successfully validates the signed request and displays the login and consent screen to the user.

Step 45 – 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:


HTTP/1.1 302 FOUND

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

code=SplxlOBeZQQYbYS6WxSbIA

&state=af0ifjsldkj

Outcome:
The confidential client receives the authorization code and verifies that the state matches its original request to prevent CSRF attacks.

Step 56 – 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:

POST /oauth/token HTTP/1.1

Host: authserver.example.com 

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


grant_type=authorization_code

&code=SplxlOBeZQQYbYS6WxSbIA

&redirect_uri=https%3A%2F%2Fapp.client.com%2Fcb

&state=af0ifjsldkj

&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJFUzI1N...


Outcome:
The Authorization Server validates:

  • The client_secret_jwtclient_assertion signature.

  • The authorization code and redirect URI.
    If valid, it issues access, ID, and refresh tokens.


Step 67 – Token response

Non-normative example:

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"

}


Outcome:

  • access_token grants access to protected APIs.

  • id_token identifies the authenticated subject.

  • refresh_token allows new tokens to be obtained without user interaction.

Step 78 – Use access token

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

Authorization: Bearer eyJhbGciOiJFQ0RILUVTIiwiZ...