Skip to content
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

Closed
wants to merge 19 commits into from
Closed
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
236 changes: 236 additions & 0 deletions text/credential-exchange-message-family/README.md
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>",
Copy link
Member

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.

"cred_name": "name",
Copy link
Member

@swcurran swcurran Feb 11, 2019

Choose a reason for hiding this comment

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

"cred_def_id": "KTwaKJkvyjKKf55uc6U8ZB:3:CL:59:tag1",
"to_did": "Mie7euMJ94nrTHbx5HZEu7",
"from_did": "Mie7euMJ94nrTHbx5HZEu7",
Copy link
Member

@swcurran swcurran Feb 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "to_did" and "from_did" seem odd and unnecessary. The cred_def is sufficient to determine who (what DID) will issue the credential and it's unlikely to be the "from_did" in the message exchange. The two parties having the conversation know each other (they are exchanging messages) and their DIDs for one another. Is there another reason those are needed?

Same reasoning applies to the same fields in the other message types.

"comment": "some comment",
"~attach": [
{
"nickname": "libindy-offer",
Copy link
Contributor

@kdenhartog kdenhartog Mar 22, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adding @type: "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/anoncreds/1.0" into the ~attach JSON-LD object of the attachment would allow us to support multiple credential types in here. We would likely need to do this for the Credential Offer, Credential Proposal, so that we can agree on the data that needs to be passed back in the Credential Request.

"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>",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the @id should be the uuid_credential, should it? It's the @id of the message.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uuid_credential is just a name that was meant to refer to some particular @id for threading. No particular credential connection here.

"rev_reg_def_id": "<rev_reg_def_id>",
Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Author

Choose a reason for hiding this comment

The 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

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this is an awesome idea!
I will add that to open questions.

#### Presentation Request
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

The 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:

Message families provide a logical grouping for message types

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.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Author

Choose a reason for hiding this comment

The 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:
Copy link
Member

Choose a reason for hiding this comment

The 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 ~thread..."

* 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
Copy link
Member

Choose a reason for hiding this comment

The 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).
Copy link
Member

Choose a reason for hiding this comment

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

https://von-anchor.readthedocs.io/en/latest/

Copy link
Author

Choose a reason for hiding this comment

The 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