Skip to main content

Verify a presentation

The verification workflow consists in three actions:

  1. Create a proof request

  2. Request a proof

  3. Manage the proof

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

Create a proof request

A proof request consists of a few components:

  • Proof schema
  • Verifier identifier
  • Choice of exchange protocol
  • Optional or dependent on specific workflows:
    • Choice of transport protocol
    • Redirect URI
    • Key to use for authentication
    • ISO mDL Engagement
    • VC Barcode object

Proof schema

A proof schema defines what information you are requesting from wallet holders and includes components such as:

  • The choice of credential or credentials you want to request.
  • If the credential format supports selective disclosure, the choice of claims you want to request and whether each claim is mandatory or optional for the holder to disclose. When verifying submitted proofs, any claims marked as required in your proof schema will cause the proof to be rejected if they are missing.
  • The expiration of claims data. This optional parameter lets you set the duration the shared data will be stored in your system. After the time expires the claims data is automatically deleted from the system.
  • If the credential you are requesting uses LVVC as its revocation method, the proof schema should include a validityConstraint defining the maximum age of an LVVC you are willing to accept as a verifier.

The schema is crucial for defining exactly what you are requesting, allowing wallets to parse the request and present the corresponding credentials to the holder for review.

When creating a proof request you choose a schema that has already been created. For guidance on creating a proof schema, see the related guide: Proof schemas.

Verifier identifier

Proof requests contain metadata about who is asking for data. The system requires you to specify a Decentralized Identifier (DID) which will go into the request as a unique identifier for you as a verifier.

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 verifying an ISO mdoc using OID4VP and http, you must use did:mdl as the identifier. Check the capabilities.verificationDidMethods of your chosen exchange protocol to see which DID methods are supported.
  • Some credential formats can only be verified using keys made with certain algorithms or with certain key storage. For example, when verifying mdocs you must use EdDSA or ECDSA as keys made with DILITHIUM cannot be represented in the x509 certificate at this time. You must also use a key with storage type INTERNAL as this storage type is the only current implementation capable of producing the ephemeral key needed to encrypt the presentation in mdoc flows. When you get the configuration through the API, check the capabilities.verificationKeyAlgorithms and capabilities.verificationKeyStorages of the credential format you are verifying for supported options.
  • With the Procivis Trust Registry, trust management runs through DIDs. If you want the wallet holder to know that you are a trusted verifier, 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 system makes the request to the wallet and how the wallet responds. It's a language that both the wallet and the verifier speak so that requests can be made and presentations shared.

Important considerations for choosing an exchange protocol:

  • The wallet you are requesting from must support the chosen protocol. When you later request the proof, the system generates a URL that is specific to the exchange protocol. The wallet must be able to parse this URL to retrieve the request and submit a proof.
  • Some exchange protocols are specific to a credential format, such as for VC Barcodes. For the PHYSICAL_CARD format only SCAN_TO_VERIFY can be used as the exchange protocol. When you get the configuration through the API, check the capabilities.proofExchangeProtocols of the credential format specified in the schema for a list of all exchange protocols that can be used to verify presentations.
  • Some DID methods may not be compatible with some exchange protocols. When you get the configuration through the API, check the capabilities.verificationDidMethods 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.

Whichever exchange protocol you use, you must reference a specific configuration instance when creating a proof request. The is because the system allows for multiple configurations of the same type of exchange protocol.

For example, a configuration could include the following:

exchange:
OPENID4VC:
display: 'exchange.openid'
order: 1
type: 'OPENID4VC'
params:
public:
useRequestUri: true
presentation:
verifier:
supportedClientIdSchemes: [redirect_uri, verifier_attestation]
defaultClientIdSchema: verifier_attestation
redirectUri:
disabled: false
allowedSchemes: ['https']
MDOC_OPENID4VP:
display: 'exchange.mdocOpenid'
order: 2
type: 'OPENID4VC'
params:
public:
useRequestUri: true
presentation:
urlScheme: mdoc-openid4vp
x509CaCertificate: MIICLDCC... // CA certificate
verifier:
supportedClientIdSchemes: [x509_san_dns]
defaultClientIdSchema: x509_san_dns
redirectUri:
disabled: false
allowedSchemes: ['https']

Here we have two configuration instances of the same type, OPENID4VC. The first is for normal OpenID4VC flows while the second one uses x509_san_dns and the mdoc-openid4vp URL scheme to follow the ISO 18013-7 standard for using OpenID4VC in online presentations.

Always reference the configuration instance you want to use. Using the above example, reference either OPENID4VC or MDOC_OPENID4VP.

Other parameters

Choice of transport protocol

Systems can have multiple transport protocols enabled in the configuration. For example, a server application could support both MQTT and HTTP and a mobile verifier or wallet could support both MQTT and BLE.

In such cases, the protocol selected for use in any given interaction is determined by configuration preferences and runtime parameters.

When multiple transport protocols are enabled by the device and the configuration, use the transport array to specify which transport protocol to use. Together with the order of transport protocols in the configuration, the array enables dynamic protocol choice for exchange protocols that support multiple transport protocols.

The table below describes how the system uses the array and the configuration to determine how to make a proof request. The table assumes the values being passed are supported. Retrieve the configuration through the API and check capabilities.supportedTransports for a list of supported transport protocols for each exchange protocol instance. Always reference the configured instance when specifying transport protocols.

transport array valueSystem action
[]Of available transports from the configuration, uses highest order.
[one value]Uses the specified transport.
[multiple values]The resulting QR code contains both protocols and the wallet is free to choose which protocol to use.

When using multiple transport protocols, the QR code of the proof request contains everything needed to initialize connection with either transport, allowing the wallet to respond according to what it supports or prefers.

  • For mobile devices, the only supported combination of transport protocols is [MQTT, BLE].
  • For server solutions, the only supported combination of transport protocols is [HTTP, MQTT].

Redirect URI

During proof request creation you can specify a redirect URI. Use this for a standard URL or for a deep link. When the wallet holder shares a valid proof, they are taken to the resource specified at redirectUri.

Key for authentication

Some DIDs use multiple keys for their verification methods. If the DID chosen for verification has multiple keys specified for its authentication method, the proof request process is an opportunity to specify which key to use for authenticating as a verifier.. If a key is not specified with the verifierKey parameter, the system usesthe first key listed in the DID's authentication method.

Related guide: Keys object

ISO mDL Engagement

When verifying ISO mdocs using the in-person flow and BLE, the flow is initiated by the wallet holder. Pass the engagement QR code content received from the wallet in the isoMdlEngagement parameter.

Related guide: Verify ISO mdocs offline

VC Barcodes and scanToVerify

You can use the system to verify VC Barcodes, an implementation of W3C VCs that can be printed on a physical ID card and verified digitally. This process uses the scanToVerify object and a different workflow.

Related guide: Verify VC Barcodes

Putting it together in an API call

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

-d '{
"exchange": "OPENID4VC",
"proofSchemaId": "09325cd6-11cf-478e-a09d-64cd9ff93d9f",
"redirectUri": "http://www.example.com",
"verifierDid": "3a7d1cfb-57c7-4422-b95d-be09a8e80ddf"
}'

Here we have specified:

  • What we're asking for via the UUID of the proof schema.
  • Which DID we're using as the identifier via the UUID of the verifier DID.
  • Which exchange protocol we will use to make the request.
  • A redirect URI as a resource for the wallet holder to visit after submitting a valid proof.

Request a proof

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

To request the proof, pass the UUID of the proof request to the request endpoint, /api/proof-request/v1/:id/share. This action generates a URL that results from a combination of the system configurations and the exchange protocol used for the request. The generated URL is typically encoded in the frontend as a QR code. Share this with the wallet holder and you've successfully requested a proof.

The holder then scans the QR code, the wallet parses the code according to the exchange protocol, and then fetches and presents the request to the wallet holder for review.

Verification process

Once you have shared the proof request with the wallet holder, the system handles the rest of the verification process.

The system checks the submitted presentation and only accepts it when all checks are successful. The precise calculations depend on factors such as the credential format but several checks are key:

  • Verify the proof: We need to know that the credential is authentic and has not been manipulated. The system resolves the issuer's public key and verifies that the credential was signed by the issuer's private key, and checks the hash, ensuring that credential data has not been modified since issuance.
  • Verify holder binding: We need to know that the person presenting the proof is the same person to whom the credential was issued. Since the credential includes the public key of the holder, or a reference to it, the system checks that the presentation was signed by the corresponding private key.
  • Check the status: We need to know that the credential is valid and has not been suspended or revoked. This could involve, for example, checking a status list with a web call or the valid until date of the MSO of an mdoc. The system checks the status of the credential according to the revocation method inherent to the credential as issued.
  • Validate the schema: We need to know that the credential data matches expectations. The system checks that the presentation data follows the expected structure, that all required fields are present, and that the claim data matches the expected type.

All of the above checks must succeed or the verification process fails and returns an error.

Manage the proof request

Manage proof requests by following their state transitions in the system.

If the wallet holder submits a valid proof, management of the shared data is limited to handling the claims information appropriately. As a verifier, it is your responsibility to securely manage and ultimately delete the claims data once it is no longer needed.

Related guide: Manage proof requests