Requesting claims
How to ask for claims, and how to ask for as few as possible.
Claims are requested through the claims parameter on the authorization request. It is a URL-encoded JSON object with two namespaces.
Standard OIDC claims
The usual scopes work as you would expect - openid, profile, email, phone - and individual OIDC claims can be named under their scope:
{"profile": ["given_name", "family_name"]}
TrueVault claims
Everything specific to us lives under the true key, as an array of claim keys:
{"true": ["trueidentity.valid", "sanctionscheck.is_sanctioned"]}
Keys are {credential}.{field}, or document.{type}.{field} for a field read from one document. The claim reference lists all of them.
Essential claims
Marking a claim essential does more than insist on it. It tells us to obtain the credential during the journey if the person does not already hold one:
{"true": {"acicncchc.credential": {"essential": true}}}
A person arriving without a criminal history check is taken through getting one, and comes back with it. Without essential, the same request returns whatever they happen to hold already, which for a first-time person is nothing.
This is how you ask for a check to be performed, rather than merely read.
Three things follow from how it works:
- The whole credential becomes mandatory, not the one claim. Marking
acicncchc.resultessential requires the ACIC credential, not just that field. You still only receive the claims you asked for. - Only obtainable credentials can be essential:
acicncchc,vevortw,sanctionscheck,courtcheck,studentandphonenumber. Asking for anything else is rejected asinvalid_requestat the authorization request. document.*claims can never be essential. A document is required through the ruleset, not through the claims parameter, and asking is an error: "Claims for essential document types can only be enforced by using an appropriate rule set". If you need a driving licence number, pick a ruleset that requires a driving licence.
Those errors come back to you at the authorization request, before the person sees anything, so a misconfigured integration fails in your logs rather than halfway through somebody's journey.
Ask for less
The most common mistake is asking for a whole credential when a single claim would do. Some worked substitutions:
| If you need to know | Do not ask for | Ask for |
|---|---|---|
| They have a verified identity | trueidentity.credential | trueidentity.valid |
| Whether to escalate for sanctions | sanctionscheck.matches | sanctionscheck.is_pep and is_sanctioned |
| Their check came back clear | acicncchc.source_download | acicncchc.result |
| They can work here | vevortw.source_data | vevortw.work_entitlements |
The pattern: a summary claim answers the question, and the detail behind it contains material you then have to store, secure and eventually delete. For sanctions and court checks, the detail also contains other people - the matches are names from a database, most of whom are not your customer.
Where the pattern runs out: age
There is no claim that answers "is this person over eighteen". To check an age you ask for trueidentity.birth_date and calculate it yourself, which means taking a full date of birth to answer a yes-or-no question, and then holding it.
We are stating that plainly rather than leaving you to discover it. If age is the thing you actually need, tell us - the assertion pattern already exists in trueidentity.valid, which returns a bare true or false and discloses nothing else.
Checking what is available
The live list is published in the discovery metadata under true_claims_supported. Read it from there rather than hard-coding a list, and you will pick up new claims without a release.
An unknown claim key is rejected rather than ignored, so a typo fails loudly at the authorization request instead of quietly returning nothing.