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

http
Copy to clipboard.
1POST https://YOUR_TENANT_URL/v2/credentials/web-semantic/configurations

Using a request body similar to the following

json
Copy to clipboard.
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 not VerifiableCredential.

  • additionalTypes (optional): Some additional types that can be referenced for this Web Credential.

  • issuer: The details of the issuer such as name, 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

json
Copy to clipboard.
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:

json
Copy to clipboard.
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:

  1. Authentication provider (via claimsToSync) - Not recommended as the claims retrieved from the authentication provider get synced with the platform.

  2. 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.

  3. 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:

  1. Required claims

  2. Optional claims

  3. Claims with default values

  4. 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

json
Copy to clipboard.
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

json
Copy to clipboard.
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

json
Copy to clipboard.
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

json
Copy to clipboard.
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.

json
Copy to clipboard.
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:

json
Copy to clipboard.
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

json
Copy to clipboard.
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.

json
Copy to clipboard.
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

json
Copy to clipboard.
1{
2   "claimMappings": {
3      "email": {
4         "defaultValue": "noreply@example.com"
5      }
6   }
7}

Example user data

json
Copy to clipboard.
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.

json
Copy to clipboard.
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:

json
Copy to clipboard.
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}