Skip to main content

Issue a credential

The issuance workflow consists in three actions:

  1. Create a credential

  2. Issue the credential

  3. Manage the credential

Here you will learn what is required for each step and how to complete them.

Create a credential

A credential consists of a few components:

  • Credential schema
  • Claims being asserted
  • Issuer identifier
  • Choice of exchange protocol
  • Optional:
    • Key to use for assertion
    • Redirect URI

Credential schema

A credential schema defines the type of credential you are issuing and includes components such as:

  • How the credential data will be formatted and secured.
  • The method to be used for future suspension and revocation, if any.
  • The kind of claims that will be asserted during issuance, in the form of keys such as Name or Birthdate and datatypes for validating the claims made during issuance.
  • Design and layout properties of the credential, so wallets know how to render the credential visually for the holder.
  • Issuer requests about the properties of the wallet, such as whether the wallet should use software- or hardware-based keys for signing the credential on issuance.

The schema is crucial for defining and distributing the expected structure of credentials, allowing wallets and verifiers to parse, interpret and handle credentials appropriately.

When creating a credential you choose a schema that has already been created, defining the type of credential you plan on issuing. For guidance on creating a credential schema, see the related guide: Credential schemas.

Claims assertion

Issuing a credential is asserting claims about a subject. During the credential creation process you take the claims keys from the credential schema and fill in real values. These values can be alphanumeric strings, numbers, booleans, dates, or files such as photographs. The claim key is a human-readable attribute name that defines the nature of the claim; common keys are things like Name, Address, Birthdate, Photo, Employee number and other similar keys.

In addition to defining the attribute keys of a credential, the schema defines a few components that shape how you assert claims during credential creation:

  • Whether a claim key requires a value or if it can be left empty during issuance.
  • What kind of data is expected for a value.
  • The data structure of claims when the datatype is OBJECT or when the claim is an array, or list.

If a claim is required by the schema but no value is entered, or if a claim expects a date but a file is entered, or if the data structure passed for the claims does not match up with what is defined in the schema, an error is returned and the credential is not created.

Related guide: Datatypes

Claim values in the API

Use the claimValues[] object to make claims during credential creation.

For each claim being made, three things are required:

{
"claimValues": [
{
"claimId": "31e4e82e-1663-4775-ad6a-bf828037eace", // UUID of the claim from the credential schema
"path": "Family plan members/0/Full name", // path, described below
"value": "Jim Smith" // value being asserted by the issuer
}
]
}

path is used to point to the particular claim key within the structure of the credential schema. This field accepts a JSON Pointer with the following format:

root/nested_array/0

For single attribute claims that are neither an obect nor an array, the path is the attribute key (that is, the root object):

{
"claimId": "3246dbce-f04a-40e8-a3c4-7784ce420afb",
"path": "First name",
"value": "Alice"
},

For arrays, the root is followed by the index (note that the claimId is the same):

{
"claimId": "469b303a-8bf6-4207-acdb-6be79ab5c751",
"path": "Attribute key/0", // first item in the array
"value": "First array item value"
},
{
"claimId": "469b303a-8bf6-4207-acdb-6be79ab5c751",
"path": "Attribute key/1", // second item in the array
"value": "Second array item value"
},

For objects, the root is the name of the object followed by the relevant attribute key:

{
"claimId": "ccba3d15-59d5-4d7e-a327-bfe282c38cd4",
"path": "Object/Attribute key 1",
"value": "Attribute value 1"
},
{
"claimId": "02a1a327-3e75-4f06-8849-126378cf8f2a",
"path": "Object/Attribute key 2",
"value": "Attribute value 2"
}

If this last claim were an array, the index would be added to the path:

{
"claimId": "02a1a327-3e75-4f06-8849-126378cf8f2a",
"path": "Object/Attribute key 2/0",
"value": "Attribute value 2"
}

Issuer identifier

Issued credentials contain metadata about who issued them. The system requires you to specify a Decentralized Identifier (DID) which will go into the credential as a unique identifier for you as an issuer.

Important considerations for choosing a DID:

  • Some DID methods in the system are format-specific or act as proxies. For example, did:mdl is a proxy DID method that does not represent a real DID method according to the W3C standard but enables Document Signer Certificates to work within standard credential flows. When issuing an ISO mdoc, you must use did:mdl as the identifier. Check the capabilities.issuanceDidMethods of your chosen credential format to see which DID methods are supported.
  • Some credential formats have limitations with the type of key algorithm that can be used to sign the credential. You must choose a DID which has as its assertion method a key which is compatible with the credential format. When you get the configuration through the API, check the capabilities.signingKeyAlgorithms of the credential format specified in the schema for a list of all key algorithms that can be used to sign during issuance.
  • With the Procivis Trust Registry, trust management runs through DIDs. If you want the wallet holder and the verifier to know that you are a trusted issuer, be sure to use a DID that is registered as a trust entity on the system's trust anchor.

Related guides: Capabilities and Procivis Trust Registry

Exchange protocol

An exchange protocol defines how the credential is issued to the wallet holder. It's a language that both the issuer and the wallet speak so that credentials can be successfully bundled up and transmitted from the issuer to the holder's wallet.

Important considerations for choosing an exchange protocol:

  • The wallet you are issuing to must support the chosen protocol. When you later issue the credential, the system generates a URL that is specific to the exchange protocol. The wallet must be able to parse this URL to retrieve and accept the offered credential.
  • Some exchange protocols are only used for verifying credentials. When retrieving the configuration through the API, check the capabilities.issuanceExchangeProtocols of the credential format specified in the schema for a list of all exchange protocols that can be used to issue credentials of that format.
  • Some DID methods may not be compatible with some exchange protocols. When you get the configuration through the API, check the capabilities.issuanceDidMethods for a list of DID methods that are compatible with the given exchange protocol.
  • Some operations for exchange protocols may be disabled in the configuration. When you get the configuration through the API, check the capabilities.operations for a list of operations enabled for the given exchange protocol.

Related guides: Capabilities

Optional parameters

  • Some DIDs use multiple keys for their verification methods. If the DID chosen for issuance has multiple keys specified for its assertion method, the credential creation process is an opportunity to specify which key to use for signing this particular credential. If a key is not specified with the issuerKey parameter, the system uses the first key listed in the DID's assertion method.
  • During credential creation you can specify a redirect URI. Use this for a standard URL or for a deep link. When the wallet holder accepts the credential issuance, they are taken to the resource specified at redirectUri.

Related guide: Keys object

Putting it together in an API call

Here's an example curl call, without headers, to create a credential:

-d '{
"claimValues": [
{
"claimId": "38569fa1-10ba-4ad6-abb5-0c7dfa09b6a3",
"path": "Name",
"value": "Jane A. Smith"
},
{
"claimId": "c62e6f62-e4f5-4416-a0be-f371aa1e7e86",
"path": "Address/Street",
"value": "123 Maple St."
},
{
"claimId": "058597d2-5048-4b51-b434-ae2b72086f4b",
"path": "Address/City",
"value": "Springfield"
},
{
"claimId": "3899e362-b897-4d4a-8d11-70b1875fa532",
"path": "Address/Postal code",
"value": "62701"
},
{
"claimId": "18f1bd79-d7f3-4414-bc29-95f399cbb1cc",
"path": "Date of birth",
"value": "1985-01-14T23:00:00.000Z"
},
{
"claimId": "abd3cb68-3dca-43ce-a94c-dd69853cd45d",
"path": "Email",
"value": "jsmith85@example.com"
}
],
"credentialSchemaId": "ad0e33be-09ca-4b84-8bb6-be761cbf2a7d",
"exchange": "OPENID4VC",
"issuerDid": "a635a9e2-e6f0-4ef3-9800-6e9c38e5a258",
"redirectUri": "https://www.example.com/accepted"
}'

Here we have specified:

  • What type of credential we're issuing via the UUID of the credential schema.
  • Which DID we're using as the identifier via the UUID of the issuer DID.
  • Which exchange protocol we will use to issue to the wallet.
  • A redirect URI as a resource for the wallet holder to visit after acceptance.
  • The set of claims we are making as an issuer.

Issue a credential

Creating a credential creates the data structure in the system but it doesn't, by itself, transmit it in any way to the appropriate wallet holder.

To issue the credential, pass the credential's UUID to the issue endpoint, /api/credential/v1/:id/share. This action generates a URL that results from a combination of the system configurations and the exchange protocol chosen for issuance. The generated URL is typically encoded in the frontend as a QR code. The holder then scans the QR code, the wallet parses the code according to the exchange protocol, and then fetches and presents the offered credential to the wallet holder for review.

Manage a credential after issuance

If the wallet holder accepts the offered credential, management of the credential is done by maintaining the validity of the credential through the use of suspension and revocation, assuming the schema allows for suspension and revocation.

Related guide: Manage credential status