# Integration

## Endpoints

Acceptance/Staging: <https://acc-auth.t1t.eu>

Production: <https://auth.t1t.eu>

## Integration Steps

The integration can be summarized in 2 required steps, and 1 optional step:

* **start a new session** and redirect the user to the authentication page
* **parse the result** (through a webhook) and give access to requester (user of your application)
* **\[optionally] retrieve a detailed validation report**

#### **Postman Collection**

The HTTP REST collection is available on [Postman](https://documenter.getpostman.com/view/106007/2sA3JFA4gE)

### Overview Sequence Flow

The following sequence diagram denotes partially the steps executed, with regards to the user who needs to be authenticated.

<figure><img src="https://2008314047-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTItBZU9vNSXUfazlNCln%2Fuploads%2F1JJ22AWe0aWU0mWElb2w%2F00_wallid_redirect_info.png?alt=media&#x26;token=04fff454-79ed-424a-bd89-bcdfb19efd10" alt=""><figcaption><p>Simplified authentication sequence flow</p></figcaption></figure>

### **Start a new Session**

The initial call sets the context for a new session. The context must be unique for each user who needs to log in. Once the context has been created a JWT is issued and can be used to redirect the user to the authentication page.

```
// Example redirect URL
https://auth.t1t.eu?token={{received JWT from SET context}}
```

#### Set Context

A new session can be started by initiating a **POST** request with your provided **'apikey'**:

```
curl --location 'http://localhost:9000/v1/token' \
--header 'apikey: {{secret_api_key}}' \
--header 'Content-Type: application/json' \
--data '{
    "correlationId": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
    "useCase": "auth",
    "means": ["beid", "luxid","smart-id"],
    "redirectUri": "https://trust1team.com",
    "webhookUri": "https://mbwgm22d.ngrok.app",
    "sessionTimeInMinutes": 30
}'
```

#### Properties

| property             | value type        | description                                                                                                                                                                                                                                                                                                    |
| -------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| correlationId        | string            | A UNIQUE identifier created by the service consumer                                                                                                                                                                                                                                                            |
| useCase              | string            | predefined use case: "auth" starts the authentication flow                                                                                                                                                                                                                                                     |
| means                | list of strings   | denotes which means should be available for the end-user; when 'beid' and 'luxid' are added, user device will search for Belgian eID and Luxembourg ID tokens in connected readers. The abbreviations allign with the Trust1Connector module names. All registered tokens from the Trust1Connector can be uses |
| redirectUri          | Option\[string]   | This is the page where the user is redirected towards, once the flow has been completed (for both success AND failure scenario)                                                                                                                                                                                |
| webhookUri           | Option\[string]   | this is the URI which will be used by the service to POST a HTTP (Json) request with the authentication flow result                                                                                                                                                                                            |
| sessionTimeInMinutes | integer           | this defines the expiration time of the issues JWT token, and hence the time in which the session will stay valid                                                                                                                                                                                              |
| pubKey               | Optional\[string] | base64 encoded PEM for the public key provided by the integration provider (consuming web application); the key is used to encrypt sensitive data (biometric property in the webhook response) received from the authenticating user                                                                           |
| lang                 | Optional\[string] | nl, fr, en, de (the languaged loaded by default)                                                                                                                                                                                                                                                               |

{% hint style="info" %}
The pubKey used must be a&#x20;

`4096 bit RSA`

, the encryption padding uses is:&#x20;

`PKCS1_OAEP`
{% endhint %}

{% hint style="warning" %}

#### The webhooUri and redirectUri, when not provided, no feedback is provided to the consumer, the consumer needs to GET the information using the HTTP/REST API.&#x20;

{% endhint %}

#### Example Response

The HTTP reponse contains a Json reponse with a `token` property

```postman_json
{
    "token": "eyJ0eXAiOiJKV1Qi...wtZpmCWoJVQ"
}
```

The token MUST be set for the end-user to start the flow on the Authentication web page.

The token is added as a query parameter on the URL for the Authentication web page:

```
// Example redirect URL
https://auth.t1t.eu?token=eyJ0eXAiOiJKV1Qi...wtZpmCWoJVQ
```

From here the user will be guided through the authentication flow

#### Optional: Provide a public key for response encryption

In the `set context` request, an optional public key can be provided by the web application who wants to use the Trust1Authentication service.&#x20;

When a public key is provided, the biometric information from the authentication user will be encrypted with the provided public key, on the user's device itself, avoiding any data to be leaked during the authentication flow.&#x20;

No sensitive data is stored on the Trust1Authentication service.&#x20;

### Parse the received result (success)

Once the user has completed the flow, the webhookUri will be used, prior to initiating the `redirect` (redirectUri).&#x20;

The webhook MUST be a POST HTTP endpoint, who will expect the following data to be received:

```json
{
    "sessionContext": {
        "id": "66961584-a00d-46dc-96e6-c494582e99f2",
        "org_id": "187144be-e4ef-4826-8845-93057ac4fae3",
        "org_name": "Trust1Team",
        "correlation_id": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
        "use_case": "auth",
        "means": "beid,luxid",
        "redirect_uri": "https://trust1team.com",
        "webhook_uri": "https://mbwgm22d.ngrok.app",
        "webhook_http_method": "POST",
        "session_time_in_minutes": 30,
        "created_at": "2024-05-02T07:10:44.490751"
    },
    "sessionTracker": {
        "id": "66961584-a00d-46dc-96e6-c494582e99f2",
        "token_issued": true,
        "token_validated": true,
        "connector_installed": true,
        "reader_connected": true,
        "identity_found": true,
        "mean_pin_result": true,
        "mean_cert_valid": true,
        "gsm_input": true,
        "gsm_otp_input": true,
        "gsm_otp_code": "1938",
        "gsm_nr": "+32...",
        "auth_digest_signed": "ZmVkZGJlMmM5NWNiYzA1YmI2N2ZlOGI4YTg2ZGE0Mzk5NzAxZTkwN2Y3NmFhMjQyOGE3Mjg1ZTM0YzZlNjljNg==",
        "error_state": false,
        "cancel_state": false,
        "success_state": true,
        "result_state": "SEND",
        "created_at": "2024-05-02T07:10:44.500004",
        "updated_at": "2024-05-02T09:12:10.315752"
    },
    "bio": "bio OR encrypted(bio)",
    "validationReport": "https://acc-auth-api.t1t.eu/v1/auth/report/06c74b0b-f5f5-4b71-847d-5813bde62e63",
    "isSuccess": true
}
```

The included bio data is provided as a Json string (encrypted only if the session has been created with a public key property).&#x20;

The Json has the following format:

```json
{
        "birthDate": "03 MEI 2001",
        "birthLocation": "Leuven",
        "cardDeliveryMunicipality": "Brussel",
        "cardNumber": "000001244125",
        "cardValidityDateBegin": "05.07.2022",
        "cardValidityDateEnd": "05.07.2032",
        "chipNumber": "U0xHkAJRAAAiJSiPEpIDYw==",
        "documentType": "1",
        "firstNames": "Nora Angèle",
        "name": "Specimen",
        "nationalNumber": "01050399963",
        "nationality": "BELG",
        "nobleCondition": "",
        "pictureHash": "R2osQHL1+wdkLiVtXt/XnGpnX8aSYtMn+ZeQUVF7CAE=",
        "rawData": "AQwwMDAwMDEyNDQxMjUCEFNMR5ACUQAAIiUojxKSA2MDCjA1LjA3LjIwMjIECjA1LjA3LjIwMzIFB0JydXNzZWwGCzAxMDUwMzk5OTYzBwhTcGVjaW1lbggMTm9yYSBBbmfDqGxlCQAKBEJFTEcLBkxldXZlbgwLMDMgTUVJIDIwMDENAVYOAA8BMRABMBEgR2osQHL1+wdkLiVtXt/XnGpnX8aSYtMn+ZeQUVF7CAE=",
        "sex": "V",
        "signature": "MGYCMQDRA/MOgdMSE3GoJFTanZOILLdEH14T/O489tLFa1g4AsI/S0q+uw5mZzuXHKE3WXwCMQDHqPdSSfrsxsnMG1SKKz02N1X64JAORW/CdYqrAWjrI08lJVa68zgezM3FdXXGt4oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
        "specialStatus": "0",
        "thirdName": "",
        "version": "0"
    }
```

> When there is no bio information available (typically for PKCS11 only tokens), the bio not be provided upon a successful authentication response

### Parse the received result (failed)

When the session has been expirect, and no successfull result has been pushed OR when the use case fails in a way that the end-user is blocked, a response will be sent to the webhook with `isSuccess: false` An additional `error` property is added with more explanation. The session context and tracker is always provided in the respone:

```
{
    "sessionContext": {
        "id": "66961584-a00d-46dc-96e6-c494582e99f2",
        "org_id": "187144be-e4ef-4826-8845-93057ac4fae3",
        "org_name": "Trust1Team",
        "correlation_id": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
        "use_case": "auth",
        "means": "beid,luxid",
        "redirect_uri": "https://trust1team.com",
        "webhook_uri": "https://mbwgm22d.ngrok.app",
        "webhook_http_method": "POST",
        "session_time_in_minutes": 30,
        "created_at": "2024-05-02T07:10:44.490751"
    },
    "sessionTracker": {
        "id": "66961584-a00d-46dc-96e6-c494582e99f2",
        "token_issued": true,
        "token_validated": true,
        "connector_installed": true,
        "reader_connected": true,
        "identity_found": true,
        "mean_pin_result": true,
        "mean_cert_valid": false,
        "gsm_input": true,
        "gsm_otp_input": true,
        "gsm_otp_code": "1938",
        "gsm_nr": "+32...",
        "auth_digest_signed": "ZmVkZGJlMmM5NWNiYzA1YmI2N2ZlOGI4YTg2ZGE0Mzk5NzAxZTkwN2Y3NmFhMjQyOGE3Mjg1ZTM0YzZlNjljNg==",
        "error_state": true,
        "cancel_state": false,
        "success_state": false,
        "result_state": "ACKED",
        "created_at": "2024-05-02T07:10:44.500004",
        "updated_at": "2024-05-02T09:12:10.315752"
    },
    "error": "[blocking] Certificate validation failed",
    "validationReport": "https://acc-auth-api.t1t.eu/v1/auth/report/06c74b0b-f5f5-4b71-847d-5813bde62e63",
    "isSuccess": false
}
```

### Parse the received result (cancelled)

When a user cancels, the webhook is called with a similar response as the failure response. The main difference is that the `cancel_state` property will be set to `false`&#x20;

## Examples

### Generate 4096 bit RSA Keypair

The RSA keypair generated MUST have a size of 4096 bit:

````
```shell
# Generate rsa private key
openssl genrsa -out key.pem 4096

# Generate rsa public key
openssl rsa -in key.pem -outform PEM -pubout -out public.pem
```
````

Public key must be send in a base64 encoded format!

Copy base64 encoded public key as a single string to the clipboard (Mac example):

````
```shell
base64 --encode < key.pem | tr -d '[[:space:]]' | pbcopy
base64 --encode < public.pem | tr -d '[[:space:]]' | pbcopy
```
````

```
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2UzR2bWtTaHFLaE02ZStLcGtPcQp5L2s1OXdMejBaWDJ4TkNmZG53YWFLcktBem9NZHoyK3NNQllyckdDSUl5enZHWSs3S0crYkpnVkI1QU5nYndkCnpvbGZ1YjMyendoSFBtb3hwOUpPc1MxYS8rYVpybkM1RDA0T245NU1hQzIyam1xMklrMFRjSTVGd0gzei9lalIKN2VYMXd1bVYzQTVZZERWWExJZzF3WERrOUd2MkJVSzhFd1NCNWc4SnMvMm5zcEEvekpScTEyTzUzRVUvL3dNZwp2ekt1cW9sTWJrWVlEQ1JyZTd3U0ErZlpVbnI0QkNtUE1IZXlGZG02S3diaVdhVGFId0o2VEpnR3Zra1d6Y1gyCmNFZFlkby9LYUxnaDRNaGtERkFOb1ZQZi9CV205QjRYbEFZdFV4UVpvV3BSeVEyeUVoK2N5SGljbnBhR1ZSQXMKRkdmenNZcFllVkExeDhkaERUYXphdmFRdDcwQ3R0U2FMQXVITDJaTnp2cjNkUng4dzY0WFFFVW4zdlF5eS9XMwpFQ0ljNnV1WlV1NE1iUGY0bS8yVzdCRGxtb01DTmFaZWxhR1JwbzZMYyswa1JQZGFtdHJaRURBd1NNcDNEeGNjCjN0ZzZ5dkRqdVV2T1YrYnE1N0V6NzRzQ0lNNmJyMWxjdndhNWRDaG4wNXU5Q0gySGlQbm5tSDhUcHp2ZndUQm4KNld1RnR4RmhUZEtGYVc0Q25vbkxoYmY2ZWxaWXFvQmtkbGQwYU4xSFdhbXFUN3V1dUM3Q005NlpQVkxjY1dhMApxYzNlbFNQZEZjdytVeFBubzQwd3JmbklWS3VwNUxWSlFlWEdmNWp6b0l1UU9WVHBFSnVHbGR4Q0ZSRHdBODNHCnA1MmNUblFOaXBNWVRTTWlXRzQvSUlVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo=
```

Setting up the session context, becomes

```
curl --location 'http://localhost:9000/v1/token' \
--header 'apikey: {{apikey}}' \
--header 'Content-Type: application/json' \
--data '{
    "correlationId": "06c74b0b-f5f5-4b71-847d-5813bde62e63",
    "useCase": "auth",
    "means": ["beid", "luxid", "gsm", "smartid"],
    "redirectUri": "https://trust1team.com",
    "webhookUri": "https://mbwgm22d.ngrok.app",
    "sessionTimeInMinutes": 30,
    "pubKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF2UzR2bWtTaHFLaE02ZStLcGtPcQp5L2s1OXdMejBaWDJ4TkNmZG53YWFLcktBem9NZHoyK3NNQllyckdDSUl5enZHWSs3S0crYkpnVkI1QU5nYndkCnpvbGZ1YjMyendoSFBtb3hwOUpPc1MxYS8rYVpybkM1RDA0T245NU1hQzIyam1xMklrMFRjSTVGd0gzei9lalIKN2VYMXd1bVYzQTVZZERWWExJZzF3WERrOUd2MkJVSzhFd1NCNWc4SnMvMm5zcEEvekpScTEyTzUzRVUvL3dNZwp2ekt1cW9sTWJrWVlEQ1JyZTd3U0ErZlpVbnI0QkNtUE1IZXlGZG02S3diaVdhVGFId0o2VEpnR3Zra1d6Y1gyCmNFZFlkby9LYUxnaDRNaGtERkFOb1ZQZi9CV205QjRYbEFZdFV4UVpvV3BSeVEyeUVoK2N5SGljbnBhR1ZSQXMKRkdmenNZcFllVkExeDhkaERUYXphdmFRdDcwQ3R0U2FMQXVITDJaTnp2cjNkUng4dzY0WFFFVW4zdlF5eS9XMwpFQ0ljNnV1WlV1NE1iUGY0bS8yVzdCRGxtb01DTmFaZWxhR1JwbzZMYyswa1JQZGFtdHJaRURBd1NNcDNEeGNjCjN0ZzZ5dkRqdVV2T1YrYnE1N0V6NzRzQ0lNNmJyMWxjdndhNWRDaG4wNXU5Q0gySGlQbm5tSDhUcHp2ZndUQm4KNld1RnR4RmhUZEtGYVc0Q25vbkxoYmY2ZWxaWXFvQmtkbGQwYU4xSFdhbXFUN3V1dUM3Q005NlpQVkxjY1dhMApxYzNlbFNQZEZjdytVeFBubzQwd3JmbklWS3VwNUxWSlFlWEdmNWp6b0l1UU9WVHBFSnVHbGR4Q0ZSRHdBODNHCnA1MmNUblFOaXBNWVRTTWlXRzQvSUlVQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo="
}'
```

The following response contains a token, which can be used to redirect the user to the login page:

````
```json
{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dSI6Imh0dHBzOi8vYXBpbS50MXQuYmUva2V5cy9wdWIifQ.eyJpc1NlcnZpY2VBY2NvdW50Ijp0cnVlLCJzdWIiOiI5NmNhNzI5NS0wYmU3LTQyNDQtODJlNi1mMDg4MWQ5MjU4MjMiLCJpc3MiOiJUcnVzdDFUZWFtIiwiZXhwIjoxNzE0OTczODg2LCJuYmYiOjE3MTQ5NzE0ODZ9.BuRipUci4QoeLKVVJTpybp0k2tkDvKEoznVGhcQRQGc9qOSOdaeSOcGLFJyqilaO1-EYr2PokiJcvx1oVmjV7_OY-Aq7WN_vK1Ta5Oh1Xa99BetjqQLhxi6lRbaEAw9Y-pkw_RBH3HqGEyb6TuXS7mtsm0pKz9y5nnWNcNvidniVGg28xAlu3rrDnGAIwSyCzoE3DeZj9xwQH1llF_Enx9V1F88RIm7zedNoZGGrm8tgRsmHjNDyFNhM8nMb-8395ZhMEBauFgY7HqzVHxx4AuNyviedLyNkLFltjSAqRZVViUDhJ53xermF5xEKaKe0Pilts3O-A2iHCNkgNOpHlw"
}
```
````

Redirect URL:

```
https://auth.t1t.eu/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dSI6Imh0dHBzOi8vYXBpbS50MXQuYmUva2V5cy9wdWIifQ.eyJpc1NlcnZpY2VBY2NvdW50Ijp0cnVlLCJzdWIiOiI5NmNhNzI5NS0wYmU3LTQyNDQtODJlNi1mMDg4MWQ5MjU4MjMiLCJpc3MiOiJUcnVzdDFUZWFtIiwiZXhwIjoxNzE0OTczODg2LCJuYmYiOjE3MTQ5NzE0ODZ9.BuRipUci4QoeLKVVJTpybp0k2tkDvKEoznVGhcQRQGc9qOSOdaeSOcGLFJyqilaO1-EYr2PokiJcvx1oVmjV7_OY-Aq7WN_vK1Ta5Oh1Xa99BetjqQLhxi6lRbaEAw9Y-pkw_RBH3HqGEyb6TuXS7mtsm0pKz9y5nnWNcNvidniVGg28xAlu3rrDnGAIwSyCzoE3DeZj9xwQH1llF_Enx9V1F88RIm7zedNoZGGrm8tgRsmHjNDyFNhM8nMb-8395ZhMEBauFgY7HqzVHxx4AuNyviedLyNkLFltjSAqRZVViUDhJ53xermF5xEKaKe0Pilts3O-A2iHCNkgNOpHlw
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://t1t.gitbook.io/t1authentication/integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
