Claims#
Claims are the individual pieces of information asserted in tokens. A claim has a name and a value and can be: primitive (string, number, etc.), structured (object, array), composite (built from other claims) or generated dynamically. Curity treats OpenID Connect standard claims as a subset of a broader claim system you can extend.
Requesting claims#
Clients obtain claims by:
- Requesting a scope that bundles those claims; if all are granted the scope label appears in the token.
- Supplying the claims to ask for specific claims explicitly. Only claims allowed through configured scopes may be requested individually.
If some bundled claims are withheld (e.g. consent not given) the scope label is omitted but permitted claims are still included.
The “claims” request parameter#
There are two ways to request profile data to be included in the ID-token or the response of the user info endpoint, which are by requesting scopes and by requesting individual claims through the claims request parameter. As specified by OpenID Connect, the claims parameter is a JSON document which has the option to request each claim individually, as opposed to the claim sets that are specified by the OpenID scopes.
Given that OpenID Connect is enabled on the profile, claims request parameter support is enabled by default. The claims mapping subsystem will automatically map these claims to the tokens given that the client is allowed to request them.
The claims request parameter is used to establish which claims from the profile data must be included in an ID token or in the user info response.
There is access control applied on the claims that can be requested by clients. This access control is based on the allowed scopes. These scopes represent a set of claims, and by allowing these scopes to be requested by a client, this also allows the claims that they represent to be requested through the claims parameter. However, the scope itself does not have to be requested when using the claims parameter.
For example, in case the client does not allow the profile scope to be requested, yet there is a request for the picture claim, this request will be rejected because it is not mapped to a scope that the client is configured with.
Note that requesting the acr claim with a specific value will result in requiring authentication to be performed with that particular acr.
Example of requesting a scope and its claims#
Given the following configuration:
The scope show_balance has claims bank_account and account_name. A client balance_shower_123 is configured with the show_balance scope.
When the client makes a request for a token through the code flow, the request URL could look like:
https://curity.example.org/authorize?response_type=code&client_id=balance_shower_123&scope=show_balance
Once the user is authenticated, and the claims are consented to, a code will be returned that the client can redeem for an access token from the token endpoint through the code flow:
POST /oauth/v2/token HTTP/1.1
Host: curity.example.org
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
client_id=balance_shower_123&
code=<the-authorization-code>
The response to this request, will be an access token, the scope that was added to the access token, as well as the claim names that are granted to the access token:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token":"0f16ace4-9c95-4917-b77b-28c761450328",
"token_type":"bearer",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"scope":"show_balance",
"claims":"bank_account account_name"
}
Example of requesting individual claims#
Given the configuration from the previous example, the client needs an access token that contains the bank_account claim and wants to obtain it through the implicit flow. To express this, the client needs to send the claims request parameter, and creates its value like this:
{
"access_token": {
"bank_account": null
}
}
The redirect URL takes the claims parameter value, URL-encode it, and pass it in the claims request parameter. The resulting URL would look like:
https://curity.example.org/authorize?response_type=token&cliet_id=balance_shower_123&claims=%7B%0A%20%20%22access_token%22%20%3A%20%7B%0A%20%20%20%20%22bank_account%22%20%3A%20null%0A%20%20%7D%0A%7D
When the user is authenticated and the claim can be released, the redirect URI will look like:
https://balance-shower-123.example.org/callback#access_token=f421bf9a-9e60-4327-99df-42a1d2a94566&token_type=bearer&expires_in=3600&claims=bank_account
Note that no scope is returned in the response.
Claim configuration#
The concepts that have been described above are brought together in the claims configuration. Here, claims properties are set, but it is also configured how the claim value is established, as well as to what scope or scopes a claim belongs.
A claim value is sourced from a claim value provider . This claim value provider returns a bunch of attributes. When the attribute that is returned from the claim value provider has the same name as the claim name, it can be taken as claim value without any further processing.
However, the value can be transformed by a claim transformation procedure. This procedure takes as input the attributes that the claim value provider produces as output, and returns a value that is used as the claim’s value that will be included in the token. The input attribute names that are provided to the value transformation procedure must be manually defined in the claim’s configuration settings.

Value transformation or generator procedure#
When establishing a claim’s value, a procedure can be used to process input attributes. In case there are no input attributes defined for a claim, and the claim does not define a claim value provider, this transformation procedure is called a generator.
A value transformation procedure must be implemented using the transform method fingerprint:
function transform(attributes) {
// the `attributes` parameter provides the input-attributes, as defined on the claim's settings
// return the claim's value
}
A generator procedure must be implemented using the generator method fingerprint:
function generate() {
// the generate() method does not have any input, but has a procedure context to interact with
// return the claim's value
}
Claim without Value Provider#
The most common type of claim is described in the previous paragraph: a claim that takes its value from a claim value provider , and can optionally be transformed by a custom procedure. However, a claim does not have to source its value from a claim value provider : it is possible to have a claim without a claim value provider that establishes its value in a generator procedure, as described in Value transformation or generator procedure .
Reference Claim#
Another type of claim is the so-called Reference Claim. A Reference Claim defines a reference to another claim as the source of its value. Once the referenced claim value is resolved, the reference claim can optionally configure a transformation procedure to transform its value into the value to be issued as the reference claim’s value. This will create the resulting value to be issued for the reference claim.
When a value transformation procedure is defined, it will always be given the value of the referenced claim, by the name of that referenced claim, as its input, as described in value transformation or generator procedure .
For example, when given a claim with the name first_name, that is configured with an account-manager-claims-provider type claim value provider , and another claim that is a reference claim called initials and references the first_name claim, we can write the following value transformation procedure on the reference claim:
function transform(attributes) {
return attributes.first_name
.split(' ')
.map((name) => name.charAt(0).toUpperCase())
.join(' ')
}
Note that it is possible to reference another reference claim, up to 10 levels deep.
Composite Claim#
A Composite Claim is a claim that acts like a container for other claims, also referred to as its parts. When Curity resolves a composite claim, it resolves its parts. A Composite Claim can have another Composite Claim as one of its parts, resulting in a nested claim value structure.
For example, a Composite Claim called contact that has two other Composite Claims email and phone inside them, could look like this:
{
"contact": {
"email": {
"email_unverified": "teddie@unverified.example.com",
"email_verified": "teddie@example.com"
},
"phone": {
"phone_unverified": "192837465"
}
}
}
Claim Type#
It is possible to specify that a claim value must have a certain type, and whether the claim value may be null or missing.
The existing types are inspired by the JSON Specification:
any(useful when specifying only that the claim value must not benull).stringnumberbooleanobjectarray

If a claim resolves to a value which does not satisfy the selected type, a Server Error occurs. This includes when a claim value resolves to null but its type does not allow for a missing value.
The claim value is checked against the Claim Type only after any value transformation or generator procedure is executed.
The table below shows a few examples of when a claim value is valid according to its type:
| Value | Type | Allow missing | Is valid? |
|---|---|---|---|
"some string" | string | true or false | true |
"some string" | number | true or false | false |
10 | number | true or false | true |
10 | object | true or false | false |
[1, 2, 3] | array | true or false | true |
[1, 2, 3] | object | true or false | false |
{"foo": 1} | object | true or false | true |
{"foo": 1} | array | true or false | false |
null | any | true | true |
null | any | false | false |
null | string | true | true |
null | object | true | true |
If a Claim Type is not specified, any claim value is considered to be valid.