-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposed HIPE: Credential Exchange Message Family #89
Changes from 3 commits
3e03649
e6139fd
96701d5
146fed5
2d65ace
f089858
dda922e
33d78df
2acd7cf
3054894
f7fd428
7e461f4
5700ead
cf6b03d
46a01df
9b6503a
0b74448
12ad001
2e85595
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,236 @@ | ||
- Name: credential-exchange-message-family | ||
- Author: Nikita Khateev | ||
- Start Date: 2019-01-30 | ||
- PR: (leave this empty) | ||
- Jira Issue: (leave this empty) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
Formalization and generalization of existing message formats used for credential | ||
exchange according to existing HIPEs about message formats. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
Standartize the message family used for credential exchange for future developers' use | ||
|
||
# Tutorial | ||
[tutorial]: #tutorial | ||
|
||
The Credential Exchange Message Family consists of 5 messages: | ||
* Credential Offer | ||
* Credential Request | ||
* Credential | ||
* Presenttion Request | ||
* Presentation | ||
|
||
#### Credential Offer | ||
This message is sent by Issuer to Prover to initiate credential issuance. Schema: | ||
```json | ||
{ | ||
"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-exchange/1.0/credential-offer", | ||
"@id": "<uuid-offer>", | ||
"cred_id": "<id>", | ||
"cred_name": "name", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this field is intended to be used for an (optional) interaction with a user - e.g. for a notification on a phone. If so, I'd be tempted to use some other word - e.g. "cred_description" here and make it localized. If it is really the technical name, I'd leave it off as that can be derived from the |
||
"cred_def_id": "KTwaKJkvyjKKf55uc6U8ZB:3:CL:59:tag1", | ||
"to_did": "Mie7euMJ94nrTHbx5HZEu7", | ||
"from_did": "Mie7euMJ94nrTHbx5HZEu7", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "to_did" and "from_did" seem odd and unnecessary. The Same reasoning applies to the same fields in the other message types. |
||
"comment": "some comment", | ||
"~attach": [ | ||
{ | ||
"nickname": "libindy-offer", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. adding |
||
"mime-type": "application/json", | ||
"content": { | ||
"base64": "<bytes for base64>" | ||
} | ||
}, | ||
{ | ||
"nickname": "credential-preview", | ||
"mime-type": "application/json", | ||
"content": { | ||
"base64": "<bytes for base64>" | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Description of fields: | ||
* `comment` -- a field that provide some human readable information about this Credential Offer. | ||
* `cred_id` -- id of credential. | ||
* `cred_name` -- name of credential | ||
* `cred_def_id` -- id cof credential definition for offered credential | ||
* `to_did` -- DID of Prover | ||
* `from_did` -- DID of Issuer | ||
* attachment `libindy-offer` -- data for libindy about credential offer | ||
* attachment `credential-preview` -- preview of credential. | ||
|
||
#### Credential Request | ||
This message is sent in response to Credential Offer by Prover to give needed details for credential issuance. Schema: | ||
```json | ||
{ | ||
"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-exchange/1.0/credential-request", | ||
"@id": "<uuid-request>", | ||
"cred_def_id": "2hoqvcwupRTUNkXn6ArYzs:3:CL:1766", | ||
"comment": "some comment", | ||
"to_did": "<did>", | ||
"from_did": "<did>", | ||
"~attach": [ | ||
{ | ||
"nickname": "libindy_cred_req", | ||
"mime-type": "application/json", | ||
"content": { | ||
"base64": "<bytes for base64>" | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Description of Fields: | ||
* `cred_def_id` -- Credential Definition ID for requested credential | ||
* `to_did` -- DID of Issuer | ||
* `from_did` -- DID of Prover | ||
* `comment` -- a field that provide some human readable information about this Credential Offer. | ||
* attachment `libindy_cred_req` -- an attachment with data that is needed to Issuer to generate a credential. | ||
|
||
#### Credential | ||
This message contains the credential and sent in responce to Credential Request. Schema: | ||
```json | ||
{ | ||
"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-exchange/1.0/credential", | ||
"@id": "<uuid-credential>", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
"rev_reg_def_id": "<rev_reg_def_id>", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this embedded in the attachment? Does it need to be called out, or does that just make it easier for the prover to handle the incoming credential? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is also a field inside of an attachment, but it is needed to save the credential (id is needed to get the json in case of libindy). If we send it in this message, messaging library won't need to parse the libindy-specific attachment. |
||
"cred_def_id": "2hoqvcwupRTUNkXn6ArYzs:3:CL:1766", | ||
"from_did": "44oqvcwupRTUNkXn6ArYzs", | ||
"~attach": [ | ||
{ | ||
"nickname": "libindy-cred", | ||
"mime-type": "application/json", | ||
"content": { | ||
"base64": "<bytes for base64>" | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Description of fields: | ||
|
||
* `rev_reg_def_id` -- an ID of Revocation Registry Definition for this credential | ||
* `cred_def_id` -- ID of Credential Definition this credential were issued to | ||
* `from_did` -- DID of Issuer | ||
* attachment `libindy-cred` -- an actual credential to store, it is a json encoded in base64 | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although revocation is an operation between the Issuer and the Ledger, should we add a message that notifies the holder that a credential issued to them has been revoked? Related; A common pattern with credentials will be that a change of information will trigger the revocation of a credential and the issuance of a new credential. Perhaps that common credential lifecycle pattern is worthy of enhancing the "credential_offer" message to have an optional, associated credential revocation indicator. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you, this is an awesome idea! |
||
#### Presentation Request | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since credential issuance and presentation (and revocation, if/depending on how we include it) are different protocols. Should they be in separate message families? At minimum, if properly defined state-transition models for the message family are added (which I think need to be added) - it should be clear that the issuance and presentation are separate. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't formally prove that they should be in one message family. However, I can't go through the same process about two message families as well. The problem here is that we don't have a clear formal definition of "Message Family" in previous HIPEs. The only definition (not formal, though) that I found is in HIPE #21. It says:
All of these message types are used for operations with credentials. We can as well state that we can unite them into two groups -- one about credential issuance, and the second one about proof verification. It might be even more convenient to use them as two message families as we can make their versioning separately. Formally, two message families are at the value level same as one here. In terms of common sense two seems to be better, but I have to think more about it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a proposed HIPE that defines how to document Message Families (aka protocols) with an example (tic-tac-toe) - #69. I took a look at it as I was reading this and I think that would lead us to separating out these into several protocols. That might help as you think about this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, there are two families instead of one. I had split them. |
||
Presentation Request is a message from Verifier to Prover that describes values that need to be revealed and predicates that need to be fulfilled. Schema: | ||
```json | ||
{ | ||
"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-exchange/1.0/presentation-request", | ||
"@id": "<uuid-request>", | ||
"comment": "some comment", | ||
"~attach": [ | ||
{ | ||
"nickname": "libindy-proof-request", | ||
"mime-type": "application/json", | ||
"content": { | ||
"base64": "<bytes for base64>" | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Description of fields: | ||
|
||
* `comment` -- a field that provide some human readable information about this Credential Offer. | ||
* attachment `libindy-proof-request` -- base64-encoded data needed for libindy to process proof request. | ||
|
||
#### Presentation | ||
This message is a response to a Presentation Request message and contains signed presentations. Schema: | ||
```json | ||
{ | ||
"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-exchange/1.0/presentation", | ||
"@id": "<uuid-presentation>", | ||
"to_did": "2hoqvcwupRTUNkXn6ArYzs", | ||
"from_did": "2hoqvcwupRTUNkXn6ArYzs", | ||
"comment": "some comment", | ||
"~attach": [ | ||
{ | ||
"nickname": "libindy-presentation", | ||
"mime-type": "application/json", | ||
"content": { | ||
"base64": "<bytes for base64>" | ||
} | ||
} | ||
] | ||
} | ||
``` | ||
|
||
Decription of fields: | ||
|
||
* `to_did` -- DID of Verifier | ||
* `from_did` -- DID of Prover | ||
* `comment` -- a field that provide some human readable information about this Credential Offer. | ||
* attachment `libindy-presentation` -- actual presentation for presentation request, represented by base64-encoded json. | ||
|
||
### Threading | ||
|
||
All of the messages support threading. Using it we can mark what message we are responding to. This is a short set of rules that should be followed to use threading correctly: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this section needs to be adjusted to use enforcement language - e.g. "All of the messages REQUIRE the use of threading." and "...you MUST add a decorator |
||
* If you send a message in response to a non-threaded message, you should add a decorator `~thread` with a field `thid` with value of `@id` field of that message. | ||
* If you send a message in response to an already threaded message, you should add a decorator `~thread` with `pthid` field with value of original `thid` and `thid` with n `@id` of message you respond to. | ||
More details about threading you can find in the [threading and message id HIPE](https://github.com/hyperledger/indy-hipe/blob/master/text/0027-message-id-and-threading/README.md) | ||
|
||
### Previews and negotiation | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels like there should be more here on non-happy path handling. However, if experience with VCX indicates that this is not necessary - that's fine. Implementation experience matters! |
||
|
||
This section is still in development and might be changed. | ||
|
||
In the previous sections pretty straightforward way of credential exchange has been described. It can be improved with preview of credential and counterrequest of presentation/credential. In general, request/counterrequest model is described [here](https://github.com/sovrin-foundation/ssi-protocol/tree/master/flow/std/negotiate_msg). | ||
As a preview we can add an attachment to Credential offer message: | ||
|
||
``` | ||
... | ||
"~attach": [ | ||
... | ||
{ | ||
"nickname": "credential-preview", | ||
"mime-type": "application/json", | ||
"content": { | ||
"base64": "<bytes for base64>" | ||
} | ||
} | ||
] | ||
``` | ||
|
||
The credential in preview should not have any signatures over the separate fields so it could not be used by anybody else for presentations. | ||
|
||
Prover can now respond with Credential Request with the same attachment, which results into an issuance of credential, or he/she can respond with a modified credential in the attachment. | ||
|
||
Then, Issuer issues the credential with Credential message (if Prover has agreed with the initial credential or Issuer agreed with the credential from counterrequest) or goes into another cycle of Offer/Request. | ||
|
||
It is important to mention that this process can be started as from Credential Offer message, as from Credential Request. | ||
|
||
The same process is applicable for presentation. Instead of the requested presentation Prover can offer its own presentation to Verifier in the attachment `libindy-presentation-offer`. Verifier can accept it, reject it or send another Presentation Request. | ||
|
||
All reasoning for another step of negotiation can be given inside of the `comment` field. | ||
|
||
# Reference | ||
[reference]: #reference | ||
|
||
* [VCX](https://github.com/hyperledger/indy-sdk/tree/master/vcx/libvcx/src/api) -- this implementation might not be perfect and needs to be improved, you can gather some info on parameters purpose from it | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
Why should we *not* do this? | ||
|
||
# Prior art | ||
[prior-art]: #prior-art | ||
|
||
Similar (but simplified) credential exchanged was already implemented in [von-agent](https://von-agent.readthedocs.io/en/latest/von_agent.html2). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This reference should be to "von-anchor", rather than von-agent. A rename was done some time back from von-agent to von-anchor, when it was recognized that the code was not an "agent", but rather a foundation for making an agent. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed that |
||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
- We might need to propose a new MIME type for credential (the same way as .docx is not processed as generic xml). The issue in W3C/vc-data-model: https://github.com/w3c/vc-data-model/issues/421 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
cred_id
needed or is this covered by the thread decorator that will be needed throughout the exchange? I think the term should be used differently later in the process on the issuer side so that they have a handle to be used for tracking and revoking the actual issued credential. It would not be part of the message exchange, but an id held by the issuer. I just don't like the idea of using the same term multiple times.