Advanced
Documents
Some scope may be associated to a binary document. For instance, the claim postal_address
may have a sub-claim proof_of_residence
. In such a case, the document is provided in the following format :
{ user_consent: { jwe: "encryptedUserConsent" }, user_info: { postal_address: { formatted: "John DOE 3 rue Bellini 92800 Puteaux", proof_of_residence: { file_wrapper: { base64: "BINARY_DATA_IN_BASE64_ENCODING", filename: "proof_of_residence.pdf" } } } } }
The full-response will look like:
{ data: { links: [ { href: "https://sbx-app.m-itrust.com/user_data/v1/userinfo", rel: "self" } ], user_consent: { jwe: "encryptedConsent", links: [ { href: "https://sbx-app.m-itrust.com/service_provider/v1/userconsent", rel: "self" } ] }, user_info: { address: { country: "FR", formatted: "3 RUE BELLINI 92800 PUTEAUX Complément d'adresse : 3EG", locality: "", postal_code: "92800", region: "", street_address: "" }, email: "[email protected]", family_name: "DOE", gender: "Mr", given_name: "JOHN", name: "DOE JOHN", phone_number: "0123456789", postal_address: { formatted: "John DOE 3 rue Bellini 92800 Puteaux", proof_of_residence: { file_wrapper: { base64: "BINARY_DATA_IN_BASE64_ENCODING", filename: "RE1_01_6456455601_6146559528.pdf" } } } } }, message: "Here are some data about user: 44c87444-b642-4d10-9c39-c97dcf53e5e9", status: "succes" }
{
data: {
links: [
{
href: "https://sbx-app.m-itrust.com/user_data/v1/userinfo",
rel: "self"
}
],
user_consent: {
jwe: "ecnryptedConsent",
links: [
{
href: "https://sbx-app.m-itrust.com/service_provider/v1/userconsent",
rel: "self"
}
]
},
user_info: {
address: {
country: "FR",
formatted: "3 RUE BELLINI 92800 PUTEAUX Complément d'adresse : 3EG",
locality: "",
postal_code: "92800",
region: "",
street_address: ""
},
email: "[email protected]",
family_name: "DOE",
gender: "Mr",
given_name: "JOHN",
name: "DOE JOHN",
phone_number: "0123456789",
postal_address: {
formatted: "John DOE 3 rue Bellini 92800 Puteaux",
proof_of_residence: {
file_wrapper: {
base64: "BINARY_DATA_IN_BASE64_ENCODING",
filename: "RE1_01_6456455601_6146559528.pdf"
}
}
}
}
},
message: "Here are some data about user: 44c87444-b642-4d10-9c39-c97dcf53e5e9",
status: "succes"
}
Headless and autoupdate modes
Data can be fetched in Headless mode (without a graphical user interface) in two situations:
- When no end user credentials are required: a lot of corporate data is publicly available (ex. : registration certificates from Infogreffe.fr),
- When end user credentials were previously provided with user consent: they are encrypted in an AutoUpdate Token
In both cases, an encrypted token has to be provided in order to initiate the transaction.
The main steps to perform a Headless Session are the following:
- Generate a "headless" token (unless you already have an AutoUpdate Token)
- Initiate a headless session
- Poll for response
- Fetch the user info
- Delete the headless session
What's Autoupdate?
AutoUpdateis a MiTrust feature that allows users to set up the synchronization of some of their data (and documents), automatically and periodically, between a data source (DP) and an online service (SP). A distinction is made between an "initial" (classic) transaction and "ulterior" (headless) transactions. The initial transaction generates an AutoUpdate Token, which is entrusted to the SP and enables the execution of a subsequent transaction. The token can only be decrypted by MiTrust.
Generate a “headless” token
This step is not applicable if you already have an AutoUpdate Token from a previous user transaction.
In other cases, headless transactions require a “headless” token, which is generated from a “clients credentials” access token.
First, request a “clients credentials” access token through a POST request with BASIC authentication and a grant_type=client_credentials
. The client_credentials
grant type is used by clients to obtain an access token outside of the context of a user.
See our postman example: Generate client_credentials
access_token
for Headless transaction
{ body:{ grant_type: "client_credentials", scope: "headless" }, headers: { Authorization: "Basic + 'Base64(client_id:secret_key)'", Content-Type: "application/x-www-form-urlencoded" }, method: "POST", url: "https://sbx-app.m-itrust.com/oauth/token" }
The response of this POST would look like:
{ access_token: "client_credentials_access_token", expires_in: 3599, jti: "DXrWeEKW2nJ_xDW9yqQWutcRysM", scope: "headless", token_type: "bearer" }
Second, based on a scope, your client_credentials
access_token
can now be used to generate a Headless Token (which is equivalent to an AutoUpdate Token):
See our postman example: Postman Generate Headless Token Example
{ body: { company.country: "FR", company.registration_number: "SIREN Number" }, headers: { Authorization: "Bearer 'client_credentials_access_token'", type: "application/json" }, method: "POST", url: "https://sbx-app.m-itrust.com/v2/sp/headless/company" }
This will return a HeadlessToken, which has an expiry limited to 90 days, and can be used to start multiple headless sessions (e.g. fetch multiple KBIS)
{ data: { access_token_wrapper: { access_token: "eyJhbGciOi[....]", expires_in: 3600, links: [ { href: "http://localhost:8085/v2/sp/headless", rel: "self" } ], token_type: "headless_token" } }, status: "success" }
Given a headlessCredentialsToken, one can start a Headless Session.
Initiate a headless session
If your headlessCredentialsToken has been generated by an auto update feature, don't forget to create your access_token
This Headless Session represents an actual transaction, and is similar to a SharingFlow
To start your Headless Session, you have to make a POST request with your previously created access_token
and HeadlessToken:
{ headers: { Authorization: "Bearer 'client_credentials_access_token'", headless_token: "headless_token" }, method: "POST", url: "https://sbx-app.m-itrust.com/v2/sp/headless/" }
If the AutoUpdate Token size is greater than 64kB, you should send it as a Payload instead of the header.
{ headers: { Authorization: "Bearer 'client_credentials_access_token'" }, method: "POST", payload: { headless_token: "headless_token" }, url: "https://sbx-app.m-itrust.com/v2/sp/headless/" } }
The response of this POST will return to you a Headless Session token:
{ data: { headless_session: "headless_session", sharing_flow_id: "2c2c05e4-cc02-4f7b-a42f-4787cc44827f" }, status: "success" }
See our postman example: Postman Fetch headless_session
token
Poll for response
Now that you have your headless_session
, your backend shall poll MiTrust BE with it as a header.
{ headers: { Authorization: "Bearer 'client_credentials_access_token'", headless_session: "headless_session" }, method: "GET", url: "https://sbx-app.m-itrust.com/v2/sp/headless/" }
You should poll until the status is completed.
The HTTP response code could be :
-
HTTP 429 (
Too many requests
), in case your application polls MiTrust API too aggressively. This error is not permanent, and the call should be retried after a short delay (e.g. a few seconds). You should consider reducing the polling-rate of your application.- Header
x-ms-retry-after-ms
: The number of milliseconds to wait to retry the operation after an initial operation received HTTP status code 429 and was throttled.
- Header
-
HTTP 200 (
OK
) with one of the following status messages in the response body:-
ongoing
: continue polling every N seconds, -
completed
: the user info will be available at /userinfo entrypoint , -
failed
: the status failed is associated with a reason. Possible reasons are:login
: Issue with the login: (invalid input, MFA, ...).profile_not_found
: Issue with profiles: there is not a single profile matching the initial transaction.profile_ambiguity
: Issue with profiles: there is multiple profiles matching the invariants of the initial transaction.internal
: Issue within the platform.
-
See our postman example: Postman PollBackend for response
Fetch the user info
Make a request on https://sbx-app.m-itrust.com/user_data/v1/userinfo using your access_token
(see here) and your headless_session
.
{ Headers: { Authorization: "Bearer 'converted_access_token'", headless_session: "headless_session" } }
As a response, you will receive a JSON that contains user_info and the associated user_consent.
{ data: { user_consent: { jwe: "encryptedUserConsent" }, user_info: { address: { locality: "Paris" }, name: "John DOE" } }, message: " some message ", status: "succes" }
See our postman example: Postman Get userInfo For AutoUpdate
Delete the session
Once completed, you should acknowledged to good reception of data.
You should systematically delete the headless_session
. See our postman example: Postman DELETE headless session
{ headers: { Authorization: "Bearer 'client_credentials_access_token'", headless_session: "headless_session" }, method: "DELETE", url: "https://sbx-app.m-itrust.com/v2/sp/headless/" }
Headless token expiration and refresh
Headless tokens (including autoupdate tokens) expire after 90 days. During that period, you may refresh your token, therefore resetting they expiry date to 90 days. After 24 months, it is not possible any more to refresh your token.
To renew your token, you need to launch a Headless Session ( AutoUpdate Token renewal)
What's Autoupdate?
AutoUpdateis a MiTrust feature that allows users to set up the synchronization of some of their data (and documents), automatically and periodically, between a data source (DP) and an online service (SP). A distinction is made between an "initial" (classic) transaction and "ulterior" (headless) transactions. The initial transaction generates an AutoUpdate Token, which is entrusted to the SP and enables the execution of a subsequent transaction. The token can only be decrypted by MiTrust.
We recommend that you actively check the expiration of your tokens, and renew them in a timely manner, e.g. every 60 days for a 90 days expiration delay, by making a speficic call with your token, so that its expiry is reset long before expiration.
As a ServiceProvider, you may want to check the final date of expiration (24 months limit). It is encoded into the AutoUpdate Token, by parsing the
refresh_token
claim as a JWS object, and looking at its exp claim.{ headers: { Authorization: "Bearer 'client_credentials_access_token'", headless_token: "old_autoupdate_token" }, method: "POST ", url: "https://sbx-app.m-itrust.com/v2/sp/autoupdate" }
The response of this call will return :
{ date: { autoupdate: { access_token_wrapper: { access_token: "renewed_autoupdate_token", expires_in: 7776000, links: [ { href: "https://sbx-app.m-itrust.com/v2/sp/headless", rel: "self" } ], token_type: "headless" } } }, status: "success" }
Some errors you can encounter while integrating AutoUpdate:
{ error: "access_denied", error_description: "Access is denied" }
If you encounter an error message of this type, create a JIRA SP Update issue and request for an headless authorization.
Error management
If the End User abandons the MiTrust flow, or meets an error, the End User will be redirected to the ServiceProvider‘s redirect URI, with additionnal parameters such as error
& error_description
.
<redirect_uri>"?error=someErrorCode& error_description=Some%20details%20about%20the%20error
The error parameter will always be one of the values listed below:
access_denied
: The End User made an action to end the process, for example closing the pop-up window or going back to your website.timeout
: The End User exceeds the session duration, it can happen on every page. Each session is valid for 10 minutes.invalid_scope
: Your application is misconfigured, you selected a scope in the URL starting the SharingFlow while this scope is not activated in your application.temporarily_unavailable
: This error occurs when MiTrust platform is under maintenance or deploying a new version of the service.invalid_request
: We miss a parameter to properly build a session session_corrupted: The End User session has been corrupted (i.e :parameters have been removed from the url or such)
The error_description
parameter is HTML encoded and describe the circumstance of the error.
Popup vs full-screen integration
MiTrust supports various integration modes (popup, full screen, new tab). However, popup is very, very strongly recommended if you don’t want to lose users.
In order to open a Mitrust popup, it is recommend to use window.open
call :
window.open('https://sbx-app.m-itrust.com/v2/sp/sharingflow/start?client_id=' + client_id + '&scope=' + scope + '&state=' + encodeURIComponent(state) + '&redirect_uri=' + encodeURIComponent(redirectUri), 'name of your popup', 'width=414,height=736');
The size of the popup is defined as a params of window.open
. We recommend a size of width 414px & height 736px
Opening a popup with a <a>
HTML tag is not recommended, because you will be unable to define the popup size.
About popup clockers
Some browsers may block the opening of the popup or new tab
Warning
The call to
window.open
should be done on the userclick
event. Any delay (like the use ofsetTimeout
, XHR call or Promises) may lead to popup being blocked by the browser.Therefore, the MiTrust start flow URL must be integrated directly into the page, or retrieved on page load, but not after the user has clicked on the MiTrust button, as this would be considered lazy loading and blocked by some browsers.
You need to test your integration with the appropriate configuration (Android, iOS, Chrome, Safari, Edge) to make sure it's not blocked by the browser.
See Popups reference links:
Google Chrome: https://support.google.com/chrome
Apple Safari: https://support.apple.com/guide/safari
Firefox: https://support.mozilla.org/pop-blocker-settings-exceptions-troubleshooting
In case the MiTrust button stays visible in your UI while the Sharing Flow is in progress in its own popup, there is always the possibility that the End User might navigate between windows. Therefore, we recommend handling the clicking on the MiTrust button like this :
- If a popup is already opened and backgrounded, restore it as the front window by calling
focus()
on thewindow
object handling the popup - Otherwise, open a new popup to start a fresh Sharing Flow, and keep a reference to it
After the end of the MiTrust flow, somewhere on your redirect URI page, you should close the popup
window.close();
Scope, grammar, granularity and attributes
The list of sources (Data Providers) proposed to the end ensure is computed automatically based on the scope. Only data providers capable of producing valid and complete profiles are proposed to the user.
Each Data Provider may provide a different granularity for the same data. For instance, some Data Providers will provide a name, but not separate given_name and family name. Some Data Providers will provide a postal_address.formatted
, but not separate elements like address.street
, address.city
, etc.
The full list of claims will be shared with you in the course of the set-up project
The MiTrust Grammar (full claims list)
- Several attributes may be added to the claims composing a scope. Here are a few examples:
- Data requirement:
name#essential family_name#softly_required
- AutoUpdate role:
name#invariant proof_of_address#mutable
- Data source inclusion/exclusion:
tag:-sector.tax tag:sector.energy
- Tabular data / Historical depth:
finances.income.table.date#period.P3M#limit.P9M
- Data normalization:
personal.marital_status.raw, personal.marital_status.normalized, address#normalized
- Advanced features:
autoupdate, certificate
- Singular data (choose one):
public_health_insurance.beneficiary
- Plural data (get all):
public_health_insurance.beneficiaries
Scope configuration is not an obvious task, please contact us if you need further assistance or in order to setup a workshop with our data consulting team.
Browser compatibility
The compatibility matrix of browsers is very fragmented, but MiTrust has extensive real-world support. You may enquire about a specific user-agent directly to us.
Browser | Version | OS |
---|---|---|
Chrome | Latest stable | iOs, Linux, Android, Windows |
Edge | Latest stable | Linux, Android |
Firefox | Latest version | iOs, Linux, Android, Windows |
Safari | Latest version | iOs, Android |
Environments
View the descriptions for sandbox and production environments below.
Production | Sandbox | |
---|---|---|
Short name | PRD | SBX |
Description | For your production environment, all successful sharing flows are billed | For development and test with stub sources (no need for credentials), unlimited requests and free. Live sources are also available, but not covered by our SLA |
Entry point | https://app.m-itrust.com | https://sbx-app.m-itrust.com |
Mobile integration
There isn't a specific SDK for the integration of Mitrust into iOS or Android but the MiTrust data verification can be used directly within a webbrowser under mobile devices (especially Android and iOS). The recommended way to do it is to launch the mobile's default browser and redirect the EndUser to your mobile application once the SharingFlow is done. It is also possible to embed MiTrust in a webview, although this it is discouraged for security reasons as the users credentials could be maliciously fetched.
Here is some technical documentation about how an external browser can interact with a native application :
https://developer.android.com/training/app-links
https://developer.android.com/guide/components/intents-common#Browser https://developers.facebook.com/docs/facebook-login/security/#surfacearea
About iOS, the typical way would be:
let safariViewController = SFSafariViewController ( url : "m-itrust.com" ) present ( safariViewController , animated : true )
WKWebView should be avoided as it allows HTML customisation and JS injection
About SSO, once the user account is ready : https://github.com/openid/AppAuth-iOS/issues/120
Server certificate
HTTPS
The MiTrust API will only serve traffic over HTTPS, and will include an HSTS response header in order to let browsers and other client so ware enforce this.
Server certificate
The MiTrust API server certificate should be trusted by all supported browsers, including latest versions of Chrome, Firefox, Edge, and Safari.
If your software uses a custom certificate trust store, and / or certificate pinning, you will have to trust:
- Let's encrypt trust anchor for SBX platform. More on https://letsencrypt.org/certificates/
- Sectigo's EV trust anchors for PRD platform. More on sectigo.com
Note that MiTrust renew its Let's Encrypt server certificates every 3 months. To avoid unexpected connectivity issues, MiTrust therefore recommends against depending on any part of the server certificate. The trust root is ISG Root X1, which can be downloaded at the address above.
For production, MiTrust uses EV certificates that are renewed every year. In case of emergency, MiTrust may use a Let's Encrypt certificate in PRD environment, as a degraded mode.
About certificate pinning
Certificate pinning Let's Encrypt root certificate does not bring security, as anybody is free to generate a certificate with Let'sEncrypt. Hence, if we provided a way to pin a certificate which would not roll every 3 months, please understand this does not provide any safety regarding MiTrust actual legitimacy.
Availability API
You may want to check if a defined set of DataProvider is available to access the required data according to your scope
. You can do it by calling the availability endpoint with a GET
request corresponding to your environment (SBX or PRD), providing your scope
and client_id
as parameters.
This API can be used to automatically set up a "downgraded mode" in your UI, in which the MiTrust functionality is hidden, possibly informing the users of the temporary unavailability of the service.
The availability endpoint is described in our API documentation: Get count of available DP . The caller can expect the API to be fast most of the time, but a very occasional delay is expectable.
'https://sbx-app.m-itrust.com/v2/public/dp/statistics?scope='
+ encodeURIComponent(scope)
+ '&client_id='
+ encodeURIComponent(client_id)
Example of a request with scope: name adress.formatted#softly_required
curl -X GET "https://sbx-app.m-itrust.com/v2/public/dp/statistics?scope=name%20address.formatted%23softly_required&client_id=myClientId"
will return:
{
"status": "success",
"data": {
"active_dps": 53,
"client_id": "myClientId",
"scope": "name address.formatted#softly_required"
}
}
Updated about 2 months ago