Setup a credential configuration
Credential configurations define how to construct the credentials you want to issue via OID4VCI.
At minimum, you have to provide values for name
, type
, an issuer
, as well as the claimMappings
field to create a new credential configuration.
The claimMappings
field is particularly important, because it specifies which user attributes will be added into the Web Credential during credential issuance.
Each credential configuration will also have a unique ID. These IDs are used to create credential issuance offer URIs.
For this tutorial, we are issuing a computer science course credential. Be sure to change values depending on the type of credential you'd like to issue. Start by making the following request to
1POST https://YOUR_TENANT_URL/v2/credentials/web-semantic/configurations
Using a request body similar to the following
1
2 "name": "Computer Science Course Credential",
3 "description": "Completed the Computer Science course at Kakapo University",
4 "type": "CourseCredential",
5 "additionalTypes": [
6 "EducationCredential"
7 ],
8 "issuer": {
9 "name": "Kakapo University",
10 "logoUrl": "https://example.edu/img/logo.png",
11 "iconUrl": "https://example.edu/img/icon.png"
12 },
13 "credentialBranding": {
14 "backgroundColor": "#B00AA0",
15 "watermarkImageUrl": "https://example.edu/img/watermark.png"
16 },
17 "claimMappings": {
18 "firstName": {
19 "mapFrom": "claims.firstName",
20 "required": true
21 },
22 "address": {
23 "mapFrom": "claims.address.formatted"
24 },
25 "picture": {
26 "mapFrom": "claims.picture",
27 "defaultValue": "http://example.edu/img/placeholder.png"
28 },
29 "badge": {
30 "defaultValue": "http://example.edu/img/badge.png"
31 },
32 "providerSubjectId": {
33 "mapFrom":"authenticationProvider.subjectId"
34 }
35 },
36 "persist": false,
37 "revocable": true,
38 "claimSourceId": "945214ad-3635-4aff-b51d-61d69a3c8eee"
39}
We've setup a credential configuration to create a Web Semantic Credential with CourseCredential
as its type that will be issued by Kakapo University
.
The issued credential will have custom branding configured to represent Kakapo Uni, and the credential will include claims for the firstName
, address
, picture
, badge
and providerSubjectId
.
Here's what each field of the request payload means:
name
: The name of the Web Credential configuration that is being created.description
: Description of the Web Credential being issued.type
: The type of the Web Credential Configuration. This is a unique identifier that the system uses to differentiate between different types of Web Credentials. It must be unique among all the credential configurations on your tenant, and must be a value that is notVerifiableCredential
.additionalTypes
(optional): Some additional types that can be referenced for this Web Credential.issuer
: The details of the issuer such asname
,logoURL
(optional),iconURL
(optional) of the Web Credential.credentialBranding
(optional): The branding details of the issuer which will be applied while issuing the credentials.claimMappings
: This is an object where you specify how to map claims (user attributes) into the Web Credential.persist
(default:false
): It defines whether both the credential data and the credential metadata will be held in the registry or just the metadata itself.revocable
(default:true
): It defines whether the issued credentials can be revoked.claimSourceId
(optional): This refers to the ID of the claim source which can be used to retrieve claims for the user during the issuance of credentials. In the example, we're using the same claim source ID that we configured previously in the claim source tutorial.expiresIn
(optional): You can also set an expiry time for credentials that are issued. Take a look at the api reference to learn more.
Once you create a configuration, you will get a response that contains your configuration id
. Keep a note of this as you will be using it to offer credentials later
1{
2 "id": "983c0a86-204f-4431-9371-f5a22e506599",
3 "name": "Computer Science Course Credential",
4 "description": "Completed the Computer Science course at Kakapo University",
5 //... rest of your credential configuration
6}
Claim Mappings
Let's look at how the claim mappings work in detail.
Claim mappings define the subject claims a credential will be issued with. The fields in claimMappings
correspond to the claims in the Web Credential. Each field contains one or more from the following attributes:
mapFrom
: It refers to the path of where to find the claims from the user object.defaultValue
: As the name suggests, it refers to a default value for the claim if it's not resolved during mapping.required
: It indicates whether the claim is required (default:false
)
Note: When following the recommendation to use a URL as a namespace identifier for claims, make sure to access the claim value by using bracket notation, e. g.
mapFrom: "claims['https://example.com/claim-name']"
.
Where does user data come from?
The user data is created from your authentication provider, which contains the information you can use to map your claims. By default data from the idToken is not stored on VII. If you want to store data, you have to include values from the idToken in claimsToSync array.
This is an example of what a user object looks like for each of your users:
1{
2 "authenticationProvider": {
3 "url": "https://account.example.com",
4 "subjectId": "145214ad-3635-4aff-b51d-61d69a3c8eee"
5 },
6 "claims": {
7 "given_name": "John",
8 "family_name": "Doe",
9 "email": "john.doe@example.com",
10 "address": {
11 "formatted": "123FooRd,BarWorld"
12 }
13 }
14}
The authenticationProvider
references the IdP that was used to authenticate the end user.
In the example above, we can see that claims
has given_name
family_name
, email
and address
for us to do the claim mapping. For them to exist, they are added in the claimsToSync
array when creating an authentication provider on MATTR VII. The idToken returned from the provider then must include the claims for them to be persisted.
Claims for a credential can be composed from one or more of the following sources:
Authentication provider (via
claimsToSync
) - Not recommended as the claims retrieved from the authentication provider get synced with the platform.Claims source (via an external API) - Recommended as these are retrieved every time a credential is issued allowing you to keep an updated user profile on your own database.
Interaction hook (encoded in the session token of the response)
Types of claims
Claims in your credential configuration can be required or optional, and have default or static values. Below are example responses for how each claim type interacts with a given user data.
These are the types of claims you can include in claimMappings
:
Required claims
Optional claims
Claims with default values
Static claims
The section below walks through situations using each type by providing an example claim mapping, the theoretical user object that exists on VII and what the issued credential would look like.
Required claim
If required
is set to true
, and the claim fails to map, the credential will not be issued.
Example claim mappings
1{
2 "claimMappings":{
3 "dateOfBirth": {
4 "mapFrom": "claims.dateOfBirth",
5 "required": true
6 },
7 "email":{
8 "mapFrom": "claims.email",
9 "required": false
10 }
11 }
12}
Example user data
1{
2 "authenticationProvider": {
3 "url": "https://account.example.com",
4 "subjectId": "145214ad-3635-4aff-b51d-61d69a3c8eee"
5 },
6 "claims": {
7 "email": "john.doe@example.com"
8 }
9}
Issued credential example
The issuance will result in an error and the credential will not be issued as dateOfBirth
doesn’t exist in the user data.
Optional claim
If required
is not present in claimMappings
or if it's set to false
and the claim fails to map, the credential will still be issued but will not contain the claim.
Example claim mappings
1{
2 "claimMappings": {
3 "dateOfBirth": {
4 "mapFrom": "claims.dateOfBirth",
5 "required": false
6 },
7 "email":{
8 "mapFrom": "claims.email",
9 "required": false
10 }
11 }
12}
Example user data
1{
2 "authenticationProvider": {
3 "url": "https://account.example.com",
4 "subjectId": "145214ad-3635-4aff-b51d-61d69a3c8eee"
5 },
6 "claims": {
7 "email": "john.doe@example.com"
8 }
9}
Issued credential example
The user data only has email
in claims, but not dateOfBirth
. Since we've set dateOfBirth
to be an optional field, the issued credential will only contain email
mapped from user data, but it won't contain dateOfBirth
as a claim.
1{
2 "credentialSubject": {
3 "email": "john.doe@example.com"
4 }
5}
Claims with default values
If a default value is supplied, and the claim fails to map, the credential will be issued with the claim using the default value.
Example claim mappings:
1{
2 "claimMappings": {
3 "dateOfBirth": {
4 "mapFrom": "claims.dateOfBirth",
5 "defaultValue": "Not provided"
6 },
7 "email":{
8 "mapFrom": "claims.email",
9 "required": true
10 }
11 }
12}
Example user data
1{
2 "authenticationProvider": {},
3 "claims":{
4 "email": "john.doe@example.com"
5 }
6}
Issued credential example
The user data has email
in claims
but it doesn't have the dateOfBirth
, which means we won't be able to map values for dateOfBirth
into the credential. However, we have setup the defaultValue
for date of birth as "Not Provided", which means MATTR VII will use Not provided
on the issued credential.
1{
2 "credentialSubject": {
3 "dateOfBirth": "Not provided",
4 "email": "john.doe@example.com"
5 }
6}
Static value for a claim
Static values can be set by providing a default value without mapFrom
Example claim mappings
1{
2 "claimMappings": {
3 "email": {
4 "defaultValue": "noreply@example.com"
5 }
6 }
7}
Example user data
1{
2 "authenticationProvider":{},
3 "claims":{
4 "email": "john.doe@example.com"
5 }
6}
Issued credential example
Even though the user has an email claim, the issued credential will use the default value configured in the credential configuration.
1{
2 "credentialSubject": {
3 "email": "noreply@example.com"
4 }
5}
Support for other value types
MATTR VII supports claims in various value types like string, numeric, JSON or Array as shown in the example below.
Example claim mappings from a credential configuration with different value types:
1{
2 "claimMappings": {
3 "staticStringValue": {
4 "defaultValue": "foo"
5 },
6 "staticNumericValue": {
7 "defaultValue": 12.34
8 },
9 "staticJsonValue": {
10 "defaultValue": {
11 "foo": "bar"
12 }
13 },
14 "staticArrayValue": {
15 "defaultValue": [
16 "foo",
17 "bar"
18 ]
19 }
20 }
21}