Present proof
The Present Proof Protocol allows:
- a Verifier to request a verifiable credential presentation from a Holder/Prover
- a Holder/Prover responds by presenting a cryptographic proof to the Verifier
The protocol provides endpoints for a Verifier to request new proof presentations from Holder/Provers and for a Holder/Prover to respond to the presentation request using a specific verifiable credential they own.
Roles
The present proof protocol has two roles:
- Verifier: A subject requesting a proof presentation by sending a request presentation message, then verifying the presentation.
- Holder/Prover: A subject that receives a proof presentation request, prepares a proof, and sends it to the verifier by sending a proof presentation message.
Prerequisites
Before using the Proof Presentation protocol, the following conditions must be present:
- Holder/Prover and Verifier Cloud Agents must be up and running
- A connection must be established between the Holder/Prover and Verifier Cloud Agents (see Connections)
- The Holder/Prover should hold a verifiable credential (VC) received from an Issuer see Issue.
Overview
This protocol supports the presentation of verifiable claims between two Cloud Agents, the Holder/Prover and the Verifier.
The protocol consists of the following main parts:
- The Verifier creates a new proof presentation request using the
/present-proof/presentations
endpoint. It includes the identifier of an existingconnection
between both parties,domain
, and achallenge
to protect from potential replay attacks. - The Holder/Prover receives the presentation request from the Verifier and can retrieve the list of existing requests using the
/present-proof/presentations
endpoint. - The Holder/Prover can then review and accept a specific request using the
/present-proof/presentations/{presentationId}
endpoint, providing the identifier of thecredential
record to use in the proof presentation. - The Verifier receives the proof presentation from the Holder/Prover and can accept it using the
/present-proof/presentations/{presentationId}
endpoint, specifyingpresentation-accept
as the action type.
Endpoints
Endpoint | Method | Description | Role |
---|---|---|---|
/present-proof/presentations | POST | Creates and sends a new proof presentation request. | Verifier |
/present-proof/presentations | GET | Retrieves the collection of all the existing presentation proof records - sent or received. | Verifier, Holder/Prover |
/present-proof/presentations/{id} | GET | Retrieves a specific presentation proof record by id . | Verifier, Holder/Prover |
/present-proof/presentations/{id} | PATCH | Updates an existing presentation proof record to, e.g., accept the request on the Holder/Prover side or accept the presentation on the Verifier side. | Verifier, Holder/Prover |
For more detailed information, please, check the full Cloud Agent API.
Verifier interactions
This section describes the interactions available to the Verifier with the Cloud Agent.
Creating and sending a Presentation Request
The Verifier needs to create a proof presentation request to start the process.
To do this, he makes a POST
request to the /present-proof/presentations
endpoint with a JSON payload that includes the following information:
connectionId
: This field represents the unique identifier of an existing connection between the verifier and the Holder/prover. It is for exchanging messages related to the protocol flow execution.challenge
anddomain
: The Verifier provides the random seed challenge and operational domain, and the Holder/Prover must sign the generated proof to protect from replay attacks.
- JWT
- AnonCreds
- SDJWT
curl -X 'POST' 'http://localhost:8070/cloud-agent/present-proof/presentations' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"connectionId": "872ddfa9-4115-46c2-8a1b-22c24c7431d7",
"proofs":[],
"options": {
"challenge": "11c91493-01b3-4c4d-ac36-b336bab5bddf",
"domain": "https://prism-verifier.com"
}
}'
curl -X 'POST' 'http://localhost:8070/cloud-agent/present-proof/presentations' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"connectionId": "872ddfa9-4115-46c2-8a1b-22c24c7431d7",
"anoncredPresentationRequest": {
"requested_attributes": {
"attribute1": {
"name": "Attribute 1",
"restrictions": [
{
"cred_def_id": "credential_definition_id_of_attribute1"
}
],
"non_revoked": {
"from": 1635734400,
"to": 1735734400
}
}
},
"requested_predicates": {
"predicate1": {
"name": "age",
"p_type": ">=",
"p_value": 18,
"restrictions": [
{
"schema_id": "schema_id_of_predicate1"
}
],
"non_revoked": {
"from": 1635734400
}
}
},
"name": "Example Presentation Request",
"nonce": "1234567890",
"version": "1.0"
},
"credentialFormat": "AnonCreds"
}'
a. SD-JWT
The absence of the cnf
key claim in the SD-JWT Verifiable Credential (VC) means that the Holder/Prover is unable to create a presentation and sign the challenge
and domain
supplied by the verifier
curl -X 'POST' 'http://localhost:8070/cloud-agent/present-proof/presentations' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"connectionId": "872ddfa9-4115-46c2-8a1b-22c24c7431d7",
"proofs":[],
"credentialFormat": "SDJWT",
"claims": {
"emailAddress": {},
"givenName": {},
` "region": {},
"country": {}`
}
}'
b. SD-JWT
The presence of the cnf
key as a disclosable claim in the SD-JWT Verifiable Credential (VC) allows the Holder/Prover to create a presentation and sign the challenge
and domain
given by the verifier.
curl -X 'POST' 'http://localhost:8070/cloud-agent/present-proof/presentations' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"connectionId": "872ddfa9-4115-46c2-8a1b-22c24c7431d7",
"proofs":[],
"options": {
"challenge": "11c91493-01b3-4c4d-ac36-b336bab5bddf",
"domain": "https://prism-verifier.com"
},
"credentialFormat": "SDJWT",
"claims": {
"emailAddress": {},
"givenName": {},
"region": {},
"country": {}
}
}'
SDJWT Specific attributes
credentialFormat
: SDJWT.claims
: The claims to be disclosed by Holder/Prover.
Upon execution, a new presentation request record gets created with an initial state of RequestPending
. The Verifier Cloud Agent will send the presentation request message to the Cloud Agent of the Holder/Prover through the specified DIDComm connection. The record state then is updated to RequestSent
.
The Verifier can retrieve the list of presentation records by making a GET
request to the /present-proof/presentations
endpoint:
curl -X 'GET' 'http://localhost:8070/cloud-agent/present-proof/presentations' \
-H 'accept: application/json' \
-H "apikey: $API_KEY"
Accept presentation proof received from the Holder/prover
Once the Holder/Prover has received a proof presentation request, he can accept it using an appropriate verifiable credential. The Cloud Agent of the Verifier will receive that proof and verify it. Upon successful verification, the presentation record state gets updated to PresentationVerified
.
The Verifier can then explicitly accept the specific verified proof presentation to change the record state to PresentationAccepted
by making a PATCH
request to the /present-proof/presentations/{id}
endpoint:
curl -X 'PATCH' 'http://localhost:8070/cloud-agent/present-proof/presentations/{PRESENTATION_ID}' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"action": "presentation-accept"
}'
Holder/Prover
This section describes the interactions available to the Holder/Prover with his Cloud Agent.
Reviewing and accepting a received presentation request
The Holder/Prover can retrieve the list of presentation requests received by its Cloud Agent from different Verifiers making a GET
request to the /present-proof/presentations
endpoint:
curl -X 'GET' 'http://localhost:8090/cloud-agent/present-proof/presentations' \
-H 'accept: application/json' \
-H "apikey: $API_KEY"
The Holder/Prover can then accept a specific request, generate the proof, and send it to the Verifier Cloud Agent by making a PATCH
request to the /present-proof/presentations/{id}
endpoint:
- JWT
- AnonCreds
- SDJWT
curl -X 'PATCH' 'http://localhost:8090/cloud-agent/present-proof/presentations/{PRESENTATION_ID}' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"action": "request-accept",
"proofId": ["{CRED_RECORD_ID}"]
}'
The Holder/Prover will have to provide the following information:
presentationId
: The unique identifier of the presentation record to accept.proofId
: The unique identifier of the verifiable credential record to use as proof.
curl -X 'PATCH' 'http://localhost:8090/cloud-agent/present-proof/presentations/{PRESENTATION_ID}' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"action": "request-accept",
"anoncredPresentationRequest":{
"credentialProofs":[
{
"credential":"3e849b98-f0fd-4cb4-ae96-9ea527a76267",
"requestedAttribute":[
"age"
],
"requestedPredicate":[
"age"
]
}
]
}
}'
curl -X 'PATCH' 'http://localhost:8090/cloud-agent/present-proof/presentations/{PRESENTATION_ID}' \
-H 'Content-Type: application/json' \
-H "apikey: $API_KEY" \
-d '{
"action": "request-accept",
"proofId": ["{CRED_RECORD_ID}"]
"claims": {
"emailAddress": {},
"givenName": {},
"address": {
"region": {},
"country": {}
}
},
"credentialFormat": "SDJWT"
}'
The Holder/Prover will have to provide the following information:
presentationId
: The unique identifier of the presentation record to accept.proofId
: The unique identifier of the verifiable credential record to use as proof.credentialFormat
: SDJWT.claims
: The Verifier requests specific claims to disclose. The path of these claims must match exactly with those in the SD-JWT Verifiable Credential (VC).
- 📌 Note: When a SD-JWT Verifiable Credential (VC) has nested claims such as region and country within an address object, as shown in the example above, it falls under the Holder's responsibility to supply the correct nested JSON structure for the claims attribute(s) that is being disclosed.
- 📌 Note: The holder or prover of the claims is only required to disclose the attribute names and the correct JSON path. The actual values are not necessary. A special JSON placeholder
{}
, can be used instead.
The Holder/Prover will have to provide the following information:
presentationId
: The unique identifier of the presentation record to accept.anoncredPresentationRequest
: A list of credential unique identifier with the attribute and predicate the credential is answering for.
The record state is updated to PresentationPending
and processed by the Holder/Prover Cloud Agent. The agent will automatically generate the proof presentation, change the state to PresentationGenerated
, and will eventually send it to the Verifier Agent, and change the state to PresentationSent
.
Sequence diagram
The following diagram shows the end-to-end flow for a verifier to request and verify a proof presentation from a Holder/prover.
JWT Present Proof Flow Diagram
Anoncreds Present Proof Flow Diagram
- JWT
- AnonCreds