OpenID Connect for Identity Assurance, explained by an implementer
OpenID Connect for Identity Assurance 1.0 (OIDC4IDA or IDA) is a technical specification that the eKYC-IDA Working Group of OpenID Foundation has developed. It uses OAuth 2.0 and OpenID Connect (OIDC) as its base and defines a JSON structure that conveys verified claims of a natural person.
“Claim” here is a technical term that means a user attribute such as given name, birthday, address, and so on.
“Verified” here means that the authenticity of the claim has been verified with evidence such as passport, driver’s license, and so on.
In the Internet, there are many web services that users can sign up. They often require users to register user attributes, but the attributes are only self-asserted by users. Such unverified attributes cannot be used in legal contexts. Here OIDC4IDA comes in.
Implementer’s Draft 3 — The third version was published in November, 2021 (annoucement). The version is called Implementer’s Draft 3 (ID3). As of this writing (in May, 2022), ID3 is the lastest version among officially-published drafts.
Next Draft — The past Implementer’s Drafts repeated to introduce breaking changes. And again, it is certain that the next version will contain breaking changes because breaking changes have already been merged into the master branch of the eKYC-IDA Git repository (e.g. PR 87). Considering the amount of breaking changes and addition of new properties, it is highly likely that the Implementer’s Draft 4 will be published before the future final version.
This article is written based on the latest specification in the eKYC-IDA Git repository as the author of this article (me) attends weekly meetings of the eKYC-IDA WG and can share information about the latest status of the specification with you readers.
The specification defines a JSON structure that conveys verified claims. It is intended that the JSON structure is embedded in other JSON structures such as payloads of ID Token (OIDC Core, Section 2) and responses from UserInfo Endpoint (OIDC Core, Section 5.3).
When the JSON structure appears in other JSON structures, it is labeled with
"verified_claims". The following figure illustrates how it is embedded in the payload of an ID Token.
verification and claims
"verified_claims" JSON object contains
"claims" as top-level properties.
"verification" JSON object describes pieces of information about the verification process such as “based on what regulation?”, “with what evidence?”, “when?” and “by whom?”
"claims" JSON object contains pairs of name and value of verified claims.
To request an authorization server to embed
"verified_claims" in ID Token and/or UserInfo responses, client applications use the
claims request parameter of an authorization request that is defined in the Section 5.5 of OpenID Connect Core 1.0.
The format of the
claims request parameter is JSON. The JSON contains either or both of
"userinfo" as top-level properties. A client application lists names of claims it requests to be embedded in ID Token in the
"id_token" JSON object and likewise lists names of claims it requests to be embedded in UserInfo responses in the
"userinfo" JSON object. This rule is written in the OIDC Core specification.
When a client application wants to get verified claims, it includes
"verified_claims" in the
"id_token" JSON object and/or the
"userinfo" JSON object like the figure below shows.
The specification requires that servers not return data that are not explicitly requested. This policy is called data minimization. Therefore, for a simple
verified_claims request like below:
the server returns only
"given_name" as follows.
If a client application wants more information, it must construct a complex
verified_claims request. The following is an example value of the
claims parameter that includes a complex
verified_claims request (excerpted from the specification).
Constraints by value, values, max_age
When a claim in a
verified_claims request has a JSON object that contains
"max_age" and the claim is under
verified_claims/verification (i.e. not under
verified_claims/claims), the JSON object is used as a filtering condition.
"value"— The actual value of the claim must match the value specified by
"values"— The actual value of the claim must match one or more elements in the
"max_age"— The elapsed time since the date time that the actual value of the claim expresses must not exceed the number of seconds specified by
"value" example> The example below requests verified claims that have been verified by the rules of the trust framework
uk_tfida. If the server does not have verified claims that satisfy the condition,
"verified_claims" is not returned.
"values" example> The example below requests verified claims that have been verified by the rules of either the trust framework
nist_800_63A or the trust framework
"max_age" example> The example below requests that the elapsed time since the identity verification process took place not exceed 30 days (= 2,592,000 seconds). If the server does not have verified claims that were verified within the last 30 days,
"verified_claims" is not returned.
Logical OR by Array
The “Requesting Verification Data” section of the specification contains interesting requirements for the
evidence array as excerpted below.
A single entry in the
evidencearray represents a filter over elements of a certain evidence type. The RP therefore MUST specify this type by including the
typefield including a suitable
valuesub-element value. The
valuessub-element MUST NOT be used for the
If multiple entries are present in
evidence, these filters are linked by a logical OR.
As a result, the following request will result in that all available evidence whose type is either
"electronic_signature" are included in the resultant
This special rule should apply to other properties of array type such as
check_details. However, there is a special rule for
assurance_details as excerpted from the specification below.
assurance_detailsis an array representing how the
check_detailsmeets the requirements of the
trust_framework. RP SHOULD only request this where they need to know this information. Where
assurance_detailshave been requested by an RP the OP MUST return the
assurance_detailselement along with all sub-elements that it has. If an RP wants to filter what types of
check_methodsthey MUST use those methods to do so, e.g. requesting an
assurance_typeshould have no filtering effect.
That is, all available sub-elements of
assurance_details are returned when the property is requested. Data minimization and logical-or filtering don’t apply.
Example of Data Minimization and Filtering
Suppose the server holds a dataset that is equivalent to the content of the JSON below.
If the following
verified_claims request is made against the dataset,
the server should generate the following
Points to note are as follows:
- The dataset on the server side contains two elements in the
"evidence"array, but the
"evidence"array in the generated
"verified_claims"contains only one element. It is because the constraint,
check_details/*/organization == "OpenBankingTPP", filtered out the unmatched element.
- The generated
"verified_claims"does not contain the
"family_name"claim. It is because the actual value of the
"family_name"claim in the dataset on the server side is not
"Unknown". When the
"max_age"constraints are not satisfied under
verified_claims/verification, the entire or partial dataset containing the unmatched property is omitted. On the other hand, under
verified_claims/claims, unmatched claims are just omitted without affecting other parts.
- Many properties are omitted from the generated
"verified_claims"for the data minimization policy. For example,
"locality". Other properties such as
“Attachments” is a relatively big feature among others that were added by the third Implementer’s Draft. The feature enables to attach media that are related to the identity verification process. For example, scans of signed forms, photocopies of evidence, and so on.
Attachments can be embedded directly in the
"attachments" array like below (
embedded_attachments.json; copy from the eKYC-IDA Git repository).
Or, in the case where contents of attachments are hosted on a remote server, only their URLs can be included in the
"attachments" array with an optional access token like below (
external_attachments.json; copy from the eKYC-IDA Git repository).
Transformed Claims (TC) is not a part of the OIDC4IDA specification but a part of “OpenID Connect Advanced Syntax for Claims (ASC) 1.0” that is one of the specifications discussed in the eKYC-IDA WG.
The feature of Transformed Claims enables to transform values of claims by applying transformation functions.
For example, by applying the
years_ago transformation function to the
birthdate claim, the age of the user can be computed and embedded in ID Tokens and/or UserInfo responses. Furthermore, if the
gte transformation function (
gte means “greater than or equal to”) with an argument
18 is applied to the result of the
years_ago transformation function, a boolean value can be obtained that indicates whether the user is above 18 or not. This example can be used in scenarios where age verification is required but personal information such as birthday should not be disclosed.
A reason to pay attention to the TC specification is that age verification is one of key factors in a scenario that is described in the whitepaper of GAIN (Global Assured Identity Network), which is a project to build a global high-trust digital identity network over the Internet.
Transformed Claim Definition
A transformed claim consists of the following components.
- Name of the transformed claim
- Claim referenced as input
- Transformation functions (which may require arguments) applied to the input
In the case of example illustrated in the figure of “Concept of Transformed Claims”, the name of the transformed claim is
age_18_or_over, the referenced claim is
birthdate, and the transformation functions applied are
18 as an argument).
A transformed claim is defined as a property in a JSON object. The key of the property is the name of the transformed claim and the value of the property is a JSON object which contains a
claim property and a
fn property. The
claim property is a referenced claim and the
fn property is a list of transformation functions.
For example, the
age_18_or_over transformed claim can be defined as follows.
The value of the
fn property is an array. Each element of the array represents a transformation function with or without arguments. When a transformation function takes no argument, only the name of the transformation function is put in the
fn array (e.g.
"years_ago"). On the other hand, when a transformation function takes arguments, the name of the transformation function and the arguments are packed into an array and the array is put in the
fn array (e.g.
Places for Transformed Claim Definitions
There are two places to put definitions of transformed claims in. One is the
claims request parameter (OIDC Core, Section 5.5) of an authorization request. The other is the discovery document (OIDC Discovery, Section 4) of the authorization server.
The specification defines
transformed_claims as a new property that can appear in the
claims request parameter. A client application can put definitions of transformed claims there.
The following is an example of the content of the
claims request parameter. It contains
"transformed_claims" which contains the definition of
age_18_or_over transformed claim.
One more point to note is that the name of the defined transformed claim is referenced in
"claims". When a transformed claim defined in
"transformed_claims" is referenced, a colon (
:) is prefixed like
The specification defines
transformed_claims_predefined as a new server metadata that may be included in the discovery document. An authorization server can put definitions of transformed claims there.
The following is an example of the
transformed_claims_predefined server metadata.
Client applications can use transformed claims predefined by the authorization server in the
claims request parameter without redefining them. The following is an example of the
claims request parameter that references a predefined transformed claim by prefixing two colons (
::) to the name.
Chain of Transformation Functions
fn property in a definition of transformed claim is a list of transformation functions. The first transformation function in the list will receive a known claim as input. The second and the subsequent transformation functions will receive the execution result of their immediately preceding transformation function. The execution result of the last transformation function will be used as the value of the transformed claim.
For example, the
years_ago transformation function in the example shown previously receives the value of the
birthdate claim as input and may generate
30 for instance as an execution result. Then, the
gte transformation function receives
30 as input and generates
true as an execution result. The
true generated by
gte becomes the value of the
age_18_or_over transformed claim.
Predefined Transformation Functions
The following transformation functions are predefined in the specification. See the ASC specification for details.
years_ago— computes the number of elapsed years since the input
eq— true if the input is equal to the argument
gt— true if the input is greater than the argument
lt— true if the input is less than the argument
gte— true if the input is greater than or equal to the argument
lte— true if the input is less than or equal to the argument
hash— computes a hash value of the input
any— true if any of elements in the input array is true
all— true if all of elements in the input array are true
none— true if none of elements in the input array are true
get— get the value of a specified property from the input JSON object
match— true if the input matches the regular expression specified by the argument
Demo of Transformed Claims
The author of this article (me) gave a demo of Transformed Claims in a session of OAuth Security Workshop on December 1, 2021. The recorded video is available on YouTube. The demo starts from 28:32.
Implementation of Data Minimization and Filtering
As soon as you start to implement the OIDC4IDA specification without compromise, you will realize that it is difficult to implement the logic of the data minimization policy and the filtering rules.
In OIDC Core, all claims are flatly listed as top-level properties in the payload of ID Tokens and UserInfo responses (except the
address claim; OIDC Core, Section 5.1.1). However, the structure of
"verified_claims" request is too complex.
For discouraged developers, I have published an implementation of the logic as open source here:
authlete-java-common/DatasetExtractor.java at master · authlete/authlete-java-common
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below…
DatasetExtractor class is a part of the authlete-java-common library. The library is for Authlete, but the logic implemented in the class is independent of Authlete APIs. Therefore, you can port the logic to your implementation.
Implementation of Transformed Claims
AFAIK, Authlete 2.3 is the only working implementation of Transformed Claims in the world as of this writing (in May, 2022). The feature of Transformed Claims is implemented in Authlete Server, which is not open source. Please contact Authlete if you want to try Transformed Claims.
Implementation of Authorization Server
java-oauth-server is an open-source sample implementation of authorization server. It uses Authlete as a backend system that interprets OAuth/OIDC requests, generates & manages access tokens, and prepares OAuth/OIDC responses on behalf of a frontend authorization server.
If java-oauth-server is configured to use Authlete 2.3 that supports the latest IDA specification and Transformed Claims, you can try the specification explained in this article.
Below is a sample authorization request for java-oauth-server.
The JSON below is a formatted version of the content of the
claims request parameter for readability.
java-oauth-server will return an authorization page like below as a response to the authorization request.
An account for testing the latest IDA specification is
inga (Login ID =
inga, Password =
inga). Verified claims of the account are loaded from
document_UKTDIF.json (that were copied from the
examples/response directory in the eKYC-IDA Git repository).
If you input
inga to the Login ID & Password fields and press the “Authorize” button, the web browser will be redirected to the redirection endpoint hosted on java-oauth-server.
The payload part of the issued ID Token is as follows. You can confirm that data minimization and filtering worked and the transformed claims are contained in
Because of complexity and instability, it is hard to keep pace with evolution of the OIDC4IDA specification. However, by using Authlete as a backend system of your OAuth/OIDC server, you can delegate the hard task to domain experts in Authlete, Inc.
Please contact Authlete if you need a high-quality and leading-edge implementation of OAuth, OpenID Connect, Financial-grade API, Identity Assurance and other related standard specifications.