Skip to main content
Skip table of contents

OIDC Relying Party

The Trinity Backend Service behaves as every other OIDC (or OAuth 2.0) provider and can be integrated accordingly. On your website, application, or backend service, you have to initiate the authorization code flow with PKCE to receive an ID token, Access token, and the UserInfo. Various (certified and uncertified) libraries are available that help you with different frameworks.

You can find even more implementations at the OpenID homepage.

Just so you know, the OIDC certification process for the Trinity OIDC backend service is currently ongoing, so you might experience some non-compliant hiccups here and there.

Client Registration

Before you can get started with the actual implementation of your client, you will need to register at the Trinity OIDC backend service.

The following endpoints are implemented for registration:



URL / comment

registration_endpoint - requires initial access token

registration_client_uri - Use the value provided in the registration response - this endpoint definition is just for reference

Gaining access

In order to use the full functionality of the API, a client has to be registered using OpenID Connect Dynamic Client Registration.

Initial Access Token

Registration requires an initial access token. This token is valid for two days and can only be used for a single registration. In order to request a token, send a mail to

For a self-hosted environment, the Client Invitation Management Endpoint (GET) /oidc/v1/management/invite_client? also provides the functionality to issue initial access tokens, protected by a Basic Authentication Header as specified in the Endpoint protection section.

You will receive the token in plaintext to your specified email. This token can then be used as a Bearer token in the Authorization Header of your Registration Request.

curl -X POST "" -HAuthorization: Bearer <INITIAL_ACCESS_TOKEN>" "-H "accept: application/json" -H "Content-Type: application/json" -d "{\"redirect_uris\":[\"https://your_url\"]}"
  "client_id": <YOUR CLIENT ID>,
  "registration_access_token": <YOUR TOKEN>,
  "registration_client_uri": <YOUR CLIENT URI>,
  "client_id_issued_at": 1592205743

Client Registration request

The registration endpoint is (as specified in the discovery response): . The endpoint behavior matches the OIDC standard. The minimal request only requires providing redirect_uris.

If you want to ensure an end-to-end encryption on data layer (i.e. encrypted ID token and UserInfo) as a JWE response to your client from the UserInfo and token Endpoints, please provide a public-key as either a jwks_uri or jwks in the client registration body. For further details, see Encryption and Signing.

To test your client against a local setup, please set the application_type to native as this will allow localhost in redirect_uris.

The response contains some crucial information you need to store:




This ID has to be used for any authorization request. It is auto-generated by our backend and does not contain any information about your service in itself.


Use this token for updating client information. Your service information cannot be updated without this access token.


URI you have to use to update your information. While the format of the URI is predefined, per standard this value has to be used to ensure consistency.


Next to the initial registration, a client configuration can be updated at any time. The configuration URL is part of the registration response. Both configuration retrieval (GET) and updates (POST) are supported.


As per OIDC standard, this endpoint has to return all information we store of the client. Thus it contains both your registration data as well as the registration response.

A side effect of this call is the creation of a new access token. Every following call has to use this new access token.

Every previously issued access token for updating this client is invalid after this call.

The newly created client access token does not affect any token issued for an end user of that client.


This endpoint can be used to change the configuration of a client. The request matches the one for registration. There are some aspects that need to be considered when updating the client configuration:

  • Every change is applied immediately - there is no grace period

  • Tokens issued before a change are not invalidated

    • token lifetimes are not updated

  • Changes in keys are applied immediately

    • new id tokens are immediately using the new keys

On any kind of conflict, a user is usually redirected to a login (based on your client application), so there is always a recovery for an impacted session.

A POST requires the client access token as Bearer token for authentication purposes.

Parameter specification

Encryption and Signing

This service supports encryption and signing of both ID tokens as well as UserInfo.

For both signing and encryption, the following constraints apply: - only asymmetric algorithms are supported - 'NONE' is never supported - only values of RFC 7518 are supported - claims are only submitted when encryption is specified

All supported signing and encryption values can be retrieved over the configuration endpoint.

Claims are only submitted with valid encryption.

To achieve a valid encryption, we need to know your public-key. This can be specified in the JSON body during the Client Registration request or in the Client Configuration.

curl --location --request POST '' \
--header 'Authorization: Bearer <INITIAL_ACCESS_TOKEN>' \
--header 'Content-Type: application/json' \
--data-raw '{   
    "application_type": "native",
    "client_name": "test client",
    "redirect_uris": [
    "jwks": {
        "keys": [
                "kty": "RSA",
                "e": "AQAB",
                "use": "enc",
                "kid": "test client",
                "n": "<RSA-PUBLIC-KEY>"
    "userinfo_encrypted_response_alg" : "RSA1_5",
    "userinfo_encrypted_response_enc" : "A256GCM",
    "allow_unencrypted_userinfo": false

Data protection is crucial for us. We never want to be able to see any user data. To protect you, your customers but also us from ever coming into this situation, we only transmit user data when a valid encryption is specified. For the same reason, we limit algorithms to asymmetric ones.

JWKS content

The keys supplied by the jwks parameter or retrieved by the jwks_uri are validated before they are applied. The following constraints are applied:

  • When encryption is specified for the ID-Token, UserInfo or request object, a JWKS with valid keys has to be present

  • The keys either need to supply use="enc" or key_ops=["encrypt"] . Keys without these parameters are filtered out.

  • The encryption keys need to support the algorithms specified for ID token/userinfo/request object.

    • you can specify different algorithms for ID token/userinfo/request object.

    • you can specify different key types (RSA, EC) for ID token/userinfo/request object.

If no JWKS/JWKS URI was provided or, after filtering and sanity checking, there is no valid key left that can support the specified encryption a registration/configuration request will be rejected.

You can add certificate-related claims to your JWKs (x5c, x5u, x5t, x5t#S256). Adding these will result in a basic validation of the certificate:

  • The key of the certificate has to match the key of the JWK

  • If x5t/x5t#S256 are specified, they have to match to the certificate

  • If x5u is used, the certificate has to be downloadable. The certificate is validated the same way as one specified in x5c

As specified above, only asymmetric algorithms are supported. When a symmetric algorithm is specified, this will be rejected. The supported algorithms can be retrieved via the service's discovery.

If you want to allow for an unencrypted UserInfo, please specify the allow_unencrypted_userinfo as true during client registration or configuration.

Management Endpoint

This endpoint contains useful management functionalities for self-hosted Trinity backend instances.

Endpoint protection

The endpoint is secured by basic authentication with a username and password. The credentials can be set in the file found in the root-folder by changing the and properties. This user will automatically be assigned the MANAGEMENT role.

Make sure to change your credentials during the initial setup, since every instance comes with default credentials!

Client Invitation

As already mentioned in the Initial Access Token section, the Client Invitation Management Endpoint (GET) /oidc/v1/management/invite_client? can also be used to deliver an Initial Access Token to an email address. This requires the basic authentication specified above. The Initial Access Token will be delivered to the email in plaintext and can subsequently be used for the Client Registration request.

curl --location --request GET '<EMAIL-TO-BE-INVITED>' \
--header 'Authorization: Basic bWFuYWdldjpzdXAxcnNzY3IzdA=='

Requesting Claims

This section will soon be updated with regards to the support of standard OIDC claims.

curl '<YOUR_CLIENT_ID>&state=<STATE>&<NONCE>&'

Verified data or authentication factors are requested as member of the userinfo top-level member of claim request parameter (see OIDC specification). The parameter has to be a valid JSON and must be URL-encoded in order to send it as part of the request URL.

Authentication claims which facilitate verified data, e.g. an OTP, do not include the actual data but a proof of execution.

Claim syntax

Beside the supported OIDC standard claims, every other custom claim for TBS starts with comuny, followed by whether it's a verification of authentication claim, so:

  • comuny.ver for all verification claims and

  • comuny.auth for all authentication claims

Every claim has to be followed by an object. The options are:

  "userinfo": {
    "": { "essential": true },
    "comuny.ver.idcard.l3": null
  • null (future release): the claims is voluntary, so the user can decide whether or not to fulfill it.

  • JSON object to narrow down the information provided by a claims. The following members are supported:

    • essential: boolean: true means that this claim is required while false means it is optional (so basically the same as null above)

If multiple claims are specified with essential: true , all of them have to be provided by the user.

Specifying alternatives

You can specify alternatives on all hierarchies of the claim below ver and auth using an array syntax. This syntax can be nested.

  "userinfo": {
    "comuny.ver.[mobile,email].l2": { "essential": true },
    "comuny.ver.idcard.l2.[video,nfc]": { "essential": true },
    "comuny.ver.[driverslicense.l2.nfc,idcard.l2.[video,nfc]]": { 
      "essential": true

You can specify that you want to have alternative data sets, but all with verification level 2, by setting an array on the data set hierarchy, e.g. requesting either email or mobile.

Within a data set and level, you can specify alternative procedures to verify the data set, so e.g. use Video Identification (video) or NFC (nfc)for verifying an ID card. The user now can choose which procedure they want.

Alternatives can be encapsulated within each other. So you can specify that you either want to have a driver's license with NFC (driverslicense.l2.nfc)or an idcard with NFC (idcard.l2.nfc)or Video (

Client Endpoints

The Client Endpoints adheres to the OIDC standard. The exact specification can be taken from the swagger documentation. It includes parameter descriptions and examples.

TBS implements OpenID connect discovery on See the examples and sample response in the Swagger documentation for this endpoint .

The result of the discovery endpoint is the most accurate representation of the current state. This state is verified before every release of the service. If in doubt, the discovery endpoint reflects the truth.

Implemented OIDC endpoints:










The API documentation contains a more detailed description of the endpoints.

IAM integration

You can also extend and integrate existing IAM solutions to delegate parts of the process to Trinity. As TBS is full OIDC compliant, this usually works without any custom code but with plain configuration. A high-level architecture, using keycloak as example, is in the right column. Here's a list of some IAM solutions and their configuration for external identity providers:


Documentation for connecting an external identity provider


identity brokers


external identity providers

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.