Identity Service — Relying Party Developer Guide
1. Introduction: Identity Data
Before we go into the details of the identity flow, we introduce the basic concepts behind the data available through the identity service.
What kind of data is needed depends on your business case. If you need advice, feel free to talk to your contact! |
1.1. Verified and Unverified Data
Generally speaking, the Identity Service offers the retrieval of verified and unverified user information. Some data fields (called claims in OpenID Connect) are available both as unverified claims and as verified claims. In one request, all types of claims can be combined. As a rule of thumb, unverified data is generally free, verified data is generally priced according to the price list.
Verified Claims: A selected set of data is available as verified claims. The data comes from the IDP’s KYC processes (for example, during the set-up of a new bank account), maintained according to the respective anti-money laundering laws. The available claims include certain data about the user (name, address, nationalities, and other data) as well as data from the verification process itself, for example, the ID card or passport number, date of issuance, and the issuer.
Unverified claims: This data can be used for all purposes where you would normally accept self-declared data from a user, i.e., to replace form filling. There is no guarantee on the correctness of the data and the IDP may give the user the option to edit the data before it is transmitted to you. For example, if you have a sign up form in a web shop, but would give the user the option to use the data from their online banking, you can use the unverified data provided by the Identity Service to speed up the process. This data includes, for example, name, address, email address, phone number, gender, and salutation.
The following table shows a selection of the most important claims, see Appendix 1 - User Information and Appendix 2 - Verified Claims for claim details, data formats, and the request syntax.
Availability: U = unverified, V = verified, S = special (see notes).
Claim | Type* | Notes |
---|---|---|
Pseudonymous Identifier |
S |
OpenID Connect |
Given/Family Name |
U or V |
|
Date and Place of Birth |
U or V |
|
Nationalities |
U or V |
|
Address |
U or V |
|
Gender, Salutation, Title |
U |
|
|
U |
|
Phone number |
U |
|
Tax ID |
S |
Not editable by the user. |
IBAN |
S |
User can select one IBAN if multiple are associated with the online banking account. Not editable by the user. |
ID document type, issuer, etc. |
V |
|
Transaction Identifier |
S |
For audit purposes. Not editable by the user. |
1.2. Userinfo vs. ID Token
OpenID Connect defines two ways for transferring claims to
the relying party: Via the ID Token or via the Userinfo
endpoint. The ID Token is transmitted directly in the
response from the token endpoint (which needs to be called
in any case). See Step 22 in the chart above. The userinfo
endpoint needs to be called separately, using the access
token acquired from the token endpoint. This is shown in the
optional Steps 25 and 26 above. Using the
claims
parameter, you can define at which
endpoint you want to retrieve which data, see the next
example.
As a relying party, you are free to use either of the methods for both verified and unverified data.
The ID Token is available without having to do another request/response round trip, slightly reducing overall latency. Therefore, the ID Token is generally preferable. |
1.3. Availability of Data and Billing
Most claims are "Mandatory to Implement" for IDPs (see details in Appendix 1 - User Information and Appendix 2 - Verified Claims). Nonetheless, due to unavailable data or for technical reasons, some claims can be unavailable in rare cases. In this case, the respective claim is omitted in the response.
It is therefore important to check that all required information for your business case have been returned from the flow. |
Claims that are billed (generally, verified data, see your contract for details), are billed each time the claim is transferred from the IDP to you. That is, if you request the same claim both in the ID Token and in the Userinfo endpoint, you will be billed for the claim twice. If you request the data multiple times from the Userinfo endpoint, you will be billed for each request.
You can mark certain claims as "essential" in the request (see example below). If one or more claims marked as essential are not available, the delivery of the other claims will not be billed. |
1.4. Requesting Claims
The way claims can be requested follows the convention
introduced by the OpenID Connect specification (cf.
OpenID Connect Specification). Basically, the claims are added to the respective
section (id_token
or userinfo
,
depending on how you request user infos) of the
claims
. Verified claims are contained in a
special structure, verified_claims
. For
details, see
Appendix 2 - Verified Claims.
An example is shown in the following:
claims
Parameter
The following JSON document shows contents of the
claims
parameter in the authentication
request.
In this example, the phone number, salutation (both
unverified), and the IBAN are retrieved in the ID Token.
The user identifier (sub
) will also be
contained in the ID Token.
From the userinfo endpoint, address and the tax ID are retrieved as unverified claims. The name, birthdate, place of birth, and nationalities are requested as verified claims. Name and birthdate are marked as essential - when either of the claims is not available to the IDP, the rest of the claims will be delivered, but not billed.
Please refer to the
OpenID Connect Specification
for details on the basic syntax and to
Appendix 2 - Verified Claims for
details on the contents of verified_claims
.
{
"id_token":{
"phone_number": null,
"salutation": null,
"https://www.openbanking.verimi.cloud/claims/preferred_iban":null
},
"userinfo":{
"verified_claims": {
"verification": {
"trust_framework": null
},
"claims": {
"given_name":{
"essential": true
},
"family_name":{
"essential": true
},
"birthdate":{
"essential": true
},
"place_of_birth":null,
"nationalities":null
}
},
"address":null,
"https://www.openbanking.verimi.cloud/claims/tax_id":null
}
}
2. Issuer URI Check
Before you can start the identity flow, you need to send the user to the account chooser, as described in the base document. You will receive an issuer URI from that process.
After you got back the issuer URI from the Account Chooser you have to check if the IDP (which belongs to the Issuer URI) is valid and active.
This check MUST take place in the backend, not in the user’s browser. |
To do this, you have to perform a GET request to the following
endpoint with the Issuer URI as a URL query parameter:
https://accounts.sandbox.openbanking.verimi.cloud/idp/?iss={issuer_url}
for the sandbox or
https://accounts.openbanking.verimi.de/idp/?iss={issuer_url}
for the production environment.
Make sure to URL-encode the iss parameter
properly, as with all URL parameters.
|
Request:
GET accounts.sandbox.openbanking.verimi.cloud/idp/?iss=https%3A%2F%2Ftestidp
.sandbox.yes.com%2Fissuer%2F10000001
Host: accounts.sandbox.openbanking.verimi.cloud
Response:
HTTP/1.1 204
The API returns an HTTP status code and an empty body.
-
If the IDP is found and active, the returned status code is
204
(no content). -
If the Issuer URI is not a valid URI, the returned status code is
400
(bad request). -
If the IDP is not found, the returned status code is
404
(not found). -
If the IDP is found but not active, the returned status code is
423
(locked).
In the case of status code 204 (no content) you can perform the redirect to the IDP, otherwise you have to do an exception handling.
The flow may only be continued with the status code 204. All other codes must be treated as an error and the user has to be informed that she cannot continue with her bank at the moment. |
3. OpenID Connect Process
Now your app is prepared to talk to the OP in order to authenticate the user and get access to her personal data (so-called "claims").
The issuer_url
, obtained in the previous step,
points to a identity service-compliant OpenID Connect OP.
3.1. OpenID Connect Configuration
Each identity service-compliant OP provides an
OpenID Provider Configuration
accessible via a GET request to
{issuer_url}/.well-known/openid-configuration
.
Your app uses this configuration to determine the different
endpoint URLs and further metadata that will be used in the
course of the OpenID Connect process.
The OpenID configuration is a JSON document which contains (amongst others) the following attributes:
-
issuer
REQUIRED: the OpenID Connect issuer URL of this OP.
This value MUST exactly match the
issuer_url .
|
-
jwks_uri
REQUIRED: The URI to the public keys (JWK Set) needed to validate the signature of ID tokens issued by this OP. -
authorization_endpoint
REQUIRED: the URL the Authentication Request is sent to -
token_endpoint
REQUIRED: the URL of the token endpoint that is later in the protocol used to exchange the authorization code for tokens and identity claims -
userinfo_endpoint
REQUIRED: the URL to get identity claims from if the UserInfo Endpoint is used. -
claims_supported
REQUIRED: the list of claims supported by this OP. For a list of claims see Appendix 1 - User Information and Appendix 2 - Verified Claims. -
acr_values_supported
REQUIRED: this claim publishes all Authentication Context Class References supported by the OP For a list of acr values see acr values. -
claims_in_verified_claims_supported
REQUIRED: JSON array containing all claims supported within the verified claims. -
id_documents_supported
andid_documents_verification_methods_supported
REQUIRED: JSON arrays containing all id document identifiers and verification method identifiers supported within the verified claims.
Request:
GET testidp.sandbox.openbanking.verimi.cloud/issuer/10000001/.well-known/openid-configuration
Accept: application/json
Host: testidp.sandbox.openbanking.verimi.cloud
Response (abbreviated):
HTTP/1.1 200
Content-type: application/json;charset=UTF-8
Content-length: 7258
{
"authorization_endpoint":"https://...",
"token_endpoint":"https://...",
"registration_endpoint":"https://...",
"issuer":"https://testidp.sandbox.openbanking.verimi.cloud/issuer/10000001",
...
}
3.2. Authentication Request
Now that you know the authorization endpoint of the IDP, you
can start the authentication flow by redirecting the user
agent (HTTP status code 302) to the
authorization_endpoint
.
When creating the authentication request, you have to decide
on which user data you want to request via
claims
, as explained above.
3.2.1. Parameters
As usual, all parameters MUST be properly encoded.
Please ensure that your library also properly encodes
a + sign (especially if you have a
base64-encoded value for nonce or
state ) and { and
} (for example, in claims ).
The latter two are sometimes not properly encoded by
libraries, see
this discussion.
|
The authentication request supports the following parameters
-
response_type
REQUIRED: always set tocode
in the identity service scheme. -
client_id
REQUIRED: theclient_id
of your app. Please take care to use the correct client id for the intended environment here (sandbox/production). -
redirect_uri
REQUIRED: the user agent is sent to this destination after the completion of the authentication process. This must exactly match one of the Redirect URIs you registered with the identity service. -
claims
OPTIONAL: JSON object according to the OpenID Specification defining the identity claims your app wants to obtain for a user, as described above. -
scope
REQUIRED: MUST always beopenid
to turn on OpenID Connect. -
state
OPTIONAL: a cryptographic random value, freshly chosen by the client that must be used to detect CSRF attacks. Usually created by an OAuth library. -
nonce
REQUIRED*: a cryptographic random value, freshly chosen by the client to link the OpenID Connect authentication request to subsequent steps in the message flow and to detect CSRF attacks. Usually created by an OpenID Connect library. -
purpose
OPTIONAL: see below -
acr_values
OPTIONAL: see below
* Instead of nonce , you can instead use
PKCE
(parameters code_challenge and
code_verifier ) as well, as both provide
similar levels or protection. The use of PKCE is
described in the
signing service developer guide.
|
Your app can only use claims that are registered for it. |
The parameter response_mode is not
supported by the identity service IDPs and can lead to
errors when used.
|
3.2.2. Request-specific Purpose
A dedicated purpose has to be set for every transfer of user data. The purpose text is shown in the IDP’s user interface to give the user context on what they are about to do.
For convenience, a default purpose is set on client
registration. To set a transaction specific purpose, use
the additional purpose parameter like this:
purpose={Purpose}
.
Some authorization servers filter out special
characters in parameters of the authorization request
(most likely as an attempt to prevent cross-site
scripting). If possible, avoid using the characters
<>(){}'\ and HTML tags.
|
The purpose cannot be shorter than 3 characters and may
not be longer than 300 characters. If these rules are
violated, the authorization request will fail, i.e., the
authorization response redirection URL (HTTP status code
302) will carry the parameters
error=invalid_request
and
error_description=invalid_purpose_length
.
https://{Redirect URI}?state=-ZBPQz_Rj5DA8c9X7Y9wzgiMsJYdtYoRpwOB0qdeyBQ &error=invalid_request&error_description=invalid_purpose_length
3.2.3. Authentication Policy
OPs can authenticate the user using two different
authentication levels. You request an authorization level
using the acr_values
parameter.
The following two authentication levels are available:
-
https://www.openbanking.verimi.cloud/acrs/online_banking
(default): Single factor authentication using the primary online banking credentials, e.g., a code or a password. The user either enters her username or the username was automatically determined based on data from previous logins. -
https://www.openbanking.verimi.cloud/acrs/online_banking_sca
: Two factor authentication (strong customer authentication) utilizing online banking credentials and a second factor or TAN approach. The user either enters her username or the username was automatically determined based on data from previous logins.
The acr
values supported can be found in the
issuer’s OIDC configuration’s value
acr_values_supported
.
In the JSON you can see - in the acr
property
- which acr level the authentication was done with.
The server can use a lower acr value than the one
requested. Always check the
acr claim in the response for the acr
value actually used by the server.
|
3.2.4. Implementation Notes
HTTP/1.1 302 Found
Location: https://testidp.sandbox.openbanking.verimi.cloud/services/authz/10000001?cl
ient_id=sandbox.yes.com%3Ae85ff3bc-96f8-4ae7-b6b1-894d8dde9e
be&scope=openid&response_type=code&redirect_uri=http%3A%2F%2
Flocalhost%3A3000%2Fyes%2Foidccb&nonce=FMIGY3-9VrVDzKLATMJx0
-V1F4gV3fDx6y110UzQJpk&acr_values=https%3A%2F%2Fwww.yes.com%
2Facrs%2Fonline_banking_sca&claims=%7B%22id_token%22%3A%7B%2
2given_name%22%3Anull%2C%22family_name%22%3Anull%2C%22verifi
ed_claims%22%3A%7B%22verification%22%3A%7B%22trust_framework
%22%3Anull%7D%2C%22claims%22%3A%7B%22birthdate%22%3Anull%7D%
7D%7D%2C%22userinfo%22%3A%7B%22salutation%22%3Anull%2C%22tit
le%22%3Anull%2C%22verified_claims%22%3A%7B%22verification%22
%3A%7B%22trust_framework%22%3Anull%7D%2C%22claims%22%3A%7B%2
2place_of_birth%22%3Anull%2C%22nationalities%22%3Anull%7D%7D
%7D%7D&state=V1F4gV3fDx6y110UzQJpk
Using a nicer formatting, the request to
https://testidp.sandbox.openbanking.verimi.cloud/services/authz/10000001
contains the following request parameters:
?client_id=sandbox.yes.com:e85ff3bc-96f8-4ae7-b6b1-894d8dde9ebe &scope=openid &response_type=code &redirect_uri=http://rpbackend.acme.com/yes/oidccb &state=V1F4gV3fDx6y110UzQJpk &nonce=FMIGY3-9VrVDzKLATMJx0 &acr_values=https://www.openbanking.verimi.cloud/acrs/online_banking_sca &claims={ "id_token":{ "given_name":null, "family_name":null, "verified_claims":{ "verification":{ "trust_framework":null }, "claims":{ "birthdate":null } } }, "userinfo":{ "salutation":null, "title":null, "verified_claims":{ "verification":{ "trust_framework":null }, "claims":{ "place_of_birth":null, "nationalities":null } } } }
In order to prevent CSRF attacks, both
nonce and state (if used)
MUST be associated with the user agent where the
request originated. This binding MUST be checked after
the RP received the
Authentication Response
and Token Response.
|
The authorization endpoint URI may contain parameters
which have to be preserved when using the URI. Please
make sure that your code or the library used supports
parameters in endpoint URIs so that you don’t run into
problems because of parameters being cut off or a
duplicate ? being used resulting in an
invalid URI.
|
Screen control is with the OP now which will guide your user through login and consent. The OP requires information about your app in the course of this flow. You therefore have to provide a privacy policy and may provide an optional terms of service document and label upon registration.
The way the OP authenticates the user and asks her to consent at the discretion of the OP. |
3.3. Authentication Response
After successful authentication, authorization, and consent,
the OP will redirect (HTTP status code 302) your user to the
{redirect_uri}
given in the
Authentication Request
including the following request parameters:
-
code
: the authorization code you need to get the ID and access token -
iss
: the issuer URL of the OP that created this response. You app MUST check that this value is equal to the issuer URL used in the previous steps. This is a countermeasure against mix-up attacks.
The check and the token endpoint request MUST be implemented in the backend logic of the application as this does not expose the results to client side attacks and allows to use client secrets to authenticate the client. |
GET /yes/oidccb?code=rDx7qadXAgCrkTGxF7WjrA.gs8gNEgMhH6Ww-VBZbz04w&
iss=https://testidp.sandbox.openbanking.verimi.cloud/issuer/10000001&state=V1F
4gV3fDx6y110UzQJpk HTTP/1.1
Host: rpbackend.acme.com
3.4. Authentication Error Response
Errors according to
OAuth 2.0 Authorization Error Response,
OAuth 2.0 Error Response, or
OIDC 1.0 Authentication Error Response
may occur and must be handled. In case of an error the
parameter error
will deliver an error code with
optional details in the parameter
error_description
.
There is a identity service specific error code
account_selection_requested which is
returned by the OP if the user clicks 'Select another
bank' during the online banking login and shall cause a
forced bank selection in the account chooser.
|
3.5. Token Request
If your app received a successful authentication response,
your backend at {redirect_uri}
needs to
exchange the authorization code for tokens at the
token_endpoint
. The token request is a POST
request with content type
application/x-www-form-urlencoded
and the
following parameters:
-
grant_type
REQUIRED: must be set toauthorization_code
-
code
REQUIRED: authorization code returned in the authorization response -
client_id
REQUIRED: yourclient_id
-
redirect_uri
REQUIRED: sameredirect_uri
as used in the authorization request. This is a security countermeasure against client impersonation.
Your RP backend has to perform client authentication with the OP via mutual TLS (aka. TLS client authentication): Your RP has to be configured so that it uses the self-signed certificate with which you registered your RP for the TLS handshake with the OP. |
POST testidp.sandbox.openbanking.verimi.cloud/issuer/10000001/token
Accept: application/json
Accept-encoding: gzip, deflate
Content-type: application/x-www-form-urlencoded
Content-length: 261
Host: testidp.sandbox.openbanking.verimi.cloud
grant_type=authorization_code&code=rDx7qadXAgCrkTGxF7WjrA.gs8gNEgMhH6W
w-VBZbz04w&redirect_uri=http%3A%2F%2Frpbackend.acme.com%2Fyes%2Foidccb
&client_id=sandbox.yes.com%3Ae85ff3bc-96f8-4ae7-b6b1-894d8dde9ebe
3.6. Token Response
Nearly there! The IDP will respond with a JSON object, i.e.,
the response will contain the header
Content-Type: application/json;charset=UTF-8
.
The JSON object has the following attributes (and may have others)
-
access_token
OPTIONAL: the access token (not needed in the identity service) -
token_type
REQUIRED: always set tobearer
-
expires_in
RECOMMENDED: seconds until expiration -
id_token
REQUIRED: the ID Token, a JWT signed by the OP
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
{
"access_token":"2ZUIENkskjfiejkpAA",
"token_type":"bearer",
"expires_in":3600,
"scope":"openid",
"id_token":"eyKRJKLFJLIjlkdjkjhdkjhdlkl3k5lkjl..."
}
ID Token Contents.*
{
"sub": "f647f683-e46d-43bd-bc76-526d93429b86",
"aud": "sandbox.yes.com:e85ff3bc-96f8-4ae7-b6b1-894d8dde9ebe",
"iss": "https://testidp.sandbox.openbanking.verimi.cloud/issuer/10000001",
"exp": 1599642067,
"iat": 1599641167,
"nonce": "FMIGY3-9VrVDzKLATMJx0",
"given_name": "Given001",
"family_name": "Family001",
"verified_claims": {
"verification": {
"trust_framework": "de_aml"
},
"claims": {
"birthdate": "1950-01-01"
}
}
}
The ID Token is a
JWT signed
by the OP with the RSA SHA-256 algorithm and a private key
belonging to one of the public keys (or certificates) in the
JWKS available via the jwks_uri
provided in the
OpenID Connect Configuration. The
ID token payload contains the following attributes (and may
contain others):
-
iss
REQUIRED: MUST be validated to be equal to the Issuer URI -
aud
REQUIRED: MUST be validated to be equal to yourclient_id
-
sub
REQUIRED: the user ID (unique only in the scope of the issueriss
which is important if you store user IDs) -
nonce
REQUIRED: MUST be checked to be equal to the nonce in the authorization request -
exp
REQUIRED: (int) token expiration, token MUST NOT be accepted after exp -
iat
REQUIRED: (int) token issued at (time)
The ID token will contain further identity claims as
requested in the authentication request using the
claims
parameter.
3.6.1. Handling Returned Data
It is important to know what to expect from the returned data and how to handle it: You must first check that the response is correct and complete before using the user data in your application.
Follow these steps to ensure that the returned data is trustworthy:
-
Check that the ID token is a valid JWT.
-
Check that the
iss
value matches the issuer URL returned from the account chooser. -
Check that
aud
matches your client ID. -
Check the signature of the JWT using the keys provided in the OpenID Connect Configuration document retrieved earlier.
-
Check that the algorithm for the signature is
RS256
. -
Check that
nonce
matches the nonce selected earlier in the process. -
Check that the current time is between
iat
andexp
.
These steps should be performed by an OpenID Connect library. If any check fails, the process must be aborted.
Skipping any of the steps of the validation of the ID token will lead to security vulnerabilities in your application. |
Now, check that the contents of the response match your expectations:
-
If a two-factor authentication is important to your application, you will have used the
acr_values
parameter in the authentication request (see Authentication Policy for details). Now, ensure that theacr
claim in the ID token reflects this value. -
Check that all requested claims are contained in the response and that the contents match your expectations. In some circumstances, data delivered by the IDP may be incomplete. It is your responsibility to act accordingly, e.g., to ask the user to fill in missing data or to inform the user that the process cannot be completed. See also Availability of Data and Billing.
Your application may now use the user ID and other identity claims, e.g., to log the user in.
You MUST build the identifier used to look up the user
profile locally by using the iss and the
sub as composite key (e.g., by
concatenating using a separator character), since the
sub
is guaranteed to be unique within the scope of a
particular IDP only.
|
3.7. Token Error Response
Errors according to
OAuth 2.0 Error Response, or
OIDC 1.0 Token Error Response
may occur and must be handled. In case of an error the
returned JSON object will normally contain an
error
attribute.
3.8. UserInfo Request/Response (optional)
Obtaining user data from the ID token provided in the Token Response is the quickest way. Alternatively, the data can be retrieved from the IDP’s UserInfo Endpoint.
To access the UserInfo Endpoint you will send a GET request
to the address extracted during the
OpenID Connect Configuration adding
the access token as a Bearer
authorization
header:
-
URL:
{userinfo_endpoint}
-
Request Header:
Authorization: Bearer {access_token}
Remember to make the TLS handshake with your self-signed
certificate and to add your
client_id as a request parameter as
explained in the
token request section
(Client authentication).
|
The return value is a JSON object, i.e., a response with a
header
Content-Type: application/json;charset=UTF-8
.
The JSON object contains at least the attribute
-
sub
REQUIRED: user ID which MUST be verified by the RP to match the one from the ID token
and the claims as requested in the authentication request.
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
{
"sub":"c7734893464991805caeda94c39414a163f5907caeadd61823b1feb386dcb198",
"https://www.openbanking.verimi.cloud/claims/place_of_birth":{
"locality":"Rösrath"
},
"birthdate":"1980-01-01",
"address":{
"country":"DE",
"street_address":"Lüghauser Str. 16",
"formatted":"Lüghauser Str. 16\n51503 Rösrath\nDEUTSCHLAND",
"locality":"Rösrath",
"postal_code":"51503"
},
"phone_number":"+4915245678900",
"given_name":"Yasmin",
"family_name":"Verimi",
"email":"yasmin@verimi.de"
}
Appendix 1 - User Information
The identity service IDP MUST allow RPs to request user information (claims) belonging to the user’s online banking account.
With version 2.x of this developer guide, some claim names have changed. For new implementations, please only use the new names for the claims as shown in the following. |
The RP requests the claims using the
claims
request parameter in the
Authentication Request.
The RP can select whether the claims are provided via the ID
Token or at the UserInfo Endpoint. The ID Token is easier to
implement and faster and therefore the preferred way.
The following claims are supported:
Claim | Type | Description | MTI | ||
---|---|---|---|---|---|
|
string |
see OpenID Connect, section 5.1 |
yes |
||
|
string |
based on OpenID Connect, section 5.1, representation of the phone number according to E.164 in the format
regular expression:
Example: It is recommended to provide the RP with the preferred mobile phone number of the user. |
yes |
||
|
string |
see OpenID Connect, section 5.1 |
yes |
||
|
string |
see OpenID Connect, section 5.1 |
yes |
||
|
string |
The gender selected by this person,
see OpenID Connect, section 5.1 |
no |
||
|
string |
end-user’s salutation, e.g., |
no |
||
|
string |
end-user’s title, e.g., |
no |
||
|
JSON object |
end-user’s place of birth as defined in OpenID Connect for Identity Assurance
The sub-field |
yes |
||
|
string |
ISO 8601:2004 YYYY-MM-DD format, e.g.,
|
yes |
||
|
string array |
ICAO 2-letter codes, e.g., |
yes |
||
|
JSON object |
see OpenID Connect, section 5.1.1
|
yes |
||
|
string |
tax identification number |
no |
||
|
string |
IBAN of the debit account the users wants to use for transactions. How this account is determined (if there are more than a single account associated with the user’s online banking account) is at the discretion of the identity service IDP. The IDP might ask the user within the flow but should utilize sensible default and preferences in order to make the user experience as frictionless as possible. |
no |
||
|
string |
see OpenID Connect for Identity Assurance. Note: This claim is available independent of verified claims. |
yes |
Appendix 2 - Verified Claims
The identity service IDPs MUST support the attestation of verified claims. This attestation consists of
-
the verified data (claims) about the online banking user’s identity,
-
data about the verification process used to bind a person’s identity to a certain online banking account, and
-
data about the actual authentication process used to ensure the binding between user account and the actual user.
The latter data are carried using the acr value as described
in Authentication Policy. The verified
claims and the data about the verification process are
represented as a structure within a special claim,
verified_claims
.
Requesting Verified Claims
Requests to OPs MUST follow OpenID Connect for Identity Assurance and use the identifier defined in OpenID Connect for Identity Assurance Identifiers. Please refer to these documents for full details. The most important features are shown in the following.
Let’s start with an example request and response that
shows how the verified_claims
claim can be
requested alongside unverified claims:
Request. In this example, different sets of data are requested in the ID token and from the userinfo endpoint:
{
"id_token":{ (1)
"given_name":null,
"family_name":null,
"verified_claims":{
"verification":{
"trust_framework":null (2)
},
"claims":{
"birthdate":null (3)
}
}
},
"userinfo":{ (4)
"salutation":null,
"title":null,
"verified_claims":{
"verification":{
"trust_framework":null
},
"claims":{
"place_of_birth":null, (5)
"nationalities":null
}
}
}
}
1 | In the ID token, the given name and family name are requested without further verification. |
2 |
The trust framework must always be requested if
verified claims are requested. de_aml ,
identifying the Germany Anti-Money Laundering Law,
is currently the only supported trust framework.
|
3 | In the ID token, the birthdate is requested as a verified claim. |
4 | From the userinfo endpoint, the salutation and title are requested unverified. |
5 | Place of birth and the nationalities are requested as verified claims. |
ID Token. This is an example for the ID token that would be produced from the request above.
{
"sub": "f647f683-e46d-43bd-bc76-526d93429b86",
"aud": "sandbox.yes.com:7011b6c1-d4f3-4ee3-865b-50af0475755f",
"iss": "https://testidp.sandbox.openbanking.verimi.cloud/issuer/10000001",
"exp": 1599642067,
"iat": 1599641167,
"nonce": "42",
"given_name": "Given001",
"family_name": "Family001",
"verified_claims": {
"verification": {
"trust_framework": "de_aml"
},
"claims": {
"birthdate": "1950-01-01"
}
}
}
Userinfo. At the userinfo endpoint, the
following data might be returned (here taken from the
Test IDP with user test001
, see for Test
IDP and test user details):
{
"sub": "f647f683-e46d-43bd-bc76-526d93429b86",
"salutation": "Herr",
"title": "Dr.",
"verified_claims": {
"verification": {
"trust_framework": "de_aml"
},
"claims": {
"place_of_birth": {
"locality": "Berlin",
"country": "DE"
},
"nationalities": [
"DE"
]
}
}
}
Since the same request syntax can be used within
userinfo and id_token in the
claims parameter, the outer layer of the
claims parameter is omitted in the
following examples. We will only show the
verified_claims claim.
|
The following example shows the core of a
verified_claims
structure that you can build
upon to create your own request:
Note: Outer level of claims
structure
omitted for presentation.
{
"verified_claims":{ (1)
"verification":{ (1)
"trust_framework": …, (4)
"time": …, (5)
"verification_process": …, (6)
"evidence":[ (7)
{
"type":{ (8)
"value": …
},
"method": …, (3)
"document":{ (2)
"type": …, (4)
"issuer":{ (2)
"country": …, (3)
"name": …, (6)
"… any other keys …": … (6)
},
"… any other keys …": … (6)
}
"… any other keys …": … (6)
}
]
},
"claims":{ (1)
"given_name": …, (3)
"family_name": …, (3)
"birthdate": …, (3)
"place_of_birth": …, (3)
"nationalities": …, (3)
"address": … (3)
}
},
… (claims)
}
1 |
This key MUST NOT be omitted and MUST contain an
object with at least one key (verified_claims
MUST contain verification and
claims ).
|
2 | This key MAY be omitted completely. Otherwise, its value MUST be an object. |
3 |
This claim MAY be requested using
null or an object. The object MAY
contain the keys essential and either
value or values . Other
keys are not permitted in the object.
|
4 |
This key MUST be requested (unless the parent
element is omitted) using null or an
object. The object MAY contain the keys
value or values . Other
keys are not permitted in the object.
|
5 |
time MAY be omitted. Otherwise, its
value MUST be either null or an object
with the max_age key and/or the
essential key. Other keys are not
permitted in the object.
|
6 |
This key MAY be requested using null or
an object. The object MAY contain the key
essential . Other keys are not permitted
in the object.
|
7 |
evidence MUST either be omitted or MUST
contain an array with exactly one object.
|
8 |
evidence /type MUST be
requested (if evidence is not omitted)
using a concrete value . Other keys are
not permitted in the object.
|
value
, values
,
essential
, max_age
are used as
defined in
OpenID Connect for Identity Assurance. If a key is omitted in the request, the response will not
contain the respective key.
The IDP will also omit certain parts of the response if user data is not available or does not match the requirements in request - this is explained in more detail in Data Handling by the IDP. |
Only "leaf" claims can be marked essential .
Object/array claims (place_of_birth ,
nationalities , address ) are
considered leaf claims and can only be essential as a
whole (or not).
|
OPs will reject requests not complying with this syntax.
Request. Note: Outer level of
claims
structure omitted for presentation.
{
"verified_claims":{
"verification":{
"trust_framework": null
},
"claims":{
"family_name": null
}
}
}
Request. Note: Outer level of
claims
structure omitted for presentation.
{
"verified_claims":{
"verification":{
"trust_framework": {
"value": "de_aml"
},
"time": {
"max_age": 864000000
},
"evidence":[
{
"type": {
"value": "id_document"
},
"method": null,
"document":{
"type": null,
"issuer":{
"country": {
"essential": true
},
"name": null
}
}
}
]
},
"claims":{
"given_name": {
"essential": true
},
"family_name": {
"essential": true
},
"birthdate": {
"essential": true
}
}
},
"txn": null
}
Response. Example ID token response
from the Test IDP with user test006
(see
for Test IDP and test user details):
{
"sub": "524aeddd-7922-4c36-b496-217f32c45a14",
"aud": "sandbox.yes.com:7011b6c1-d4f3-4ee3-865b-50af0475755f",
"verified_claims": {
"claims": {
"birthdate": "1975-06-06",
"given_name": "Given006",
"family_name": "Family006"
},
"verification": {
"trust_framework": "de_aml",
"time": "2019-01-02T06:06:06.060+01",
"evidence": [
{
"method": "sripp",
"document": {
"type": "idcard",
"issuer": {
"country": "DE",
"name": "Stadt Köln"
}
},
"type": "id_document"
}
]
}
},
"iss": "https://testidp.sandbox.openbanking.verimi.cloud/issuer/10000001",
"txn": "34b65a01-921f-4c44-914a-7208d45f646e",
"exp": 1599643443,
"iat": 1599642543,
"nonce": "42"
}
Never include data in value or
values that could identify a user (personally identifiable information), as the contents of value and
values end up in the billing system.
|
Data Handling by the IDP
The IDP will check if the data available for the online banking user is sufficient to fulfill the requirements encoded in your request. Depending on the available data, the IDP will either send a full response or omit certain elements from the response:
-
If a requirement (using
value
,values
, ormax_age
) withinverified_claims
/verification
cannot be fulfilled by the IDP, the IDP will omit the wholeverified_claims
element from the response. -
The
essential
designation does not influence whether claims or verification elements are delivered or not. For example, if a verification element marked asessential
(but not restricted usingvalue
/values
/max_age
) is not available, the IDP omits the particular element from the response as usual, but does not omit theverified_claims
element as it would do with avalue
restriction. -
If a particular claim within
verified_claims
/claims
cannot be deliviered by the IDP, for example if the data is not available, or if requirements are expressed that cannot be fulfilled by the IDP, the IDP will not deliver the respective claim. If the resultingverified_claims
/claims
set is empty, the IDP will omitverified_claims
from the response, according to OpenID Connect for Identity Assurance. -
If an IDP is unable to map the available identity document for its user to one of the types listed below or to map the verification method to one of the verification methods listed below, the IDP will omit the
verified_claims
element from the response.
Common cases where data is not available to the IDP
include the verification method (method )
and the country of the issuer.
|
IDP Support
The identity service IDPs must support the following features for verified claims:
-
The following Claims must be supported:
given_name
,family_name
,birthdate
,place_of_birth
,nationalities
,address
. -
The
trust_framework
identifierde_aml
must be supported and is the currently only supported trust framework in the ecosystem. -
The
evidence
typeid_document
must be supported and is the currently only supported type of evidence. -
The identity service IDPs map the identity document used to verify the bank customer’s identity to the the following
id_document
types:-
idcard
-
passport
-
de_idcard_foreigners
-
de_emergency_idcard
-
de_erp
-
de_erp_replacement_idcard
-
de_idcard_refugees
-
de_idcard_apatrids
-
de_certificate_of_suspension_of_deportation
-
de_permission_to_reside
-
de_replacement_idcard
-
-
The identity service IDPs map the verification methods used to verify the bank customer’s identity to the the following
verification
methods:-
pipp
-
sripp
-
-
Constraints on verification data described in the request syntax above are supported at the following verification data elements:
-
trust_framework
-
time
-
evidence
/type
-
evidence
/method
-
evidence
/document
/type
-
evidence
/document
/issuer
/country
-
See OpenID Connect for Identity Assurance Identifiers for details on the various identifiers used here! |
The identity service IDPs advertise their capabilities with
respect to verified claims in the standard
openid-configuration
as defined in
OpenID Connect for Identity Assurance.