diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..b44347e3d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,39 @@ + # For details on how this file works refer to: + # - https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file +version: 2 +updates: + # Maintain dependencies for GitHub Actions + # - Check for updates once a week + # - Group all updates into a single PR + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + all-actions: + patterns: [ "*" ] + + # Maintain dependencies for Python Packages + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + time: "04:00" + timezone: "Canada/Pacific" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] + + # Maintain dependencies for Python Packages + - package-ecosystem: "pip" + directory: "/.circleci" + schedule: + interval: "weekly" + day: "monday" + time: "04:00" + timezone: "Canada/Pacific" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-major"] + diff --git a/.github/workflows/indexgenerate.yml b/.github/workflows/indexgenerate.yml deleted file mode 100644 index 273731124..000000000 --- a/.github/workflows/indexgenerate.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Index Generation - -on: - pull_request: - branches: [master] - types: [closed] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v1 - with: - python-version: "3.7" - - name: Generate Index - run: | - python code/generate_index.py - - name: Create Pull Request - id: cpr - uses: peter-evans/create-pull-request@v3 - with: - commit-message: Generate Index - author: GitHub Action - committer: GitHub Action - signoff: true - branch: index-generator - title: "[AUTO] Update Index" - body: | - Update Index diff --git a/.github/workflows/publish-site.yml b/.github/workflows/publish-site.yml new file mode 100644 index 000000000..d03d4007b --- /dev/null +++ b/.github/workflows/publish-site.yml @@ -0,0 +1,39 @@ +name: publish-docs + +on: + push: + # Publish `main` as latest, and when pushes are done to branches with "v-doc" prefix + branches: + - main + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # fetch all commits/branches + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - uses: actions/cache@v4 + with: + key: ${{ github.ref }} + path: .cache + - name: Install Python dependencies + run: pip install -r ./mkdocs-requirements.txt + - name: Configure git user + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + + - name: Deploy docs + run: | + python --version + # Generate the content into the docs folder + code/genSite.sh + mike deploy --push --update-aliases main latest + mike set-default latest diff --git a/.gitignore b/.gitignore index fc427a3eb..3b7c0be90 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ __pycache__ *.pyc *.tmp .pytest_cache +docs \ No newline at end of file diff --git a/0000-template-protocol.md b/0000-template-protocol.md index 8cec461fa..a18427487 100644 --- a/0000-template-protocol.md +++ b/0000-template-protocol.md @@ -1,18 +1,19 @@ # Aries RFC 0000: Your Protocol 0.9 -- Authors: [your name](you@github-email) -- email is optional +- Authors: [your name](mailto:you@github-email) -- email is optional - Status: [PROPOSED](/README.md#proposed) - Since: 2019-12-26 (date you submit your PR) - Status Note: (explanation of current status) - Supersedes: (link to anything this RFC supersedes) - Start Date: 2018-12-26 (date you started working on this idea) -- Tags: feature, protocol +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) +- URI: https://didcomm.org/your_protocol_name/%VER ## Summary One paragraph explanation of the feature. -> If the RFC you are proposing is **NOT** a protocol, please use [this template](https://github.com/hyperledger/aries-rfcs/tree/master/0000-template.md) as a starting point. +> If the RFC you are proposing is **NOT** a protocol, please use [this template](https://github.com/hyperledger/aries-rfcs/tree/main/0000-template.md) as a starting point. > When completing this template and before submitting as a PR, please remove the template text in sections (other than **Implementations**). The implementations section should remain as is. @@ -30,11 +31,11 @@ Specify the official name of the protocol and its version, e.g., "My Protocol 0. Protocol names are often either lower_snake_case or kebob-case. The non-version components of the protocol named are matched exactly. -URI: https://didcomm.org/lets_do_lunch// +URI: `https://didcomm.org/lets_do_lunch//` -Message types and protocols are identified with special URIs that match certain conventions. See [Message Type and Protocol Identifier URIs](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0003-protocols/uris.md) for more details. +Message types and protocols are identified with special URIs that match certain conventions. See [Message Type and Protocol Identifier URIs](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/README.md#message-type-and-protocol-identifier-uris) for more details. -The version of a protocol is declared carefully. See [Semver Rules for Protocols](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0003-protocols/semver.md) for details. +The version of a protocol is declared carefully. See [Semver Rules for Protocols](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/README.md#semver-rules-for-protocols) for details. ### Key Concepts @@ -49,7 +50,7 @@ variants. ### Roles -> See [this note](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0003-protocols/roles-participants-etc.md) for definitions of the terms +> See [this note](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0003-protocols/roles-participants-etc.md) for definitions of the terms "role", "participant", and "party". Provides a formal name to each role in the protocol, says who and how many can @@ -60,7 +61,7 @@ credential must be known to the issuer"). The formal names for each role are important because they are used when [agents discover one another's -capabilities](https://github.com/hyperledger/aries-rfcs/tree/master/features/0031-discover-features); +capabilities](https://github.com/hyperledger/aries-rfcs/tree/main/features/0031-discover-features); an agent doesn't just claim that it supports a protocol; it makes a claim about which *roles* in the protocol it supports. An agent that supports credential issuance and an agent that supports credential holding may have very different @@ -75,7 +76,7 @@ errors, and what should happen to state as a result. A formal representation of this information is provided in a _state machine matrix_. It lists events as columns, and states as rows; a cell answers the question, "If I am in state X (=row), and event Y (=column) occurs, what happens to my state?" The [Tic Tac -Toe example](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0003-protocols/tictactoe/README.md#states) is typical. +Toe example](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/tictactoe/README.md#states) is typical. [Choreography Diagrams]( https://www.visual-paradigm.com/guide/bpmn/bpmn-orchestration-vs-choreography-vs-collaboration/#bpmn-choreography) @@ -91,8 +92,8 @@ the matrix form is used in many early RFCs. We leave it up to the community to settle on whether it wants to strongly recommend specific diagram types. -The formal names for each state are important, as they are used in [`ack`s](https://github.com/hyperledger/aries-rfcs/tree/master/features/0015-acks) -and [`problem-report`s](https://github.com/hyperledger/aries-rfcs/tree/master/features/0035-report-problem)). +The formal names for each state are important, as they are used in [`ack`s](https://github.com/hyperledger/aries-rfcs/tree/main/features/0015-acks) +and [`problem-report`s](https://github.com/hyperledger/aries-rfcs/tree/main/features/0035-report-problem)). For example, a `problem-report` message declares which state the sender arrived at because of the problem. This helps other participants to react to errors with confidence. Formal state names are also used in the @@ -102,14 +103,14 @@ By convention, state names use lower-kebab-case. They are compared case-sensitively. State management in protocols is a deep topic. For more information, please -see [State Details and State Machines](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0003-protocols/state-details.md). +see [State Details and State Machines](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/state-details.md). ### Messages This section describes each message in the protocol. It should also note the names and versions of messages from other message families that are adopted by the -protocol (e.g., an [`ack`](https://github.com/hyperledger/aries-rfcs/tree/master/features/0015-acks) -or a [`problem-report`](https://github.com/hyperledger/aries-rfcs/tree/master/features/0035-report-problem)). +protocol (e.g., an [`ack`](https://github.com/hyperledger/aries-rfcs/tree/main/features/0015-acks) +or a [`problem-report`](https://github.com/hyperledger/aries-rfcs/tree/main/features/0035-report-problem)). Typically this section is written as a narrative, showing each message type in the context of an end-to-end sample interaction. All possible fields may not appear; an exhaustive catalog is saved for the "Reference" @@ -117,7 +118,7 @@ section. Sample messages that are presented in the narrative should also be checked in next to the markdown of the RFC, in [DIDComm Plaintext format]( -https://github.com/hyperledger/aries-rfcs/tree/master/features/0044-didcomm-file-and-mime-types#didcomm-messages-dm). +https://github.com/hyperledger/aries-rfcs/tree/main/features/0044-didcomm-file-and-mime-types#didcomm-messages-dm). The _message_ element of a message type URI are typically lower_camel_case or lower-kebab-case, matching the style of the protocol. JSON items in messages are lower_camel_case and inconsistency in the @@ -152,13 +153,13 @@ and its definition announces that it has adopted generic 1.x `ack` messages. When such `ack` messages are sent, the `@type` should now use the alias defined inside the namespace of the `rendezvous` protocol: -![diff on @type caused by adoption](concepts/0003-protocols/adoption.png) +[![diff on @type caused by adoption](concepts/0003-protocols/adoption.png)](https://docs.google.com/presentation/d/15UAkh_2WfDk7wlto7pSL7YU9NJr_XVMgGAOeNIRbzK8/edit#slide=id.g9e66a1f72d_0_0) Adoption should be declared in an "Adopted" subsection of "Messages". When adoption is specified, it should include a __minimum adopted version__ of the adopted message type: "This protocol adopts `ack` with version >= 1.4". All versions of the adopted message that share -the same major number should be compatible, given the [semver rules](concepts/0003-protocols/semver.md) +the same major number should be compatible, given the [semver rules](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/README.md#semver-rules-for-protocols) that apply to protocols. ### Constraints @@ -182,7 +183,7 @@ needs to be known about all message fields, this is where the data type, validation rules, and semantics of each field in each message type are details. Enumerating possible values, or providing ABNF or regexes is encouraged. Following conventions such as [those for date- -and time-related fields](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0074-didcomm-best-practices#date-time-conventions) +and time-related fields](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0074-didcomm-best-practices#date-time-conventions) can save a lot of time here. Each message type should be associated with one or more roles in the @@ -210,15 +211,15 @@ If communication in the protocol involves humans, then localization of message content may be relevant. Default settings for localization of all messages in the protocol can be specified in an `l10n.json` file described here and checked in with the RFC. See ["Decorators at Message -Type Scope"](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0011-decorators#decorator-scope) -in the [Localization RFC](https://github.com/hyperledger/aries-rfcs/tree/master/features/0043-l10n). +Type Scope"](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0011-decorators#decorator-scope) +in the [Localization RFC](https://github.com/hyperledger/aries-rfcs/tree/main/features/0043-l10n). ### Codes Catalog If the protocol has a formally defined catalog of codes (e.g., for errors or for statuses), define them in this section. See ["Message Codes and -Catalogs"](https://github.com/hyperledger/aries-rfcs/blob/master/features/0043-l10n/README.md#message-codes-and-catalogs) -in the [Localization RFC](https://github.com/hyperledger/aries-rfcs/blob/master/features/0043-l10n). +Catalogs"](https://github.com/hyperledger/aries-rfcs/blob/main/features/0043-l10n/README.md#message-codes-and-catalogs) +in the [Localization RFC](https://github.com/hyperledger/aries-rfcs/blob/main/features/0043-l10n). ## Drawbacks @@ -270,7 +271,7 @@ solution that comes out of this doc? The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -*Implementation Notes* [may need to include a link to test results](README.md#accepted). +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). Name / Link | Implementation Notes --- | --- diff --git a/0000-template.md b/0000-template.md index 866ba6953..f6608e2ef 100644 --- a/0000-template.md +++ b/0000-template.md @@ -1,17 +1,17 @@ # Title (Ex. 0000: RFC Topic) -- Authors: [your name](you@github-email) -- email is optional +- Authors: [your name](mailto:you@github-email) -- email is optional - Status: [PROPOSED](/README.md#proposed) - Since: 2019-12-26 (date you submit your PR) - Status Note: (explanation of current status) - Supersedes: (link to anything this RFC supersedes) - Start Date: 2018-12-26 (date you started working on this idea) -- Tags: feature, protocol +- Tags: [concept](/tags.md#concept) ## Summary One paragraph explanation of the feature. -> NOTE: If you are creating a **protocol** RFC, please use [this template](https://github.com/hyperledger/aries-rfcs/blob/master/0000-template-protocol.md)instead. +> NOTE: If you are creating a **protocol** RFC, please use [this template](https://github.com/hyperledger/aries-rfcs/blob/main/0000-template-protocol.md) instead. ## Motivation @@ -93,7 +93,7 @@ solution that comes out of this doc? The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -*Implementation Notes* [may need to include a link to test results](README.md#accepted). +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). Name / Link | Implementation Notes --- | --- diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 000000000..7def48055 --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,73 @@ +# Maintainers + +## Active Maintainers + + + +| Name | Github | LFID | +| ---------------- | ---------------- | ---------------- | +| Daniel Hardman | dhh1128 | | +| George Aristy | llorllale | | +| Nathan George | nage | | +| Stephen Curran | swcurran | | +| Drummond Reed | talltree | | +| Sam Curren | TelegramSam | | + +## Emeritus Maintainers + +| Name | Github | LFID | +|--------------|---------|---------| +| | | | + +## Becoming a Maintainer + +The Aries community welcomes contributions. Contributors may progress to become a +maintainer. To become a maintainer the following steps occur, roughly in order. + +- 5 significant changes have been authored by the proposed maintainer and + accepted. +- The proposed maintainer has the sponsorship of at least one other maintainer. + - This sponsoring maintainer will create a PR modifying the list of + maintainers. + - The proposed maintainer accepts the nomination and expresses a willingness + to be a long-term (more than 6 month) committer. + - This would be a comment in the above PR. + - This PR will be communicated in all appropriate communication channels. It + should be mentioned in any maintainer/community call. It should also be + posted to the appropriate mailing list or chat channels if they exist. +- Approval by at least 3 current maintainers within two weeks of the proposal or + an absolute majority of current maintainers. + - These votes will be recorded in the PR modifying the list of maintainers. +- No veto by another maintainer within two weeks of proposal are recorded. + - All vetoes must be accompanied by a public explanation as a comment in the + PR for adding this maintainer + - The explanation of the veto must be reasonable. + - A veto can be retracted, in that case the approval/veto timeframe is reset. + - It is bad form to veto, retract, and veto again. +- The proposed maintainer becomes a maintainer + - Either two weeks have passed since the third approval, + - Or an absolute majority of maintainers approve. + - In either case, no maintainer presents a veto. + +## Removing Maintainers + +Being a maintainer is not a status symbol or a title to be maintained +indefinitely. It will occasionally be necessary and appropriate to move a +maintainer to emeritus status. This can occur in the following situations: + +- Resignation of a maintainer. +- Violation of the Code of Conduct warranting removal. +- Inactivity. + - A general measure of inactivity will be no commits or code review comments + for one reporting quarter, although this will not be strictly enforced if + the maintainer expresses a reasonable intent to continue contributing. + - Reasonable exceptions to inactivity will be granted for known long term + leave such as parental leave and medical leave. +- Other unspecified circumstances. + +Like adding a maintainer the record and governance process for moving a +maintainer to emeritus status is recorded in the github PR making that change. + +Returning to active status from emeritus status uses the same steps as adding a +new maintainer. Note that the emeritus maintainer already has the 5 required +significant changes as there is no contribution time horizon for those. diff --git a/README.md b/README.md index b8b3867a5..a89ea2b48 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ If you are here to learn about Aries, we recommend you use the [the RFC Index](i There are 2 types of Aries RFCs: -* RFCs that describe individual features (in the [features](./features) folder) -* RFCs that explain concepts underpinning many features (in the [concepts](./concepts) folder) +* RFCs that describe individual features (in the `./features` folder) +* RFCs that explain concepts underpinning many features (in the `./concepts` folder) RFCs are for developers *building on* Aries. They don't provide guidance on how Aries components implement features internally; individual Aries repos have design docs for that. Each @@ -20,7 +20,18 @@ Aries RFC includes an "implementations" section and all RFCs with a status great RFCs go through a standard lifecycle. -![lifecycle](lifecycle.png) + + +![lifecycle](https://www.plantuml.com/plantuml/png/TP1DZeCm38NtEKK6rbnXHAKUe6gNg8iKN43AJ-GOUlsIoa60mYQs_Db-UQu3AQJ9QF570nYGy_X2PKayI178uWuq8dI5L45oBilbINm9MZFdVCjlwBmBiQR7Vg0U0IoZAnXd0w6YBBwqBVWJv3sw-O1MfQefVvLdzR_J43l1gdCVk-bCSeAJJ0Uh7lPeU5CJ7SSUlX0lESUyAeytLZ3wMpdVLt1Cq-iFqvoemNQJqLy0) #### PROPOSED To __propose__ an RFC, [use these instructions to raise a PR]( @@ -33,13 +44,17 @@ exploring. __Demonstrated__ RFCs have one or more implementations available, listed in the "Implementations" section of the RFC document. As with the PROPOSED status, demonstrated RFCs haven't been endorsed by the community, but the ideas put forth have been more thoroughly explored through the implementation(s). The demonstrated status is an optional step in the lifecycle. For protocol-related RFCs, work on protocol tests SHOULD begin in the [test suite repo](https://github.com/hyperledger/aries-protocol-test-suite) by the time this status is assigned. #### ACCEPTED -To get an RFC __accepted__, [build consensus](contributing.md#how-to-get-an-RFC-accepted) for your RFC on [chat](https://chat.hyperledger.org/channel/aries) and in community meetings. If your RFC is a feature that's protocol- or decorator-related, it MUST have reasonable tests in the [test suite repo](https://github.com/hyperledger/aries-protocol-test-suite), it MUST list the test suite in the protocol RFC's [Implementations section](../0000-template.md#implementations), at least one other implementation must have passed the relevant portions of the test suite, and all implementations listed in this section of the RFC MUST hyperlink to their test results. An accepted RFC is incubating on a standards track; the community has decided to polish it and is exploring or pursuing implementation. +To get an RFC __accepted__, [build consensus](contributing.md#how-to-get-an-RFC-accepted) for your RFC on [chat](https://chat.hyperledger.org/channel/aries) and in community meetings. If your RFC is a feature that's protocol- or decorator-related, it MUST have reasonable tests in the [test suite repo](https://github.com/hyperledger/aries-agent-test-harness), it MUST list the test suite in the protocol RFC's [Implementations section](/0000-template.md#implementations), at least one other implementation must have passed the relevant portions of the test suite, and all implementations listed in this section of the RFC MUST hyperlink to their test results. An accepted RFC is incubating on a standards track; the community has decided to polish it and is exploring or pursuing implementation. #### ADOPTED To get an RFC __adopted__, [socialize and implement](contributing.md#how-to-get-an-rfc-adopted). An RFC gets this status once it has significant momentum--when implementations accumulate, or when the mental model it advocates has begun to permeate our discourse. In other words, adoption is acknowledgment of a _de facto_ standard. To __refine__ an RFC, propose changes to it through additional PRs. Typically these changes are driven by experience that accumulates during or after adoption. Minor refinements that just improve clarity can happen inline with lightweight review. Status is still ADOPTED. +#### STALLED +An RFC is __stalled__ when a [proposed](#proposed) RFC makes +no progress towards implementation such that it is extremely unlikely it will ever move forward. The __stalled__ state differs from [retired](#retired) in that it is an RFC that has never been implemented or superseded. Like the [retired](#retired) state, it is (likely) an end state and the RFC will not proceed further. Such an RFC remains in the repository on the off chance it will ring a chord with others, be returned to the [proposed](#proposed) state, and continue to evolve. + #### RETIRED An RFC is __retired__ when it is withdrawn from community consideration by its authors, when implementation seems permanently stalled, or when significant refinements require a superseding document. If a retired RFC has been superseded, its `Superseded By` field should contain a link to the newer spec, and the newer spec's `Supersedes` field should contain a link to the older spec. Permalinks are not broken. diff --git a/code/aipUpdates.py b/code/aipUpdates.py index 8961c1ba1..8c01cc6fc 100755 --- a/code/aipUpdates.py +++ b/code/aipUpdates.py @@ -11,12 +11,13 @@ description='List the RFCs set in an Aries Interop Profile (AIP) that have subsequently evolved. ' + 'By default, the AIPs in the local version of the file are processed. A specific version can be ' + 'specified, and then only that AIP version is processed. The AIP version can be a previous (not current) ' + - 'AIP. Optionally, the diffs between RFCs set in processed AIP and the "master" branch can be included.') + 'AIP. Optionally, the diffs between RFCs set in processed AIP and the "main" branch can be included.') # add arguments to the parser parser.add_argument('--version', '-v', help='The AIP version to display. Defaults to the current version(s) in the local file') parser.add_argument('--diffs', '-d', dest='diffs', action='store_true', help='Display the diffs of any updated RFCs found') +parser.add_argument('--list', '-l', help='List the RFCs and commits in the AIP with a prefixed by the name of a (for example) shell script') # parse the arguments args = parser.parse_args() @@ -64,10 +65,10 @@ def readAIP( aip_path, version ): if aip_version: # Check if we want all the AIPs in the file or this one if ( not(args.version) or aip_version.group(1) == args.version ): - print("Aries Interop Profile: %s" % (aip_version.group(1))) + print("# Aries Interop Profile: %s" % (aip_version.group(1))) ListVersionRFCs = True else: - # Not this one...don't list the changed verion + # Not this one...don't list the changed version ListVersionRFCs = False rfc = re.search(_aip_commit_and_file, line) @@ -76,14 +77,16 @@ def readAIP( aip_path, version ): # From the RFC line, get the commit ID and protocol file commit = rfc.group(3) protocol = rfc.group(5) - changed = re.search(protocol, subprocess.run(['git', 'diff', '--name-only', commit, 'master'], stdout=subprocess.PIPE).stdout.decode('utf-8')) + changed = re.search(protocol, subprocess.run(['git', 'diff', '--name-only', commit, 'main'], stdout=subprocess.PIPE).stdout.decode('utf-8')) # Has this RFC changed since it was set in the RFC? - if changed: + if args.list: + print('%s %s %s' % (args.list, protocol, commit)) + elif changed: # Yes - list it. print('>>>>>>>> Changed protocol: %s, latest commit to protocol: %s' % (protocol, subprocess.run(['git', 'log', '-n', '1', '--pretty=format:%H', '--', protocol], stdout=subprocess.PIPE).stdout.decode('utf-8'))) if args.diffs: # If we're showing diffs, then show the diffs print('') - print(subprocess.run(['git', 'diff', commit, 'master', protocol], stdout=subprocess.PIPE).stdout.decode('utf-8')) + print(subprocess.run(['git', 'diff', commit, 'main', protocol], stdout=subprocess.PIPE).stdout.decode('utf-8')) exit() diff --git a/code/check_links.py b/code/check_links.py index 83793fa8d..6b81d80cf 100644 --- a/code/check_links.py +++ b/code/check_links.py @@ -216,4 +216,4 @@ def main(full_check = False): if __name__ == '__main__': full_check = (len(sys.argv) > 1 and sys.argv[1] == '--full') error_count = main(full_check) - sys.exit(error_count) \ No newline at end of file + sys.exit(error_count) diff --git a/code/cpAIPs.sh b/code/cpAIPs.sh new file mode 100755 index 000000000..6d38c7016 --- /dev/null +++ b/code/cpAIPs.sh @@ -0,0 +1,19 @@ +#! /bin/bash + +# Usage: Given an RFC name and a commit, retrieve all the files of the RFC into the AIP RFC at the right commit. +# Example: code/cpAIP.sh concepts/0003-protocols c3b0e2120ad24810598375663b6922b980f85d00 +# Designed to fetch files in subdirectories, although it is not clear how to add them to the documentatioon + +PROTOCOL=$1 +COMMIT=$2 +AIP2=aip2 + +# echo Getting AIP docs for RFC $PROTOCOL, Commit $COMMIT +cd docs +for i in $(find $PROTOCOL -type f); do + AIPFile=$(echo $i | sed -r "s#(features|concepts)/#${AIP2}/#") + # echo $i $AIPFile + mkdir -p $(dirname $AIPFile) + curl -s https://raw.githubusercontent.com/hyperledger/aries-rfcs/${COMMIT}/$i -o $AIPFile +done +cd .. diff --git a/code/genSite.sh b/code/genSite.sh new file mode 100755 index 000000000..e56f2ee65 --- /dev/null +++ b/code/genSite.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +# echo Updating the Docs for Aries RFCs + +# Clean out the docs folder +rm -rf docs/* +mkdir -p docs + +# Root folder -- README.md +cp -r contributing.md github-issues.md MAINTAINERS.md README.md SECURITY.md tags.md 0000*.md *.png collateral docs +cp LICENSE docs/LICENSE.md +sed -e "s#/tags.md#tags.md#g" index.md > docs/RFCindex.md + +# Features and Concept -- collect all of the RFCs +cp -r features concepts docs + +# Update the index.md file +python code/generate_index.py + +# Make a copy of AIP 2 RFCs using the right commit for each +python code/aipUpdates.py -v 2.0 -l "./code/cpAIPs.sh" | \ + sed -e "/0317-please-ack/d" -e "/0587-encryption-envelope-v2/d" -e "/0627-static-peer-dids/d" \ + > copy_aip.sh +source copy_aip.sh +rm copy_aip.sh + +# Cleanup a few things in README, contributing and 0000-templates +for i in docs/contributing.md docs/README.md docs/0000*.md; do + sed \ + -e 's#../../##g' \ + -e 's#index.md#RFCindex.md#' \ + -e 's#LICENSE)#LICENSE.md)#' \ + $i >$i.tmp + mv $i.tmp $i +done + + +# Cleanup missing mailtos -- will always be needed for aip2 folder, but will be cleaned up in files +for i in docs/features/*/README.md docs/concepts/*/README.md docs/aip2/*/README.md; do + sed -e '/Authors/s#](#](mailto:#g' -e 's#mailto:mailto:#mailto:#g' $i >$i.tmp; mv $i.tmp $i +done + +# Cleanup the links in the RFCs +for i in docs/features/*/README.md docs/concepts/*/README.md docs/aip2/*/README.md; do + sed \ + -e 's#(/#(../../#g' \ + -e 's#index.md#RFCindex.md#' \ + -e 's#[\./]*\(concepts\)#../../\1#g' \ + -e 's#[\./]*\(features\)#../../\1#g' \ + -e 's#discover-../../#discover-#g' \ + $i >$i.tmp + mv $i.tmp $i +done + +# Remove the existing AIP and By Status Links -- we'll add them back +MKDOCS=mkdocs.yml +MKDOCSTMP=${MKDOCS}.tmp +MKDOCSIDX=mkdocs_index.yml + +# Strip off the old navigation +sed '/RFCs by AIP and Status/,$d' ${MKDOCS} >${MKDOCSTMP} + +# Add back in the marker +echo '# RFCs by AIP and Status' >>${MKDOCSTMP} + +# Navigation for AIP 2.0 files +echo "- AIP 2.0:" >>${MKDOCSTMP} +for i in docs/aip2/*/README.md ; do head -n 1 $i | sed -e "s/# / - /" -e "s/: / /" -e "s#\$#: $i#" -e "s#docs/##"; done >>${MKDOCSTMP} + +# Navigation for all RFCs by Status +python code/generate_mkdocs_index.py +cat ${MKDOCSIDX} >>${MKDOCSTMP} +rm ${MKDOCSIDX} + +mv ${MKDOCSTMP} ${MKDOCS} diff --git a/code/generate_mkdocs_index.py b/code/generate_mkdocs_index.py new file mode 100644 index 000000000..65fc7b36b --- /dev/null +++ b/code/generate_mkdocs_index.py @@ -0,0 +1,46 @@ +import argparse +from operator import itemgetter +import os +from pathlib import Path +import sys + +import rfcs + +def update(fname, tmp_fname): + if not os.path.exists(fname): + os.rename(tmp_fname, fname) + # print('Generated %s.' % fname) + return + with open(fname, encoding='utf-8', mode='rt') as f: + old = f.read() + with open(tmp_fname, encoding='utf-8', mode='rt') as f: + new = f.read() + if old == new: + # print('No change to %s.' % fname) + return + os.remove(fname) + os.rename(tmp_fname, fname) + # print('Updated %s.' % fname) + + +def main(fname = None): + if not fname: + fname = os.path.join(rfcs.root_folder, 'mkdocs_index.yml') + # Load all metadata + all = [rfc for rfc in rfcs.walk()] + all.sort(key=lambda x: x.num) + tmp_fname = fname + '.tmp' + with open(tmp_fname, 'w', encoding='utf-8') as out: + for status in rfcs.status_list: + out.write(f"- {status}:\n") + with_status = [rfc for rfc in all if rfc.status == status] + for rfc in with_status: + out.write(f" - {rfc.num} {rfc.title}: {rfc.relpath}\n") + update(fname, tmp_fname) + + +if __name__ == '__main__': + ap = argparse.ArgumentParser('Generate index') + ap.add_argument('altpath', metavar='PATH', nargs='?', default=None, help='override where index is generated') + args = ap.parse_args() + main(args.altpath) diff --git a/code/rfcs.py b/code/rfcs.py index aa0a04940..320862e5b 100644 --- a/code/rfcs.py +++ b/code/rfcs.py @@ -6,7 +6,7 @@ ' status_note start_date supersedes superseded_by tags content_idx impl_count impl_table') -status_list = ["ADOPTED", "ACCEPTED", "DEMONSTRATED", "PROPOSED", "RETIRED"] +status_list = ["ADOPTED", "ACCEPTED", "DEMONSTRATED", "PROPOSED", "STALLED", "RETIRED"] root_folder = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) diff --git a/code/test_rfcs.py b/code/test_rfcs.py index 86e441acd..2ec544400 100644 --- a/code/test_rfcs.py +++ b/code/test_rfcs.py @@ -160,20 +160,20 @@ def find_refs(dict, key, value): matches.append(ref[3]) return matches - for key, value in pretty_for_normalized_names.items(): - if len(value) > 1: - offenders = '\n'.join(find_refs(pretty_for_normalized_names, key, value)) - e(offenders, '\n inconsistent variants on impl name: %s' % ', '.join(['"%s"' % v for v in value])) - - for key, value in normalized_for_base_uri.items(): - if len(value) > 1: - offenders = '\n'.join(find_refs(normalized_for_base_uri, key, value)) - e(offenders, '\n same site maps to multiple impl names: %s' % ', '.join(['"%s"' % v for v in value])) - - for key, value in base_uri_for_normalized.items(): - if len(value) > 1: - offenders = '\n'.join(find_refs(base_uri_for_normalized, key, value)) - e(offenders, '\n impl name "%s" maps to multiple sites: %s' % (key, ', '.join(['"%s"' % v for v in value]))) + # for key, value in pretty_for_normalized_names.items(): + # if len(value) > 1: + # offenders = '\n'.join(find_refs(pretty_for_normalized_names, key, value)) + # e(offenders, '\n inconsistent variants on impl name: %s' % ', '.join(['"%s"' % v for v in value])) + + # for key, value in normalized_for_base_uri.items(): + # if len(value) > 1: + # offenders = '\n'.join(find_refs(normalized_for_base_uri, key, value)) + # e(offenders, '\n same site maps to multiple impl names: %s' % ', '.join(['"%s"' % v for v in value])) + + # for key, value in base_uri_for_normalized.items(): + # if len(value) > 1: + # offenders = '\n'.join(find_refs(base_uri_for_normalized, key, value)) + # e(offenders, '\n impl name "%s" maps to multiple sites: %s' % (key, ', '.join(['"%s"' % v for v in value]))) if errors: msg = '\n' + '\n'.join(errors) diff --git a/collateral/favicon.ico b/collateral/favicon.ico new file mode 100644 index 000000000..90697b9fd Binary files /dev/null and b/collateral/favicon.ico differ diff --git a/concepts/0003-protocols/README.md b/concepts/0003-protocols/README.md index a57619cb1..54e4af608 100644 --- a/concepts/0003-protocols/README.md +++ b/concepts/0003-protocols/README.md @@ -1,7 +1,7 @@ # Aries RFC 0003: Protocols -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-04-01 - Status Note: standards track and beginning to influence many mental models, but not yet [ADOPTED](/README.md#rfc-lifecycle). - Supersedes: [Indy PR #69]( https://github.com/hyperledger/indy-hipe/pull/69) @@ -342,13 +342,9 @@ The following are examples of valid MTURIs and PIURIs: ([https://github.com/hyperledger/aries-rfcs/tree/18c4f82]( https://github.com/hyperledger/aries-rfcs/tree/18c4f82 )) and look for documentation on the `trust_ping/1.0` protocol. -* `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/trust_ping/1.0/ping` (MTURI) This - uses a DID reference to look up an endpoint named `spec` that serves - information about protocols. (The exact syntax of DID references--URIs - where the DID functions like a domain name, and additional info is - fetched from a DID Doc in much the same way IP address and hostname - definitions are fetched from a DNS record--is still being finalized. - See the latest [DID Spec](https://w3c-ccg.github.io/did-spec/) for details.) +* `https://didcomm.org/trust_ping/1.0/ping` (MTURI) This + uses an https reference that could serve + information about protocols. ### Semver Rules for Protocols @@ -374,16 +370,35 @@ message family](https://semver.org/#spec-item-8). Within a given major version of a protocol, an agent should: -- respond to a minimum supported minor version, defaulting to "0" -- respond with or initiate a protocol instance the current fully supported minor version +- Respond to a minimum supported minor version, defaulting to "0". + - An agent SHOULD keep minimum supported minor version at "0" unless it is unsecure or extremely complicated to do so. +- Respond with or initiate a protocol instance the current fully supported minor version. This leads to the following received message handling rules: -- message types received with a minor versions below the minimum may be answered with a `problem-report` message with code `version-not-supported` -- message types received with a minor version at or higher than the minimum supported and less than the current minor version are processed, ideally with a response using the same minor version of the received message - - The recipient may want to send a warning `problem-report` message with code `version-with-degraded-features` -- message types received with a minor version higher than the current minor version are processed with any unrecognized fields ignored - - The recipient may want to send a warning `problem-report` message with code `fields-ignored-due-to-version-mismatch` +- Message types received with minor versions below the minimum MAY be ignored, or preferably, MAY be answered only with a `problem-report` message with code `version-not-supported`. +- Message types received with a minor version __at or higher than__ the minimum supported __and less than__ the current minor version are processed as follows: + - The processing MAY be with the same minor version of the received message. + - To support this, an implementation must implement each minor version from minimum to current within the major version. + - The processing MAY be with the current minor version (higher than received). + - This approach is used when maintaining each minor version from minimum to current within the major version is impractical. + - Recipients of the response message SHOULD detect from the response [PIURI](#piuri) that a higher minor version was used in the response, and to compensate if needed and as necessary. + - Prior wording of this protocol included the following suggestion that is now considered deprecated. See note below about deprecating the "warning" problem reports. + - In addition to responding with the protocol message (if necessary), the agent MAY also want to send a warning `problem-report` message with code `version-with-degraded-features`. +- Message types received with a minor version higher than the current minor version MUST be processed with any unrecognized fields ignored. + - The response MUST use the current minor version. + - Recipients of the response message SHOULD detect from the response [PIURI](#piuri) that a lower minor version was used in the response, and to compensate if needed and as necessary. + - Prior wording of this protocol included the following that is now considered deprecated. See note below about deprecating the "warning" problem reports. + - In addition to responding with the protocol message, an agent MAY send a warning `problem-report` message with code `fields-ignored-due-to-version-mismatch` + +**Note:** The deprecation of the "warning" `problem-reports` in cases of minor +version mismatches is because the recipient of the response can detect the +mismatch by looking at the [PIURI](#piuri), making the "warning" unnecessary, +and because the `problem-report` message may be received after (and definitely +at a different time than) the response message, and so the warning is of very +little value to the recipient. Recipients should still be aware that minor +version mismatch warning `problem-report` messages may be received and handle +them appropriately, likely by quietly ignoring them. As documented in the semver documentation, these requirements are not applied when major version 0 is used. In that case, minor version increments are considered breaking. @@ -506,7 +521,7 @@ to move the interaction forward.) #### Roles -The __roles__ in a protocol are the perspectives (responsibilities, privileges) that parties take i an +The __roles__ in a protocol are the perspectives (responsibilities, privileges) that parties take in an interaction. This perspective is manifested in three general ways: diff --git a/concepts/0003-protocols/adoption.png b/concepts/0003-protocols/adoption.png index d1e67c5e0..34b0ffcf5 100644 Binary files a/concepts/0003-protocols/adoption.png and b/concepts/0003-protocols/adoption.png differ diff --git a/concepts/0003-protocols/tictactoe/README.md b/concepts/0003-protocols/tictactoe/README.md index 2d7ca7e96..cbfb06412 100644 --- a/concepts/0003-protocols/tictactoe/README.md +++ b/concepts/0003-protocols/tictactoe/README.md @@ -29,7 +29,7 @@ capture 3 cells of the grid in a straight line. ### Name and Version This defines the `tictactoe` protocol, version 1.x, as identified by the -following [PIURI](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0003-protocols/uris.md#piuri): +following [PIURI](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0003-protocols#message-type-and-protocol-identifier-uris): did:sov:SLfEi9esrjzybysFxQZbfq;spec/tictactoe/1.0 @@ -78,7 +78,7 @@ but it would be an error on the part of the other player, and would trigger a `problem-report` message as described above, leaving the state unchanged. -In the `receive-move` state, `send move` is an impossible event for a +In the `their-move` state, `send move` is an impossible event for a properly behaving player. All 3 of the other events could occur, causing a state transition. diff --git a/concepts/0004-agents/README.md b/concepts/0004-agents/README.md index b1147aaea..0fb1e6d39 100644 --- a/concepts/0004-agents/README.md +++ b/concepts/0004-agents/README.md @@ -1,10 +1,10 @@ # Aries RFC 0004: Agents -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [ACCEPTED](/README.md#accepted) - Since: 2019-01-15 - Status Note: On a standards track and beginning to influence many mental models, but not yet [ADOPTED](/README.md#rfc-lifecycle). -- Supersedes: [Indy HIPE 0002](https://github.com/hyperledger/indy-hipe/tree/master/text/0002-agents) +- Supersedes: [Indy HIPE 0002](https://github.com/hyperledger/indy-hipe/tree/main/text/0002-agents) - Start Date: 2017-11-01 (approx, backdated) - Tags: [concept](/tags.md#concept) @@ -169,7 +169,7 @@ Here are some thought questions to clarify intent: We said it's hard to provide a recipe for an agent without specifics. However, the majority of agents _do_ have two things in common: they listen to and process A2A messages, and they use a [wallet]( -https://github.com/hyperledger/indy-hipe/blob/master/text/0013-wallets/README.md) +https://github.com/hyperledger/indy-hipe/blob/main/text/0013-wallets/README.md) to manage keys, credentials, and other sensitive material. Unless you have uses cases that involve IoT, cron jobs, or web hooks, your agent is likely to fit this mold. @@ -236,7 +236,7 @@ in the DID Doc of the recipient, and finding an intersection between transports they use, and transports the sender can speak. Line 3 requires the keys of the sender, which would normally be held in a [wallet]( -https://github.com/hyperledger/indy-hipe/blob/master/text/0013-wallets/README.md). +https://github.com/hyperledger/indy-hipe/blob/main/text/0013-wallets/README.md). If you are building this sort of code using Aries technology, you will certainly want to use [Aries Agent SDK]( @@ -253,7 +253,7 @@ or in its Getting Started Guide. * Hang out and ask questions on `#aries` on [chat.hyperledger.org](https://chat.hyperledger.org). * Use the mailing list: [aries@lists.hyperledger.org](mailto:aries@lists.hyperledger.org) -* Follow the Aries Cloud Agent - Python [Getting Started Guide (for developers)](https://github.com/hyperledger/aries-cloudagent-python/tree/master/docs/GettingStartedAriesDev) +* Follow the Aries Cloud Agent - Python [Getting Started Guide (for developers)](https://github.com/hyperledger/aries-cloudagent-python/tree/main/docs/GettingStartedAriesDev) * Study the [Aries Protocol Test Suite](https://github.com/hyperledger/aries-protocol-test-suite) | * Study the sample mobile agent at [github.com/sovrin-foundation/connector-app](https://github.com/sovrin-foundation/connector-app). * Browse other [RFCs](../../index.md). @@ -365,7 +365,7 @@ that gap. ###### Identity Wallets "Identity wallet" is a term that's [carefully defined]( -https://github.com/hyperledger/indy-hipe/blob/master/text/0013-wallets/README.md#what-is-an-identity-wallet) +https://github.com/hyperledger/indy-hipe/blob/main/text/0013-wallets/README.md#what-is-an-identity-wallet) in our ecosystem, and in strict, technical usage it maps to a concept much closer to "database" than "agent". This is because it is an inert storage container, not an active interacter. However, in @@ -398,7 +398,7 @@ A cron job that runs once a night at Faber, scanning a database and revoking credentials that have changes status during the day, is an agent for Faber. This is true even though it doesn't listen for incoming messages (it only talks [revocation protocol]( -https://github.com/hyperledger/indy-hipe/tree/master/text/0011-cred-revocation) to the ledger). In order to +https://github.com/hyperledger/indy-hipe/tree/main/text/0011-cred-revocation) to the ledger). In order to talk that protocol, it must hold keys delegated by Faber, and it is surely Faber's fiduciary. @@ -503,4 +503,4 @@ Name / Link | Implementation Notes [Verity](https://www.evernym.com/products/) | Commercially licensed enterprise agent, SaaS or on-prem. [Aries Protocol Test Suite](https://github.com/hyperledger/aries-protocol-test-suite) | [Pico Labs](http://picolabs.io/) | [Pico Agents](https://github.com/Picolab/G2S) protocols: connections, trust_ping, basicmessage, routing - +[Rust Agent](https://github.com/tatmanblue/rust-aries-agent) | Rust implementation of a framework for building agents of all types diff --git a/concepts/0005-didcomm/README.md b/concepts/0005-didcomm/README.md index 34a9dc78b..14ece200a 100644 --- a/concepts/0005-didcomm/README.md +++ b/concepts/0005-didcomm/README.md @@ -1,7 +1,7 @@ # Aries RFC 0005: DID Communication -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-11-21 - Status Note: Mature as concept, with multiple implementations. - Supersedes: [Indy PR #98](https://github.com/hyperledger/indy-hipe/pull/98) @@ -13,6 +13,8 @@ Explain the basics of __DID communication__ (__DIDComm__) at a high level, and link to other RFCs to promote deeper exploration. +>NOTE: The version of DIDComm collectively defined in Aries RFCs is known by the label "DIDComm V1." A [newer version of DIDComm](https://identity.foundation/didcomm-messaging/spec/) ("DIDComm V2") is now being [incubated](https://github.com/decentralized-identity/didcomm-messaging) at DIF. Many concepts are the same between the two versions, but there are some differences in the details. For information about detecting V1 versus V2, see [Detecting DIDComm Versions](../../features/0044-didcomm-file-and-mime-types/README.md#detecting-didcomm-versions). + ## Motivation The DID communication between [agents](../0004-agents/README.md) and [agent-like things](../0004-agents/README.md#the-agent-ness-continuum) is a rich subject with a lot of tribal @@ -26,14 +28,14 @@ We need a standard high-level reference. >This discussion assumes that you have a reasonable grasp on topics like [self-sovereign identity](https://medium.com/evernym/the-three-models-of-digital-identity-relationships-ca0727cb5186), [DIDs and DID docs](https://w3c-ccg.github.io/did-spec/), and [agents]( -https://github.com/hyperledger/indy-hipe/pull/86). If you find yourself +https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0004-agents/README.md). If you find yourself lost, please review that material for background and starting assumptions. Agent-like things have to interact with one another to get work done. How they talk in general is DIDComm, the subject of this RFC. The specific interactions enabled by DIDComm--connecting and maintaining relationships, issuing credentials, providing proof, etc.--are called __protocols__; they are described [elsewhere]( -https://github.com/hyperledger/indy-hipe/pull/69). +https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/README.md). ### Rough Overview diff --git a/concepts/0006-ssi-notation/README.md b/concepts/0006-ssi-notation/README.md index a05b115ef..aee530b67 100644 --- a/concepts/0006-ssi-notation/README.md +++ b/concepts/0006-ssi-notation/README.md @@ -9,37 +9,19 @@ ## Summary -This RFC describes a simple, standard notation for various concepts related -to independent identity (II) and self-sovereign identity (SSI). (II and SSI -are related but not synonymous, in that IoT things are independent but not -sovereign owners; the RFC covers both but uses SSI in its name as the more -recognized term.) - -The notation could be used in design docs, other RFCs, source code comments, -chat channels, scripts, debug logs, and miscellaneous technical -materials throughout the Aries ecosystem. We hope it is also used in the larger -SSI community. - -This RFC is complementary to the [Sovrin Glossary]( -https://sovrin.org/library/glossary/), which carefully curates terms and their -meanings. We start from the concepts and verbiage defined there. Another -complementary effort is the work to standardize ZKLang (a symbolic -language for representing zero knowledge proof.) +This RFC describes a simple, standard notation for various concepts related to decentralized and self-sovereign identity (SSI). + +The notation could be used in design docs, other RFCs, source code comments, chat channels, scripts, debug logs, and miscellaneous technical materials throughout the Aries ecosystem. We hope it is also used in the larger SSI community. + +This RFC is complementary to official terms like the ones curated in the [TOIP Concepts and Terminology Working group](https://trustoverip.org/working-groups/concepts-and-terminology/), the [Sovrin Glossary]( https://sovrin.org/library/glossary/), and so forth. ## Motivation -All technical materials in our ecosystem hinge on fundamental concepts of -self-sovereign identity such as owners, keys, DIDs, and agents. We need a -standard, documented notation to refer to such things, so we can -use it consistently, and so we can link to the notation's spec for -definitive usage. +All technical materials in our ecosystem hinge on fundamental concepts of self-sovereign identity such as controllers, keys, [DIDs](https://www.w3.org/TR/did-core/), and [agents](../0004-agents/README.md). We need a standard, documented notation to refer to such things, so we can use it consistently, and so we can link to the notation's spec for definitive usage. ## Tutorial -The following explanation is meant to be read sequentially and should provide a -friendly overview for most who encounter the RFC. See the -[Reference section](#reference) -for quick lookup. +The following explanation is meant to be read sequentially and should provide a friendly overview for most who encounter the RFC. See the [Reference section](#reference) for quick lookup. ## Requirements @@ -51,334 +33,151 @@ This notation aims to be: * Easy to learn, understand, guess, and remember * Representable in 7-bit ASCII plain text -The final requirement deserves special comment. Cryptologists are -a major stakeholder in SSI theory. They already have many -notational conventions, some more standardized than others. -Generally, their notation derives from advanced math and uses -specialized symbols and fonts. These experts also tend -to intersect strongly with academic circles, where LaTeX and similar -rendering technologies are common. - -Despite the intersection between SSI, cryptology, and academia, SSI -has to serve a broader audience. Its practicioners are not just -mathematicians; they may include support and IT staff, lawyers -specializing in intellectual property, business people, auditors, -regulators, and individuals sometimes called "end users." In particular, SSI -ecosystems are built and maintained by coders. -Coders regularly write docs in markdown and html. They interact with -one another on chat. They write emails and source code where comments -might need to be embedded. They create UML diagrams. They type in shells. -They paste code into slide decks and word processors. All of these -behaviors militate against a notation that requires complex markup. -Instead, we want something simple, clean, and universally supported. -Hence the 7-bit ASCII requirement. A future version of this RFC, -or an addendum to it, might explain how to map this 7-bit -ASCII notation to various schemes that use mathematical symbols -and are familiar to experts from other fields. - -### Solution - -#### Entities +The final requirement deserves special comment. Cryptologists are a major stakeholder in SSI theory. They already have many notational conventions, some more standardized than others. Generally, their notation derives from advanced math and uses specialized symbols and fonts. These experts also tend to intersect strongly with academic circles, where LaTeX and similar rendering technologies are common. -Entities are the primary actors in the SSI ecosystem. They, at minimum -control but often own their self-sovereign domain. They are not, conceptually -at least, a digital actor. This notation separates the need for an Identity -from the software/hardware that implement the functionality that might -be described by this notation that provides digital identity. Entities -could be a thing that would seem to be a digital actor (ex. self-driving -car), but the notation will still specify both the Entity and other -elements of their domain the provide digital functionality. +Despite the intersection between SSI, cryptology, and academia, SSI has to serve a broader audience. Its practicioners are not just mathematicians; they may include support and IT staff, lawyers specializing in intellectual property, business people, auditors, regulators, and individuals sometimes called "end users." In particular, SSI ecosystems are built and maintained by coders. Coders regularly write docs in markdown and html. They interact with one another on chat. They write emails and source code where comments might need to be embedded. They create UML diagrams. They type in shells. They paste code into slide decks and word processors. All of these behaviors militate against a notation that requires complex markup. -Two types of entities are being defined. Things and Identity Owners. -Each have their own sections below and define their own syntax. +Instead, we want something simple, clean, and universally supported. Hence the 7-bit ASCII requirement. A future version of this RFC, or an addendum to it, might explain how to map this 7-bit ASCII notation to various schemes that use mathematical symbols and are familiar to experts from other fields. -![taxonomy](taxonomy.png) +### Solution -### Identity Owners +#### Controllers and Subjects -In a self-sovereign worldview, the conceptual center of gravity is -__identity owners__. These are people and institutions--the type of -entity that can (at least theoretically) be held legally accountable -for its actions. Identity owners control a __sovereign domain__ that -encompasses all their agents, data, and devices. The notation's first -goal is therefore an efficient and unambiguous way to anchor -derivative concepts to owners and their domains. +An identified thing (the referent of an identifier) is called an __identity subject__. Identity subjects can include: + + * passive things (pets, digital documents, symphonies, rivers, asteroids, strains of bacteria...) + * active things (people, institutions, IoT devices) + +The latter category may also act as an __identity controller__ -- something that projects its intent with respect to identity onto the digital landscape. -Identity owners are denoted with a single -capital ASCII alpha, often corresponding to their first initial. For -example, Alice might be represented as `A`. By preference, the first -half of the alphabet is used (because "x", "y", and "z" tend to have -other ad-hoc meanings). When reading aloud, the spoken form of -a symbol like this is the name of the letter. The relevant [ABNF]( -https://tools.ietf.org/html/rfc5234) fragment is: +When an identity controller controls its own identity, we say that it has __self sovereignty__ -- and we call it a __self__. (The term __identity owner__ was originally used for an identity controller managing itself, but this hid some of the nuance and introduced [legal concepts of ownership that are problematic](https://medium.com/@hackylawyER/do-we-really-want-to-sell-ourselves-the-risks-of-a-property-law-paradigm-for-data-ownership-b217e42edffa), so we'll avoid it here.) + +In our notation, selves (or identity controllers) are denoted with a single *upper-case* ASCII alpha, often corresponding to a first initial of their human-friendly name. For example, Alice might be represented as `A`. By preference, the first half of the alphabet is used (because "x", "y", and "z" tend to have other ad-hoc meanings). When reading aloud, the spoken form of a symbol like this is the name of the letter. The relevant [ABNF]( https://tools.ietf.org/html/rfc5234) fragment is: ```ABNF ucase-alpha = %x41-5A ; A-Z lcase-alpha = %x61-7A ; a-z digit = %x30-39 ; 0-9 - identity-owner = ucase-alpha + self = ucase-alpha ``` -Because the domain of an identity owner is like their private -universe, the name or symbol of an identity owner is often used -to denote a domain as well; context eliminates ambiguity. You -will see examples of this below. - -#### Things - -Identity owners are not the only participants in an SSI ecosystem. -Other participants include Things that control their own domain. -These __entities__ may have a high degree of autonomy (e.g., an AI in -a self-driving car), but they are owned, operated, or controlled in at -least some sense by another party. -Note that non-identity-owner entities also control a __domain__, -but it is not _self-sovereign_. Anywhere that the notation allows domains, -any type of domain is possible. - -Things are denoted with a single lower case ASCII alpha. Can correspond to -the first letter of a larger name for the thing. For example, Car AI could be -`c`. For clarity, it would be best practice to choose letter that don't match -other Identity Owners used in the same description. Identity Owners and Things -differ in character case but using the same letter would often be confusing. +Identity subjects that are not self-controlled are referenced in our notation using a single *lower-case* ASCII alpha. For example, a movie might be `m`. For clarity in scenarios where multiple subjects are referenced, it is best to choose letters that differ in something other than case. ```ABNF - thing = lcase-alpha + controlled = lcase-alpha - entity = identity-owner / thing + subject = self / controlled ``` +The set of devices, keys, endpoints, data, and other resources controlled by or for a given subject is called the subject's __identity domain__ (or just __domain__ for short). When the controller is a self, the domain is __self-sovereign__; otherwise, the domain is __controlled__. Either way, the domain of an identity subject is like its private universe, so the name or symbol of a subject is often used to denote its domain as well; context eliminates ambiguity. You will see examples of this below. + #### Association -Since Entities don't directly act in the SSI Ecosystem; people, -organizations and even things can't of themselves do digital operations -(ex. compute digital signatures). They require software and/or hardware -to do the digital work of their digital Identity. These software/hardware -elements are part of the Entity's domain and serve the master of the domain. -Elements associated with a domain must be named in a way that -makes their association clear, using a `name@context` pattern familiar -from email addresses: `1@A` (“one at A”) is agent 1 in A’s sovereign domain. -(Note how we use an erstwhile identity owner symbol, `A`, to reference a -domain here, but there is no ambiguity.) This fully qualified form of an -entity reference is useful for clarification but is often not necessary. - -In addition to domains, this same associating notation may be used where -a _relationship_ is the context, because sometimes the association is -to the relationship rather than to a participant. See the DID -example in the next section. +Elements associated with a domain are named in a way that makes their association clear, using a `name@context` pattern familiar from email addresses: `1@A` (“one at A”) is agent 1 in A’s sovereign domain. (Note how we use an erstwhile identity owner symbol, `A`, to reference a domain here, but there is no ambiguity.) This fully qualified form of a subject reference is useful for clarification but is often not necessary. + +In addition to domains, this same associating notation may be used where a _relationship_ is the context, because sometimes the association is to the relationship rather than to a participant. See the DID example in the next section. #### Agents -Agents are not Entities. They neither control or own a domain. They -live and act with in a domain. They are always owned and controlled by -Entity and live within the their domain. Agents are the first example -of elements associated with an Entity. Despite this, agents are the -primary source of action with SSI ecosystem. - -Additionally, agents are distinct from devices, even though -we often (and inaccurately) used them interchangeably. We may -say things like "Alice's iPhone sends a message" when we more -precisely mean "the agent on Alice's iPhone sends a message." -In reality, there may be zero, one, or more than one agents -running on a particular device. - -Agents are numbered and are represented by up to three digits and -then with an association. In most discussions, one digit is -plenty, but three digits are allowed so agents can be -conveniently grouped by prefix (e.g., all edge agents in Alice's -domain might begin with `1`, and all cloud might begin with `2`). +Agents are not subjects. They neither control or own a domain; rather, they live and act within it. They take instructions from the domain's controller. Agents ([and hubs, and other things like them](../0004-agents/README.md#the-agent-ness-continuum)) are the first example of elements associated with an identity subject. Despite this, agent-ish things are the primary focus of interactions within SSI ecosystems. + +Additionally, agents are distinct from devices, even though we often (and inaccurately) used them interchangeably. We may say things like "Alice's iPhone sends a message" when we more precisely mean "the agent on Alice's iPhone sends a message." In reality, there may be zero, one, or more than one agents running on a particular device. + +Agents are numbered and are represented by up to three digits and then with an association. In most discussions, one digit is plenty, but three digits are allowed so agents can be conveniently grouped by prefix (e.g., all edge agents in Alice's domain might begin with `1`, and all cloud might begin with `2`). ```ABNF - agent = 1*3digit "@" entity + agent = 1*3digit "@" subject ``` #### Devices -Devices are another example of an element that are part of an Entity's -domain. Devices are digital hardware that are part of an Entity's domain. - -Devices are both represented with two or more -lower-case ASCII alphanumerics or underscore characters, where the -first char cannot be a digit and ended with an association: - `bobs_car@B`, `drone4@F`, `alices_iphone9@A`. +Devices are another element inside a subject's domain. They are represented with two or more lower-case ASCII alphanumerics or underscore characters, where the first char cannot be a digit. They end with an association: `bobs_car@B`, `drone4@F`, `alices_iphone9@A`. ```ABNF name-start-char = lcase-alpha / "_" ; a-z or underscore name-other-char = digit / lcase-alpha / "_" ; 0-9 or a-z or underscore - device = name-start-char 1*name-other-char "@" entity + device = name-start-char 1*name-other-char "@" subject ``` -Agents are distinct from devices, even though -we often (and inaccurately) used them interchangeably. We may -say things like "Alice's iPhone sends a message" when we more -precisely mean "the agent on Alice's iPhone sends a message." -In reality, there may be zero, one, or more than one agents -running on a particular device. - -Agents are numbered and are represented by up to three digits. -In most discussions, one digit is plenty, but three digits are -allowed so agents can be conveniently grouped by prefix (e.g., -all agents in Alice's domain might begin with `1`, and all Bob's -agents might begin with `2`). - - ```ABNF - agent = 1*3digit - ``` -Note that non-identity-owner entities also control a __domain__, -but it is not _self-sovereign_. Anywhere that the notation allows domains, -any type of domain is possible. - ### Cross-Domain Relationships #### Short Form (more common) -Alice’s pairwise relationship with Bob is represented with colon -notation: `A:B`. This is read aloud as “A to B” (preferred because -it’s short; alternatives such as “the A B relationship” or “A colon B” -or “A with respect to B” are also valid). When written in the other order, -it represents the same relationship as seen from Bob’s point of view. -Note that IoT things may also participate in relationships: `A:bobs_car`. -(Contrast [Intra-Domain Relationships](#intra-domain-relationships) below.) +Alice’s pairwise relationship with Bob is represented with colon notation: `A:B`. This is read aloud as “A to B” (preferred because it’s short; alternatives such as “the A B relationship” or “A colon B” or “A with respect to B” are also valid). When written in the other order, it represents the same relationship as seen from Bob’s point of view. Note that passive subjects may also participate in relationships: `A:bobs_car`. (Contrast [Intra-Domain Relationships](#intra-domain-relationships) below.) -N-way relationships (e.g., doctor, hospital, patient) are written with -the perspective-governing entity's identifier, a single colon, then by all other -identifiers for members of the relationship, in alphabetical order, -separated by `+`: `A:B+C`, `B:A+C`. This is read aloud as in "A to B -plus C." +N-wise relationships (e.g., doctor, hospital, patient) are written with the perspective-governing subject's identifier, a single colon, then by all other identifiers for members of the relationship, in alphabetical order, separated by `+`: `A:B+C`, `B:A+C`. This is read aloud as in "A to B plus C." ```ABNF - next-entity = "+" entity - short-relationship = entity ":" entity *next-entity + next-subject = "+" subject + short-relationship = subject ":" subject *next-subject ``` #### Long Form -Short form is convenient and brief, but it is inconsistent because each -party to the relationship describes it differently. Sometimes this may -be undesirable, so a long and consistent form is also supported. The long -form of both pairwise and N-way relationships lists all participants to -the right of the colon, in alphabetical order. Thus the long forms of the -Alice to Bob relationship might be `A:A+B` (for Alice's view of this -relationship) and `B:A+B` (for Bob's view). For a doctor, hospital, -patient relationship, we might have `D:D+H+P`, `H:D+H+P`, and `P:D+H+P`. -Note how the enumeration of parties to the right of the colon is consistent. +Short form is convenient and brief, but it is inconsistent because each party to the relationship describes it differently. Sometimes this may be undesirable, so a long and consistent form is also supported. The long form of both pairwise and N-way relationships lists all participants to the right of the colon, in alphabetical order. Thus the long forms of the Alice to Bob relationship might be `A:A+B` (for Alice's view of this relationship) and `B:A+B` (for Bob's view). For a doctor, hospital, patient relationship, we might have `D:D+H+P`, `H:D+H+P`, and `P:D+H+P`. Note how the enumeration of parties to the right of the colon is consistent. -Long form and short form are allowed to vary freely; any tools that parses -this notation should treat them as synonyms and stylistic choices only. +Long form and short form are allowed to vary freely; any tools that parses this notation should treat them as synonyms and stylistic choices only. -The ABNF for long form is identical to short form, except that we are -guaranteed that after the colon, we will see at least two parties and -one `+` character: +The ABNF for long form is identical to short form, except that we are guaranteed that after the colon, we will see at least two parties and one `+` character: ```ABNF - long-relationship = entity ":" entity 1*next-entity + long-relationship = subject ":" subject 1*next-subject ``` #### Generalized Relationships -Some models for SSI emphasize the concept of __personas__. These are -essentially "masks" that an identity owner assumes, exposing a limited -subset of self to a generalized audience. For example, Alice might assume -one persona in her employment relationships, another for government -interactions, another for friends, and another when she's a customer. -(The wisdom of personas versus pairwise relationships is a matter of -some debate.) +##### Contexts +Some models for SSI emphasize the concept of __personas__ or __contexts__. These are essentially "masks" that an identity controller enables, exposing a limited subset of the subject's identity to an audience that shares that context. For example, Alice might assume one persona in her employment relationships, another for government interactions, another for friends, and another when she's a customer. -Personas can be modeled as a relationship with a generalized audience: -`A:Work`, `A:Friends`. +Contexts or personas can be modeled as a relationship with a generalized audience: `A:Work`, `A:Friends`. ```ABNF general-audience = ucase-alpha 1*name-other-char - general-relationship = entity ":" general-audience + general-relationship = subject ":" general-audience relationship = short-relationship / long-relationship / general-relationship ``` -The concept of public DIDs suggests that someone may think about a -relationship as unbounded, or as not varying no matter who the other -entity is. For example, a company may create a public DID and advertise -it to the world, intending for this connection point to begin relationships -with customers, partners, and vendors alike. While best practice suggests -that such relationships be used with care, and that they primarily serve to -bootstrap pairwise relationships, the notation still needs to represent the -possibility. - -The [token `Any` is reserved](#reserved-tokens) for these semantics. If Acme Corp -is represented as `A`, then Acme's public persona could be denoted with -`A:Any`. When `Any` is used, it is never the entity whose perspective is -captured; it is always a faceless "other". This means that `Any` appears -only on the right side of a colon in a relationship, and it probably doesn't -make sense to combine it with other participants since it would subsume them -all. +##### Any -### Intra-Domain Relationships +The concept of public DIDs suggests that someone may think about a relationship as unbounded, or as not varying no matter who the other subject is. For example, a company may create a public DID and advertise it to the world, intending for this connection point to begin relationships with customers, partners, and vendors alike. While best practice suggests that such relationships be used with care, and that they primarily serve to bootstrap pairwise relationships, the notation still needs to represent the possibility. -Within a domain, relationships among agents or devices may be interesting. Such -relationships use the `~` (tilde) character. Thus, the intra-domain relationship -between Alice's agent 1 and agent 2 could be written `1~2` and read as "one tilde two". +The [token `Any` is reserved](#reserved-tokens) for these semantics. If Acme Corp is represented as `A`, then Acme's public persona could be denoted with `A:Any`. When `Any` is used, it is never the subject whose perspective is captured; it is always a faceless "other". This means that `Any` appears only on the right side of a colon in a relationship, and it probably doesn't make sense to combine it with other participants since it would subsume them all. +##### Self -### Association +It is sometimes useful to model a relationship with onesself. This is done with the reserved token `Self`. -Entities associated with a domain may be named in a way that -makes that association clear, using a `name@context` pattern familiar -from email addresses: `1@A` (“one at A”) is agent 1 in A’s sovereign domain. -(Note how we use an erstwhile identity owner symbol, `A`, to reference a -domain here, but there is no ambiguity.) This fully qualified form of an -entity reference is useful for clarification but is often not necessary. +### Intra-Domain Relationships -In addition to domains, this same associating notation may be used where -a _relationship_ is the context, because sometimes the association is -to the relationship rather than to a participant. See the DID -example in the next section. +Within a domain, relationships among agents or devices is sometimes interesting. Such relationships use the `~` (tilde) character. Thus, the intra-domain relationship between Alice's agent 1 and agent 2 is written `1~2` and read as "one tilde two". -### Inert Items +### Constituents -In contrast to entities that may be capable of independent action -and that may have identities in an II or SSI sense, inert or passive -constituents of a sovereign domain (for example, data, money, keys) -use dot notation for ownership: `A.ls`, (A’s link secret), `A.policy`, -etc. +Items that belong to a domain rather than having independent identity of their own (for example, data, money, keys) use dot notation for containment or ownership: `A.ls`, (A’s link secret), `A.policy`, etc. -Names for inert things use the same rules as names for agents and devices. +Names for constituents use the same rules as names for agents and devices. -Alice’s DID for her relationship with Bob is inert and therefore owned, but -it is properly associated with the relationship rather than just Alice. It is -thus represented with `A.did@A:B`. (The [token `did` is reserved](#reserved-tokens) -for DIDs). This is read as “A’s DID at A to B”. Bob’s complementary DID would -be `B.did@B:A`. +Alice’s DID for her relationship with Bob is an inert constituent datum, but it is properly associated with the relationship rather than just Alice. It is thus represented with `A.did@A:B`. (The [token `did` is reserved](#reserved-tokens) for DIDs). This is read as “A’s DID at A to B”. Bob’s complementary DID would be `B.did@B:A`. ```ABNF inert = name-start-char 1*name-other-char nested = "." inert - owned-inert = entity 1*nested + owned-inert = subject 1*nested associated-to = identity-owner / relationship - associated = entity 0*nested "@" associated-to + associated = subject 0*nested "@" associated-to ``` -If `A` has a cloud agent `2`, then the public key (verification key or verkey) -and private, secret key (signing key or sigkey) used by -`2` in `A:B` would be: `2.pk@A:B` and `2.sk@A:B`. This is read as “2 -dot P K at A to B” and “2 dot S K at A to B”. Here, `2` is known to -belong to `A` because it takes `A`’s perspective on `A:B`--it would -be equivalent but unnecessary to write `A.2.pk@A:B`. +If `A` has a cloud agent `2`, then the public key (verification key or verkey) and private, secret key (signing key or sigkey) used by `2` in `A:B` would be: `2.pk@A:B` and `2.sk@A:B`. This is read as “2 dot P K at A to B” and “2 dot S K at A to B”. Here, `2` is known to belong to `A` because it takes `A`’s perspective on `A:B`--it would be equivalent but unnecessary to write `A.2.pk@A:B`. ### DID Docs and DID References -The mention of keys belonging to agents naturally raises the question of DID -Docs and the things they contain. How do they relate to our notaiton? -[DIDs are designed to be URIs]( -https://w3c-ccg.github.io/did-spec/#generic-did-syntax), and items that carry -an `id` property within a DID Doc [can be referenced with standard URI fragment -notation]( https://w3c-ccg.github.io/did-spec/#fragments). This allows someone, for example, -to refer to the first public key used by one of the agents owned by Alice with -a notation like: `did:sov:VUrvFeWW2cPv9hkNZ2ms2a;#key1`. - -This notation is important and useful, but it is somewhat orthogonal to the concerns -of this RFC. In the context of SSI notation, we are not DID-centric; we are -owner centric, and owners are identified by a single capital alpha instead of -by their DID. This helps with brevity. It lets us ignore the specific DID value -and instead focus on the higher level semantics; compare: +The mention of keys belonging to agents naturally raises the question of DID docs and the things they contain. How do they relate to our notation? + +[DIDs are designed to be URIs]( https://w3c-ccg.github.io/did-spec/#generic-did-syntax), and items that carry an `id` property within a DID Doc [can be referenced with standard URI fragment notation]( https://w3c-ccg.github.io/did-spec/#fragments). This allows someone, for example, to refer to the first public key used by one of the agents owned by Alice with a notation like: `did:sov:VUrvFeWW2cPv9hkNZ2ms2a;#key1`. + +This notation is important and useful, but it is somewhat orthogonal to the concerns of this RFC. In the context of SSI notation, we are not DID-centric; we are subject centric, and subject are identified by a single capital alpha instead of by their DID. This helps with brevity. It lets us ignore the specific DID value and instead focus on the higher level semantics; compare:
{A.did@A:B}/B --> B
@@ -390,26 +189,15 @@ and instead focus on the higher level semantics; compare: using the agent possessing did:sov:PXqKt8sVsDu9T7BpeNqBfe;#key1 to encrypt with the corresponding signing key. -We expect DID reference notation (the verbose text above) to be relevant for -concrete communication between computers, and SSI notation (the terse equivalent -shown first) to be more convenient for symbolic, higher -level discussions between human beings. Occasionally, we may get very specific -and map SSI notation into DID notation (e.g., `A.1.vk = did:sov:PXqKt8sVsDu9T7BpeNqBfe;#key1`). +We expect DID reference notation (the verbose text above) to be relevant for concrete communication between computers, and SSI notation (the terse equivalent shown first) to be more convenient for symbolic, higher level discussions between human beings. Occasionally, we may get very specific and map SSI notation into DID notation (e.g., `A.1.vk = did:sov:PXqKt8sVsDu9T7BpeNqBfe;#key1`). ### Counting and Iteration -Sometimes, a concept or value evolves over time. For example, a given discussion -might need to describe a DID Doc or an endpoint or a key across multiple -state changes. In mathematical notation, this would typically be modeled with -subscripts. In our notation, we use square brackets, and we number beginning -from zero. `A.pk[0]@A:B` would be the first pubkey used by A in the `A:B` -relationship; `A.pk[1]@A:B` would be the second pubkey, and so on. Likewise, a -sequence of messages could be represented with `msg[0]`, `msg[1]`, and `msg[2]`. +Sometimes, a concept or value evolves over time. For example, a given discussion might need to describe a DID Doc or an endpoint or a key across multiple state changes. In mathematical notation, this would typically be modeled with subscripts. In our notation, we use square brackets, and we number beginning from zero. `A.pk[0]@A:B` would be the first pubkey used by A in the `A:B` relationship; `A.pk[1]@A:B` would be the second pubkey, and so on. Likewise, a sequence of messages could be represented with `msg[0]`, `msg[1]`, and `msg[2]`. ### Messages -Messages are represented as quoted string literals, or with the [reserved token](#reserved-tokens) -`msg`, or with kebab-case names that explain their semantics, as in `cred-offer`: +Messages are represented as quoted string literals, or with the [reserved token](#reserved-tokens) `msg`, or with kebab-case names that explain their semantics, as in `cred-offer`: ```ABNF string-literal = %x22 c-literal %x22 @@ -419,81 +207,27 @@ kebab-msg = 1*kebab-char *kebab-suffix message = "msg" / string-literal / kebab-msg ``` -### Negotiation Patterns +### Payments -A common interaction pattern in SSI ecosystems is negotiation. It involves -sequences like this: +Economic activity is part of rich SSI ecosystems, and requires notation. A __payment address__ is denoted with the [`pay` reserved token](#reserved-tokens); `A.pay[4]` would be A's fifth payment address. The public key and secret key for a payment address use the [`ppk` and `psk` reserved token](#reserved-tokens), respectively. Thus, one way to reference the payment keys for that payment address would be `A.pay[4].ppk` and `A.pay[4].psk`. (Keys are normally held by agents, not by people--and every agent has its own keys. Thus, another notation for the public key pertaining to this address might be `A.1.pay[4].ppk`. This is an area of clumsiness that needs further study.) -![negotiation pattern](negotiation-pattern.png) +### Encryption -Credential issuance follows this pattern: credential offer (step 1a) is either -followed by an incompatible credential request (1b)--and this pair of messages -repeats as needed--or by a compatible credential request (2). A credential is -then issued (3). Possibly the holder of the credential acknowledges receipt (4). +Encryption deserves special consideration in the SSI world. It often figures prominently in discussions about security and privacy, and our notation needs to be able to represent it carefully. -Proving follows this pattern (though it nearly always begins with a request). -Connections follow this pattern. Price negotiations follow this pattern. +The following crypto operations are recognized by the notation, without making a strong claim about how the operations are implemented. (For example, inline Diffie Helman and an ephemeral symmetric key might be used for the *_crypt algorithms. What is interesting to the notation isn't the low-level details, but the general semantics achieved.) -The notation [reserves standard kebab suffixes](#reserved-tokens) on messages to -make this pattern obvious and consistent: `-offer` (step 1a), `-req` (step 1b -or 2), and `-receipt` (step 4). Step 3 is typically named without a suffix. -Thus: `proof-offer`, `proof-request`, `proof` (no suffix), `proof-receipt`. +* `anon_crypt(msg, recipient_pubkey)` -- Encrypt only for recipient, achieving confidentiality. Sender is anonymous. Parties may have had no prior contact, though sender must discover recipient's pubkey. The message is tamper evident. -### Payments +* `auth_crypt(msg, recipient_pubkey, sender_privkey)` -- Encrypt only for recipient, achieving confidentiality. Recipient learns sender’s pubkey but can’t prove to anybody else who the sender is (making the message repudiable). Parties may have had no prior contact, though sender must discover recipient's pubkey. The message is tamper evident. -Economic activity is part of rich SSI ecosystems, and requires notation. A -__payment address__ is denoted with the [`pay` reserved token](#reserved-tokens); -`A.pay[4]` would be A's fifth payment address. -The public key and secret key for a payment address use the -[`ppk` and `psk` reserved token](#reserved-tokens), respectively. Thus, one way to reference -the payment keys for that payment address would be `A.pay[4].ppk` and -`A.pay[4].psk`. (Keys are normally held by agents, not by people--and every -agent has its own keys. Thus, another notation for the public key -pertaining to this address might be `A.1.pay[4].ppk`. This is an area of -clumsiness that needs further study.) +* `sign(msg, signer_privkeys)` -- Associate a signature with a message, making the message [non-repudiable](../0049-repudiation/README.md). This also makes the message tamper-evident. A signature does not automatically encrypt and therefore is not a way to achieve confidentiality. Note that complex signature schemes (multisig, M of N, ring) use this operation as well. -### Encryption +* `verify(msg, signature, signer_pubkeys)` -- Verify a signature over a message with select keys. Note that complex verification schemes (multiverify, M of N, ring) use this operation as well. -Encryption deserves special consideration in the SSI world. It often figures -prominently in discussions about security and privacy, and our notation needs -to be able to represent it carefully. - -The following crypto operations are recognized by the notation, without -making a strong claim about how the operations are implemented. (For -example, inline Diffie Helman and an ephemeral symmetric key might be -used for the *_crypt algorithms. What is interesting to the notation -isn't the low-level details, but the general semantics achieved.) - -* `anon_crypt(msg, recipient_pubkey)` -- Encrypt -only for recipient, achieving confidentiality. Sender is anonymous. -Parties may have had no prior contact, though sender must discover -recipient's pubkey. The message is tamper evident. -* `auth_crypt(msg, recipient_pubkey, sender_privkey)` -- Encrypt -only for recipient, achieving confidentiality. Recipient -learns sender’s pubkey but can’t prove to anybody else who the sender -is (making the message repudiable). Parties may have had no prior contact, -though sender must discover recipient's pubkey. -The message is tamper evident. -* `sign(msg, signer_privkeys)` -- Associate a signature with a -message, making the message [non-repudiable]( -https://github.com/sovrin-foundation/protocol/blob/master/janus/repudiation.md). -This also makes the message tamper-evident. A signature does not -automatically encrypt and therefore is not a way to achieve -confidentiality. Note that complex signature schemes (multisig, M of N, ring) -use this operation as well. -* `verify(msg, signature, signer_pubkeys)` -- Verify a signature over a -message with select keys. Note that complex verification schemes -(multiverify, M of N, ring) use this operation as well. -* `sym_crypt(msg, sym_key)` -- Symmetrically encrypt for anyone -who has the symmetric key, achieving a limited form of confidentiality. -Key must be shared in advance with both parties. Likely tamper -evident. If multiple parties know the symmetric key, the sender is -not knowable to the recipient. - -The notation for these crypto primitives uses curly braces around the -message, with suffixes to clarify semantics. Generally, -it identifies a recipient as an identity owner or thing, without clarifying -the key that's used--the pairwise key for their DID is assumed. +* `sym_crypt(msg, sym_key)` -- Symmetrically encrypt for anyone who has the symmetric key, achieving a limited form of confidentiality. Key must be shared in advance with both parties. Likely tamper evident. If multiple parties know the symmetric key, the sender is not knowable to the recipient. + +The notation for these crypto primitives uses curly braces around the message, with suffixes to clarify semantics. Generally, it identifies a recipient as an identity owner or thing, without clarifying the key that's used--the pairwise key for their DID is assumed. ```ABNF asymmetric = "/" ; suffix @@ -502,133 +236,84 @@ sign = "#" ; suffix multiplex = "%" ; suffix verify = "?" ; suffix -anon-crypt = "{" message "}" asymmetric entity ; e.g., {"hi"}/B +anon-crypt = "{" message "}" asymmetric subject ; e.g., {"hi"}/B - ; sender is first entity in relationship, receiver is second + ; sender is first subject in relationship, receiver is second auth-crypt = "{" message "}" asymmetric short-relationship ; e.g., {"hi"}/A:B -sym-crypt = "{" message "}" symmetric entity ; e.g., {"hi"}*B +sym-crypt = "{" message "}" symmetric subject ; e.g., {"hi"}*B -verify = "{" message "}" verify entity ; e.g., {"hi"}?B +verify = "{" message "}" verify subject ; e.g., {"hi"}?B ``` -The relative order of suffixes reflects whether encryption or -signing takes place first: `{"hello"}*B#` says that symmetric -encryption happens first, and then a signature is computed over -the cypertext; `{"hello"#}*B` says that plaintext is signed, and -then both the plaintext and the signature are encrypted. (The -`{"hello"}#*B` variant is nonsensical because it splits the -encryption notation in half). - -All suffixes can be further decorated with a parenthesized algorithm -name, if precision is required: `{"hello"}*(aes256)B` or -`{"hello"}/(rsa1024)A:B` or `{"hello"#(ecdsa)}/B`. - -With signing, usually the signer and sender are assumed to be identical, -and the notation omits any clarification about the signer. However, -this can be added after `#` to be explicit. Thus, `{msg#B}/C` would be -a message with plaintext signed by B, anon-encrypted for C. Similarly, -`{msg#(ring-rabin)BGJM}/A:C` would be a message with plaintext signed -according to a Rabin ring signature algorithm, by B, G, J, and M, and -then auth-encrypted by A for C. - -Signing verification would be over the corresponding message and which -entities perform the action. `{msg#A}?B` would be a message with plaintext -signed by A verified by B. `{msg#(threshold-sig)ABC}?DE` would be a plaintext -message signed according to a threshold signature algorithm by A, B, C -and then verified by D and E. - -Multiplexed asymmetric encryption is noted above, but has not yet been -described. This is a technique whereby a message body is encrypted with -an ephemeral symmetric key, and then the ephemeral key is encrypted -asymmetrically for multiple potential recipients (each of which has a unique -but tiny payload [the key] to decrypt, which in turn unlocks the main payload). The -notation for this looks like `{msg}%BCDE` for multiplexed anon\_crypt (sender -is anonymous), and like `{msg}%A:BCDE` for multiplexed auth\_crypt (sender -is authenticated by their private key). +The relative order of suffixes reflects whether encryption or signing takes place first: `{"hello"}*B#` says that symmetric encryption happens first, and then a signature is computed over the cypertext; `{"hello"#}*B` says that plaintext is signed, and then both the plaintext and the signature are encrypted. (The `{"hello"}#*B` variant is nonsensical because it splits the encryption notation in half). + +All suffixes can be further decorated with a parenthesized algorithm name, if precision is required: `{"hello"}*(aes256)B` or `{"hello"}/(rsa1024)A:B` or `{"hello"#(ecdsa)}/B`. + +With signing, usually the signer and sender are assumed to be identical, and the notation omits any clarification about the signer. However, this can be added after `#` to be explicit. Thus, `{msg#B}/C` would be a message with plaintext signed by B, anon-encrypted for C. Similarly, `{msg#(ring-rabin)BGJM}/A:C` would be a message with plaintext signed according to a Rabin ring signature algorithm, by B, G, J, and M, and then auth-encrypted by A for C. + +Signing verification would be over the corresponding message and which entities perform the action. `{msg#A}?B` would be a message with plaintext signed by A verified by B. `{msg#(threshold-sig)ABC}?DE` would be a plaintext message signed according to a threshold signature algorithm by A, B, C and then verified by D and E. + +Multiplexed asymmetric encryption is noted above, but has not yet been described. This is a technique whereby a message body is encrypted with an ephemeral symmetric key, and then the ephemeral key is encrypted asymmetrically for multiple potential recipients (each of which has a unique but tiny payload [the key] to decrypt, which in turn unlocks the main payload). The notation for this looks like `{msg}%BCDE` for multiplexed anon\_crypt (sender is anonymous), and like `{msg}%A:BCDE` for multiplexed auth\_crypt (sender is authenticated by their private key). ### Other punctuation -Message sending is represented with arrows: `->` is most common, though `<-` -is also reasonable in some cases. Message content and notes about sending -can be embedded in the hyphens of sending arrow, as in this example, where -the notation says an unknown party uses http to transmit "hello", anon-enrcypted -for Alice: +Message sending is represented with arrows: `->` is most common, though `<-` is also reasonable in some cases. Message content and notes about sending can be embedded in the hyphens of sending arrow, as in this example, where the notation says an unknown party uses http to transmit "hello", anon-enrcypted for Alice: ``` -- http: {"hello"}/A --> 1``` -Parentheses have traditional meaning (casual usage in written language, plus -grouping and precedence). +Parentheses have traditional meaning (casual usage in written language, plus grouping and precedence). -Angle braces `<` and `>` are for placeholders; any -reasonable explanatory text may appear inside the angle braces, so to -represent Alice's relationship with a not-yet-known entity, the notation -might show something like `A:`. +Angle braces `<` and `>` are for placeholders; any reasonable explanatory text may appear inside the angle braces, so to represent Alice's relationship with a not-yet-known subject, the notation might show something like `A:`. ## Reference ### Examples -* `A`: an identity owner like Alice or Acme Corp. -* `alices_pixel@A` or `bobs_alexa@B`: a device or IoT thing +* `A`: a self (sovereign identity subject) like Alice or Acme Corp. +* `alices_pixel@A` or `bobs_alexa@B`: an object in a given domain * `7@A`: an agent, arbitrarily assigned number 7 -* `A:B` or `A:A+B`: The Alice to Bob relationship, as seen from Alice's perspective (short form, then long form). - Bob's view of this relationship would be `B:A` or `B:A+B`. +* `A:B` or `A:A+B`: The Alice to Bob relationship, as seen from Alice's perspective (short form, then long form). Bob's view of this relationship would be `B:A` or `B:A+B`. * `B:ACD` or `B:A+B+C+D`: The 4-way relationship between A, B, C, and D, as seen from B's perspective (short form, then long form) * `A:Dating`: Alice's dating persona * `A.pay[3].ppk`: The public payment key for the fourth payment address belonging to A. * `F.did@F:Any`: Faber's public DID. * `C.ls`: Carol's link secret. * `D.padr`: Doug's policy address. -* `F.micro@F:A`: F's microledger for the F:A relationship. +* `F.state@F:A`: F's state for the F:A relationship. * `A.uri@A:B`: Alice's URI (endpoint of DID doc) in the Alice to Bob relationship. * `F.uri@F:Any`: The endpoint where the DID doc for Faber's public DID is hosted. -* `escrow-offer`: A message that represents step 1a in a standard negotiation about escrow. - (The escrow concept is unknown to the notation, and we don't know the format of - its messages, but we know they are used in a standard way because of the `-offer` - kebab suffix). +* `escrow-offer`: A message that represents step 1a in a standard negotiation about escrow. (The escrow concept is unknown to the notation, and we don't know the format of its messages, but we know they are used in a standard way because of the `-offer` kebab suffix). * `{msg}/A`: A message anon-encrypted for A. * `{"hello"}/A:B`: A message auth-encrypted for B by A. -* `{bail-req#(p2sh)DF}/(rsa)B`: A message that represents step 1b or step 2 in a standard negotiaion - about bail. This message was signed as plaintext using the p2sh multisig algorithm - by D and F, and was then anon-encrypted for B using an RSA algorithm. -* `{advice-receipt}*A`: A message that that represents step 4 in a - standard negotiaion about advice. The message was symmetrically encrypted - and sent to A. -* `{msg[4]}%C:1+2`: A message (5th in sequence) that was multiplex-encrypted by - C for agents 1 and 2. +* `{bail-req#(p2sh)DF}/(rsa)B`: A message that represents step 1b or step 2 in a standard negotiaion about bail. This message was signed as plaintext using the p2sh multisig algorithm by D and F, and was then anon-encrypted for B using an RSA algorithm. +* `{advice-receipt}*A`: A message that that represents step 4 in a standard negotiaion about advice. The message was symmetrically encrypted and sent to A. +* `{msg[4]}%C:1+2`: A message (5th in sequence) that was multiplex-encrypted by C for agents 1 and 2. ### Reserved Tokens -* `Any`: The name for the public side of a relationship between a - specific entity and the public. -* `did`: The DID belonging to an entity in a given relationship, as in `A.did@A:B` +* `Any`: The name for the public side of a relationship between a specific subject and the public. +* `Self`: The name for one's one identity in a self relationship. +* `did`: The DID belonging to an subject in a given relationship, as in `A.did@A:B` * `ipk` and `isk`: Issuer public (verification) key and issuer secret key. * `key`: A symmetric key. -* `ls`: The link secret belonging to an entity, as in `A.ls`. -* `micro`: The microledger belonging to an entity in a given relationship, as in `A.micro@A:B` +* `ls`: The link secret belonging to an subject, as in `A.ls`. +* `state`: The state belonging to an subject in a given relationship, as in `A.state@A:B` * `msg`: A generic message. * `-offer`: kebab suffix for messages that express willingness to give - something. Step 1a in a [negotiation pattern](#negotiation-patterns). + something. * `padr`: a policy address, as in `F.padr`. * `pay`: A payment address belonging to an identity owner, as in `C.pay`. * `ppk` and `psk`: Payment address public (verification) and secret key (control cryptocurrency). -* `pk`: The public verification key (verkey) portion of an asymmetric - keypair. The more specific form, `vk`, is only recommended if elliptic - curve crypto is specifically intended. -* `-receipt`: kebab suffix for messages that formally acknowledge receipt after - receiving a delivered item. Step 4 in a [negotiation pattern](#negotiation-patterns). -* `-req`: kebab suffix for messages that formally request something. Step 1b or - step 2 in a [negotiation pattern](#negotiation-patterns). +* `pk`: The public verification key (verkey) portion of an asymmetric keypair. The more specific form, `vk`, is only recommended if elliptic curve crypto is specifically intended. +* `-receipt`: kebab suffix for messages that formally acknowledge receipt after receiving a delivered item. +* `-req`: kebab suffix for messages that formally request something. * `rpk` and `rsk`: Revocation public (verification) and secret key. -* `sk`: The private key (privkey, sigkey) portion of an asymmetric - keypair. +* `sk`: The private key (privkey, sigkey) portion of an asymmetric keypair. * `uri`: An endpoint for a relationship, as in `B.uri@A:B` -* `vk`: The public verification key (verkey) portion of an asymmetric - keypair. The more generic form, `pk`, is recommended instead, unless elliptic - curve crypto is specifically intended. -* `wallet`: An identity wallet belonging to an entity. +* `vk`: The public verification key (verkey) portion of an asymmetric keypair. The more generic form, `pk`, is recommended instead, unless elliptic curve crypto is specifically intended. +* `wallet`: An identity wallet belonging to an subject. ### ABNF @@ -641,24 +326,24 @@ name-other-char = digit / lcase-alpha / "_" ; 0-9 or a-z or underscore identity-owner = ucase-alpha thing = lcase-alpha -entity = identity-owner / thing +subject = identity-owner / thing -agent = 1*3digit "@" entity -device = name-start-char 1*name-other-char "@" entity +agent = 1*3digit "@" subject +device = name-start-char 1*name-other-char "@" subject -next-entity = "+" entity -short-relationship = entity ":" entity *next-entity -long-relationship = entity ":" entity 1*next-entity +next-subject = "+" subject +short-relationship = subject ":" subject *next-subject +long-relationship = subject ":" subject 1*next-subject general-audience = ucase-alpha 1*name-other-char -general-relationship = entity ":" general-audience +general-relationship = subject ":" general-audience relationship = short-relationship / long-relationship / general-relationship inert = name-start-char 1*name-other-char nested = "." inert -owned-inert = entity 1*nested +owned-inert = subject 1*nested associated-to = identity-owner / relationship -associated = entity 0*nested "@" associated-to +associated = subject 0*nested "@" associated-to string-literal = %x22 c-literal %x22 kebab-char = lcase-alpha / digit @@ -671,25 +356,22 @@ symmetric = "*" ; suffix sign = "#" ; suffix multiplex = "%" ; suffix -anon-crypt = "{" message "}" asymmetric entity ; e.g., {"hi"}/B +anon-crypt = "{" message "}" asymmetric subject ; e.g., {"hi"}/B - ; sender is first entity in relationship, receiver is second + ; sender is first subject in relationship, receiver is second auth-crypt = "{" message asymmetric short-relationship ; e.g., {"hi"}/A:B -sym-crypt = "{" message "}" symmetric entity ; e.g., {"hi"}*B +sym-crypt = "{" message "}" symmetric subject ; e.g., {"hi"}*B ``` ## Drawbacks -* Creates one more formalism to learn. SSI is already a dense topic with a steep - learning curve. +* Creates one more formalism to learn. SSI is already a dense topic with a steep learning curve. * Creates something that needs to be version-controlled. ## Rationale and alternatives -- Why is this design the best in the space of possible designs? -- What other designs have been considered and what is the rationale for not choosing them? -- What is the impact of not doing this? +- Could use informal verbiage instead. However, it would be inconsistent and poorly documented. ## Prior art diff --git a/concepts/0006-ssi-notation/negotiation-pattern.png b/concepts/0006-ssi-notation/negotiation-pattern.png deleted file mode 100644 index 9fb724959..000000000 Binary files a/concepts/0006-ssi-notation/negotiation-pattern.png and /dev/null differ diff --git a/concepts/0006-ssi-notation/taxonomy.png b/concepts/0006-ssi-notation/taxonomy.png deleted file mode 100644 index 4c4a11e73..000000000 Binary files a/concepts/0006-ssi-notation/taxonomy.png and /dev/null differ diff --git a/concepts/0008-message-id-and-threading/README.md b/concepts/0008-message-id-and-threading/README.md index 495e82767..bbd875dea 100644 --- a/concepts/0008-message-id-and-threading/README.md +++ b/concepts/0008-message-id-and-threading/README.md @@ -1,7 +1,7 @@ # Aries RFC 0008: Message ID and Threading -- Authors: [Daniel Bluhm](daniel.bluhm@sovrin.org), [Sam Curren](sam@sovin.org), [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: [Daniel Bluhm](mailto:daniel.bluhm@sovrin.org), [Sam Curren](mailto:sam@sovin.org), [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) - Since: 2018-10-01 - Status Note: Implemented broadly in Indy, but not yet elsewhere. - Start Date: 2018-08-03 @@ -61,7 +61,8 @@ Message threading will be implemented as a [decorator](../0011-decorators/README "thid": "98fd8d72-80f6-4419-abc2-c65ea39d0f38", "pthid": "1e513ad4-48c9-444e-9e7e-5b8b45c5e325", "sender_order": 3, - "received_orders": {"did:sov:abcxyz":1} + "received_orders": {"did:sov:abcxyz":1}, + "goal_code": "aries.vc.issue" }, "example_attribute": "example_value" } @@ -70,6 +71,10 @@ Message threading will be implemented as a [decorator](../0011-decorators/README The `~thread` decorator is generally required on any type of response, since this is what connects it with the original request. +While not recommended, the initial message of a new protocol instance MAY have an +empty (`{}`) `~thread` item. Aries agents receiving a message with an empty +`~thread` item MUST gracefully handle such a message. + #### Thread object A thread object has the following fields discussed below: @@ -81,16 +86,17 @@ A thread object has the following fields discussed below: from other sender(s) on the thread. (This value is often missing if it is the first message in an interaction, but should be used otherwise, as it provides an implicit ACK.) +* `goal_code`: Optional. See [RFC 0519: Goal Codes](../0519-goal-codes/README.md). #### Thread ID (`thid`) Because multiple interactions can happen simultaneously, it's important to differentiate between them. This is done with a Thread ID or `thid`. -The Thread ID is the Message ID (`@id`) of the first message in the thread. The -first message may or may not declare the `~thread` attribute block; it -does not, but carries an -implicit `thid` of its own `@id`. +If the Thread object is defined and a `thid` is given, the Thread ID is the value +given there. But if the Thread object is not defined in a message, the Thread ID is +implicitly defined as the Message ID (`@id`) of the given message and that message is +the first message of a new thread. #### Sender Order (`sender_order`) diff --git a/concepts/0011-decorators/README.md b/concepts/0011-decorators/README.md index 6d2574559..e92b20217 100644 --- a/concepts/0011-decorators/README.md +++ b/concepts/0011-decorators/README.md @@ -1,7 +1,7 @@ # Aries RFC 0011: Decorators - Authors: Daniel Hardman -- Status: [ACCEPTED](/README.md#accepted) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-01-31 - Status Note: broadly used in Indy, but not yet harmonized with DIF work on hubs. - Start Date: 2018-12-14 diff --git a/concepts/0013-overlays/README.md b/concepts/0013-overlays/README.md index 9a088d9ca..1684d860f 100644 --- a/concepts/0013-overlays/README.md +++ b/concepts/0013-overlays/README.md @@ -1,216 +1,8 @@ # Aries RFC 0013: Overlays -- Authors: Paul Knowles, Dativa -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-05-20 -- Status Note: socialized for many months; no implementations yet +- Authors: Paul Knowles, The Human Colossus Foundation +- Status: [RETIRED](/README.md#retired) +- Since: 2023-01-15 +- Status Note: Although this RFP is in the **retired** status, the use of overlays and the Overlays Capture Architecture (OCA) is active in Aries. This RFP is an early of the OCA specification, and its content is replaced by the [Overlays Capture Architecture Specification](https://oca.colossi.network/specification/). The use of OCA in Aries is described in [RFC 0755: OCA for Aries](../../features/0755-oca-for-aries/README.md). - Start Date: 2018-10-01 - Tags: [concept](/tags.md#concept) - -## Summary - -Describes a standard approach to data capture that separates raw schema -building blocks from additional semantic layers such as data entry business -logic and constraints, knowledge about data sensitivity, and so forth. - -## Motivation - -The post millennial generation has witnessed an explosion of captured data points which has sparked profound possibilities in both Artificial Intelligence (AI) and Internet of Things (IoT) solutions. This has spawned the collective realization that society’s current technological infrastructure is simply not equipped to fully protect personally identifiable information (PII) or to entice corporations to break down internal data silos, streamline data harmonization processes and ultimately resolve worldwide data duplication and storage resource issues. - -The FAIR Data Principles are a set of guiding principles in order to make data findable, accessible, interoperable and reusable (Wilkinson et al., 2016). These principles provide guidance for scientific data management and stewardship and are relevant to all stakeholders in the current digital ecosystem. - -In line with the FAIR principles, data harmonization and interoperability processes between internal departments and functions is a high priority for companies but the current cognitive framework available for global data capture is hampered by limitations to the foundational data object architecture. - -## Tutorial - -In terms of creating a fully-fledged decentralized data economy, we are still in the early turbulent stages of business, legal and technological innovation with gaps, grey areas and required revision aplenty but, one thing is for certain, we are heading into an era where siloed data ownership will be superseded by consented access to subsets of decentralized data. - -Data-centric innovation points to a future society where new values and services will be created continuously, making people’s lives more conformable and sustainable. Developing and deploying the right data capture architecture will improve the quality of externally pooled data for future AI and IoT solutions. The Overlays Data Capture Architecture (ODCA) was conceived for this purpose. - -### Overlays Data Capture Architecture (ODCA) - -ODCA is a standardized global solution for data capture and exchange which protects PII data and provides a positive alternative to current architectures. - -A schema, a machine-readable definition of the semantics of a data structure, is typically created as a single data object. However, ODCA represents a schema as a multi-dimensional object consisting of a stable schema base and linked overlays, data objects that provide additional extensions, coloration, and functionality to the base object. Any sponsor can use a pre-existing schema base and build their own suite of linked overlays to add extra context to transform how information is displayed to a viewer or to guide an agent in how to apply a custom process to schema data. - -ODCA was primarily devised for data object interoperability and privacy compliant data sharing. The architecture promises to significantly enhance the ability to pool data more effectively in terms of simplicity, accuracy, and allocation of resources. The degree of separation between schema bases and overlays allows multiple parties to use the same base objects for similar data capture requirements thus providing a standard base from which to decentralize data. - -![Figure 1: Muliple overlays developed by different organizations to provide a set of metadata that adequately describes a single set of data](figure-1.png) - -ODCA offers many advantages, including: - -1. Data pooling. Decoupling can occur at any time as overlays are linked objects. With all coloration stored in the overlays, combining data from related sources becomes much easier. Overlays can be removed from the base objects before the data merging process begins and reapplied to ensure consistent coloration post data pooling. -2. Stable schema bases. Most schema updates tend to be done at the application layer. In the case of ODCA, all extension, coloration, and functionality definitions are applied in the overlays. This enables issuers to edit one or more of the linked objects to create simple updates rather than having to reissue schema bases on an ongoing basis. -3. PII encryption. Using the Blinding Identity Taxonomy (BIT) as a reference [see section below], issuers can flag PII attributes in the schema base. With PII attributes flagged at the base object layer, all corresponding data can be treated as sensitive throughout the data lifecycle and encrypted or removed at any stage. This ensures that data protection of personal data is guaranteed as entity identification is impossible. -4. Data decentralization. ODCA enables schema base definitions to remain in their purest form thus providing a standard base from which to decentralize data. Organizations wishing to contribute data to a decentralized data lake for consented third-party usage can capture data using generic open source schema bases. This ensures that data standardization is done prior to any data lake migration. - -#### BLINDING IDENTITY TAXONOMY (BIT) - -Internet-related services and social media companies founded in the late ‘90s and early ‘00s triggered a digital hoarding revolution with large amounts of personal data captured and stored in corporate data silos under centralized control. Silicon Valley’s largest technology companies have subsequently seen revenue figures soar through deployed marketing tools built to enable third party vendors to target subsets of individuals according to dynamic criteria searches. Revenue models have tended to rely heavily on these targeted advertising mechanisms which has encouraged an unparalleled corporate drive for data ownership. - -Corporate responsibility regarding data privacy should have escalated in parallel with the relentless drive for data ownership but, until the General Data Protection Regulation (GDPR) came into force in May 2018, strong legislation was not in place to prevent the unethical distribution of personal data. - -GDPR is a set of laws that provide a legal framework for the data protection and privacy of all individuals within the European Union (EU) and the European Economic Area (EEA) whilst also addressing the export of personal data outside the EU and EEA areas. It aims to empower individuals by improving their right to self-determination regarding their personal data. However well intentioned, GDPR does not sufficiently define a concrete list of PII elements which is problematic when it comes to tech implementation and personal data processing. - -The Blinding Identity Taxonomy (BIT) was created to define a list of elements that could potentially unblind the identity of a person, an organization, or a thing. - -![Figure 2: The Blinding Identity Taxonomy is a list of 46 PII elements that could potentially unblind the identity of a person, an organization, or a thing.](figure-2.png) - -The BIT is one of those critical pieces of behind-the-scenes plumbing that is expected to fundamentally improve data protection of personal data as deployment rates in both traditional and distributed ledger technology (DLT) domains rise. - -In terms of ODCA implementation, issuers can reference the BIT and flag PII attributes in the schema bases. With PII attributes flagged at the base object layer, all corresponding data can be treated as sensitive throughout the data lifecycle and encrypted or removed at any stage, making identifying individuals impossible and thus guaranteeing their privacy. - -The BIT resides with Kantara Initiative, a non-profit industry consortium and professional trade association dedicated to advancing technical and legal innovation and trust framework operations related to digital identity management and data privacy. - -The latest version of the BIT is available at: - ->https://kantarainitiative.org/confluence/display/infosharing/Blinding+Identity+Taxonomy - -### Background - -In conjunction with the exponential rise of data capture, Satoshi Nakamoto’s groundbreaking white paper “Bitcoin: A Peer-to-Peer Electronic Cash System” was published in November 2008 triggering a peer-to-peer (P2P) computing revolution where files and transaction proofs could be shared directly between network nodes without the need of a central server. In 2009, Bitcoin became the first cryptocurrency to utilize a decentralized ledger to keep a record of all transactions taking place across a P2P network. It was not until the launch of Ethereum in July 2015, that the foundational technology, “blockchain”, would feature smart contract functionality giving rise to a golden age of DLT solutions that continue to mould a decentralized data economy. - -DLT solutions will continue to drive uniform data processing mechanisms, verifiable proof of consent, secure data portability and self-sovereign identity (SSI). With ODCA, a standardized global solution for data capture and exchange, community driven data standards, interoperable data capture objects and PII encryption capability can also be realized. - -It is ultimately a combination of these ingredients that will enable an improved ontology-driven approach to data management allowing data to be decentralized and better AI and IoT solutions to be built for societal benefit. - -### Methods - -Rather than a schema being created as a single data object, ODCA represents a schema as a multi-dimensional object consisting of a schema base and linked overlays. Each of these data objects serve a specific function in the overall schema definition which, when amalgamated, provide a set of metadata that adequately describes a single set of data. - -Each data object contains its own decentralized identifier (DID), a new type of identifier that is globally unique, resolvable with high availability, and cryptographically verifiable. In order for an overlay to be linked to a schema base, the DID of the base object must be referenced in the metadata block of the overlay. In other words, a linked overlay will contain both its own DID and, for coupling purposes, the DID of the schema base. - -#### Schema Base - -A schema base is a stable base object that defines a single set of data in its purest form thus providing a standard base from which to decentralize data. - -Apart from any metadata relating to the object, attribute names and types are defined in the schema base. The construct also facilitates a PII schema object which allows the issuer to flag PII attributes. With PII attributes flagged at the base layer, all corresponding data can be treated as sensitive throughout the data lifecycle and encrypted or removed at any stage thus protecting the identity of captured data subjects. - -The DID of the schema base is contained in the metadata and allows the object to remain immutable and interoperable in both traditional and DLT environments. - -![Figure 3: Example of a Schema Base. Attribute names and types are defined in the schema base. The construct also facilitates a PII schema object for flagging PII attributes.](figure-3.png) - -#### Source Overlay - -A source overlay is an optional linked object that can be used to specify an endpoint path containing a dynamic variable whose address is determined when the program is run. - -DIDs for both the overlay and associated schema base are referenced in the metadata block of the source overlay. The DID for the schema base can then be used as a coupling point to link the two data objects. - -#### Encode Overlay - -An encode overlay is a core linked object that can be used to specify a character encoding standard (e.g. UTF-8, ISO-8859-1, Windows-1251, Base58Check, etc.) or character set (e.g. English, Japanese, Arabic, etc.) for the schema. - -DIDs for both the overlay and associated schema base are referenced in the metadata block of the encode overlay. The DID for the schema base can then be used as a coupling point to link the two data objects. - -#### Entry Overlay - -An entry overlay is a core linked object that can be used to add predefined field values in a specified language to schema attributes. - -DIDs for both the overlay and associated schema base are referenced in the metadata block of the entry overlay. The DID for the schema base can then be used as a coupling point to link the two data objects. - -![Figure 4: Example of an entry overlay. Predefined field values are defined in an entry overlay.](figure-4.png) - -#### Label Overlay - -A label overlay is a core linked object that can be used to add labels in a specified language to schema attributes and categories. - -DIDs for both the overlay and associated schema base are referenced in the metadata block of the label overlay. The DID for the schema base can then be used as a coupling point to link the two data objects. - -![Figure 5: Example of a label overlay. Labels for schema attributes and categories are defined in a label overlay.](figure-5.png) - -#### Format Overlay - -A format overlay is a core linked object that can be used to add formats and field lengths to schema attributes. - -DIDs for both the overlay and associated schema base are referenced in the metadata block of the format overlay. The DID for the schema base can then be used as a coupling point to link the two data objects. - -#### Conditional Overlay - -A conditional overlay is an optional linked object that can be used to add simple conditional logic within the schema definition to trigger certain actions. - -DIDs for both the overlay and associated schema base are referenced in the metadata block of the conditional overlay. The DID for the schema base can then be used as a coupling point to link the two data objects. - -![Figure 6: Example of a conditional overlay. Simple conditional logic can be added to the schema definition to trigger certain actions. The logic is defined in a conditional overlay.](figure-6.png) - -#### Subset Overlay - -A subset overlay is an optional linked object that can be used to create a schema subset. - -DIDs for both the overlay and associated schema base are referenced in the metadata block of the subset overlay. The DID for the schema base can then be used as a coupling point to link the two data objects. - -![Figure 7: Example of a subset overlay. A schema subset is defined in a subset overlay.](figure-7.png) - -#### Sensitive Overlay (Holder Only) - -In contrast to other overlay types which are assigned by an issuer, a sensitive overlay is an optional object assigned by the data holder that can be used to flag user-defined sensitive attributes. For example, gender is not defined as a PII element in its most common presentation of male or female as, in isolation, it cannot identify an individual. However, Thailand has 18 different gender identities that are recognized in the local lexicon and, as such, may be deemed as sensitive to a Thai citizen. In this case, a sensitive overlay could be coupled to a data vault on a personal device or a data repository held by a trusted agent to flag the element. - -![Figure 8: Example of a sensitive overlay. User-defined sensitive attributes are defined in a sensitive overlay by the data holder. Rather than coupling the object to a schema base, a sensitive overlay can be coupled to a data vault on a personal device or a data repository held by a trusted agent.](figure-8.png) - -### Conclusion - -Primarily devised for data object interoperability and privacy compliant data sharing, ODCA significantly enhances the ability to pool data more effectively in terms of simplicity, accuracy, and allocation of resources. The degree of separation between schema bases and overlays allows multiple parties to use the same base objects for similar data capture requirements thus providing a standard base from which to decentralize data. - -ODCA aims to provide a standardized global solution for data capture and exchange which can facilitate a global decentralized lake containing non-PII data to be used for societal benefit. - -## Reference - -Provide guidance for implementers, procedures to inform testing, -interface definitions, formal function prototypes, error codes, -diagrams, and other technical details that might be looked up. -Strive to guarantee that: - -- Interactions with other features are clear. -- Implementation trajectory is well defined. -- Corner cases are dissected by example. - -## Drawbacks - -Why should we *not* do this? - -## Rationale and alternatives - -- Why is this design the best in the space of possible designs? -- What other designs have been considered and what is the rationale for not -choosing them? -- What is the impact of not doing this? - -## Prior art - -Discuss prior art, both the good and the bad, in relation to this proposal. -A few examples of what this can include are: - -- Does this feature exist in other SSI ecosystems and what experience have -their community had? -- For other teams: What lessons can we learn from other attempts? -- Papers: Are there any published papers or great posts that discuss this? -If you have some relevant papers to refer to, this can serve as a more detailed -theoretical background. - -This section is intended to encourage you as an author to think about the -lessons from other implementers, provide readers of your proposal with a -fuller picture. If there is no prior art, that is fine - your ideas are -interesting to us whether they are brand new or if they are an adaptation -from other communities. - -Note that while precedent set by other communities is some motivation, it -does not on its own motivate an enhancement proposal here. Please also take -into consideration that Aries sometimes intentionally diverges from common -identity features. - -## Unresolved questions - -- What parts of the design do you expect to resolve through the -enhancement proposal process before this gets merged? -- What parts of the design do you expect to resolve through the -implementation of this feature before stabilization? -- What related issues do you consider out of scope for this -proposal that could be addressed in the future independently of the -solution that comes out of this doc? - -## Implementations - -The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. - -Name / Link | Implementation Notes ---- | --- - | | diff --git a/concepts/0017-attachments/README.md b/concepts/0017-attachments/README.md index 393c69caa..2e193e236 100644 --- a/concepts/0017-attachments/README.md +++ b/concepts/0017-attachments/README.md @@ -1,8 +1,8 @@ # Aries RFC 0017: Attachments -- Authors: [Daniel Hardman](daniel.hardman@gmail.com), Sam Curren, Andrew Whitehead -- Status: [ACCEPTED](/README.md#accepted) -- Since: 2019-01-31 +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com), Sam Curren, Andrew Whitehead +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 - Status Note: Used in a number of other RFCs. - Start Date: 2018-12-24 - Tags: [concept](/tags.md#concept) @@ -136,7 +136,7 @@ manifest like this: Embedding is a less direct mechanism than inlining, because the data is no longer readable by a human inspecting the message; it is -base64-encoded instead. A benefit of this approach is that the data +base64url-encoded instead. A benefit of this approach is that the data can be any MIME type instead of just JSON, and that the data comes with useful metadata that can facilitate saving it as a separate file. @@ -235,11 +235,11 @@ in a schema. There are multiple ways to include content in an attachment. Only one method should be used per attachment. -#### base64 +#### base64url -Base64 content encoding is an obvious choice for any content different than JSON. +This content encoding is an obvious choice for any content different than JSON. You can embed content of any type using this method. Examples are plentiful -throughout the document. +throughout the document. Note that this encoding is always [base64url encoding, not plain base64](https://tools.ietf.org/html/rfc4648#section-5), and that padding is not required. Code that reads this encoding SHOULD tolerate the presence or absence of padding and base64 versus base64url encodings equally well, but code that writes this encoding SHOULD omit the padding to guarantee alignment with encoding rules in the JOSE (JW*) family of specs. #### json @@ -262,7 +262,7 @@ attachment's bytes are directly inlined in the message in some way. This is a useful mode of data delivery, but it is not the only mode. Another way that attachment data can be incorporated is *by reference*. For -example, you can link to the content on IPFS by replacing `data.base64` +example, you can link to the content on a web server by replacing `data.base64` or `data.json` with `data.links` in an attachment descriptor: [![links example](crime-scene-links.png)](crime-scene-links.json) @@ -272,69 +272,27 @@ message and an attachment that can be fetched separately. This makes it possible to send brief descriptors of attachments and to make the downloading of the heavy content optional (or parallelizable) for the recipient. -IPFS is not the only option for attaching by reference. You can do the same -with S3 (showing just the `data` fragment now): - -```JSON -"data": { - "sha256": "1d4db525c5ee4a2d42899040cd3728c0f0945faf9eb668b53d99c002123f1ffa", - "links": ["s3://mybucket/mykeyoyHw8T7Afe4DbWFcJYocef5"] -} -``` - -Or on an ordinary HTTP/FTP site or CDN: -```JSON -"data": { - "links": ["https://github.com/sovrin-foundation/launch/raw/master/sovrin-keygen.zip"] -} -``` - -Or on BitTorrent: -```JSON -"byte_count": 192834724, -"data": { - "links": ["torrent://content of a .torrent file as a data URI"] -} -``` - -Or via double indirection (URI for a BitTorrent): -```JSON -"data": { - "links": ["torrent@http://example.com/mycontent.torrent"] -} -``` - -Or as content already attached to a previous DIDComm message: +The `links` field is plural (an array) to allow multiple locations to be +offered for the same content. This allows an agent to fetch attachments using +whichever mechanism(s) are best suited to its individual needs and capabilities. -```JSON -"data": { - "links": ["didcomm://my-previous-message-id.~attach#id"] -} -``` +##### Supported URI Types -Or even via a promise to supply the content at some point in the future, in -a subsequent DIDComm message: +The set of supported URI types in an attachment link is limited to: -```JSON -"data": { - "links": ["didcomm://fetch"] -} -``` -[TODO: how does the message that actually delivers this content refer back -to the promise made earlier, to claim it has been fulfilled?] +- HTTP +- HTTPS -The set of supported URI types in an attachment link is not static, and -recipients of attachments that are incorporated by reference are not required to -support all of them. However, they should at least recognize the meaning of each -of the variants listed above, so they can perform intelligent error handling and -communication about the ones they don't support. +Additional URI types may be added via updates to this RFC. -The `links` field is plural (an array) to allow multiple locations to be -offered for the same content. This allows an agent to fetch attachments using -whichever mechanism(s) are best suited to its individual needs and capabilities. +If an attachment link with an unsupported URI is received, the agent SHOULD +respond with a [Problem Report](../../features/0035-report-problem/README.md) +indicated the problem. -[TODO: discuss sending an empty message with just attachments, and how to -request a send of an attachment, or an alternate download method for it] +An ecosystem (coordinating set of agents working in a specific business area) +may agree to support other URI types within that ecosystem. As such, implementing a +mechanism to easily add support for other attachment link URI types might be useful, +but is not required. ### Signing Attachments @@ -346,10 +304,7 @@ signing key when the sender is performing key rotation. Embedded and appended attachments support signatures by the addition of a `data.jws` field containing a signature in [JWS (RFC 7515) format](https://tools.ietf.org/html/rfc7515) -with [Detached Content](https://tools.ietf.org/html/rfc7515#appendix-F). -The payload of the JWS is the raw data of the attachment, whether externally referenced -or encoded in base64 format, and is not contained within the signature itself. -Signatures over inlined JSON attachments are not currently defined as this +with [Detached Content](https://tools.ietf.org/html/rfc7515#appendix-F). The payload of the JWS is the raw bytes of the attachment, appropriately base64url-encoded per JWS rules. If these raw bytes are incorporated by value in the DIDComm message, they are already base64url-encoded in `data.base64` and are thus directly substitutable for the suppressed `data.jws.payload` field; if they are externally referenced, then the bytes must be fetched via the URI in `data.links` and base64url-encoded before the JWS can be fully reconstituted. Signatures over inlined JSON attachments are not currently defined as this depends upon a canonical serialization for the data. Sample JWS-signed attachment: @@ -498,13 +453,12 @@ attachment. Contains the following subfields: * `links`: A list of zero or more locations at which the content may be fetched. Optional. - * `base64`: Base64-encoded data, when representing arbitrary content inline instead + * `base64`: Base64url-encoded data, when representing arbitrary content inline instead of via `links`. Optional. * `json`: Directly embedded JSON data, when representing content inline instead of via `links`, and when the content is natively conveyable as JSON. Optional. - ## Drawbacks By providing 3 different choices, we impose additional complexity on @@ -531,8 +485,7 @@ However, they are an inspiration for what we are showing here. # Unresolved questions -- What additional clarity do we need to provide for the URIs used -to fetch attachment content later? +- N/A ## Implementations diff --git a/concepts/0020-message-types/README.md b/concepts/0020-message-types/README.md index 316606c8c..804ae747d 100644 --- a/concepts/0020-message-types/README.md +++ b/concepts/0020-message-types/README.md @@ -1,10 +1,10 @@ # Aries RFC 0020: Message Types -- Authors: [Daniel Bluhm](daniel.bluhm@sovrin.org), [Sam Curren](sam@sovrin.org) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: Daniel Bluhm, Sam Curren +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-05-24 - Status Note: -- Supersedes: [HIPE 0021 Message Types](https://github.com/hyperledger/indy-hipe/tree/master/text/0021-message-types) +- Supersedes: [HIPE 0021 Message Types](https://github.com/hyperledger/indy-hipe/tree/main/text/0021-message-types) - Start Date: 2018-07-06 - Tags: [concept](/tags.md#concept) @@ -29,124 +29,13 @@ Types are specified within a message using the `@type` attribute: } ``` -Message types are URIs that resolve to developer documentation for the message type, as described in [Protocol URIs](../0003-protocols/README.md#message-type-and-protocol-identifier-uris). - -We recommend that message types are ledger resolvable DIDs with an endpoint specifier and path. This allows for the document locations to be updated to a new location for a stable definition. - -### Example DID and DID Document for Message Type Specification - -The following was taken from a presentation by Drummond Reed during the Agent Summit. A link to this presentation can be found below in the [Reference](#reference) section. - -#### Problem - -How to use a DID to identify a digital object that: - -1. Can be widely referenced. -2. Is cryptographically verifiable. -3. Is human readable *enough* for developers. - -#### Solution - -Use a full DID reference that contains a service name and path. - -##### Example DID Reference - -This DID reference contains a service name (`;spec`) followed by a path that expresses the semantics of an example protocol. - -``` -did:sov:123456789abcdefghi1234;spec/exampleprotocol/1.0/exampletype -``` - -#### Example DID Document - -This example DID document shows a service endpoint that includes a name property (emphasized) whose purpose is to enable creation of DID references that can deterministically select that service in order to have an algorithmic transformation into a concrete URI. - -```jsonc -{ - "@context": "https://w3id.org/did/v1", - "id": "did:example:123456789abcdefghi", - "publicKey": [{ - "id": "did:example:123456789abcdefghi#keys-1", - "type": "RsaSigningKey2018", - "owner": "did:example:123456789abcdefghi", - "publicKeyPem": "-----BEGIN PUBLIC KEY...END PUBLIC KEY-----\r\n" - }], - "authentication": [{ - "type": "RsaSignatureAuthentication2018", - "publicKey": "did:example:123456789abcdefghi#keys-1" - }], - "service": [{ - "type": "Document", - "name": "spec", // <--- Name property - "serviceEndpoint": "https://sovrin.org/specs/" - }] -} -``` - -#### Resolution Process - -This is the full ABNF for a DID: - -```ABNF - did-reference = did [ ";" did-service ] [ "/" did-path ] [ "?" did-query ] - [ "#" did-frag ] - did = "did:" method ":" specific-idstring - method = 1*namechar - namechar = %x61-7A / DIGIT - specific-idstring = idstring *( ":" idstring ) - idstring = 1*idchar - idchar = ALPHA / DIGIT / "." / "-" - did-service = 1*servchar *( ";" 1*servchar ) - servchar = idchar / "=" / "&" -``` - -The purpose of the `did-service` component that may optionally follow a DID is to enable construction of a DID reference that may be algorithmically transformed into a concrete URL to access the target resource. There are two algorithms for this transformation. Both begin with the same first step: - -1. Extract the DID plus the `did-service` component from the DID reference. Call this the *DID service locator*. Call the rest of the DID reference the `service-specific` string. - -#### Service Selection by ID - -This algorithm MUST be used if the `did-service` component does NOT begin with the string `type=`. - -2. Select the first `service` object whose id property contains an exact match to the DID service locator. -3. Select the `serviceEndpoint` property of the selected `service` object. -4. Extract the value of the `serviceEndpoint` property. Call this the *endpoint URL*. -5. Append the service-specific string to the endpoint URL. -6. The final result is the concrete URL. - -##### Example - -The following agent message is received with a type not known to the developer: - -```json -{ - "@type": "did:sov:123456789abcdefghi1234;spec/exampleprotocol/1.0/exampletype", - "attr_a": 5, - "attr_b": "Gouda" -} -``` - -The `@type` is extracted, with a DID reference that resolves to the example `service` block above: - -``` json -did:sov:123456789abcdefghi1234;spec/exampleprotocol/1.0/exampletype -``` - -A DID resolver would algorithmically transform that DID reference to the following concrete URL: - -``` -https://sovrin.org/specs/exampleprotocol/1.0/exampletype -``` - -The developer would then be able to load this URL in a browser to discover the meaning of `attr_a` and `attr_b`. +Message types are URIs that may resolve to developer documentation for the message type, as described in [Protocol URIs](../0003-protocols/README.md#message-type-and-protocol-identifier-uris). We recommend that message type URIs be HTTP URLs. ### Aries Core Message Namespace -> The Aries community is currently in the process of changing the prefix for protocol message types that currently use the did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/ to use https://didcomm.org/. This proces is described in RFC 0348 [Transition Message Type to HTTPs](../../features/0348-transition-msg-type-to-https/README.md). - -`did:sov:BzCbsNYhMrjHiqZDTUASHg` will be used to namespace protocols defined by the community as "core protocols" or protocols that agents should minimally support. +`https://didcomm.org/` is used to namespace protocols defined by the community as "core protocols" or protocols that agents should minimally support. -This DID is currently held by Daniel Hardman. Ownership will be transferred to the correct entity as soon as possible. +The `didcomm.org` [DNS entry](https://whois.whoisxmlapi.com/lookup-report/zjRXrYwV5r) is currently controlled by the [Decentralized Identity Foundation (DIF)](https://identity.foundation) based on their role in standardizing the [DIDComm Messaging specification](https://identity.foundation/didcomm-messaging/spec/). ### Protocols @@ -161,29 +50,29 @@ number. To summarize, a change in the major protocol version number indicates a These guidelines are guidelines on purpose. There will be situations where a good design will have to choose between conflicting points, or ignore all of them. The goal should always be clear and good design. -#### Respect Reserved Attribute Names +### Respect Reserved Attribute Names Reserved attributes are prefixed with an `@` sign, such as `@type`. Don't use this prefix for an attribute, even if use of that specific attribute is undefined. -#### Avoid ambiguous attribute names +### Avoid ambiguous attribute names Data, id, and package, are often terrible names. Adjust the name to enhance meaning. For example, use `message_id` instead of `id`. -#### Avoid names with special characters +### Avoid names with special characters Technically, attribute names can be any valid json key (except prefixed with @, as mentioned above). Practically, you should avoid using special characters, including those that need to be escaped. Underscores and dashes [_,-] are totally acceptable, but you should avoid quotation marks, punctuation, and other symbols. -#### Use attributes consistently within a protocol +### Use attributes consistently within a protocol Be consistent with attribute names between the different types within a protocol. Only use the same attribute name for the same data. If the attribute values are similar, but not exactly the same, adjust the name to indicate the difference. -#### Nest Attributes only when useful +### Nest Attributes only when useful Attributes do not need to be nested under a top level attribute, but can be to organize related attributes. Nesting all message attributes under one top level attribute is usually not a good idea. ### Design Examples -**Example 1** +#### Example 1 ```json { @@ -199,7 +88,7 @@ Attributes do not need to be nested under a top level attribute, but can be to o Suggestions: Ambiguous names, unnecessary nesting, symbols in names. -**Example 1 Fixed** +#### Example 1 Fixed ```json { @@ -211,14 +100,10 @@ Suggestions: Ambiguous names, unnecessary nesting, symbols in names. } ``` - - ## Reference -- [Drummond Reed's presentation on using DIDs as message type specifiers](https://docs.google.com/document/d/1t-AsCPjvERBZq9l-iXn2xffJwlNfFoQhktfIaMFjN-c/edit#heading=h.x1wbqftasrx2) - [Daniel Hardman's Agent Summit Notes](https://docs.google.com/document/d/1TP_7MKfuIrlY3rz4cz_tuuCFi7hdUWifeKwr5h-QTYM/edit) - [Stephen Curran's presentation summarizing the Agent Summit](https://docs.google.com/presentation/d/1l-po2IKVhXZHKlgpLba2RGq0Md9Rf19lDLEXMKwLdco/edit) -- [DID Spec](https://w3c.github.io/did-core/) - [Semantic Versioning](../0003-protocols/README.md#semver-rules-for-protocols) - [DIDComm Message Anatomy](../0021-didcomm-message-anatomy/README.md) diff --git a/concepts/0021-didcomm-message-anatomy/README.md b/concepts/0021-didcomm-message-anatomy/README.md index 41c59442b..6ee2b9606 100644 --- a/concepts/0021-didcomm-message-anatomy/README.md +++ b/concepts/0021-didcomm-message-anatomy/README.md @@ -1,7 +1,7 @@ # Aries RFC 0021: DIDComm Message Anatomy -- Authors: [Tobias Looker](tobias.looker@mattr.global), [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [PROPOSED](/README.md#proposed) +- Authors: [Tobias Looker](mailto:tobias.looker@mattr.global), [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-05-25 - Start Date: 2019-05-25 - Tags: [concept](/tags.md#concept), [decorator](/tags.md#decorator) @@ -62,7 +62,7 @@ The most important concepts to introduce about these conventions are the followi #### Message Type Every message contains a message type which allows the context of the message to be established and therefore process the content, -see [here](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0020-message-types/README.md) for more information. It is also important to +see [here](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0020-message-types/README.md) for more information. It is also important to note that in DIDComm, the message identification does not just identify the message, the message type also identifies the associated protocol. These protocols are essentially a group of related messages that are together required to achieve some form of multi-step flow see [here](../0003-protocols/README.md) for more information. diff --git a/concepts/0029-message-trust-contexts/README.md b/concepts/0029-message-trust-contexts/README.md index c4b9affd6..80af2bc8c 100644 --- a/concepts/0029-message-trust-contexts/README.md +++ b/concepts/0029-message-trust-contexts/README.md @@ -1,9 +1,9 @@ # Aries RFC 0029: Message Trust Contexts -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [DEMONSTRATED](/README.md#demonstrated) -- Since: 2019-05-10 -- Status Note: Only implemented in one codebase and in the sample code here. +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: Not practically applied. - Supersedes: [Indy HIPE PR #120](https://github.com/hyperledger/indy-hipe/pull/120) - Start Date: 2018-02-10 (approx, backdated) - Tags: [concept](/tags.md#concept) @@ -133,12 +133,12 @@ MTCs apply to the entirety of the associated message's attributes. However, _emb attachments present the unique situation of nested content with the potential for a trust context that differs from the parent message. -The [attachment descriptor](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0017-attachments/README.md#embedding), +The [attachment descriptor](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#embedding), used for both _embedded_ and _appended_ attachments, shares the same MTC as the parent message. Unpacked attachment data have their own Trust Contexts populated as appropriate depending on how the data was retrieved, whether the attachment is signed, whether an integrity checksum was provided and verified, etc. -Attachments delivered by the parent message, i.e. as Base64 encoded data, inherit relevant trust contexts from the +Attachments delivered by the parent message, i.e. as base64url-encoded data, inherit relevant trust contexts from the parent, such as `confidentiality` and `authenticated_origin`, when the message was delivered as an authenticated encrypted message. diff --git a/concepts/0046-mediators-and-relays/README.md b/concepts/0046-mediators-and-relays/README.md index fe7f389d8..a24e82f0f 100644 --- a/concepts/0046-mediators-and-relays/README.md +++ b/concepts/0046-mediators-and-relays/README.md @@ -1,6 +1,6 @@ # Aries RFC 0046: Mediators and Relays -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [ACCEPTED](/README.md#accepted) - Since: 2019-02-01 - Status Note: Socialized and broadly understood in other conceptual RFCs about routing. @@ -245,3 +245,4 @@ Name / Link | Implementation Notes --- | --- [Connect.Me](https://www.evernym.com/blog/connect-me-sovrin-digital-wallet/) | Free mobile app from Evernym. Installed via app store on iOS and Android. [Verity](https://www.evernym.com/products/) | Commercially licensed enterprise agent, SaaS or on-prem. +[DIDComm mediator](https://github.com/Sirius-social/didcomm-mediator) | Open source cloud-based mediator with Firebase support. diff --git a/concepts/0047-json-ld-compatibility/README.md b/concepts/0047-json-ld-compatibility/README.md index 4c3961f24..fdde98d7c 100644 --- a/concepts/0047-json-ld-compatibility/README.md +++ b/concepts/0047-json-ld-compatibility/README.md @@ -1,10 +1,10 @@ # Aries RFC 0047: JSON-LD Compatibility -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [ACCEPTED](/README.md#accepted) - Since: 2019-02-20 - Status Note: Has guided Indy design choices for several months. Not yet ratified by greater Aries community. -- Supersedes: [Indy HIPE 0035](https://github.com/hyperledger/indy-hipe/tree/master/text/0035-json-ld-compatibility) +- Supersedes: [Indy HIPE 0035](https://github.com/hyperledger/indy-hipe/tree/main/text/0035-json-ld-compatibility) - Start Date: 2019-01-23 - Tags: [concept](/tags.md#concept), [decorator](/tags.md#decorator) diff --git a/concepts/0049-repudiation/README.md b/concepts/0049-repudiation/README.md index bedfdd3d4..217c49f23 100644 --- a/concepts/0049-repudiation/README.md +++ b/concepts/0049-repudiation/README.md @@ -1,10 +1,10 @@ # Aries RFC 0049: Repudiation -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [ACCEPTED](/README.md#accepted) - Since: 2019-03-01 - Status Note: Well understood and baked into various protocol designs and DIDComm processes--but not yet ratified by the larger Aries community. -- Supersedes: [Indy HIPE 0037]( https://github.com/hyperledger/indy-hipe/tree/master/text/0037-repudiation) +- Supersedes: [Indy HIPE 0037]( https://github.com/hyperledger/indy-hipe/tree/main/text/0037-repudiation) - Start Date: 2018-03-01 (backdated) - Tags: [concept](/tags.md#concept) diff --git a/concepts/0050-wallets/README.md b/concepts/0050-wallets/README.md index 561034847..ee8b90313 100644 --- a/concepts/0050-wallets/README.md +++ b/concepts/0050-wallets/README.md @@ -4,7 +4,7 @@ - Status: [ACCEPTED](/README.md#accepted) - Since: 2018-07-01 - Status Note: Fully implemented in Indy SDK, but not yet socialized well in the broader Aries community. Needs some updates to promote better key management; see related RFC about [lox](../../features/0042-lox/README.md). -- Supersedes: [Indy HIPE 0013]( https://github.com/hyperledger/indy-hipe/tree/master/text/0013-wallets) +- Supersedes: [Indy HIPE 0013]( https://github.com/hyperledger/indy-hipe/tree/main/text/0013-wallets) - Start Date: 2018-05-22 - Tags: [concept](/tags.md#concept) diff --git a/concepts/0051-dkms/README.md b/concepts/0051-dkms/README.md index 5b39b6cc9..d3a0a9539 100644 --- a/concepts/0051-dkms/README.md +++ b/concepts/0051-dkms/README.md @@ -1,9 +1,9 @@ # Aries RFC 0051: Decentralized Key Management -- Authors: [Drummond Reed](drummond@connect.me) et al. -- Status: [DEMONSTRATED](/README.md#demonstrated) -- Since: 2019-03-29 -- Status Note: Somewhat familiar to many in the community, and influential in the designs of other RFCs--but not yet deeply explored or socialized. +- Authors: [Drummond Reed](mailto:drummond@connect.me) et al. +- Status: [RETIRED](/README.md#retired) +- Since: 2024-04-03 +- Status Note: Covered elsewhere and not specific to Aries. - Start Date: 2018-09-01 (approx, backdated) - Tags: [concept](/tags.md#concept) diff --git a/concepts/0074-didcomm-best-practices/README.md b/concepts/0074-didcomm-best-practices/README.md index 241ed53cc..f0c744cac 100644 --- a/concepts/0074-didcomm-best-practices/README.md +++ b/concepts/0074-didcomm-best-practices/README.md @@ -43,7 +43,8 @@ The two most important best practices with names are: * Pick descriptive and accurate names. [Thoughtfully chosen names can save enormous amounts of commenting and documentation]( https://codecraft.co/2012/08/28/good-code-is-named-right/). -* Be consistent. +* Be consistent. Particularly within an RFC and especially within the JSON for a set of related messages. + * For example, don't mix snake_case and other conventions within a single family of DIDComm messages. These are so common-sense that we won't argue them. But a few other points are worthy of comment. @@ -75,6 +76,11 @@ of the code around you, and in JSON that's intended to be interoperable, use snake_case unless you have a good reason not to. Definitely use the same case conventions as the other keys in the same JSON schema. +#### Pluralization + +The names of JSON items that represent arrays should be pluralized whenever possible, +while singleton items should not. + #### Terminology and Notation Use terms correctly and consistently. @@ -364,7 +370,7 @@ https://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC). ### Blobs -In general, blobs are encoded as base64 strings in DIDComm. +In general, blobs are [encoded as base64url](https://tools.ietf.org/html/rfc4648#section-5) strings in DIDComm. ### Unicode @@ -392,7 +398,7 @@ to make the content as useful as possible: with (possibly) many documents. * Hyperlinks from one RFC to another should be in relative form (`../features/my-rfc/README.md`), not in absolute form (`/features/my-rfc/README.md`) or external form -(`https://github.com/hyperledger/aries-rfcs/blob/master/features/my-rfc/README.md`). +(`https://github.com/hyperledger/aries-rfcs/blob/main/features/my-rfc/README.md`). This lets us move or embed the content, and it prevents branch names from cluttering the hyperlink. diff --git a/concepts/0094-cross-domain-messaging/README.md b/concepts/0094-cross-domain-messaging/README.md index d052a188f..604a0fba3 100644 --- a/concepts/0094-cross-domain-messaging/README.md +++ b/concepts/0094-cross-domain-messaging/README.md @@ -1,8 +1,8 @@ # Aries RFC 0094: Cross-Domain Messaging -- Authors: [Stephen Curran](swcurran@gmail.com) -- Status: [ACCEPTED](/README.md#accepted) -- Since: 2018-10-29 +- Authors: [Stephen Curran](mailto:swcurran@gmail.com) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 - Status Note: Socialized and broadly understood in other conceptual RFCs about routing. - Supersedes: [0022-Cross-Domain-Messaging](https://github.com/hyperledger/indy-RFC/blob/master/text/0022-cross-domain-messaging/README.md) - Start Date: 2018-08-13 @@ -175,7 +175,7 @@ If there are mediators specified in the DID service endpoint for the Receiver ag ```json { - "@type" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/routing/1.0/forward", + "@type" : "https://didcomm.org/routing/1.0/forward", "@id": "54ad1a63-29bd-4a59-abed-1c5b1026e6fd", "to" : "did:sov:1234abcd#4", "msg" : { json object from } @@ -245,7 +245,7 @@ The core message type "forward", version 1.0 of the "routing" family is defined ```json { - "@type" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/routing/1.0/forward", + "@type" : "https://didcomm.org/routing/1.0/forward", "@id": "54ad1a63-29bd-4a59-abed-1c5b1026e6fd", "to" : "did:sov:1234abcd#4", "msg" : { json object from } diff --git a/concepts/0104-chained-credentials/README.md b/concepts/0104-chained-credentials/README.md index 15fa5fb35..f3da54cc9 100644 --- a/concepts/0104-chained-credentials/README.md +++ b/concepts/0104-chained-credentials/README.md @@ -119,7 +119,7 @@ The first entity in the provenance chain for authority (Ur Wheels National, in o A chained credential delivers these features by obeying some special conventions over and above the core requirements of an ordinary VC: -1. It contains a special field named `schema` that is a base64-encoded representation of *its own schema*. This makes the credential self-contained in the sense that it doesn't depend on a schema or credential definition defined by an external authority (though it could optionally embody one). This field is always disclosed in presentations. +1. It contains a special field named `schema` that is a base64url-encoded representation of *its own schema*. This makes the credential self-contained in the sense that it doesn't depend on a schema or credential definition defined by an external authority (though it could optionally embody one). This field is always disclosed in presentations. 2. It contains a special field named `provenanceProofs`. The field is an array, where each member of the array is a tuple (also a JSON array). The first member of each tuple is a list of field names; the second member of each tuple is an embedded W3C verifiable presentation that proves the provenance of the values in those fields. In the case of delegate credentials, `provenanceProofs` is proving the provenance of a field named `authorization`. @@ -129,11 +129,11 @@ A chained credential delivers these features by obeying some special conventions When a presentation is created from a chained credential, `provenanceProofs` is either disclosed (for non-ZKP proofs), or is used as evidence to prove the same thing (for ZKPs). -3. It is associated (through a name in its `type` field array and through a URI in its `trustFrameworkURI` field) with a [trust framework](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0103-indirect-identity-control/README.md#proxy-trust-framework) that describes provenancing rules. For general chained credentials, this is optional; for delegate credentails, it is required. The trust framework may partially describe the semantics of some schema variants for a family of chained credentials, as well as how provenance is attenuated or categorized. For example, a trust framework jointly published by Ur Wheelz and other car rental companies might describe delegate credential schemas for car owners, car rental offices, drivers, insurers, maintenance staff, and guest users of cars. It might specify that the permissions delegatable in these credentials include `drive`, `maintain`, `rent`, `sell`, `retire`, `delegate-further`, and so forth. The trust framework would do more than enumerate these values; it would define exactly what they mean, how they interact with one another, and what permissions are expected to be in force in various circumstances. +3. It is associated (through a name in its `type` field array and through a URI in its `trustFrameworkURI` field) with a [trust framework](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0103-indirect-identity-control/README.md#proxy-trust-framework) that describes provenancing rules. For general chained credentials, this is optional; for delegate credentails, it is required. The trust framework may partially describe the semantics of some schema variants for a family of chained credentials, as well as how provenance is attenuated or categorized. For example, a trust framework jointly published by Ur Wheelz and other car rental companies might describe delegate credential schemas for car owners, car rental offices, drivers, insurers, maintenance staff, and guest users of cars. It might specify that the permissions delegatable in these credentials include `drive`, `maintain`, `rent`, `sell`, `retire`, `delegate-further`, and so forth. The trust framework would do more than enumerate these values; it would define exactly what they mean, how they interact with one another, and what permissions are expected to be in force in various circumstances. 4. The reputation of non-root holders in a provenance chain become irrelevant as far as credential trust is concerned--trust is based on an unbroken chain back to a root public attester, not on published, permanent characteristics of secondary issuers. Only the root attester needs to have a public DID. Other issuer keys and DIDs can be private and pairwise. -5. If it is a delegate credential, it also meets all the requirements to be a __proxy credential__ as described in [Aries RFC 0103: Indirect Identity Control](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0103-indirect-identity-control/README.md#proxy-credential). Specifically: +5. If it is a delegate credential, it also meets all the requirements to be a __proxy credential__ as described in [Aries RFC 0103: Indirect Identity Control](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0103-indirect-identity-control/README.md#proxy-credential). Specifically: * It uses `credentialSubject.holder.*` fields to bind it to a particular holder, if applicable. @@ -159,7 +159,7 @@ Here is JSON that might embody credentials C1, C2, and C3 from our use case. Not ```jsonc { - "@context": ["https://w3.org/2018/credentials/v1", "https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0104-delegatable-credentials"], + "@context": ["https://w3.org/2018/credentials/v1", "https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0104-delegatable-credentials"], "type": ["VerifiableCredential", "Proxy.D/CarRentalTF/1.0/subsidiary"], "schema": "WwogICJAY29udGV4dCIsIC8vSlN... (clipped for brevity) ...ob2x", "provenanceProofs": [ diff --git a/concepts/0207-credential-fraud-threat-model/README.md b/concepts/0207-credential-fraud-threat-model/README.md index 522eb7fd0..200494607 100644 --- a/concepts/0207-credential-fraud-threat-model/README.md +++ b/concepts/0207-credential-fraud-threat-model/README.md @@ -1,8 +1,8 @@ # 0207: Credential Fraud Threat Model -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-08-30 -- Status Note: socialized on an informal credential fraud study group (https://groups.google.com/d/forum/credential-fraud-study) since ~May 2019. +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. Socialized on an informal credential fraud study group (https://groups.google.com/d/forum/credential-fraud-study) circa 2019. - Start Date: 2019-05-23 - Tags: [concept](/tags.md#concept), [credentials](/tags.md#credentials) diff --git a/concepts/0217-linkable-message-paths/README.md b/concepts/0217-linkable-message-paths/README.md index a303c65fb..d2a5345d7 100644 --- a/concepts/0217-linkable-message-paths/README.md +++ b/concepts/0217-linkable-message-paths/README.md @@ -1,8 +1,8 @@ # Aries RFC 0217: Linkable Message Paths -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-09-10 -- Status Note: Purely theoretical at this point, but may be relevant to efforts to join subprotocols to superprotocols. Mentioned in [RFC 0214 "Help Me Discover" Protocol](../../features/0214-help-me-discover/README.md). +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Start Date: 2019-08-26 - Tags: [concept](/tags.md#concept) diff --git a/concepts/0231-biometric-service-provider/README.md b/concepts/0231-biometric-service-provider/README.md index 14396c869..78b6caca1 100644 --- a/concepts/0231-biometric-service-provider/README.md +++ b/concepts/0231-biometric-service-provider/README.md @@ -1,6 +1,6 @@ # Aries RFC 0231: Biometric Service Provider -- Authors: [John Callahan](jcallahan@acm.org), [Daniel Hardman](daniel.hardman@gmail.com), [Asem Othman](aothman@veridiumid.com) +- Authors: [John Callahan](mailto:jcallahan@acm.org), [Daniel Hardman](mailto:daniel.hardman@gmail.com), [Asem Othman](mailto:aothman@veridiumid.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-09-24 - Status Note: Proposed for now based on authors joint work diff --git a/concepts/0250-rich-schemas/README.md b/concepts/0250-rich-schemas/README.md index 8783d60cc..953ea67fa 100644 --- a/concepts/0250-rich-schemas/README.md +++ b/concepts/0250-rich-schemas/README.md @@ -1,9 +1,9 @@ # RFC 0250: Rich Schema Objects -- Author: [Ken Ebert](ken@sovrin.org), [Brent Zundel](brent.zundel@evernym.com) -- Status: [ACCEPTED](/README.md#accepted) -- Since: 2019-10-08 -- Status Note: Port of [this HIPE](https://github.com/hyperledger/indy-hipe/tree/master/text/0119-rich-schemas/README.md) -- Supersedes: [this HIPE](https://github.com/hyperledger/indy-hipe/tree/master/text/0119-rich-schemas/README.md) +- Author: [Ken Ebert](mailto:ken@sovrin.org), [Brent Zundel](mailto:brent.zundel@evernym.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No recent progress and no implementations have been created. +- Supersedes: [this HIPE](https://github.com/hyperledger/indy-hipe/tree/main/text/0119-rich-schemas/README.md) - Start Date: 2019-03-19 - Tags: [concept](/tags.md#concept), [rich-schemas](/tags.md#rich-schemas) @@ -341,7 +341,7 @@ Here is the paper that defines [Camenisch-Lysyanskaya signatures.][CL-signatures] They are the source for [Indy's AnonCreds protocol](https://github.com/hyperledger/indy-hipe/pull/109). -[CL-signatures]: (https://groups.csail.mit.edu/cis/pubs/lysyanskaya/cl02b.pdf) +[CL-signatures]: https://groups.csail.mit.edu/cis/pubs/lysyanskaya/cl02b.pdf ## Drawbacks diff --git a/concepts/0257-private-credential-issuance/README.md b/concepts/0257-private-credential-issuance/README.md index f56950b7e..36a7c9335 100644 --- a/concepts/0257-private-credential-issuance/README.md +++ b/concepts/0257-private-credential-issuance/README.md @@ -1,10 +1,10 @@ # Aries RFC 0257: Private Credential Issuance - Authors: Daniel Hardman and Lovesh Harchandani -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-10-16 -- Status Note: under study +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No recent progress and no implementations have been created. - Start Date: 2019-08-26 -- Tags: concept, protocol +- Tags: [concept](/tags.md#concept), [protocol](/tags.md#protocol) ## Summary @@ -41,7 +41,7 @@ An issuer needs to register a credential definition and a revocation registry on ### Delegatable credentials as a tool -[Delegatable Credentials](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0104-delegatable-credentials) are a useful tool that we can use to solve this problem. They function like special Object Capabilities (OCAP) tokens, and may offer the beginnings of a solution. They definitely address the delegation use cases, at least. Their properties include: +[Delegatable Credentials](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0104-delegatable-credentials) are a useful tool that we can use to solve this problem. They function like special Object Capabilities (OCAP) tokens, and may offer the beginnings of a solution. They definitely address the delegation use cases, at least. Their properties include: * A root issuer that is willing to go through setup and maintenance hassle creates a normal Indy credential and issues it to a normal Indy holder. diff --git a/concepts/0268-unified-didcomm-agent-deeplinking/README.md b/concepts/0268-unified-didcomm-agent-deeplinking/README.md index 73c88f4a4..353d49a30 100644 --- a/concepts/0268-unified-didcomm-agent-deeplinking/README.md +++ b/concepts/0268-unified-didcomm-agent-deeplinking/README.md @@ -1,10 +1,10 @@ # Aries RFC 0268: Unified DIDCOMM Deeplinking -- Authors: [Dev Bharel](dev@spaceman.id), [Alexi Falquier](alexis@spaceman.id) +- Authors: [Dev Bharel](mailto:dev@spaceman.id), [Alexi Falquier](mailto:alexis@spaceman.id) - Status: [PROPOSED](/README.md#proposed) -- Since: 2019-10-23 -- Status Note: Proposed +- Since: 2019-10-23 +- Status Note: Proposed - Start Date: 2018-10-04 -- Tags: concept, agents, mobile +- Tags: [concept](/tags.md#concept) ## Summary @@ -20,7 +20,7 @@ As more and more mobile agents come to market, the user base for these wallets w Alice wants to invite Bob to connect with her. Alice sends Bob a invitation link generated by her Mobile Agent (a wallet provided by ACME Corp). -The invitation url takes the form of: "www.acmecorp.com/invite?d_m=XXXXX" where the text following the query parameter "d_m" is the base64 encoded invitation. +The invitation url takes the form of: "www.acmecorp.com/invite?d_m=XXXXX" where the text following the query parameter "d_m" is the base64url-encoded invitation. Bob recieves this link and opens it on his phone. Since he doesn't have an Aires wallet, he gets directed to the webpage, "acmecorp.com/invite" where there's a list of wallets for each platform that he can choose and pick from. On the page is also the ACME Corp offical wallet. @@ -69,6 +69,7 @@ Furthermore, messages must also be base64 encoded serialized jsons, stripped of This puts extra work on wallet developers to ensure a good experience. +On iOS only one app can be registered to handle `didcomm://` at a time; the first one to be installed will prevent others from using this custom scheme. ## Rationale and alternatives diff --git a/concepts/0270-interop-test-suite/README.md b/concepts/0270-interop-test-suite/README.md index c899bce83..a4f350710 100644 --- a/concepts/0270-interop-test-suite/README.md +++ b/concepts/0270-interop-test-suite/README.md @@ -1,11 +1,11 @@ # 0270: Interop Test Suite -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-10-25 - Status Note: Codifies some thinking about scope and mental model that are already socialized. Provides some new thinking as well. -- Supersedes: Partially, and in some ways, [Indy HIPE 0015](https://github.com/hyperledger/indy-hipe/blob/master/text/0015-agent-test-suite-interface/README.md) and [Indy HIPE 0016](https://github.com/hyperledger/indy-hipe/blob/master/text/0016-agent-test-suite-v1/README.md). Also, represents answers to questions that the community first posed in [this HackMD doc](https://hackmd.io/JW5b9xYCRGKqyqhVevTZ_g) and first attempted to answer in the [indy-agent repo](https://github.com/hyperledger/indy-agent). +- Supersedes: Partially, and in some ways, [Indy HIPE 0015](https://github.com/hyperledger/indy-hipe/blob/main/text/0015-agent-test-suite-interface/README.md) and [Indy HIPE 0016](https://github.com/hyperledger/indy-hipe/blob/main/text/0016-agent-test-suite-v1/README.md). Also, represents answers to questions that the community first posed in [this HackMD doc](https://hackmd.io/JW5b9xYCRGKqyqhVevTZ_g) and first attempted to answer in the [indy-agent repo](https://github.com/hyperledger/indy-agent). - Start Date: 2018-10-25 -- Tags: concept +- Tags: [concept](/tags.md#concept) ## Summary diff --git a/concepts/0289-toip-stack/README.md b/concepts/0289-toip-stack/README.md index 6456c8c5a..8d4b10332 100644 --- a/concepts/0289-toip-stack/README.md +++ b/concepts/0289-toip-stack/README.md @@ -1,10 +1,10 @@ # 0289: The Trust Over IP Stack -- Authors: Matthew Davie, [Dan Gisolfi](dan.gisolfi@gmail.com), [Daniel Hardman](daniel.hardman@evernym.com), [John Jordan](john.jordan@gov.bc.ca), Darrell O'Donnell, [Drummond Reed](drummond.reed@evernym.com), [Oskar van Deventer](oskar.vandeventer@tno.nl) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-11-04 -- Status Note: Initial Proposal +- Authors: Matthew Davie, [Dan Gisolfi](mailto:dan.gisolfi@gmail.com), [Daniel Hardman](mailto:daniel.hardman@evernym.com), [John Jordan](mailto:john.jordan@gov.bc.ca), Darrell O'Donnell, [Drummond Reed](mailto:drummond.reed@evernym.com), [Oskar van Deventer](mailto:oskar.vandeventer@tno.nl) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No recent progress and no implementations have been created. - Start Date: 2019-01-01 -- Tags: concept, stack, trust layer, governance framework +- Tags: [concept](/tags.md#concept), stack, trust layer, governance framework ## Summary @@ -287,7 +287,7 @@ Holders often need to verify that a credential was requested by an authoritative ### Countermeasures against coercion -The concept of "self-sovereign" identity presumes that parties are free to enter a transaction, to share personal and confidential information, and to walk away when requests by the other party are deemed unreasonable or even unlawful. In practice, this is often not the case: "What do you give an 800-pound gorilla?", answer: "Anything that it asks for". Examples of such 800-pound gorillas are some big-tech websites, immigration offices and uniformed individuals alleging to represent law-enforcement [20]. Also the typical client-server nature of web transactions reinforces this power imbalance, where the human party behind its client agent feels coerced in surrendering personal data as otherwise they are denied access to a product, service or location. Point in case are the infamous cookie walls, where a visitor of a website get the choice between "accept all cookies or go into the maze-without-exit". +The concept of "self-sovereign" identity presumes that parties are free to enter a transaction, to share personal and confidential information, and to walk away when requests by the other party are deemed unreasonable or even unlawful. In practice, this is often not the case: "What do you give an 800-pound gorilla?", answer: "Anything that it asks for". Examples of such 800-pound gorillas are some big-tech websites, immigration offices and uniformed individuals alleging to represent law-enforcement [20][21]. Also the typical client-server nature of web transactions reinforces this power imbalance, where the human party behind its client agent feels coerced in surrendering personal data as otherwise they are denied access to a product, service or location. Point in case are the infamous cookie walls, where a visitor of a website get the choice between "accept all cookies or go into the maze-without-exit". Governance frameworks may be certified to implement one or more potential countermeasures against different types of coercion. In case of a machine readable governance framework, some of such countermeasures may be automatically enforced, safeguarding its user from being coerced into action against their own interest. Different governance frameworks may choose different balances between full self-sovereignty and tight control, depending of the interests that are at play as well as applicable legislation. @@ -326,7 +326,7 @@ This RFC will be updated to track the evolution of the ToIP stack as it is furth 7. Uniform Resource Names (URNs), [RFC 8141](https://tools.ietf.org/html/rfc8141), April 2017; accessed November 2, 2019. 8. Greg Slepak, Christopher Allen, et al, [Decentralized Public Key Infrastructure](https://github.com/WebOfTrustInfo/rwot1-sf/blob/master/draft-documents/Decentralized-Public-Key-Infrastructure-CURRENT.md), December 2015, accessed January 24, 2020. 9. W3C Credentials Community Group, [DID Method Registry](https://w3c-ccg.github.io/did-method-registry/), June 2019; accessed July 6, 2019. -10. Daniel Hardman, [DID Communication](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0005-didcomm/README.md), January 2019; accessed July 6, 2019. +10. Daniel Hardman, [DID Communication](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0005-didcomm/README.md), January 2019; accessed July 6, 2019. 11. Daniel Hardman et al, [Peer DID Method 1.0 Specification](https://openssi.github.io/peer-did-method-spec/), July 2019; accessed July 6, 2019. 12. Drummond Reed, Jason Law, Daniel Hardman, Mike Lodder, [DKMS Design and Architecture V4](http://bit.ly/dkms-v4), March 2019; accessed November 2, 2019. 13. Samuel M. Smith, [Key Event Receipt Infrastructure (KERI)](https://arxiv.org/abs/1907.02143) , July 2019, accessed February 4, 2020. @@ -336,7 +336,8 @@ This RFC will be updated to track the evolution of the ToIP stack as it is furth 17. Sovrin Foundation, [Sovrin Governance Framework V2](https://sovrin.org/governance-framework/), March 2019; accessed December 21, 2019. 18. DIACC, [Pan-Canadian Trust Framework](https://diacc.ca/pan-canadian-trust-framework/), May 2019; accessed July 6, 2019. 19. Governments of British Columbia, Ontario, and Canada, [Verifiable Organizations Network (VON)](https://vonx.io/),June 2019; accessed July 6, 2019. -20. Oskar van Deventer et al, TNO, Netherlands, [Self-Sovereign Identity - The Good, The Bad And The Ugly]( https://blockchain.tno.nl/blog/self-sovereign-identity-the-good-the-bad-and-the-ugly/),May 2019. +20. Oskar van Deventer et al, TNO, Netherlands, [Self-Sovereign Identity - The Good, The Bad And The Ugly]( https://blockchain.tno.nl/blog/self-sovereign-identity-the-good-the-bad-and-the-ugly/), May 2019. +21. Oskar van Deventer (TNO), Alexander Blom (Bloqzone), Line Kofoed (Bloqzone) [Verify the Verifier - anti-coersion by design](https://blockchain.tno.nl/blog/verify-the-verifier-anti-coercion-by-design/), October 2020. ## Implementations diff --git a/concepts/0302-aries-interop-profile/README.md b/concepts/0302-aries-interop-profile/README.md index 402c96e74..91d415c49 100644 --- a/concepts/0302-aries-interop-profile/README.md +++ b/concepts/0302-aries-interop-profile/README.md @@ -1,12 +1,12 @@ # 0302: Aries Interop Profile - Authors: [Stephen Curran](mailto:swcurran@cloudcompass.ca), [John Jordan](mailto:john.jordan@gov.bc.ca) Province of British Columbia -- Status: [ACCEPTED](https://github.com/hyperledger/aries-rfcs/blob/master/README.md#accepted) -- Since: 2020-01-30 -- Status Note: This RFC defines an Aries Interop Profile process and Aries Interop Profile v1.0 +- Status: [ADOPTED](https://github.com/hyperledger/aries-rfcs/blob/main/README.md#adopted) +- Since: 2021-01-06 +- Status Note: This RFC defines an Aries Interop Profile process and Aries Interop Profile versions - Supersedes: - Start Date: 2019-11-06 -- Tags: concept +- Tags: [concept](/tags.md#concept) ## Summary @@ -15,11 +15,11 @@ This RFC defines the process for the community of Aries agent builders to: - enumerate a versioned set of Aries concept and feature RFCs which are collectively referred to as 'Aries Interop Profile Vx.y' - track Aries Interop Profile versions. -"Agent builders" are organizations or teams that are developing open source code upon which agents can be built (e.g. [aries-framework-dotnet](https://github.com/hyperledger/aries-framework-dotnet)), or deployable agents (e.g. [OSMA Mobile App](https://github.com/mattrglobal/osma)), or commercially available agents. +"Agent builders" are organizations or teams that are developing open source code upon which agents can be built (e.g. [aries-framework-dotnet](https://github.com/hyperledger/aries-framework-dotnet)), or deployable agents (e.g. [Aries Mobile Agent Xamarin](https://github.com/hyperledger/aries-mobileagent-xamarin)), or commercially available agents. -An Aries Interop Profile (AIP) version provides a clearly defined set of RFCs for Aries agent builders to target their agent implementation when they wish it to be interoperable with other agents supporting the same Aries Interop Profile version. The Aries Interop Profile versioning process is intended to provide clarity and predictability for Aries agent builders and others in the broader Aries community. The process is not concerned with proposing new, or evolving existing, RFCs, nor with the development of Aries code bases. +An Aries Interop Profile (AIP) version provides a clearly defined set of versions of RFCs for Aries agent builders to target their agent implementation when they wish it to be interoperable with other agents supporting the same Aries Interop Profile version. The Aries Interop Profile versioning process is intended to provide clarity and predictability for Aries agent builders and others in the broader Aries community. The process is not concerned with proposing new, or evolving existing, RFCs, nor with the development of Aries code bases. -At all times, the [Reference](#reference) section of this RFC defines one or more current Aries Interop Profile versions -- a number and set of links to specific commits of concept and features RFCs, along with a list of all previous Aries Interop Profile versions. Several current Aries Interop Profile versions can coexist during periods when multiple major Aries Interop Profile versions are in active use (e.g. 1.x and 2.x). Each entry in the previous versions list includes a link to the commit of this RFC associated with that Aries Interop Profile version. The [Reference](#reference) section MAY include one ".next" version for each existing current major Aries Interop Profile versions. Such "next" versions are proposals for what is to be included in the next minor AIP version. +At all times, the [Reference](#reference) section of this RFC defines one or more current Aries Interop Profile versions -- a number and set of links to specific commits of concept and features RFCs, along with a list of all previous Aries Interop Profile versions. Several current Aries Interop Profile versions can coexist during periods when multiple major Aries Interop Profile versions are in active use (e.g. 1.x and 2.x). Each entry in the previous versions list includes a link to the commit of this RFC associated with that Aries Interop Profile version. The [Reference](#reference) section MAY include one `.next` version for each existing current major Aries Interop Profile versions. Such "next" versions are proposals for what is to be included in the next minor AIP version. Once a suitably populated Aries test suite is available, each Aries Interop Profile version will include a link to the relevant subset of test cases. The test cases will include only those targeting the specific versions of the concepts and features RFCs in that version of Aries Interop Profile. A process for maintaining the link between the Aries Interop Profile version and the test cases will be defined in this RFC once the Aries test suite is further evolved. @@ -47,7 +47,7 @@ The establishment of Aries Interop Profile versions defined by the Aries agent b This RFC MUST contain the current Aries Interop Profile versions as defined by a version number and a set of links to concept and feature RFCs which have been agreed to by a community of Aries agent builders. "Agreement" is defined as when the community agrees to merge a Pull Request (PR) to this RFC that affects an Aries Interop Profile version number and/or any of the links to concept and feature RFCs. PRs that do not impact the Aries Interop Profile version number or links can (in general) be merged with less community scrutiny. -Each link to a concept or feature RFCs MUST be to a specific commit of that RFC. RFCs in the list MAY be flagged as deprecated. +Each link to a concept or feature RFCs MUST be to a specific commit of that RFC. RFCs in the list MAY be flagged as deprecated. Linked RFCs that reference external specs or standards MUST refer to as specific a version of the external resource as possible. Aries Interop Profile versions SHOULD have a link (or links) to a version (specific commit) of a test suite (or test cases) which SHOULD be used to verify compliance with the corresponding version of Aries Interop Profile. Aries agent builders MAY self-report their test results as part of their entries in the list of agents. @@ -61,6 +61,34 @@ run the following from the root of the repo: `python code/aipUpdates.py --help` +### Sub-targets + +AIP 2.0 is organized into a set of base requirements, and additional optional targets. These requirements are listed below. When indicating levels of support for AIP 2.0, subtargets are indicated in this format: `AIP 2.0/INDYCREDS/MEDIATE` with the subtargets listed in any order. + +Any RFCs within a single AIP Version and it's subtargets MUST refer to the exact same version of the RFC. + +### Discover Features Usage + +AIP Targets can be disclosed in the discover_features protocol, using the `feature-type` of `aip`. The feature's `id` is `AIP.` for base compatibility, and `AIP./` for subtargets, each subtarget being included individually. + +Example: + +```json +{ + "@type": "https://didcomm.org/discover-features/2.0/disclosures", + "disclosures": [ + { + "feature-type": "aip", + "id": "AIP2.0", + }, + { + "feature-type": "aip", + "id": "AIP2.0/INDYCRED" + } + ] +} +``` + ## Reference The Aries Interop Profile version number and links to other RFCs in this section SHOULD only be updated with the agreement of the Aries agent builder community. There MAY be multiple active major Aries Interop Profile versions. A list of previous versions of Aries Interop Profile are [listed after](#previous-versions) the current version(s). @@ -84,17 +112,203 @@ Concept | [0050-wallets](https://github.com/hyperledger/aries-rfcs/tree/64e5e55c Concept | [0094-cross-domain messaging](https://github.com/hyperledger/aries-rfcs/tree/64e5e55c123b2efaf38f4b0911a71a1c40a7f29d/concepts/0094-cross-domain-messaging) Feature | [0015-acks](https://github.com/hyperledger/aries-rfcs/tree/5cc750f0fe18e3918401489066566f22474e25a8/features/0015-acks) Feature | [0019-encryption-envelope](https://github.com/hyperledger/aries-rfcs/tree/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0019-encryption-envelope) -Feature | [0160-connection-protocol](https://github.com/hyperledger/aries-rfcs/tree/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0160-connection-protocol) +Feature | [0160-connection-protocol](https://github.com/hyperledger/aries-rfcs/tree/4d9775490359e234ab8d1c152bca6f534e92a38d/features/0160-connection-protocol) Feature | [0025-didcomm-transports](https://github.com/hyperledger/aries-rfcs/tree/b490ebe492985e1be9804fc0763119238b2e51ab/features/0025-didcomm-transports) Feature | [0035-report-problem](https://github.com/hyperledger/aries-rfcs/tree/89d14c15ab35b667e7a9d04fe42d4d48b10468cf/features/0035-report-problem) Feature | [0036-issue-credential](https://github.com/hyperledger/aries-rfcs/tree/bb42a6c35e0d5543718fb36dd099551ab192f7b0/features/0036-issue-credential) Feature | [0037-present-proof](https://github.com/hyperledger/aries-rfcs/tree/4fae574c03f9f1013db30bf2c0c676b1122f7149/features/0037-present-proof) Feature | [0056-service-decorator](https://github.com/hyperledger/aries-rfcs/tree/527849ec3aa2a8fd47a7bb6c57f918ff8bcb5e8c/features/0056-service-decorator) -#### Test Suite +#### Changelog - AIP 1.0 + +The original commit used in the definition of AIP 1.0 was: 64e5e55c123b2efaf38f4b0911a71a1c40a7f29d + +The following clarifications have been made to RFCs that make up AIP 1.0: + +- RFC 0160 Connection: `signers` was updated to `signer` in the Signature decorator example, following the RFC. + +#### AIP v1.0 Test Suite > To Do: Link(s) to version(s) of the test suite/test cases applicable to this Aries Interop Profile version. +### Aries Interop Profile Version: 2.0 + +The following are the goals used in selecting RFC versions for inclusion in AIP 2.0, and the RFCs added as a result of each goal: + +- From AIP 1.0: Aries Agents must be able to establish connections, exchange credentials and complete a connection-less proof-request/proof transaction. + +- Aries agents must be able to reuse connections. + - RFCs 0434, 0023, 0519, 0360 + +- Enable access to actionable information in Mobile Agents to enable improvements in the user experience (vs. AIP 1.0-based mobile agents). + - RFCs 0183, 0095, 0557 + +- Improve support for credential revocation use cases, independent of the revocation mechanism being used. + - RFCs 0183 + +- Improve the low-level messaging cryptography and enable a transition to DIDComm 2.0 to improve the security of the communication paths between agents. + - RFCs 0044, 0360, 0334 + +- Use protocols and standards that support multiple ledger types and verifiable credential formats. + - RFCs 0434, 0023, 0453, 0454 + +- Where appropriate, enable standard mediator coordination capabilities for mobile agents and multi-tenant agencies. + - RFC 0211 + +#### AIP 2.0 Changelog by Pull Requests + +Since approval of the AIP 2.0 profile, the following RFCs have been clarified by updating the commit in the link to the RFC: + +- 2022-03: RFC 0004 Agents, RFC 0005 DIDComm, RFC 0046 Mediators and Relays, RFC 0211 Route Coordination + - Note: In this update, a number of RFCs were changed solely for the purpose + of changing a link in the RFC to reference the "main" branch. + - Pull request: [#724](https://github.com/hyperledger/aries-rfcs/pull/724) + +- 2022-06: RFC 0023 DID Exchange, RFC 0025 DIDComm Transports, RFC 0434 Out of Band + - Pull request: [#739](https://github.com/hyperledger/aries-rfcs/pull/739) + +- 2024-02: Clarifications and removals of RFCs that have been determined to be impractical for AIP 2.0. + - See the [AIP 2.0 RFC Removed](#aip-20-rfcs-removed) section for details about the removed RFCs + - See the updated [implementer's note on encryption envelopes in AIP 2.0](#implementers-note-about-didcomm-envelopes-and-the-accept-element) that highlights the removal of RFC 0587-encryption-envelope-v2. + - Pull request: [#814](https://github.com/hyperledger/aries-rfcs/pull/814) + +- 2024-03: Clarifications and removals of RFCs that have been determined to be impractical for AIP 2.0. + - See the [AIP 2.0 RFC Removed](#aip-20-rfcs-removed) section for details about the removed RFCs + - Pull request: [#820](https://github.com/hyperledger/aries-rfcs/pull/820) + +#### AIP 2.0 Changelog by Clarifications + +The original commit used in the definition of AIP 2.0 was: `b3a3942ef052039e73cd23d847f42947f8287da2` + +The following clarifications have been made to RFCs that make up AIP 2.0. This list excludes commits changed solely because of status changes: + +- RFC 0003 Protocols: A correction to the tic-tac-toe example protocol was made; clarifications and additional guidance about the handling of minor differences in protocols by implementations. +- RFC 0017 Attachments: A clarification was made around the use of base64url encoding/decoding. +- RFC 0441 Present Proof Best Practices: A convention for representing dates to enable simple "older than" predicates was added. +- RFC 0592 Indy Attachment Format: The encoding algorithm used for credential attributes was added from RFC 0036. +- RFC 0008 Message ID and Threading: Clarification on having an empty `~thread` on a first message. +- RFC 0519 Goal Codes: Added some commonly used Goal Codes. +- RFC 0015 Acks: Clarification that an "Ack" value should not be "Fail" and Acks relationship with RFC 0035 Problem Report. +- RFC 0023 DID Exchange: Status update to Adopted, added to example the use of a DID Rotate attachment to include a signature on the the DID. +- RFC 0035 Report Problem: Clarification that a `description.code` is required, clarification on conventions for warnings. +- RFC 0044 DIDComm File and MIME Types: Clarifications on fallbacks for the mime types and why, and on using JWEs. +- RFC 0211 Route Coordination: Clarification to add a missing comma to an example. +- RFC 0434 Out of Band: Clarification that did:peer:2 can be used for reuse. +- RFC 0453 Issue Credential: Clarification about the protocol version (2.0) and that payments are not part of AIP 2.0. +- RFC 0454 Present Proof: Clarification about the protocol version (2.0) and that payments are not part of AIP 2.0. +- RFC 0592 Indy Attachments: Clarification on handling "unrevealed attributes" and on encoding integer strings as numbers (e.g. encoding both `"1"` vs. `1` as integers) +- RFC 0510 DIF Presentation Exchange Attachment: Correction of reference into the DIF spec that there is an "s" on "definitions" in `dif/presentation-exchange/definitions@v1.0` + +#### Base Requirements + + RFC Type | RFC/Link to RFC Version | Note +--- | --- | --- +Concept | [0003-protocols](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/concepts/0003-protocols) | [AIP V1.0, Reformatted](https://gist.github.com/swcurran/6976dc1fd1b10c51343cf3812288b345/revisions?diff=unified) +Concept | [0004-agents](https://github.com/hyperledger/aries-rfcs/tree/4e78319e5f79df2003ddf37f8f497d0fae20cc63/concepts/0004-agents) | AIP V1.0, Unchanged +Concept | [0005-didcomm](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/concepts/0005-didcomm) | [AIP V1.0, Minimally Updated](https://gist.github.com/swcurran/788195ea0bccec53e1f9fe3509034341/revisions?diff=unified) +Concept | [0008-message-id-and-threading](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/concepts/0008-message-id-and-threading) | [AIP V1.0, Updated](https://gist.github.com/swcurran/db72109ea4f2e336ac91f4fbab3f4048/revisions?diff=unified) +Concept | [0011-decorators](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/concepts/0011-decorators) | [AIP V1.0, Updated](https://gist.github.com/swcurran/04229583a509f12258352f9c85b9c9b6/revisions?diff=unified) +Concept | [0017-attachments](https://github.com/hyperledger/aries-rfcs/tree/7759addb1506d107fddec692403bbc9e55fe491f/concepts/0017-attachments) | [AIP V1.0, Updated](https://gist.github.com/swcurran/7d88f9866175af96a70e5c6c00fa0148/revisions?diff=unified) +Concept | [0020-message-types](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/concepts/0020-message-types) | [AIP V1.0, Updated](https://gist.github.com/swcurran/8f95c25b5c778426d3a47fe6d7c46c70/revisions?diff=unified)
Mandates message prefix `https://didcomm.org` for Aries Protocol messages. +Concept | [0046-mediators-and-relays](https://github.com/hyperledger/aries-rfcs/tree/45b4233fcffda14f1339380ae2233289f21296b0/concepts/0046-mediators-and-relays) | [AIP V1.0, Minimally Updated](https://gist.github.com/swcurran/2486b63615f7a36c1e997b6c8b10c245/revisions?diff=unified) +Concept | [0047-json-LD-compatibility](https://github.com/hyperledger/aries-rfcs/tree/4e78319e5f79df2003ddf37f8f497d0fae20cc63/concepts/0047-json-ld-compatibility) | [AIP V1.0, Minimally Updated](https://gist.github.com/swcurran/8ef311d793fc6964328687af3c0efd34/revisions?diff=unified) +Concept | [0050-wallets](https://github.com/hyperledger/aries-rfcs/tree/4e78319e5f79df2003ddf37f8f497d0fae20cc63/concepts/0050-wallets) | AIP V1.0, Unchanged +Concept | [0094-cross-domain messaging](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/concepts/0094-cross-domain-messaging) | [AIP V1.0, Updated](https://gist.github.com/swcurran/e3f27e3ab85a260aaf279352ecc4e1fb/revisions?diff=unified) +Concept | [0519-goal-codes](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/concepts/0519-goal-codes) | :new: +Feature | [0015-acks](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0015-acks) | [AIP V1.0, Updated](https://gist.github.com/swcurran/81af391bfd79539edec530150045fe51/revisions?diff=unified) +Feature | [0019-encryption-envelope](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0019-encryption-envelope) | [AIP V1.0, Updated](https://gist.github.com/swcurran/c652dfd39706e50be4145568797e667a/revisions?diff=unified)
See envelope note below +Feature | [0023-did-exchange](https://github.com/hyperledger/aries-rfcs/tree/bf3d796cc33ce78ed7cde7f5422b10719a68be21/features/0023-did-exchange) | :new: +Feature | [0025-didcomm-transports](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0025-didcomm-transports) | [AIP V1.0, Minimally Updated](https://gist.github.com/swcurran/1e64cba5f6c524d38ad596209df090df/revisions?diff=unified) +Feature | [0035-report-problem](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0035-report-problem) | [AIP V1.0, Updated](https://gist.github.com/swcurran/d9432abc436e6a069d6ffcd41dc86060/revisions?diff=unified) +Feature | [0044-didcomm-file-and-mime-types](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0044-didcomm-file-and-mime-types) | :new: +Feature | [0048-trust-ping](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0048-trust-ping) | :new: +Feature | [0183-revocation-notification](https://github.com/hyperledger/aries-rfcs/tree/4e78319e5f79df2003ddf37f8f497d0fae20cc63/features/0183-revocation-notification) | :new: +Feature | [0360-use-did-key](https://github.com/hyperledger/aries-rfcs/tree/4e78319e5f79df2003ddf37f8f497d0fae20cc63/features/0360-use-did-key) | :new: +Feature | [0434-outofband](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0434-outofband) | :new: +Feature | [0453-issue-credential-v2](https://github.com/hyperledger/aries-rfcs/tree/e8a23a7b80db5db5a12fd786aec9343116cf5147/features/0453-issue-credential-v2) | Update to V2 Protocol +Feature | [0454-present-proof-v2](https://github.com/hyperledger/aries-rfcs/tree/e8a23a7b80db5db5a12fd786aec9343116cf5147/features/0454-present-proof-v2) | Update to V2 Protocol +Feature | [0557-discover-features-v2](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0557-discover-features-v2) | :new: + +#### MEDIATE: Mediator Coordination + + RFC Type | RFC/Link to RFC Version | Note +--- | --- | --- +Feature | [0211-route-coordination](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0211-route-coordination) | :new: +Feature | [0092-transport-return-route](https://github.com/hyperledger/aries-rfcs/tree/b3a3942ef052039e73cd23d847f42947f8287da2/features/0092-transport-return-route) | :new: + +#### INDYCRED: Indy Based Credentials + + RFC Type | RFC/Link to RFC Version | Note +--- | --- | --- +Feature | [0592-indy-attachments](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0592-indy-attachments) | :new: Evolved from AIP V1.0 +Concept | [0441-present-proof-best-practices](https://github.com/hyperledger/aries-rfcs/tree/4e78319e5f79df2003ddf37f8f497d0fae20cc63/concepts/0441-present-proof-best-practices) | :new: + +#### LDCRED: JSON-LD Based Credentials + + RFC Type | RFC/Link to RFC Version | Note +--- | --- | --- +Feature | [0593-json-ld-cred-attach](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0593-json-ld-cred-attach) | :new: +Feature | [0510-dif-pres-exch-attach](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0510-dif-pres-exch-attach) | :new: + +#### BBSCRED: BBS+ Based Credentials + + RFC Type | RFC/Link to RFC Version | Note +--- | --- | --- +Feature | [0593-json-ld-cred-attach](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0593-json-ld-cred-attach) | :new: +Feature | [0646-bbs-credentials](https://github.com/hyperledger/aries-rfcs/blob/7a44f650d3cebf5b3047c1680618978393a497d5/features/0646-bbs-credentials/README.md) | :new: +Feature | [0510-dif-pres-exch-attach](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0510-dif-pres-exch-attach) | :new: + +#### CHAT: Chat related features + + RFC Type | RFC/Link to RFC Version | Note +--- | --- | --- +Feature | [0095-basic-message](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0095-basic-message) | :new: + +#### AIP 2.0 RFCs Removed + +> [!WARNING] +> After discussion amongst the Aries implementers, the following RFCs initially +> in AIP 2.0 have been **removed** as both never implemented (as far as we know) +> and/or impractical to implement. Since the RFCs have never been implemented, +> their removal does not have a practical impact on implementations. Commentary +> below the table listing the removed RFCs provides the reasoning for the removal of each RFC. + + RFC Type | RFC/Link to RFC Version | Note +--- | --- | --- +Feature | [0317-please-ack](https://github.com/hyperledger/aries-rfcs/tree/e8a23a7b80db5db5a12fd786aec9343116cf5147/features/0317-please-ack) | Removed from AIP 2.0 +Feature | [0587-encryption-envelope-v2](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0587-encryption-envelope-v2) | Removed from AIP 2.0 +Feature | [0627-static-peer-dids](https://github.com/hyperledger/aries-rfcs/tree/c3b0e2120ad24810598375663b6922b980f85d00/features/0627-static-peer-dids) | The use of static peer DIDs in Aries has evolved and all AIP 2.0 implementations should be using DID Peer types 4 (preferred), 1 or 2. + +- **0317-please-ack**: While the idea of a generic ACK request to be sent either immediately `on receipt`, or `after processing` seemed like a good idea, attempts to implement the feature proved ill-advised. + - The feature was never implemented, and there have been (as far as we know) no requests for its implementation. A good idea in theory, but not needed in practice. + - The `on receipt` use of `please-ack` might be feasible as a generic feature, but does not appear to be useful except in protocol specific ways, such as in implementing a texting protocol to get "read receipts". However, even in that case, it is not useful for the existing 0095-basic-messaging protocol, because the protocol will be complete (and likely deleted) before the `ack` can be sent back to the sender. When an `on receipt` ACK is needed, it is much preferred to add it in a protocol specific way vs. in a generic way. + - The `after processing` use of `please-ack` turned out to be impossible because its introduction changes every protocol state machine in protocol specific ways. We have determined that it is not possible to "generically" (without changing each protocol) to add such a feature and so we have decided that if there is a use case of `please-ack`-style functionality in a given protocol, it should be added/included in that protocol. Further, no one has requested that the feature be used in any implementation. + - See the [RFC 0317 Please Ack](https://github.com/hyperledger/aries-rfcs/tree/main/features/0317-please-ack) for more details on it's change of status to `RETIRED` and links to unmerged PRs that attempted to design and implement the functionality. +- 0587-encryption-envelope-v2 + - While this RFC will be crucial when the transition to DIDComm v2 is started, it is not of use until then, and hence not applicable to AIP 2.0. + - 0627-static-peer-dids: The inclusion of static peer DIDs was a transitory approach as the [DID Peer] specification evolved. The use of static peer DIDs is not in use in Aries, the [DID Peer] specification has stabilized, and the existing implementations are settled on the use of `did:peer` `4` (preferred), `2` and in some cases `1`. The removal of static peer DIDs from AIP 2.0 is to indicate where the community is currently and to lead newcomers to the community to follow the existing practices in the use of [DID Peer]. + +[DID Peer]: https://identity.foundation/peer-did-method-spec/ + +#### AIP v2.0 Test Suite + +The [Aries Agent Test Harness](https://github.com/hyperledger/aries-agent-test-harness) has a set of tests tagged to exercise AIP 1.0 and AIP 2.0, including the extended targets. + +#### Implementers Note about DIDComm Envelopes and the `ACCEPT` element + +> [!WARNING] +> The following paragraph is struck out as no longer relevant, since the +> 0587-encryption-envelope-v2 RFC has been removed from AIP 2.0. The upcoming +> (to be defined) AIP 3.0 will include the transition from DIDComm v1 to the +> next DIDComm generation, and at that time, the 0587-encryption-envelope-v2 +> will again be relevant. + +~~AIP 2.0 contains two RFCs that reference envelopes 0019-encryption-envelope and 0587-encryption-envelope-v2 (links above). +The important feature that Aries implementers should understand to differentiate which envelope format can or is being used by an agent is the +`accept` element of the DIDComm service endpoint and the out-of-band `invitation` message. If the `accept` element is not present, the +agent can only use the RFC 0019-encryption-envelope present. If it is present, the values indicate the envelope format(s) +the agent does support. See the RFCs for additional details.~~ + ### Previous Versions - None @@ -139,7 +353,7 @@ This is a typical approach to creating an early protocol certification program. The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -_Implementation Notes_ [may need to include a link to test results](https://github.com/hyperledger/aries-rfcs/blob/master/README.md#accepted). +_Implementation Notes_ [may need to include a link to test results](https://github.com/hyperledger/aries-rfcs/blob/main/README.md#accepted). Name / Link | Implementation Notes diff --git a/concepts/0345-community-coordinated-update/README.md b/concepts/0345-community-coordinated-update/README.md index 372a4084b..51f666d6c 100644 --- a/concepts/0345-community-coordinated-update/README.md +++ b/concepts/0345-community-coordinated-update/README.md @@ -1,10 +1,10 @@ # 0345: Community Coordinated Update -- Authors: [Sam Curren](telegramsam@gmail.com) +- Authors: [Sam Curren](mailto:telegramsam@gmail.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-12-26 (date you submit your PR) - Status Note: Initial Draft - Start Date: 2019-12-06 -- Tags: concept +- Tags: [concept](/tags.md#concept) ## Summary @@ -58,7 +58,7 @@ This step is formalized by writing an RFC detailing which changes are expected i ## Reference -This process should only be used for changes that are not detectable via the [Discover Features protocol](https://github.com/hyperledger/aries-rfcs/blob/master/features/0031-discover-features/README.md), either because the Discover Features Protocol cannot yet be run or the Discover Features Protocol does not reveal the change. +This process should only be used for changes that are not detectable via the [Discover Features protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0031-discover-features/README.md), either because the Discover Features Protocol cannot yet be run or the Discover Features Protocol does not reveal the change. #### Changes NOT applicable to this process @@ -89,7 +89,7 @@ This process was discussed in [Issue 318](https://github.com/hyperledger/aries-r The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -*Implementation Notes* [may need to include a link to test results](https://github.com/hyperledger/aries-rfcs/blob/master/README.md#accepted). +*Implementation Notes* [may need to include a link to test results](https://github.com/hyperledger/aries-rfcs/blob/main/README.md#accepted). Name / Link | Implementation Notes --- | --- diff --git a/concepts/0346-didcomm-between-two-mobile-agents/README.md b/concepts/0346-didcomm-between-two-mobile-agents/README.md index d24517996..a5531134b 100644 --- a/concepts/0346-didcomm-between-two-mobile-agents/README.md +++ b/concepts/0346-didcomm-between-two-mobile-agents/README.md @@ -1,9 +1,7 @@ -# 0346: DIDCOMM BETWEEN TWO MOBILE AGENTS USING CLOUD AGENT MEDIATOR -- Author: [Sukalpo Mitra](sukalpomitra@gmail.com) +# 0346: DIDComm Between Two Mobile Agents Using Cloud Agent Mediator +- Author: [Sukalpo Mitra](mailto:sukalpomitra@gmail.com) - Start Date: 2019-06-23 -- Tags: concept - -## Status +- Tags: [concept](/tags.md#concept) - Status: [PROPOSED](/README.md#proposed) - Status Date: 2019-06-23 - Status Note: ??? @@ -29,7 +27,7 @@ The cloud agent registration invite looks like below ```JSON {​ - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/didexchange/1.0/cloudagentregistrationinvitation",​ + "@type": "https://didcomm.org/didexchange/1.0/cloudagentregistrationinvitation",​ "@id": "12345678900987654321",​ "label": "CloudAgentA",​ "recipientKeys": ["8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"],​ @@ -40,7 +38,7 @@ The cloud agent registration invite looks like below }​ ``` -The registration data is base64 encrypted and is added to alink as part of the c_a_r query param. The recipient key is the public key of "Cloud Agent A". The service endpoint is where the edge agent should send the message to. Response endpoint is where a response that is being sent to Alice should be sent to. For example, if Bob wants to send a message to Alice, then Bob should send the message to the response endpoint. Consumer endpoint is where Alice's edge agent should consume the messages that are sent to her. The "Consumer" is an identifier to identify Alice's edge agent by the cloud agent "A". This identifier is different with each cloud agent and hence provides low correlation risk. Each time an invitation QR code is generated, a new consumer id is generated. No acknowledgment is required to be sent to the cloud agent or vice versa as the consumer-generated is never repeated. +The registration data is base64url-encoded and is added to alink as part of the c_a_r query param. The recipient key is the public key of "Cloud Agent A". The service endpoint is where the edge agent should send the message to. Response endpoint is where a response that is being sent to Alice should be sent to. For example, if Bob wants to send a message to Alice, then Bob should send the message to the response endpoint. Consumer endpoint is where Alice's edge agent should consume the messages that are sent to her. The "Consumer" is an identifier to identify Alice's edge agent by the cloud agent "A". This identifier is different with each cloud agent and hence provides low correlation risk. Each time an invitation QR code is generated, a new consumer id is generated. No acknowledgment is required to be sent to the cloud agent or vice versa as the consumer-generated is never repeated. All the endpoint data and the public key of the cloud agents are then stored as non secret records in Alice's wallet with a tag "cloud-agent" @@ -56,7 +54,7 @@ It then packs this message by Bob's recipient key and then creates another json ```JSON {​ - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/routing/1.0/forward",​ + "@type": "https://didcomm.org/routing/1.0/forward",​ "@id": "12345678900987654321",​ "msg": "", "to": ""​ @@ -71,7 +69,7 @@ For example, say the next random cloud agent that it chooses is Cloud Agent "C". ```JSON {​ - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/routing/1.0/forward",​ + "@type": "https://didcomm.org/routing/1.0/forward",​ "@id": "12345678900987654321",​ "msg": "", "to": ""​ @@ -109,7 +107,7 @@ In other suggested message formatting protocol Alice would provide a list of rou # Related art [related-art] #prior-art -Aries-rfc [Aries RFC 0046: Mediators and Relays](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0046-mediators-and-relays) +Aries-rfc [Aries RFC 0046: Mediators and Relays](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0046-mediators-and-relays) # Prior art [prior-art]: #prior-art @@ -124,7 +122,7 @@ Can a cloud agent have their own army of servers that just basically looks into The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -*Implementation Notes* [may need to include a link to test results](https://github.com/hyperledger/aries-rfcs/blob/master/README.md#accepted). +*Implementation Notes* [may need to include a link to test results](https://github.com/hyperledger/aries-rfcs/blob/main/README.md#accepted). Name / Link | Implementation Notes --- | --- diff --git a/concepts/0420-rich-schemas-common/README.md b/concepts/0420-rich-schemas-common/README.md index 6d9045c7c..e692d652a 100644 --- a/concepts/0420-rich-schemas-common/README.md +++ b/concepts/0420-rich-schemas-common/README.md @@ -1,8 +1,8 @@ # 0420: Rich Schema Objects Common - Author: [Alexander Shcherbakov](mailto:alexander.shcherbakov@evernym.com), [Brent Zundel](mailto:brent.zundel@evernym.com), [Ken Ebert](mailto:ken@sovrin.org) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-02-13 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No recent progress and no implementations have been created. - Start Date: 2020-02-05 - Tags: [concept](/tags.md#concept), [rich-schemas](/tags.md#rich-schemas) @@ -12,7 +12,7 @@ A low-level description of the components of an anonymous credential ecosystem that supports rich schemas, W3C Verifiable Credentials and Presentations, and correspondingly rich presentation requests. -Please see [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) +Please see [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) for high-level description. This RFC provides more low-level description of Rich Schema objects defining how they are identified and referenced. @@ -20,7 +20,7 @@ It also defines a general template and common part for all Rich Schema objects. ## Motivation -Please see [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) +Please see [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) for use cases and high-level description of why Rich Schemas are needed. This RFC serves as a low-level design of common parts between all Rich Schema objects, and can help developers to @@ -138,7 +138,7 @@ Any write request for Rich Schema object has the same fields: 'ver': # string ``` - `id` is a unique ID (for example a DID with a id-string being base58 representation of the SHA2-256 hash of the `content` field) -- The `content` field here contains a Rich Schema object in JSON-LD format (see [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas)). +- The `content` field here contains a Rich Schema object in JSON-LD format (see [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas)). It's passed and stored as-is. The `content` field must be serialized in the canonical form. The canonicalization scheme we recommend is the IETF draft [JSON Canonicalization Scheme (JCS).](https://tools.ietf.org/id/draft-rundgren-json-canonicalization-scheme-16.html) @@ -249,9 +249,9 @@ error: { ``` ## Reference -- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [0249: Aries Rich Schema Contexts](https://github.com/hyperledger/aries-rfcs/tree/master/features/0249-rich-schema-contexts) -- [0281: Aries Rich Schemas](https://github.com/hyperledger/aries-rfcs/tree/master/features/0281-rich-schemas) +- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [0249: Aries Rich Schema Contexts](https://github.com/hyperledger/aries-rfcs/tree/main/features/0249-rich-schema-contexts) +- [0281: Aries Rich Schemas](https://github.com/hyperledger/aries-rfcs/tree/main/features/0281-rich-schemas) ## Drawbacks diff --git a/concepts/0430-machine-readable-governance-frameworks/README.md b/concepts/0430-machine-readable-governance-frameworks/README.md index fc71f148f..1bd706926 100644 --- a/concepts/0430-machine-readable-governance-frameworks/README.md +++ b/concepts/0430-machine-readable-governance-frameworks/README.md @@ -1,5 +1,5 @@ # Aries RFC 0430: Machine-Readable Governance Frameworks -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2020-02-24 - Status Note: early proposal only @@ -59,7 +59,7 @@ Each problem domain will probably have unique requirements. Therefore, we start { "@context": [ // The first context must be this RFC's context. It defines core properties. - "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/context.jsonld", + "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/context.jsonld", // Additional contexts can be added to extend. "https://kmk.org/uni-accred-trust-fw" ], @@ -168,9 +168,9 @@ Alice is holding a mobile app that manages credentials for her. She clicks an in ![possible trust rules acceptance screen](ux-accept-tf.png) -Her app knew to display this message because the issuer, Faber College, communicated its reliance on this governance framework (by referencing its `data_uri`) as part of an early step in the issuance process (e.g., in the invitation or in the [`offer-credential` message](../../features/0036-issue-credential/README.md#propose-credential)). Notice how metadata from the governance framework — its title, version, topics, and descriptions — show up in the prompt. Notice as well that governance frameworks have reputations. This helps users determine whether the rules are legitimate and worth using. The "More Info" tab would link to the governance framework's `docs_uri` page. +Her app knew to display this message because the issuer, Faber College, communicated its reliance on this governance framework (by referencing its `data_uri`) as part of an early step in the issuance process (e.g., in the invitation or in the [`offer-credential` message](../../features/0036-issue-credential/README.md#offer-credential)). Notice how metadata from the governance framework — its title, version, topics, and descriptions — show up in the prompt. Notice as well that governance frameworks have reputations. This helps users determine whether the rules are legitimate and worth using. The "More Info" tab would link to the governance framework's `docs_uri` page. -Alice doesn't have to re-accept the governance framework if she's already using it (e.g., if she already activated it in her mobile app because she's it's relevant to other credentials she holds). As a person works regularly within a particular credential domain, decisions like these will become cached and seamless. However, we're showing the step here, for completeness. +Alice doesn't have to re-accept the governance framework if she's already using it (e.g., if she already activated it in her mobile app because it's relevant to other credentials she holds). As a person works regularly within a particular credential domain, decisions like these will become cached and seamless. However, we're showing the step here, for completeness. Suppose that Alice accepts the proposed rules. The governance framework requires that she also accept the KMK terms of service. These might require her to report any errors in her credential promptly, and clarify that she has the right to appeal under certain conditions (see the `redress` section of the governance framework data structure). They might also discuss the KMK governance framework's requirement for random auditing (see the `audit` section). @@ -212,7 +212,7 @@ And: ![upgrade governance framework](ux-upgrade-tf.png) -The point here is not the specifics in the UI we're positing. Different UX designers may may different choices. Rather, it's that by publishing a carefully versioned, machine-readable governance framework, such UIs become possible. The user's experience becomes less about individual circumstances, and more about general patterns that have known reputations, dependable safeguards, and so forth. +The point here is not the specifics in the UI we're positing. Different UX designers may make different choices. Rather, it's that by publishing a carefully versioned, machine-readable governance framework, such UIs become possible. The user's experience becomes less about individual circumstances, and more about general patterns that have known reputations, dependable safeguards, and so forth. #### Versioning diff --git a/concepts/0430-machine-readable-governance-frameworks/context.jsonld b/concepts/0430-machine-readable-governance-frameworks/context.jsonld index 766fd59af..1eae0fd2c 100644 --- a/concepts/0430-machine-readable-governance-frameworks/context.jsonld +++ b/concepts/0430-machine-readable-governance-frameworks/context.jsonld @@ -1,17 +1,17 @@ { "@context": { - "name": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#name", - "version": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#version", - "logo": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#logo", - "description": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#description", - "docs_uri": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#docs_uri", - "topics": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#topics", - "geos": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#geos", - "jurisdictions": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#jurisdictions", - "roles": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#roles", - "privileges": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#privileges", - "duties": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#duties", - "define": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#define", - "rules": "https://github.com/hyperledger/aries-rfcs/blob/master/0430-machine-readable-governance-frameworks/README.md#rules" + "name": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#name", + "version": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#version", + "logo": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#logo", + "description": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#description", + "docs_uri": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#docs_uri", + "topics": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#topics", + "geos": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#geos", + "jurisdictions": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#jurisdictions", + "roles": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#roles", + "privileges": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#privileges", + "duties": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#duties", + "define": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#define", + "rules": "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks/README.md#rules" } } \ No newline at end of file diff --git a/concepts/0430-machine-readable-governance-frameworks/gov-fw-covid-19.md b/concepts/0430-machine-readable-governance-frameworks/gov-fw-covid-19.md index 743bae5c3..bdfcbe0df 100644 --- a/concepts/0430-machine-readable-governance-frameworks/gov-fw-covid-19.md +++ b/concepts/0430-machine-readable-governance-frameworks/gov-fw-covid-19.md @@ -1,7 +1,7 @@ ```jsonc { "@context": [ - "https://github.com/hyperledger/aries-rfcs/concepts/0430-machine-readable-trust-frameworks", + "https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0430-machine-readable-governance-frameworks", "https://fightthevirus.org/covid19-fw" ], "name": "COVID-19 Creds" @@ -16,7 +16,7 @@ {"name": "travel", "uri": "http://ftv.org/tf/travel"}, {"name": "receive-healthcare", "uri": "http://ftv.org/tf/be-patient"}, {"name": "tlc-fragile", "uri": "http://ftv.org/tf/tlc"}, - {"name": "visit-hot-zone", "uri", "http://ftv.org/tf/visit" + {"name": "visit-hot-zone", "uri": "http://ftv.org/tf/visit"} ], // Name all the duties that are significant to understanding // interactions in this governance framework. Each duty is defined for humans @@ -70,22 +70,22 @@ "grant": "request-proof", "thus": "anyone", "duties": ["GDPR-edu-verif", "accept-kmk-tos"] }, - // Is there an authority that audits interactions? - "audit": { - // Where should reports be submitted via http POST? - "uri": "http://kmk.org/audit", - // How likely is it that a given interaction needs to - // be audited? Each party in the interaction picks a - // random number between 0 and 1, inclusive; if the number - // is <= this number, then that party submits a report about it. - "probability": "0.01" - }, - // Is there an authority to whom requests for redress can - // be made, if one party feels like another violates - // the governance framework? - "redress": { - "uri": "http://kmk.org/redress" - } - } -} + ], + // Is there an authority that audits interactions? + "audit": { + // Where should reports be submitted via http POST? + "uri": "http://kmk.org/audit", + // How likely is it that a given interaction needs to + // be audited? Each party in the interaction picks a + // random number between 0 and 1, inclusive; if the number + // is <= this number, then that party submits a report about it. + "probability": "0.01" + }, + // Is there an authority to whom requests for redress can + // be made, if one party feels like another violates + // the governance framework? + "redress": { + "uri": "http://kmk.org/redress" + } +} ``` \ No newline at end of file diff --git a/concepts/0440-kms-architectures/README.md b/concepts/0440-kms-architectures/README.md index 0d1f0c287..a9c6eeba6 100644 --- a/concepts/0440-kms-architectures/README.md +++ b/concepts/0440-kms-architectures/README.md @@ -1,11 +1,11 @@ # 0440: KMS Architectures -- Authors: [Michael Lodder](mike@sovrin.org) +- Authors: [Michael Lodder](mailto:mike@sovrin.org) - Status: [PROPOSED](/README.md#proposed) - Since: 2020-03-06 - Status Note: Proposed -- Supersedes: [Wallets](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0050-wallets/README.md), uses concepts from [LOX](https://github.com/hyperledger/aries-rfcs/blob/master/features/0042-lox/README.md) +- Supersedes: [Wallets](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0050-wallets/README.md), uses concepts from [LOX](https://github.com/hyperledger/aries-rfcs/blob/main/features/0042-lox/README.md) - Start Date: 2019-12-02 -- Tags: concept +- Tags: [concept](/tags.md#concept) ## Summary @@ -48,7 +48,7 @@ The components are listed below and described in detail in the following section 1. LOX - * Handle user authentication * Access control enforcement - * Session/context establishment and management to the previous layers as described [here](https://github.com/hyperledger/aries-rfcs/blob/master/features/0042-lox/README.md). + * Session/context establishment and management to the previous layers as described [here](https://github.com/hyperledger/aries-rfcs/blob/main/features/0042-lox/README.md). ## Architecture @@ -161,7 +161,7 @@ Upon authentication to LOX, LOX should establish connections to the enclave comp which should appear opaque to the client. LOX may need to authenticate to the enclave component or persistence component depending on where client access credentials are stored by implementors. Its preferable to store these in keychains or keystores if possible where the access is determined by the operating system and can include stronger mechanisms like -TouchID or FaceID and hardware tokens in addition to passwords or pins. As described in [LOX](https://github.com/hyperledger/aries-rfcs/blob/master/features/0042-lox/README.md), +TouchID or FaceID and hardware tokens in addition to passwords or pins. As described in [LOX](https://github.com/hyperledger/aries-rfcs/blob/main/features/0042-lox/README.md), the credentials for accessing the enclave and persistence layer can then be retrieved or generated if the client is new and stored in a secure manner. diff --git a/concepts/0441-present-proof-best-practices/README.md b/concepts/0441-present-proof-best-practices/README.md new file mode 100644 index 000000000..97d864388 --- /dev/null +++ b/concepts/0441-present-proof-best-practices/README.md @@ -0,0 +1,177 @@ +# 0441: Prover and Verifier Best Practices for Proof Presentation +- Authors: [Stephen Klump](mailto:stephen.klump@becker-carroll.com) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 +- Status Note: Interoperability guidance when using AnonCreds Present Proof. An element of the AnonCreds subtarget for [AIP v2.0](../../concepts/0302-aries-interop-profile/README.md). +- Start Date: 2020-10-31 +- Tags: [concept](/tags.md#concept), [credentials](/tags.md#credentials) + +## Summary + +This work prescribes best practices for provers in credential selection (toward proof presentation), for verifiers in proof acceptance, and for both regarding non-revocation interval semantics in fulfilment of the Present Proof protocol [RFC0037](../../features/0037-present-proof/README.md). Of particular instance is behaviour against presentation requests and presentations in their various non-revocation interval profiles. + +## Motivation + +Agents should behave consistently in automatically selecting credentials and proving presentations. + +## Tutorial + +The subsections below introduce constructs and outline best practices for provers and verifiers. + +### Presentation Requests and Non-Revocation Intervals + +This section prescribes norms and best practices in formulating and interpreting non-revocation intervals on proof requests. + +#### Semantics of Non-Revocation Interval Presence and Absence + +The presence of a non-revocation interval applicable to a requested item (see [below](#non-revocation-interval-applicability-to-requested-items)) in a presentation request signifies that the verifier requires proof of non-revocation status of the credential providing that item. + +The absence of any non-revocation interval applicable to a requested item signifies that the verifier has no interest in its credential's non-revocation status. + +A revocable or non-revocable credential may satisfy a presentation request with or without a non-revocation interval. The presence of a non-revocation interval conveys that if the prover presents a revocable credential, the presentation must include proof of non-revocation. Its presence does not convey any restriction on the revocability of the credential to present: in many cases the verifier cannot know whether a prover's credential is revocable or not. + +#### Non-Revocation Interval Applicability to Requested Items + +A **requested item** in a presentation request is an attribute or a predicate, proof of which the verifier requests presentation. A non-revocation interval within a presentation request is **specifically applicable**, **generally applicable**, or **inapplicable** to a requested item. + +Within a presentation request, a top-level non-revocation interval is **generally applicable** to all requested items. A non-revocation interval defined particularly for a requested item is **specifically applicable** to that requested attribute or predicate but **inapplicable** to all others. + +A non-revocation interval specifically applicable to a requested item overrides any generally applicable non-revocation interval: no requested item may have both. + +For example, in the following (indy) proof request + +```json +{ + "name": "proof-request", + "version": "1.0", + "nonce": "1234567890", + "requested_attributes": { + "legalname": { + "name": "legalName", + "restrictions": [ + { + "issuer_did": "WgWxqztrNooG92RXvxSTWv" + } + ] + }, + "regdate": { + "name": "regDate", + "restrictions": [ + { + "issuer_did": "WgWxqztrNooG92RXvxSTWv" + } + ], + "non_revoked": { + "from": 1600001000, + "to": 1600001000 + } + } + }, + "requested_predicates": { + }, + "non_revoked": { + "from": 1600000000, + "to": 1600000000 + } +} +``` + +the non-revocation interval on 1600000000 is **generally applicable** to the referent `"legalname"` while the non-revocation interval on 1600001000 **specifically applicable** to referent `"regdate"`. + +#### Semantics of Non-Revocation Interval Endpoints + +A non-revocation interval contains `"from"` and `"to"` (integer) EPOCH times. For historical reasons, any timestamp within this interval is technically acceptable in a non-revocation subproof. However, these semantics allow for ambiguity in cases where revocation occurs within the interval, and in cases where the ledger supports reinstatement. These best practices require the `"from"` value, should the prover specify it, to equal the `"to"` value: this approach fosters deterministic outcomes. + +A missing `"from"` specification defaults to the same value as the interval's `"to"` value. In other words, the non-revocation intervals + +```json +{ + "to": 1234567890 +} +``` + +and + +```json +{ + "from": 1234567890, + "to": 1234567890 +} +``` + +are semantically equivalent. + +##### Verifier Non-Revocation Interval Formulation + +The verifier MUST specify, as current [INDY-HIPE 11](https://github.com/hyperledger/indy-hipe/blob/main/text/0011-cred-revocation/README.md) notes, the same integer EPOCH time for both ends of the interval, or else omit the `"from"` key and value. In effect, where the presentation request specifies a non-revocation interval, the verifier MUST request a non-revocation instant. + +##### Prover Non-Revocation Interval Processing + +In querying the nodes for revocation status, given a revocation interval on a single instant (i.e., on `"from"` and `"to"` the same, or `"from"` absent), the prover MUST query the ledger for all germane revocation updates from registry creation through that instant (i.e., from zero through `"to"` value): if the credential has been revoked prior to the instant, the revocation necessarily will appear in the aggregate delta. + +### Provers, Presentation Proposals, and Presentation Requests + +In fulfilment of the [RFC0037](../../features/0037-present-proof/README.md) Present Proof protocol, provers may initiate with a presentation proposal or verifiers may initiate with a presentation request. In the former case, the prover has both a presentation proposal and a presentation request; in the latter case, the prover has only a presentation request. + +#### Credential Selection Best Practices + +This section specifies a prover's best practices in matching a credential to a requested item. The specification pertains to automated credential selection: obviously, a human user may select any credential in response to a presentation request; it is up to the verifier to verify the resulting presentation as satisfactory or not. + +Note that where a prover selects a revocable credential for inclusion in response to a requested item with a non-revocation interval in the presentation request, the prover MUST create a corresponding sub-proof of non-revocation at a timestamp within that non-revocation interval (insofar as possible; see [below](#timestamp-outside-non-revocation-interval)). + +##### With Presentation Proposal + +If prover initiated the protocol with a presentation proposal specifying a value (or predicate threshold) for an attribute, and the presentation request does not require a different value for it, then the prover MUST select a credential matching the presentation proposal, in addition to following the best practices below regarding the presentation request. + +##### Preference for Irrevocable Credentials + +In keeping with the specification [above](#semantics-of-non-revocation-interval-presence-and-absence), presentation of an irrevocable credential *ipso facto* constitutes proof of non-revocation. Provers MUST always prefer irrevocable credentials to revocable credentials, when the wallet has both satisfying a requested item, whether the requested item has an applicable non-revocation interval or not. Note that if a non-revocation interval is applicable to a credential's requested item in the presentation request, selecting an irrevocable credential for presentation may lead to a missing timestamp at the verifier (see [below](#missing-timestamp)). + +If only revocable credentials are available to satisfy a requested item with no applicable non-revocation interval, the prover MUST present such for proof. As per [above](#semantics-of-non-revocation-interval-presence-and-absence), the absence of a non-revocation interval signifies that the verifier has no interest in its revocation status. + +### Verifiers, Presentations, and Timestamps + +This section prescribes verifier best practices concerning a received presentation by its timestamps against the corresponding presentation request's non-revocation intervals. + +#### Timestamp for Irrevocable Credential + +A presentation's inclusion of a timestamp pertaining to an irrevocable credential evinces tampering: the verifier MUST reject such a presentation. + +#### Missing Timestamp + +A presentation with no timestamp for a revocable credential purporting to satisfy a requested item in the corresponding presentation request, where the requested item has an applicable non-revocation interval, evinces tampering: the verifier MUST reject such a presentation. + +It is licit for a presentation to have no timestamp for an irrevocable credential: the applicable non-revocation interval is superfluous in the presentation request. + +#### Timestamp Outside Non-Revocation Interval + +A presentation may include a timestamp outside of a the non-revocation interval applicable to the requested item that a presented credential purports to satisfy. If the latest timestamp from the ledger for a presented credential's revocation registry predates the non-revocation interval, but the timestamp is not in the future (relative to the instant of presentation proof, with a reasonable allowance for clock skew), the verifier MUST log and continue the proof verification process. + +Any timestamp in the future (relative to the instant of presentation proof, with a reasonable allowance for clock skew) evinces tampering: the verifier MUST reject a presentation with a future timestamp. Similarly, any timestamp predating the creation of its corresponding credential's revocation registry on the ledger evinces tampering: the verifier MUST reject a presentation with such a timestamp. + +### Dates and Predicates + +This section prescribes issuer and verifier best practices concerning representing dates for use in predicate proofs (eg proving Alice is over 21 without revealing her birth date). + +#### Dates in Credentials + +In order for dates to be used in a predicate proof they MUST be expressed as an Int32. While unix timestamps could work for this, it has several drawbacks including: can't represent dates outside of the years 1901-2038, isn't human readable, and is overly precise in that birth time down to the second is generally not needed for an age check. To address these issues, date attributes SHOULD be represented as integers in the form YYYYMMDD (eg 19991231). This addresses the issues with unix timestamps (or any seconds-since-epoch system) while still allowing date values to be compared with < > operators. Note that this system won't work for any general date math (eg adding or subtracting days), but it will work for predicate proofs which just require comparisons. In order to make it clear that this format is being used, the attribute name SHOULD have the suffix `_dateint`. Since most datetime libraries don't include this format, [here](https://github.com/kiva/protocol-common/blob/main/src/date.conversion.ts) are some examples of helper functions written in typescript. + +#### Dates in Presentations + +When constructing a proof request, the verifier SHOULD express the minimum/maximum date as an integer in the form YYYYMMDD. For example if today is Jan 1, 2021 then the verifier would request that `bithdate_dateint` is before or equal to Jan 1 2000 so `<= 20000101`. The holder MUST construct a predicate proof with a YYYYMMDD represented birth date less than that value to satisfy the proof request. + +## Reference + +* [RFC 0037](../../features/0037-present-proof/README.md): Present Proof protocol +* [INDY-HIPE 11](https://github.com/hyperledger/indy-hipe/blob/main/text/0011-cred-revocation/README.md): Indy revocation. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | diff --git a/concepts/0478-coprotocols/README.md b/concepts/0478-coprotocols/README.md new file mode 100644 index 000000000..5bfae4d9f --- /dev/null +++ b/concepts/0478-coprotocols/README.md @@ -0,0 +1,169 @@ +# Aries RFC 0478: Coprotocols +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No recent progress and no implementations have been created. +- Start Date: 2020-02-03 +- Tags: [concept](/tags.md#concept), [protocol](/tags.md#protocol) + +[![icon](icon.png)](https://j.mp/2XgyjH3) + +## Summary + +Explains how one protocol can invoke and interact with others, giving inputs and receiving outputs and errors. + +## Motivation + +It's common for complex business workflows to be composed from smaller, configurable units of logic. It's also common for multiple processes to unfold in interrelated ways, such that a complex goal is choreagraphed from semi-independent tasks. Enabling flexible constructions like this is one of the major goals of protocols built atop DIDComm. We need a standard methodology for doing so. + +## Tutorial + +A [protocol is any recipe for a stateful interaction](../0003-protocols/README.md). [DIDComm](../0005-didcomm/README.md) itself is a protocol, as are many primitives atop which it is built, such as HTTP, Diffie-Hellman key exchange, and so forth. However, when we talk about protocols in decentralized identity, without any qualifiers, we usually mean application-level interactions like [credential issuance](../../features/0036-issue-credential/README.md), [feature discovery](../../features/0031-discover-features/README.md), [third-party introductions](../../features/0028-introduce/README.md), and so forth. These protocols are message-based interactions that use DIDComm. + +We want these protocols to be __composable__. In the middle of issuing credentials, we may want to challenge the potential holder for proof -- and in the middle of challenging for proof, maybe we want to negotiate payment. We could build proving into issuing, and payment into proving, but this runs counter to the [DRY principle](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) and to general best practice in encapsulation. A good developer writing a script to issue credentials would probably isolate payment and proving logic in separate functions or libraries, and would strive for [loose coupling](https://en.wikipedia.org/wiki/Loose_coupling) so each could evolve independently. + +Agents that run protocols have goals like those of the script developer. How we achieve them is the subject of this RFC. + +### Subroutines + +In the world of computer science, a subroutine is a vital abstraction for complex flows. It breaks logic into small, reusable chunks that are easy for a human to understand and document, and it formalizes their interfaces. Code calls a subroutine by referencing it via name or address, providing specified arguments as input. The subroutine computes on this input, eventually producing an output; the details don't interest the caller. While the subroutine is busy, the caller typically waits. Callers can often avoid recompilation when details inside subroutines change. Subroutines can come from pluggable libraries. These can be written by different programmers in different programming languages, as long as a calling convention is shared. + +Thinking of protocols as analogs to subroutines suggests some interesting questions: + +* How do we invoke one protocol from another? +* How does a protocol emit an output? +* What is the calling convention? +* How do errors propagate (or exceptions get thrown and handled)? +* How can we make protocols work like higher-order functions (functions that take other functions as parameters)? + +### Coroutines + +Before we answer these questions, let's think about a generalization of subroutines that's slightly less familiar to some programmers: __coroutines__. Coroutines achieve the same encapsulation and reusability as subroutines, but as a category they are more flexible and powerful. Coroutines may be, but aren't required to be, call-stack "children" of their callers; they may have complex lifecycles that begin or end outside the caller's lifespan. Coroutines may receive inputs at multiple points, not just at launch. They may yield outputs at multiple points, too. Subroutines are just the simplest variant of coroutines. + +The flexiblity of coroutines gives options to programmers, and it explains why most programming languages evolve to offer them as first-class constructs when they encounter demanding requirements for asynchronicity, performance, or scale. For example, early versions of python lacked the concept of coroutines; if you wrote a loop over `range(1, 1000000)`, python allocated and filled a container holding 1 million numbers, and then iterated over the container. When generators (a type of coroutine) were added to the language, the underlying logic changed. Now `range(1, 1000000)` is a coroutine invocation that trades execution state back and forth with its sibling caller routine. The first time it is invoked, it receives and stores its input values, then produces one output (the lower bound of the range). Each subsequent time through the loop it is invoked again; it increments its internal state and yields a new output back to the caller. No allocations occur, and an early break from the loop wastes nothing. + +If we want to choose one conceptual parallel for how protocols relate to one another, we should think of them as coroutines, not subroutines; doing so constrains us less. Although payment as a subroutine inside credential issuance sounds plausible at first glance, it turns out to be clumsy under deeper analysis. A payment protocol yields more than one output -- typically a preauthorization at an intermediate stage, then a final outcome when it completes. At the preauthorization stage, it should accept graceful cancellation (a second input, after launch). And high-speed, bulk issuance of credentials is likely to benefit from payment and issuance being partly parallelized instead of purely sequential. + +![diagram of payment as a coprotocol](payment-coprotocol.png) + +Similarly, a handshake protocol like [DID Exchange](../../features/0023-did-exchange/README.md) or [Connection](../../features/0160-connection-protocol/README.md) is best framed as a coprotocol of [Introduce](../../features/0028-introduce/README.md); this makes it easy for Introduce to complete as soon as the handshake begins, instead of waiting for the handshake to finish as if it were a subroutine. + +By thinking of cross-protocol interactions like coroutine interactions, we get the best of both worlds: where the interaction is just subroutine-like, the model lets us simplify; where we need more flexibility and power, the model still fits. + +Protocols don't have to support the types of coprotocol interactions we're describing here; protocols developed by Aries developers have already proven their value even without it. But to unlock their full potential, adding __coprotocol support__ to new and existing protocol definitions may be worthwhile. This requires only a modest update to a protocol RFC, and creates little extra work for implementers. + +### The simple approach that falls apart + +When the DIDComm community first began thinking about one protocol invoking another, we imagined that the interface to the called coprotocol would simply be its first message. For example, if verfiable credential issuer Acme Corp wanted to demand payment for a credential during an issuance protocol with Bob, Acme would send to Bob a `request_payment` message that constituted the first message in a `make_payment` protocol. This would create an instance of the payment protocol running alongside issuance; issuance could then wait until it completed before proceeding. And Bob wouldn't need to lift a finger to make it work, if he already supported the payment protocol. + +Unfortunately, this approach looks less attractive after study: + +* It creates a tight coupling between issuance and payment. The logic inside issuance must know exactly what data format, semantics, and versioning rules apply to the payment protocol, in order to generate its first message. If the payment protocol changes, the issuance protocol breaks. There is no flexibility in issuance to negotiate an optimal payment protocol from among several alternatives that both parties support. The implementation of issuance is too opinionated about how to approach a logically independent task. + +* It doesn't give Bob any context. We don't want to inconvenience Bob to support payment in conjunction with issuance, but we DO want Bob to know that the payment protocol instance he participates in is related to the credential issuance protocol that's also underway. This is more than just connecting the two with DIDComm's [message threading](../0008-message-id-and-threading/README.md); if one protocol is abandoned or completes or fails, something probably needs to happen in the other. + +* It doesn't let Bob be the first mover. What if Bob should be requesting payment instead of Acme? (The [Protocol Role Request Protocol](https://github.com/hyperledger/aries-rfcs/blob/29c982e80bf29763a29ac9d036b332acd4b6f525/features/0474-protocol-role-request/index.md) partly addresses this need, but [lacks a formal way to give Bob data as input](https://github.com/hyperledger/aries-rfcs/pull/474/files#r424683769).) + +* It doesn't explain how the payment protocol emits output that its caller can consume. Individual agents could code proprietary answers to this question, but interoperability would be lost. + +* It doesn't offer a signalling mechanism that would let the two protocols proceed in parallel, syncing up only when necessary. + +* It doesn't explain how errors propagate, or how to decide what they mean for the calling protocol. + +### General Interface Needs + +What we want, instead, is a formal declaration of something a bit like a coprotocol's "function signature." It needs to describe the inputs that launch the protocol, and the outputs and/or errors emitted as it finishes. It should hide implementation details and remain stable across irrelevant internal changes. + +We need to bind compatible coprotocols to one another using the metadata in these declarations. And since coprotocol discovery may have to satisfy a remote party, not just a local one, our binding needs to work well dynamically, and late, and with optional, possibly overlapping plugins providing implementations. This suggests that our declarations must be rich and flexible about binding criteria — it must be possible to match on something more than just a coprotocol name and/or arg count+type. + +An interesting divergence from the function signature parallel is that we may have to describe inputs and outputs (and errors) at multiple __interaction points__, not just the coprotocol's initial invocation. + +Another subtlety is that protocol interfaces need to be partitioned by role; the experience of a payer and a payee with respect to a payment protocol may be quite different. The interface offered by a coprotocol must vary by which role the invoked coprotocol instance embodies. + +Given all these considerations, we choose to describe coprotocol interfaces using a _set_ of function-like signatures, not just _one_. We use a function-like notation to make them as terse and intuitive as possible for developers. + +#### Example + +Suppose we are writing a credential issuance protocol, and we want to use coprotocols to add support for situations where the issuer expects payment partway through the overall flow. We'd like it to be possible for our payment step to use Venmo/Zelle, or cryptocurrency, or traditional credit cards, or anything else that issuers and holders agree upon. So we want to encapsulate the payment problem as a pluggable, discoverable, negotiable coprotocol. + +We do a little research and discover that many DIDComm-based payment protocols exist. Three of them advertise support for the same coprotocol interface: + +```text +goal: aries.buy.make-payment +payee: + get: + - invoke(amount: float, currency: str, bill_of_sale: str) @ null + - proceed(continue: bool) @ requested:, waiting-for-commit + give: + - preauth(code: str) @ waiting-for-commit + - return(confirmation_code: str) @ finalizing +``` + +In plain English, the declared coprotocol semantics are: + +>This is a coprotocol interface for protocols that facilitate the `aries.buy.make-payment` [goal code](https://github.com/hyperledger/aries-rfcs/blob/2aba468a9a4daae69e42ba764124ab602dd66982/concepts/0519-goal-codes/README.md). The `payee` role in this coprotocol gets input at two interaction points, "invoke" and "proceed". Invoke happens when state is null (at launch); "proceed" happens when state is "requested" or "waiting-for-commit." At invoke, the caller of the co-protocol provides 3 inputs: an amount, a currency, and a bill of sale. At proceed, the caller decides whether to continue. Implementations of this coprotocol interface also give output at two interaction points, "preauth" and "return." At preauth, the output is a string that's a preauth code; at return, the output is a confirmation code. + +##### Simplified description only + +It's important to understand that this interface is NOT the same as the protocol's direct interface (the message family and state machine that a protocol impl must provide to implement the protocol as documented). It is, instead, a simplified encapuslation -- just like a function signature is a simplified encapsulation of a coroutine. A function impl can rename its args for internal use. It can have steps that the caller doesn't know about. The same is true for protocols: their role names, state names, message types and versions, and field names in messages don't need to be exposed directly in a coprotocol interface; they just need a mapping that the protocol understands internally. The specific payment protocol implementation might look like this (don't worry about details; the point is just that some might exist): + +![a specific payment protocol that uses a gateway + smart contracts](payment_protocol.png) + +When we describe this as a coprotocol, we omit most of its details, and we change some verbiage. The existence of the `payee`, `gateway` and `blockchain` roles is suppressed (though we now have an implicit new role -- the __caller__ of the coprotocol that gives what the protocol gets, and gets what the protocol gives). Smart contracts disappear. The concept of `handle to pending txn` is mapped to the coprotocol's `preauth` construct, and `txn hash` is mapped to the coprotocol's `confirmation_code`. As a coprotocol, the payee can interact according to a far simpler understanding, where the caller asks the payee to engage in a payment protocol, expose some simple hooks, and notify on completion: + +![when viewed as a coprotocol](as_coprotocol.png) + +##### Calling Convention + +More details are needed to understand exactly how the caller and the coprotocol communicate. There are two sources of such details: + +1. Proprietary methods +2. Standard Aries-style DIDComm protocol + +Proprietary methods allow aggressive optimization. They may be appropriate when it's known that the caller and the coprotocol will share the same process space on a single device, and the code for both will come from a single codebase. In such cases, there is no need to use DIDComm to communicate. + +Answer 2 may be more chatty, but is better when the coprotocol might be invoked remotely (e.g., Acme's server A is in the middle of issuance and wants to invoke payment to run on server B), or where the codebases for each party to the interaction need some independence. + +The expectation is that co-protocols share a compatible trust domain; that is, coprotocol interactions occur *within* the scope of one identity rather than across identity boundaries. Thus, interoperability is not a strong requirement. Nonetheless, approaching this question as a standard protocol problem leads to a clean, loosely couple architecture with little incremental cost in an agent. Therefore, a protocol for coprotocol coordination has been developed. This is the subject of sister document [Aries RFC 0482: Coprotocol Protocol](../../features/0482-coprotocol-protocol/README.md). + +## Reference + +More about optional fields and syntax in a coprotocol declaration. + +How to add a coprotocol decl to a protocol. + +## Drawbacks + +Why should we *not* do this? + +## Rationale and alternatives + +- Why is this design the best in the space of possible designs? +- What other designs have been considered and what is the rationale for not +choosing them? +- What is the impact of not doing this? + +## Prior art + +Coroutines — the computer science scaffolding against which coprotocols are modeled — are extensively discussed in the literature of various compiler developer communities. The discussion about adding support for this feature in Rust is particularly good background reading: https://users.rust-lang.org/t/coroutines-and-rust/9058 + +## Unresolved questions + +- What parts of the design do you expect to resolve through the +enhancement proposal process before this gets merged? +- What parts of the design do you expect to resolve through the +implementation of this feature before stabilization? +- What related issues do you consider out of scope for this +proposal that could be addressed in the future independently of the +solution that comes out of this doc? + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/concepts/0478-coprotocols/as_coprotocol.png b/concepts/0478-coprotocols/as_coprotocol.png new file mode 100644 index 000000000..a143b470c Binary files /dev/null and b/concepts/0478-coprotocols/as_coprotocol.png differ diff --git a/concepts/0478-coprotocols/as_coprotocol.puml b/concepts/0478-coprotocols/as_coprotocol.puml new file mode 100644 index 000000000..8f5c7c85f --- /dev/null +++ b/concepts/0478-coprotocols/as_coprotocol.puml @@ -0,0 +1,27 @@ +@startuml +skinparam EntityBorderColor #505050 + +title Simplified Coprotocol Interface +autonumber 5 +hide footbox +entity "Caller" as caller #red +actor "Payee" as payee +caller --> payee: invoke(amount, currency, bill_of_sale)\npayee state => requested +alt continue or not + autonumber 6.1 + payee --> payee: state =>\nwaiting for commit + payee --> caller: preauth(code) + alt commit or not + autonumber 6.3.1 + caller --> payee: proceed(continue = true)\npayee state => finalizing + payee --> caller: return(confirmation_code) + else + autonumber 6.3.0 + caller [#gray]--x payee: proceed(continue = false) + end alt +else + autonumber 6.0 + caller [#gray]--x payee: proceed(continue = false) +end alt + +@enduml \ No newline at end of file diff --git a/concepts/0478-coprotocols/icon.png b/concepts/0478-coprotocols/icon.png new file mode 100644 index 000000000..582d8224f Binary files /dev/null and b/concepts/0478-coprotocols/icon.png differ diff --git a/concepts/0478-coprotocols/payment-coprotocol.png b/concepts/0478-coprotocols/payment-coprotocol.png new file mode 100644 index 000000000..33837b78b Binary files /dev/null and b/concepts/0478-coprotocols/payment-coprotocol.png differ diff --git a/concepts/0478-coprotocols/payment-protocol.puml b/concepts/0478-coprotocols/payment-protocol.puml new file mode 100644 index 000000000..df71fbdab --- /dev/null +++ b/concepts/0478-coprotocols/payment-protocol.puml @@ -0,0 +1,30 @@ +@startuml +skinparam EntityBorderColor #505050 + +title Imagined Payment Protocol: Gateway + Smart Contract +autonumber +hide footbox +actor "Payee" as payee +actor "Payer" as payer +entity "Gateway" as gate #green +entity "Blockchain" as chain #blue +payee -> payer: Payment Request\n(payee state=requested\npayer state=requested) +alt reject or cooperate + autonumber 2.1 + payer -> gate: Payment Config\n(payer state=configured) + gate --> chain: give desired txn info\nto smart contract + chain --> chain: validate + chain --> gate: handle to pending txn + gate --> payer: handle to pending txn\n(payer state=pending) + payer --> gate: commit\n(payer state=committed) + gate --> chain: commit + chain -> chain: transfer via\nsmart contract + chain -> gate: txn hash + gate -> payer: txn hash\n(payer state=done) + payer -> payee: txn hash\n(payee state=done) +else + autonumber 2.0 + payer [#gray]-x payee: Reject\n(payer state=rejected\npayee state=abandoned) +end alt + +@enduml \ No newline at end of file diff --git a/concepts/0478-coprotocols/payment_protocol.png b/concepts/0478-coprotocols/payment_protocol.png new file mode 100644 index 000000000..f6ff1c77b Binary files /dev/null and b/concepts/0478-coprotocols/payment_protocol.png differ diff --git a/concepts/0519-goal-codes/README.md b/concepts/0519-goal-codes/README.md new file mode 100644 index 000000000..5a4bb89f8 --- /dev/null +++ b/concepts/0519-goal-codes/README.md @@ -0,0 +1,174 @@ +# 0519: Goal Codes +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2021-04-15 +- Status Note: Used in several protocols that are part of [AIP 2.0](../0302-aries-interop-profile/README.md), such as the [Out-of-Band](../../features/0434-outofband/README.md) protocol. +- Start Date: 2020-01-01 +- Tags: [concept](/tags.md#concept) + +## Summary + +Explain how different parties in an SSI ecosystem can communicate about their intentions in a way that is understandable by humans and by automated software. + +## Motivation + +[Agents](../0004-agents/README.md) exist to achieve the intents of their owners. Those intents largely unfold through [protocols](../0003-protocols/README.md). Sometimes intelligent action in these protocols depends on a party declaring their intent. We need a standard way to do that. + +## Tutorial + +Our early learnings in SSI focused on VC-based proving with a very loose, casual approach to context. We did demos where Alice connects with a potential employer, Acme Corp -- and we assumed that each of the interacting parties had a shared understanding of one another's needs and purposes. + +But in a mature SSI ecosystem, where unknown agents can contact one another for arbitrary reasons, this context is not always easy to deduce. Acme Corp's agent may support many different protocols, and Alice may interact with Acme in the capacity of customer or potential employee or vendor. Although we have [feature discovery](../../features/0031-discover-features/README.md) to learn what's possible, and we have [machine-readable governance frameworks](../0430-machine-readable-governance-frameworks/README.md) to tell us what rules might apply in a given context, we haven't had a way to establish the context in the first place. When Alice contacts Acme, a context is needed before a governance framework is selectable, and before we know which features are desirable. + +The key ingredient in context is __intent__. If Alice says to Acme, "I'd like to connect,", Acme wants to be able to trigger different behavior depending on whether Alice's intent is to be a customer, apply for a job, or audit Acme's taxes. This is the purpose of a goal code. + +### The goal code datatype + +To express intent, this RFC formally introduces the goal code datatype. When a field in a [DIDComm](../0005-didcomm/README.md) message contains a goal code, its semantics and format match the description given here. (Goal codes are often declared via the `~thread` decorator, but may also appear in ordinary message fields. See the [Scope section](#scope) below. Convention is to name this field "goal_code" where possible; however, this is only a convention, and individual protocols may adapt to it however they wish.) + +>TODO: should we make a decorator out of this, so protocols don't have to declare it, and so any message can have a goal code? Or should we just let protocols declare a field in whatever message makes sense? + +Protocols use fields of this type as a way to express the intent of the message sender, thus coloring the larger context. In a sense, goal codes are to DIDComm what the `subject:` field is to email -- except that goal codes have formalized meanings to make them recognizable to automation. + +Goal codes use a standard format. They are lower-cased, kebab-punctuated strings. ASCII and English are recommended, as they are intended to be read by the software developer community, not by human beings; however, full UTF-8 is allowed. They support hierarchical dotted notation, where more general categories are to the left of a dot, and more specific categories are to the right. Some example goal codes might be: + +* `aries.sell.consumer.fitness` +* `meetupcorp.personal.date` +* `dif.employment.check-references` +* `cci.healthcare.arrange` + +Goals are inherently self-attested. Thus, goal codes don't represent objective fact that a recipient can rely upon in a strong sense; subsequent interactions can always yield surprises. Even so, goal codes let agents triage interactions and find misalignments early; there's no point in engaging if their goals are incompatible. This has significant benefits for spam prevention, among other things. + +### Verbs + +Notice the verbs in the examples: `sell`, `date`, `hire`, and `arrange`. Goals typically involve action; a complete goal code should have one or more verbs in it somewhere. Turning verbs into nouns (e.g., `employment.references` instead of `employment.check-references`) is considered bad form. (Some namespaces may put the verbs at the end; some may put them in the middle. That's a purely stylistic choice.) + +### Directionality + +Notice, too, that the verbs may imply directionality. A goal with the `sell` verb implies that the person announcing the goal is a would-be seller, not a buyer. We could imagine a more general verb like `engage-in-commerce` that would allow either behavior. However, that would often be a mistake. The value of goal codes is that they let agents align around intent; announcing that you want to engage in general commerce without clarifying whether you intend to sell or buy may be too vague to help the other party make decisions. + +It is conceivable that this would lead to parallel branchs of a goal ontology that differ only in the direction of their verb. Thus, we could imagine `sell.A` and `sell.B` being shadowed by `buy.A` and `buy.B`. This might be necessary if a family of protocols allow either party to initiate an interaction and declare the goal, and if both parties view the goals as perfect mirror images. However, practical considerations may make this kind of parallelism unlikely. A random party contacting an individual to sell something may need to be quite clear about the type of selling they intend, to make it past a spam filter. In contrast, a random individual arriving at the digital storefront of a mega retailer may be quite vague about the type of buying they intend. Thus, the `buy.*` side of the namespace may need much less detail than the `sell.*` side. + +### Goals for others + +Related to directionality, it may occasionally be desirable to propose goals to others, rather than adovcating your own: "Let <parties = us = Alice, Bob, and Carol> <goal = hold an auction> -- I nominate Carol to be the <role = auctioneer> and get us started." The difference between a normal message and an unusual one like this is not visible in the goal code; it should be exposed in additional fields that associate the goal with a particular identifier+role pair. Essentially, you are proposing a goal to another party, and these extra fields clarify who should receive the proposal, and what role/perspective they might take with respect to the goal. + +Making proposals like this may be a feature in some protocols. Where it is, the protocols determine the message field names for the goal code, the role, and the DID associated with the role and goal. + +### Matching + +The goal code `cci.healthcare` is considered a more general form of the code `cci.healthcare.procedure`, which is more general than `cci.healthcare.procedure.schedule`. Because these codes are hierarchical, wildcards and fuzzy matching are possible for either a sender or a recipient of a message. Filename-style globbing semantics are used. + +A sender agent can specify that their owner's goal is just `meetupcorp.personal` without clarifying more; this is like specifying that a file is located under a folder named "meetupcorp/personal" without specifying where; any file "under" that folder -- or the folder itself -- would match the pattern. A recipient agent can have a policy that says, "Reject any attempts to connect if the goal code of the other party is `aries.sell.*`. Notice how this differs from `aries.sell*`; the first looks for things "inside" `aries.sell`; the latter looks for things "inside" `aries` that have names beginning with `sell`. + +### Scope + +When is a declared goal known to color interactions, and when is it undefined? + +We previously noted that goal codes are a bit like the `subject:` header on an email; they contextualize everything that follows *in that thread.* We don't generally want to declare a goal outside of a thread context, because that would prevent an agent from engaging in two goals at the same time. + +Given these two observations, we can say that a goal applies as soon as it is declared, and it continues to apply to all messages in the same thread. It is also inherited by implication through a thread's `pthid` field; that is, a parent thread's goal colors the child thread unless/until overridden. + +### Namespacing + +To avoid collision and ambiguity in code values, we need to support namespacing in our goal codes. Since goals are only a coarse-grained alignment mechanism, however, we don't need perfect decentralized precision. Confusion isn't much more than an annoyance; the worst that could happen is that two agents discover one or two steps into a protocol that they're not as aligned as they supposed. They need to be prepared to tolerate that outcome in any case. + +Thus, we follow the same general approach that's used in java's packaging system, where organizations and communities use a self-declared prefix for their ecosystem as the leftmost segment or segments of a family of identifiers (goal codes) they manage. Unlike java, though, these need not be tied to DNS in any way. We recommend a single segment namespace that is a unique string, and that is an alias for a URI identifying the origin ecosystem. (In other words, you don't need to start with "com.yourcorp.yourproduct" -- "yourcorp" is probably fine.) + +The `aries` namespace alias is reserved for goal codes defined in Aries RFCs. The URI aliased by this name is TBD. See the [Reference section](#reference) for more details. + +### Versioning + +Semver-style semantics don't map to goals in an simple way; it is not obvious what constitutes a "major" versus a "minor" difference in a goal, or a difference that's not worth tracking at all. The content of a goal — the only thing that might vary across versions — is simply its free-form description, and that varies according to human judgment. Many different versions of a protocol are likely to share the goal to make a payment or to introduce two strangers. A goal is likely to be far more stable than the details of how it is accomplished. + +Because of these considerations, goal codes do not impose an explicit versioning mechanism. However, one is reserved for use, in the unusual cases where it may be helpful. It is to append `-v` plus a numeric suffix: `my-goal-code-v1`, `my-goal-code-v2`, etc. Goal codes that vary only by this suffix should be understood as ordered-by-numeric-suffix evolutions of one another, and goal codes that do not intend to express versioning should not use this convention for something else. A variant of the goal code without any version suffix is equivalent to a variant with the `-v1` suffix. This allows human intuition about the relatedness of different codes, and it allows useful wildcard matching across versions. It also treats all version-like changes to a goal as breaking (semver "major") changes, which is probably a safe default. + +Families of goal codes are free to use this convention if they need it, or to invent a non-conflicting one of their own. However, we repeat our observation that versioning in goal codes is often inappropriate and unnecessary. + +### Declaring goal codes + +#### Standalone RFCs or Similar Sources + +Any URI-referencable document can declare famlies or ontologies of goal codes. In the context of Aries, we encourage standalone RFCs for this purpose if the goals seem likely to be relevant in many contexts. Other communities may of course document goal codes in their own specs -- either dedicated to goal codes, or as part of larger topics. The following block is a sample of how we recommend that such goal codes be declared. Note that each code is individually hyperlink-able, and each is associated with a brief human-friendly description in one or more languages. This description may be used in menuing mechanisms such as the one described in [Action Menu Protocol](../../features/0509-action-menu/README.md). + +>#### goal codes +>##### `aries.sell` +>__en__: Sell something. Assumes two parties (buyer/seller). +>__es__: Vender algo. Asume que dos partes participan (comprador/vendedor). +>##### `aries.sell.goods.consumer` +>en: Sell tangible goods of interest to general consumers. +>##### `aries.sell.services.consumer` +>en: Sell services of interest to general consumers. +>##### `aries.sell.services.enterprise` +>en: Sell services of interest to enterprises. + +#### In DIDComm-based Protocol Specs + +Occasionally, goal codes may have meaning only within the context of a specific protocol. In such cases, it may be appropriate to declare the goal codes directly in a protocol spec. This can be done using a section of the RFC as described above. + +More commonly, however, a protocol will *accomplish* one or more goals (e.g., when the protocol is fulfilling a co-protocol interface), or will require a participant to *identify* a goal at one or more points in a protocol flow. In such cases, the goal codes are probably declared external to the protocol. If they can be enumerated, they should still be referenced (hyperlinked to their respective definitions) in the protocol RFC. + +#### In Governance Frameworks +Goal codes can also be (re-)declared in a [machine-readable governance framework](../0430-machine-readable-governance-frameworks/README.md). + +## Reference + +#### Known Namespace Aliases + +No central registry of namespace aliases is maintained; you need not register with an authority to create a new one. Just pick an alias with good enough uniqueness, and socialize it within your community. For convenience of collision avoidance, however, we maintain a table of aliases that are typically used in global contexts, and welcome PRs from anyone who wants to update it. + +alias | used by | URI +-- | -- | -- +aries | Hyperledger Aries Community | TBD + +#### Well-known goal codes + +The following goal codes are defined here because they already have demonstrated utility, based on early SSI work in Aries and elsewhere. + +##### `aries.vc` + +Participate in some form of VC-based interaction. + +##### `aries.vc.issue` + +Issue a verifiable credential. + +##### `aries.vc.verify` + +Verify or validate VC-based assertions. + +##### `aries.vc.revoke` + +Revoke a VC. + +##### `aries.rel` + +Create, maintain, or end something that humans would consider a relationship. +This may be accomplished by establishing, updating or deleting a DIDComm +messaging connection that provides a secure communication channel for the +relationship. The DIDComm connection itself is not the relationship, but would +be used to carry out interactions between the parties to facilitate the +relationship. + +##### `aries.rel.build` + +Create a relationship. Carries the meaning implied today by a LinkedIn +invitation to connect or a Facebook "Friend" request. Could be as limited +as creating a DIDComm Connection. + +##### `aries.vc.verifier.once` + +Create a DIDComm connection for the sole purpose of doing the one-time execution of a [Present Proof](/features/0454-present-proof-v2/README.md) protocol. Once the protocol execution is complete, both sides **SHOULD** delete the connection, as it will not be used again by either side. + +The purpose of the goal code flow is to accomplish the equivalent of a "connection-less" present proof by having the agents establish a DIDComm connection, execute the present proof protocol, and delete the connection. The need for this goal code is when an actual connection-less present proof cannot be used because the [out-of-band](/features/0434-outofband/README.md) (OOB) message (including the presentation request) is too large for the transport being used--most often a QR code (although it may be useful for Bluetooth scenarios as well)--and a URL shortner option is not available. By using a one-time connection, the OOB message is small enough to fit into easily into a QR code, the present proof protocol can be executed using the established connection, and at the end of the interaction, no connection remains for either side to use or manage. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/concepts/0559-pppu/README.md b/concepts/0559-pppu/README.md new file mode 100644 index 000000000..8ae7669e3 --- /dev/null +++ b/concepts/0559-pppu/README.md @@ -0,0 +1,182 @@ +# Aries RFC 0559: Privacy-Preserving Proof of Uniqueness +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com), Drummond Reed, Lovesh Harchandani, Jason Law, Brent Zundel +- Status: [PROPOSED](/README.md#proposed) +- Since: 2020-10-21 +- Status Note: documents ideas mentioned at RWOT 9 (Sep 2019) and in informal conversations before and since. This is a defensive publication by the Aries community, to prevent such ideas from being encumbered by patents. +- Start Date: 2019-02-13 (first formal writeup of the concepts) +- Tags: [concept](/tags.md#concept) + +## Summary + +Documents two techniques that, while preserving holder privacy, can guarantee a single use of a verifiable credential by any given unique holder -- the so-called "one person one vote" outcome that's often desirable in VC use cases. + +## Motivation + +Many actions need to be constrained such that a given actor (usually, a human being) can only perform the action once. In government and stockholder elections, we want each voter to cast a single vote. At national borders, we want a visa to allow entrance only a single time before a visitor leaves. In refugee camps, homeless shelters, and halfway houses, we want each guest to access food or medication a single time per distribution event. + +Solving this problem without privacy is relatively straightforward. We require credentials that disclose a person’s identity, and we track the identities to make sure each is authorized once. This pattern can be used with physical credentials, or with their digital equivalent. + +The problem is that each actor’s behavior is tracked with this method, because it requires the recording of identity. Instead of just enforcing one-person-one-vote, we create a history of every instance when person X voted, which voting station they attended, what time they cast their vote, and so forth. We create similar records about personal travel or personal medication usage. Such information can be abused to surveil, to harass, to intrude, or to spam. + +What we need is a way to prove that an action is associated with a unique actor, and thus enforce the one-actor-one-action constraint, without disclosing that actor’s identity in a way that erodes privacy. Although we began with examples of privacy for humans, we also want a solution for groups or institutions wishing to remain anonymous, or for devices, software entities, or other internet-of-things actors that have a similar need. + +## Tutorial + +### Solution 1 + +This solution allows uniqueness to be imposed on provers during an arbitrary context chosen by the verifier, with no unusual setup at issuance time. For example, a verifier could decide to constrain a particular credential holder to proving something only once per hour, or once during a given contest or election. The price of this flexibility is that the credential holder must have a digital credential that already has important uniqueness guarantees (e.g., a driver's license, a passport, etc). + +In contrast, [solution 2](#solution-2) imposes uniqueness at issuance time, but requires no other credential with special guarantees. + +#### Components + +The following components are required to solve this problem: + +##### A +**one issuance to identified holder** — A trustworthy process that issues verifiable credentials exactly once to an *identified holder*. (This is not new. Governments have such processes today to prevent issuing two driver’s licenses or two passports to the same person.) + +##### B +**one issuance to anonymous holder** — A method of issuing a credential only once to an *anonymous holder*. (This is not new. Scanning a biometric from an anonymous party, and then checking it against a list of known patterns with no additional metadata, is one way to do this. There are other, more cryptographic methods, as discussed below.) + +##### C +**strong binding** — A mechanism for strongly associating credentials with a specific credential holder, such that they are not usable by anyone other than the proper holder. (This is not new. Embedding a biometric such as a fingerprint or a photo in a credential is a simple example of such a mechanism.) + +##### D +**linking mechanism** — A mechanism for proving that it is valid to combine information from multiple credentials because they describe the same credential holder, without revealing the common link between those credentials. (An easy and familiar way to prove combinability is to embed a common characteristic in each credential. For example, two credentials that are both about a person with the same social security number can be assumed to describe the same person. What is required here goes one step further--we need a way to prove that two credentials contain the same data, or were built from the same data, without revealing that data at all. This is also not new. Cryptographic commitments provide one possible answer.) + +##### E +**proving without revealing** — A method for proving the correctness of information derived from a credential, without sharing the credential information itself. (This is not new. In cryptographic circles, one such technique is known as a zero-knowledge proof. It allows Alice to hold a credential that contains her birthdate, but to prove she is over 65 years old instead of revealing the birthdate itself.) + +#### Walkthru + +We will describe how this solution uses components A-E to help a fictional voter, Alice, in an interaction with a fictional government, G. Alice wishes to remain anonymous but still cast her vote in an election; G wishes to guarantee one-citizen-one-vote, but to retain no additional information that would endanger Alice’s privacy. Extrapolating from a voting scenario to other situations that require uniqueness is left as an exercise for the reader. + +The solution works like this: + +1. Alice receives a voter credential, C1, from G. C1 strongly identifies Alice, perhaps containing her name, address, birthdate, and so forth. It is possession of this credential that proves a right to vote. G issues only one such credential to each actor. ([component A](#a)) + +2. C1 is bound to Alice so it can’t be used by anyone else. ([component C](#c)) + +3. C1 also contains data provided by Alice, and derived from a secret that only Alice knows, such that Alice can link C1 to other credentials with similarly derived data because she knows the secret. ([component D](#d)) + + ![identified issuance](identified-issuance.png) + + Steps 1-3: Alice receives a voter credential from G. + +4. Alice arrives to vote and asserts her privilege to a different government agency, G’, that administers the election. + +5. G’ chooses a random identifier, X, for the anonymous person (Alice) that wants to vote. + +6. G’ asks this anonymous voter (Alice) to provide data suitable for embedding in a new credential, such that the new credential and her old credential can be proved combinable. ([component D](#d)). + +7. G’ verifies that it has not issued a credential to this anonymous person previously. ([component B](#b)) + +8. G’ issues a new credential, C2, to the anonymous voter. C2 contains the random identifier X, plus the data that Alice provided in step 6. (This means the party playing the role of *Verifier* temporarily becomes a JIT *Issuer*.) + + ![anonymous issuance](anonymous-issuance.png) + + Steps 4-8: Anonymous (Alice) receives a unique credential from G’. + +9. G’ asks the anonymous voter to prove, without revealing any identifying information from C1 ([component E](#e)) the following assertions: + * They possess a C1 and C2 that are combinable ([component D](#d)) + * The C2 possessed by this anonymous voter contains the randomly-generated value X that was just chosen and embedded in the C2 issued by G’. At this point X is revealed. + + ![linked creds](linked-creds.png) + + Step 9: Alice proves C1 and C2 are combinable and C2 contains X. + +This solves the problem because: + +* Each actor can only receive one C1 from G. +* Each actor can only receive one C2 from G’. +* C1 cannot be shared or transferred. +* It is valid to combine information from C1 and C2 (they belong to the same actor), because of the first assertion in step 9. +* C2 is the same C2 that was just generated for the person asking to vote (it could not have been substituted), because it contains X as demonstrated by the second assertion in step 9. +* No identifying information in C1 is revealed. + +Both credentials are required. If a person only has C1, then there is no way to enforce single usage while remaining anonymous. If a person only has C2, then there is no reason to believe the unique person who shows up to vote actually deserves the voting privilege. It is the combination that proves uniqueness of the person in the voting event, plus privilege to cast a vote. Zero-knowledge proving is also required, or else the strongly identifying information in C1 may leak. + +As mentioned earlier, this same mechanism can be applied to scenarios besides voting, and can be used by actors other than individual human beings. G (the issuer of C1) and G’ (the verifier of C1 and issuer of C2) do not need to be related entities, as long as G1 trusts G. What is common to all applications of the technique is that uniqueness is proved in a context chosen by the verifier, privilege is based on previously issued and strongly identifying credentials, and yet the anonymity of the credential holder is preserved. + +#### Building in Aries + +Ingredients to build this solution are available in Aries or other Hyperledger projects (Ursa, Indy) today: + +* The behavior of [component A](#a) could be enforced by a [machine-readable governance framework](../0430-machine-readable-governance-frameworks/README.md). + +* [Component B](#b) can be built using an approach described [here](https://github.com/WebOfTrustInfo/rwot9-prague/blob/master/topics-and-advance-readings/zkp-safety.md#technique-2-prevent-link-secret-reuse); a more general description was published much earlier, in a [seminal "Clone Wars" paper](https://eprint.iacr.org/2006/454.pdf) by Camenisch et al. + +* [Component C](#c) can be accomplished using Indy's link secret construct, which uses Pedersen commitments to embed in a credential a blinded version of a secret known only to the holder. As mentioned earlier, [biometric bindings](https://ieeexplore.ieee.org/document/9031547) are also an option. Depending on requirements for level of assurance, a simple binding by DID control may also work. + +* [Component D](#d) is a mainstream feature in Indy's anoncreds library today; it combines credentials by demonstrating mathematically that they each contain a differently blinded derivation of the same link secret. A more general form of this is available in Ursa; it demonstrates that any two fields are equal in two credentials without revealing the field values. [[TODO: need link]]. + +* [Component E](#e) is available in Indy's anoncreds as well as in recent work done on BBS+ signatures by Mattr [[TODO: need link]]. + +### Solution 2 + +This is another solution that accomplishes approximately the same goal as [solution 1](#solution-1). It is particularly helpful in voting. It has much in common with the earlier approach, but differs in that uniqueness must be planned for at time of issuance (instead of being imposed just in time at verification). The issuer signs a serial number to each unique holder, and the holder then makes a Pedersen Commitment to their unique serial number while the voting is open. The holder cannot vote twice or change their vote. The voter’s privacy is preserved. + +#### Walkthru + +Suppose a poll is being conducted with p number of options as m1, m2, m3,... mp and each poll has a unique id I. Acme Corp is conducting the poll and Alice is considered an eligible voter by Acme Corp because Alice has a credential C from Acme Corp. + +##### Goals + +* **Ballot privacy**: Alice should be able to participate in the poll without Acme corp finding out which poll option was chosen by Alice. + +* **One vote per voter**: Alice should not be able to vote more than once. + +* **Immutable Ballot**: Alice should be bound to her ballot, i.e. she should not be able to change her vote. + +* **Valid choice**: Alice should not be able to vote for any option than the valid ones, i.e. other than m1, m2, m3,... mp. + +* **Verifiability**: Alice should be able to check that her vote is being counted. + +* **No preview**: Before the poll terminates, no one should be able to decide the outcome or even the favored option. This avoids bias. + +Additional condition: In some cases the poll conduction entity, Acme Corp, in this case, may be accused of creating Sybil identities vote to influence the poll. This can be mitigated if an additional constraint is enforced where only those are eligible to vote who can prove that their credential C was issued before the poll started (or at least some time t before the poll started), i.e. Alice should be able to prove to anyone that her credential C was issued to anyone. + +##### Setup +Acme corp has hosted an application AS that maintains a merkle tree and the application follows some rules to update the tree. This application should be auditable meaning that anyone should be able to check whether the application is updating the tree as per the rules and the incoming data. Thus this application could be hosted on a blockchain, or within a trusted execution environment like SGX. Also the application server maintains a dynamic set where set membership check is efficient. The merkle tree is readable by all poll participants. + +There are 2 different functions defined F1 and F2 both of which take 2 inputs and return one output and they are not invertible, even knowing one input and output should not reveal other input. The output of both on same input must be different. Thus these can be modeled as different hash functions like SHA2 and SHA3 or SHA2 with domain separation. But we want these functions to R1CS friendly so we choose a hash function like MiMC with domain separation. + +##### Basic idea +Alice generates a serial number and gets a blind signature from Acme Corp over the serial number. Then Alice creates her vote and sends the "encrypted" vote with the serial number and signature to the application server. Application server accepts the vote if the signature is valid and it has not seen that serial number before. It will then update the merkle tree with the "encrypted" vote and return a signed proof to Alice of the update. When the poll terminates, Alice will then submit the decryption key to the application server which can then decrypt the vote and do the tally. + +##### Detailed description +* Acme corp conducts a poll with p choices, m1, m2,..mp. The poll is given a unique identifier I. +* Alice wants to participate in the poll. She has a credential C from Acme with link secret l. +* Alice constructs serial number S using F1. S = F1(l, I). +* Alice blinds S and then obtains a blind signature (blind Schnorr works) from Amce Corp over it. Alice might have proved her ownership of credential C. +* Alice decides to vote for m2. She needs to commit to her vote as a Pedersen commitment. The randomness for the Pedersen commitment r is computed using F2. r = F2(l, I). The committed vote now becomes gm2.hr. Let V = gm2.hr. +* Alice sends V and S and the signature over S from Acme to application server AS. Alice also sends a proof which proves the following: +* Alice owns a credential C from Acme Corp. This can be done with CL or BBS+ signature. Additionally, it can be proved that C was issued some time ago to achieve characteristic 5. +* Serial number S is constructed from the link secret l of C and poll identifier I using F1. This can be done with Bulletproofs by using proof of knowledge of preimage. We have proving knowledge of preimage implemented. The part about establishing equivalence with link secret l has to be done. +* V is correctly formed in this way gm2.hr. This is a standard Schnorr proof. +* V's randomness r is constructed from the link secret l of C and poll identifier I using F2. Again done with Bulletproofs above and circuit to prove knowledge of opening of Pedersen commitment. The 2nd part is to be implemented. +* V's message m2 is one of m1, m2,..mp. This can be done with set membership proof of committed value with Bulletproofs. We have it implemented already. +* If application server AS accepts a proof, it returns the signed merkle proof of the presence of V in the tree to Alice. +* Alice can anytime check that her V is present in the tree. +* Once poll completes, Alice can reveal opening of V to AS and then result of poll can be computed. +* Before the poll completes (and voter reveals their m and r, no one can know which option has been voted the most or least or not at all. + +## Rationale and alternatives + + +## Prior art + + +## Unresolved questions + + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/concepts/0559-pppu/anonymous-issuance.png b/concepts/0559-pppu/anonymous-issuance.png new file mode 100644 index 000000000..7117c2f30 Binary files /dev/null and b/concepts/0559-pppu/anonymous-issuance.png differ diff --git a/concepts/0559-pppu/identified-issuance.png b/concepts/0559-pppu/identified-issuance.png new file mode 100644 index 000000000..3e80c199d Binary files /dev/null and b/concepts/0559-pppu/identified-issuance.png differ diff --git a/concepts/0559-pppu/linked-creds.png b/concepts/0559-pppu/linked-creds.png new file mode 100644 index 000000000..34034df73 Binary files /dev/null and b/concepts/0559-pppu/linked-creds.png differ diff --git a/concepts/0566-issuer-hosted-custodidal-agents/README.md b/concepts/0566-issuer-hosted-custodidal-agents/README.md new file mode 100644 index 000000000..3e3ad9a43 --- /dev/null +++ b/concepts/0566-issuer-hosted-custodidal-agents/README.md @@ -0,0 +1,108 @@ +# 0566: Issuer-Hosted Custodial Agents +- Authors: [Sam Curren](mailto:telegramsam@gmail.com) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2020-11-16 +- Status Note: Draft +- Start Date: 2020-10-27 +- Tags: concept + +In the fully realized world of Self Soverign Identity, credential holders are equipped with capable agents to help them manage credentials and other SSI interactions. Before we arrive in that world, systems that facilitate the transition from the old model of centralized systems to the new decentralized models will be necessary and useful. + +One of the common points for a transition system is the issuance of credentials. Today's centralized systems contain information within an information silo. Issuing credentials requires the recipient to have an agent capable of receiving and managing the credential. Until the SSI transition is complete, some users will not have an agent of their own. + +Some users don't have the technology or the skills to use an agent, and there may be users who don't want to participate. + +In spite of the difficulties, there are huge advantages to transition to a decentralized system. Even when users don't understand the technology, they do care about the benefits it provides. + +This situation leaves the issuer with a choice: Maintain both a centralized system AND a decentralized SSI one, or enable their users to participate in the decentralized world. + +This paper addresses the second option: How to facilitate a transition to a decentralized world by providing issuer-hosted custodial agents. + +## Issuer-Hosted Custodial Agents + +A custodial agent is an agent hosted on behalf of someone else. This model is common in the cryptocurrency space. An Issuer-Hosted Custodial Agent is exactly what it sounds like: an agent hosted for the holder of a credential by the issuer of the credential. + +This custodial arrangement involves managing the credentials for the user, but also managing the keys for the user. Key management on behalf of another is often called guardianship. + +An alternative to hosting the agent directly is to pay for the hosting by a third party provider. This arrangement addresses some, but not all, of the issues in this paper. + +This custodial arrangement is only necessary for the users without their own agents. Users running their own agents (often a mobile app), will manage their own keys and their own credentials. + +For the users with their own agents, the decentralized world has taken full effect: they have their own data, and can participate fully in the SSI ecosystem. + +For the users with hosted custodial agents, they have only made a partial transition. The data is still hosted by the issuer. With appropriate limits, this storage model is no worse than a centralized system. Despite the data storage being the same, a hosted agent provides the ability to migrate to another agent if the user desires. + +Hosting agents for users might sound like a costly endeavor, but hosted agents contain an advantage. Most hosted agents will only be used by their owners for a small amount of time, most likely similar to their interaction with the centralized system it replaces. This means that the costs are substantially lower than hosting a full agent. + +## Hosted Agent Interaction + +Hosted agents have some particular challenges in providing effective user interaction. Detailed below are several options that can be used alone or in combination. + +### Browser Based +Providing a browser based user interface for a user is a common solution when the user will have access to a computer. Authentication will likely use something familiar like a username and password. + +### Authorizing Actions +The user will often need a way to authorize actions that their agent will perform. +A good option for this is via the use of a basic cell phone through SMS text messages or voice prompts. +Less urgent actions can use an email sent to the user, prompting the user to login and authorize the actions. + +### Offline / Paper based +At times the user will have no available technology for their use. In this case, providing QR codes printed on paper with accompanying instructions will allow the user to facilitate verifier (and perhaps another issuer) access to their cloud agent. +QR Codes, such as those detailed in the Out Of Band Protocol, can contain both information for connecting to agent AND an interaction to perform. +Presenting the QR code for scanning can serve as a form of consent for the prescribed action within the QR code. +Printed QR codes can be provided by the issuer at the time of custodial agent creation, or from within a web interface available to the user. + +### Kiosk based +Kiosks can be useful to provide onsite interaction with a hosted agent. Kiosk authentication might take place via username and password, smartcard, or USB crypto key, with the possible inclusion of a biometric. +Kiosks must be careful to fully remove any cached data when a session closes. +Any biometric data used must be carefully managed between the kiosk and the hosted agent. + +### Smartphone App +While it is common for a smartphone app to be an agent by itself, there are cases where a smartphone app can act as a remote for the hosted agent. In this iteraction, keys, credentials, and other wallet related data is held in the custodial agent. The mobile app acts as a remote viewer and a way for the user to authorize actions taken by the custodial agent. + +## Best Practices + +The following best practices should be followed to ensure proper operation and continued transition to a fully realized SSI architecture. +Most of these practices depend upon and support one another. + +### Defend the SSI architecture +When issuers host custodial agents, care must be taken to avoid shortcuts that would violate SSI architecture. Deviations will frequently lead to incompatibilities. + +### DIDComm Protocol based Integration +Communication between hosted agents and credential issuing agent must be based on published DIDComm protocols. Any communication which eliminates the use of a DID must be avoided. Whenever possible, these should be well adopted community protocols. If the case a new protocol is needed for a particular interaction, this must be fully documented and published, to allow other agents to become compatible by adopting the new protocol. + +### Allow bring-your-own agents +The onboarding process must allow users to bring their own compatible agents. This will be possible as long as any communication is protocol based. No features available to hosted agents should be blocked from user provided agents. + +### Limit wallet scope to data originating from the issuer +Issuer hosted agents should have limits placed on them to prevent general use. This will prevent the agent from accepting additional credentials and data outside the scope of the issuer, therefore introducing responsibility for data that was never intended. This limtation must not limit the user in how they use the credentials issued, only in the acceptance of credentials and data from other issuers or parties. +The use of policy and filters should be used to limit the types of credentials that can be held, which issuers should be allowed, and which protocols are enabled. +None of these restrictions are necessary for bring-your-own agents provided by users. + +### Allow migrate from hosted to bring-your-own +Users must be allowed to transition from an issuer-hosted agent to an agent of their choosing. This can happen either via a backup in a standard format, or via re-issuing relevant credentials. + +### Transparent to the verifier +A verifier should not be able to tell the difference between a custodial hosted agent vs a bring-your-own agent. + +### Action Log +All actions taken by the wallet should be preserved in a log viewable to the user. This includes how actions were authorized, such as a named policy or confirmation via text message. + +### Encrypted Wallets +Hosted wallet data should be encrypted at rest. + +### Independant key management +Keys used for hosted agents should have key mangement isolated from the issuer keys. Access to the keys for hosted agents should be carefully limited to the minimum required personnel. All key access should be logged. + +### Hosted Agent Isolation +Agents must be sufficiently isolated from each other to prevent a malicious user from accessing another user's agent or data or causing interruptions to the operation of another agent. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | diff --git a/concepts/0700-oob-through-redirect/ExampleQRCode1.svg b/concepts/0700-oob-through-redirect/ExampleQRCode1.svg new file mode 100644 index 000000000..af1edb95c --- /dev/null +++ b/concepts/0700-oob-through-redirect/ExampleQRCode1.svg @@ -0,0 +1,3008 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/concepts/0700-oob-through-redirect/ExampleQRCode2.svg b/concepts/0700-oob-through-redirect/ExampleQRCode2.svg new file mode 100644 index 000000000..7b26ff60c --- /dev/null +++ b/concepts/0700-oob-through-redirect/ExampleQRCode2.svg @@ -0,0 +1,1039 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/concepts/0700-oob-through-redirect/README.md b/concepts/0700-oob-through-redirect/README.md new file mode 100644 index 000000000..14dfdd1bf --- /dev/null +++ b/concepts/0700-oob-through-redirect/README.md @@ -0,0 +1,189 @@ +# Aries RFC 0700: Out-of-Band through redirect + +- Authors: [Sudesh Shetty](mailto:sudesh.shetty@securekey.com) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2021-10-08 +- Status Note: implementation is being explored by SecureKey +- Start Date: 2019-10-08 +- Tags: [concept](/tags.md#concept), [decorator](/tags.md#decorator) + +## Summary + +Describes how one party can redirect to another party by passing out-of-band message as a query string and also recommends how to redirect back once protocol is over. + +## Motivation + +In current day e-commerce applications, while performing checkout users are usually presented with various payment options, like direct payment options or through some payment gateways. +User then chooses an option, gets redirected to a payment application and then gets redirected back once transaction is over. + +Similarly, sending an out-of-band invitation through redirect plays an important role in web based applications where an inviter who is aware of invitee application or a selection service should be able to send invitation through redirect. +Once invitee accepts the invitation and protocol gets over, then invitee should also be able to redirect back to URL shared through DIDComm message during protocol execution. +The redirect can happen within the same device (ex: clicking a link) or between devices (ex: scanning a QR code). + +## Scenario + +Best example scenario would be how an issuer or a verifier applications trying to connect to holder applications for performing present proof or issuer credential protocol. A user who visits an issuer application can click on +a link or scan a QR code to redirect to a holder application with an out-of-band message in query string (or redirect to a selection service showing available holder applications to choose from). +User's holder application decodes invitation from query string, performs issue credential protocol and redirects user back to URL it received through DIDComm message from issuer during execution of protocol. + + +## Tutorial + +There are 2 roles in this flow, + +- requestor, the one who sends out-of-band invitation using query string to initiate a protocol. +- recipient, the one who receives out-of-band invitation and also the one who is asked to redirect back to requestor once protocol is over. + +### Redirect Invitation URL +A redirect URL from inviter to connect can consist of following elements, + +- `domain and path`: domain and path are managed by inviter application and it can be a target application to which this out-of-band invitation is targeted. The target application can be a agent based application or a selection service which can present various application selection options to user. +- `out-of-band message`: A query parameter `oob` containing out-of-band message of Base64URLEncoded json format. Refer [Standard Out-of-Band Message Encoding](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md#standard-out-of-band-message-encoding) to learn more. +- `out-of-band message ID`: It seems inevitable that the length of some out-of-band message will be too long to produce a useable redirect URL or QR Code. A query parameter `oobid` containing out-of-band invitation URL which can be resolved to fetch actual invitation message. +Refer [Out-of-Band URL Shortening](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md#url-shortening) to learn more. + +##### Sample 1: redirect invitation + +Invitation: + +```json +{ + "@type": "https://didcomm.org/out-of-band/1.0/invitation", + "@id": "69212a3a-d068-4f9d-a2dd-4741bca89af3", + "label": "Faber College", + "goal_code": "issue-vc", + "goal": "To issue a Faber College Graduate credential", + "handshake_protocols": ["https://didcomm.org/didexchange/1.0", "https://didcomm.org/connections/1.0"], + "services": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] +} +``` + +Whitespace removed: + +```jsonc +{"@type":"https://didcomm.org/out-of-band/1.0/invitation","@id":"69212a3a-d068-4f9d-a2dd-4741bca89af3","label":"Faber College","goal_code":"issue-vc","goal":"To issue a Faber College Graduate credential","handshake_protocols":["https://didcomm.org/didexchange/1.0","https://didcomm.org/connections/1.0"],"services":["did:sov:LjgpST2rjsoxYegQDRm7EL"]} +``` + +Base 64 URL Encoded: + +```text +eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCAiZ29hbF9jb2RlIjoiaXNzdWUtdmMiLCJnb2FsIjoiVG8gaXNzdWUgYSBGYWJlciBDb2xsZWdlIEdyYWR1YXRlIGNyZWRlbnRpYWwiLCJoYW5kc2hha2VfcHJvdG9jb2xzIjpbImh0dHBzOi8vZGlkY29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIiwiaHR0cHM6Ly9kaWRjb21tLm9yZy9jb25uZWN0aW9ucy8xLjAiXSwic2VydmljZSI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 +``` + +Example URL: targeting recipient 'recipient.example.com' + +```text +http://recipient.example.com/handle?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCAiZ29hbF9jb2RlIjoiaXNzdWUtdmMiLCJnb2FsIjoiVG8gaXNzdWUgYSBGYWJlciBDb2xsZWdlIEdyYWR1YXRlIGNyZWRlbnRpYWwiLCJoYW5kc2hha2VfcHJvdG9jb2xzIjpbImh0dHBzOi8vZGlkY29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIiwiaHR0cHM6Ly9kaWRjb21tLm9yZy9jb25uZWN0aW9ucy8xLjAiXSwic2VydmljZSI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 +``` + +Out-of-band invitation redirect URLs can be transferred via text message, email, SMS, posting on a website, or QR Code. + +Example URL encoded as a QR Code: + +![Example QR Code](ExampleQRCode1.svg) + +##### Sample 2: redirect invitation URL + +Invitation URL from requestor which resolves to an out-of-band invitation: + +```text +https://requestor.example.com/ssi?id=5f0e3ffb-3f92-4648-9868-0d6f8889e6f3 +``` + +Base 64 URL Encoded: + +```text +aHR0cHM6Ly9yZXF1ZXN0b3IuZXhhbXBsZS5jb20vc3NpP2lkPTVmMGUzZmZiLTNmOTItNDY0OC05ODY4LTBkNmY4ODg5ZTZmMw== +``` + +Example URL: targeting recipient 'recipient.example.com' + +```text +http://recipient.example.com/handle?oobid=aHR0cHM6Ly9yZXF1ZXN0b3IuZXhhbXBsZS5jb20vc3NpP2lkPTVmMGUzZmZiLTNmOTItNDY0OC05ODY4LTBkNmY4ODg5ZTZmMw== +``` + +Out-of-band invitation redirect URLs can be transferred via text message, email, SMS, posting on a website, or QR Code. + +Example URL encoded as a QR Code: + +![Example QR Code](ExampleQRCode2.svg) + +### ``~web-redirect`` Decorator +In some scenarios, requestor would require recipient to redirect back after completion of protocol execution to proceed with further processing. For example, a verifier would request a holder application to redirect back +once present-proof protocol is over so that it can show credential verification results to user and navigate the user to further steps. + +The optional `~web-redirect` SHOULD be used in DIDComm message sent by requestor during protocol execution to send redirect information to recipient if required. + +This decorator may not be needed in many cases where requestor has control over the flow of application based on protocol status. +But this will be helpful in cases where an application has little or no control over user's navigation. +For example, in a web browser where user redirected from a verifier web application to his wallet application in a same window through some wallet selection wizard and some third party logins. In this case once the protocol execution is over, +verifier can send a URL to wallet application requesting redirect. This decorator is also useful switching from wallet mobile app to verifier mobile app in a mobile device. + +```json +"~web-redirect": { + "status": "OK", + "url": "https://example.com/handle-success/51e63a5f-93e1-46ac-b269-66bb22591bfa" +} +``` + +where, + +- `status`: The value of this property MUST be one of the statuses defined [here](https://github.com/hyperledger/aries-rfcs/blob/main/features/0015-acks/README.md#ack-status) +- `url`: URL to which recipient of this message is requested to redirect. + + +Some of the DIDComm messages which can use `~web-redirect` details to send redirect request. + +- protocol acknowledgment messages +- problem reports +- protocol messages which concludes the protocol, like [Issue Credential](https://github.com/hyperledger/aries-rfcs/blob/main/features/0453-issue-credential-v2/README.md#issue-credential) message. + +### Putting all together + +#### Sending Invitation to Recipient through redirect + +![OOB Redirect](oob-redirect.png) + +- **Step 1 - requestor prepares out-of-band redirect URL** : requestor prepares URL using encoded JSON invitation or using a URL which resolves to an invitation. +Domain and target of URL can be a known recipient. + +- **Step 2: requestor presents redirect URL to user**: redirect URL can be presented to user as a link, mobile deep link, QR Code, SMS, Email etc. +For example, user visits a verifier application and presented with link or QRCode to share his or her credentials. + +- **Step 3: user redirects to recipient**: user clicks on link or scans QR code and then authenticates himself or herself in redirected application. +For example, user clicks on a link to share credentials in a verifier application, gets redirected to a holder application and logs in using his or her login credentials. + +- **Step 4: recipient accepts invitation, connects with requestor and executes protocol**: recipient application decodes invitation, accepts it and executes DIDComm protocol. +For example, holder application accepts invitation from a verifier, performs present proof and meanwhile shows credential interaction screen to user for consent. + +- **Step 5: requestor shares web redirect info to recipient for next step**: requestor sends `~web-redirect` to recipient application through acknowledgement, problem report or any other DIDComm message which concludes protocol. + For example, verifier sending its success page URL as part of acknowledgement message to user after successful completion present proof protocol. + +- **Step 6: user redirected back to requestor**: recipient application extracts redirect info from `~web-redirect` and redirects. +For example where user is presented with successful credential verification screen and asked to proceed with further steps. + + +#### Sending Invitation to Selection Service through redirect + +![OOB Redirect through selection service](oob-redirect-mediated.png) + +This flow is similar to previous flow but target domain and path of invitation redirect URL will be selection service which presents user with various options to choose recipient application of choice. +So in Step 3, user redirects to a selection service which guides user to select right recipient. +For example a scenario where user is presented with various holder application providers to choose from while sharing/saving his or her verifiable credentials. + + +## Reference + +- [Wallet And Credential Interactions](https://identity.foundation/wallet-and-credential-interactions/) + +## Rationale and alternatives + +How different recipient applications registers with a selection service and establishing trust between requestor, recipient and selection service are out of scope of this RFC. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +Name / Link | Implementation Notes +--- | --- + | | diff --git a/concepts/0700-oob-through-redirect/oob-redirect-mediated.png b/concepts/0700-oob-through-redirect/oob-redirect-mediated.png new file mode 100644 index 000000000..a0b2837df Binary files /dev/null and b/concepts/0700-oob-through-redirect/oob-redirect-mediated.png differ diff --git a/concepts/0700-oob-through-redirect/oob-redirect.png b/concepts/0700-oob-through-redirect/oob-redirect.png new file mode 100644 index 000000000..86582e2ba Binary files /dev/null and b/concepts/0700-oob-through-redirect/oob-redirect.png differ diff --git a/concepts/0757-push-notification/README.md b/concepts/0757-push-notification/README.md new file mode 100644 index 000000000..af4b219a0 --- /dev/null +++ b/concepts/0757-push-notification/README.md @@ -0,0 +1,57 @@ +# 0757: Push Notification +- Authors: [Sam Curren](mailto:telegramsam@gmail.com) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2022-11-02 +- Status Note: +- Start Date: 2022-11-02 +- Tags: [concept](/tags.md#concept) + +## Summary + +This RFC Describes the general concept of push notification as it applies to Aries Agents. There are a variety of push notification systems and methods, each of which is described in it's own feature RFC. + +> Note: These protocols operate only between a mobile app and it's mediator(s). There is no requirement to use these protocols when mobile apps and mediator services are provided as a bundle. These protocols exist to facilitate cooperation between open source mediators and mobile apps not necessarily developed between the same parties. + +## Motivation + +Mobile agents typically require the use of Mediators to receive DIDComm Messages. When messages arrive at a mediator, it is optimal to send a push notification to the mobile device to signal that a message is waiting. This provides a good user experience and allows mobile agents to be responsive without sacrificing battery life by routinly checking for new messages. + +## Tutorial + +Though push notification is common mobile platforms, there are a variety of different systems with various requirements and mecanisms. Most of them follow a familiar pattern: + +#### Setup Phase +1. Notification Sender (mediator) registers with a push notification service. This typically involves some signup procedure. +2. Notification Recipient (mobile app) registers with the push notification service. This typically involves some signup procedure. For some platforms, or for a mediator and mobile app by the same vendor, this will be accomplished in step 1. +3. Notification Recipient (mobile app) adds code (with config values obtained in step 2) to connect to the push notification service. +4. Notification Recipient (mobile app) communicates necessary information to the Notification Sender (mediator) for use in sending notifications. + +#### Notification Phase +5. A message arrives at the Notification Sender (mediator) destined for the Notification Recipient (mobile app). +6. Notification Sender (mediator) calls an API associated with the push notification service with notification details, typically using the information obtained in step 4. +7. Notification Recipient (mobile app) is notified (typically via a callback function) of the notification details. +8. Notification Recipient (mobile app) then connects to the Notification Sender (mediator) and receives waiting messages. + +In spite of the flow similarities between the push notification platforms, the implementations, libraries used, and general code paths vary substantially. +Each push notification method is described in it's own protocol. This allows the protocol to fit the specific needs and terminology of the notification method it enables. Feature Discovery can be used between the Notification Sender and the Notification Recipient to discover push notification compatibility. + +### Public Mediators + +Some push notification methods require matching keys or secrets to be used in both sending and receiving notifications. This requirement makes these push notification methods unusable by public mediators. + +Public mediators SHOULD only implement push notification methods that do not require sharing secrets or keys with application implementations. + +## Push Notification Protcols + +0699 - [Push Notification APNS 1.0](../../features/0699-push-notifications-apns/README.md) (Apple Push Notification Service) + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/concepts/0799-long-term-support/README.md b/concepts/0799-long-term-support/README.md new file mode 100644 index 000000000..a02d4fedc --- /dev/null +++ b/concepts/0799-long-term-support/README.md @@ -0,0 +1,44 @@ +# 0799: Aries Long Term Support Releases +- Authors: [Sam Curren](mailto:telegramsam@gmail.com) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2023-11-07 +- Start Date: 2023-11-07 +- Tags: [concept](/tags.md#concept) + +Long Term Support Releases of Aries projects will assist those using the software to integrate within their development processes. + +## Motivation + +Long Term Support releases allow stable use of projects without frequent code updates. Designating LTS releases frees projects to develop features without worry of disrupting those seeking feature stable deployments. + +## Project LTS Releases +- Details specific to each project will be found within the relevant repositories. +- Projects SHOULD create an LTS policy within the code repository for the project. +- Projects MAY alter any of these suggestions to match the needs of the project. + +## LTS Release Tagging + +- No Specific version number scheme for LTS releases are set Aries-wide. Each project can use any version numbering they desire. Projects must have a way to indicate patch releases. +- The README.md file within each repository must indicate which version is an LTS release, with a link to the release or branch of the LTS +- Each LTS release MUST include detailed release notes detailing the changes from the last LTS release, including complex details or gotchas. +- It is recommended, when possible, to designate an LTS release when a project reaches compliance with an Interop Profile, including an AIP. + +## LTS Support Timeline + +- Each LTS release MUST be supported for at least 9 months AFTER the next LTS release is designated. +- When the next LTS release is designated, the prior LTS release must clearly indicate the End of Support Date at least 9 months in future. +- A branch SHOULD be created to ease bugfixes and the maintenance of LTS patch releases. +- If a support term in excess of the minimum 9 months is chosen and and End of Support Date published, that period MUST be honored for that release. +- Projects may may designate an LTS release with any candance desired by the project. +- Frequent LTS relases may result in multiple LTS releases receiving support. Seeking community input for LTS release timing may decrease support efforts. + +## LTS Release Updates + +- Each LTS release MUST be updated for security updates via patch releases for the duration of its support lifetime. +- Each LTS release MAY include bugfixes that impact usability of the release. +- LTS patch releases MUST include detailed release notes. +- Updates MUST NOT include API updates, programatic interface changes, or major logic changes. + +## References +This policy is inspired by the Fabric LTS Policy https://hyperledger.github.io/fabric-rfcs/text/0005-lts-release-strategy.html + diff --git a/contributing.md b/contributing.md index 1f124209e..936ee09c9 100644 --- a/contributing.md +++ b/contributing.md @@ -12,7 +12,7 @@ invisible to those consuming Aries, should be documented elsewhere. ### Preparation Before writing an RFC, consider exploring the idea on -[chat](https://chat.hyperledger.org/channel/aries), on community calls +[the aries chat channel](https://chat.hyperledger.org), on community calls (see the [Hyperledger Community Calendar]( https://wiki.hyperledger.org/community/calendar-public-meetings)), or on [aries@lists.hyperledger.org]( @@ -27,8 +27,8 @@ is a good sign that you're on the right track. for guidance. - Decide which parent folder is appropriate for your RFC. If it is about a specific protocol or decorator or feature, its parent - should be /features; if it is about a concept that will be used in many - different features, its parent should be /concepts. + should be `/features`; if it is about a concept that will be used in many + different features, its parent should be `/concepts`. - Create the folder and copy either `0000-template.md` or `0000-template-protocol.md` (if your RFC is for a protocol) to `//README.md`. - Fill in the RFC. [Use MUST and SHOULD per standard conventions](https://tools.ietf.org/html/rfc2119). Put care into the details: RFCs that do not present convincing motivation, demonstrate an understanding of the impact of the @@ -43,13 +43,8 @@ is a good sign that you're on the right track. this repo to figure out what the next PR number will be). Rename your folder from `` to `-`. At the top of your README.md, modify the title so it is in the form: `: Friendly Version of Your Title`. Commit your changes. - - In the root of the repo, run `python code/generate_index.py` to update the index - with your new RFC. - - In the root of your repo, run `pytest code` to see whether your RFC passes all - automated tests. The RFC tests are simple. They just check for things like - naming conventions and hyperlink correctness. - - Commit the updated version of /index.md and push your changes. + number>: Friendly Version of Your Title`. + - Commit and push your changes. - Submit a pull request. Make sure that all of your commits satisfy the [DCO requirements]( @@ -70,7 +65,7 @@ in the lifecycle, submit a PR with the following characteristics: - The title of the PR should include a deadline date for merging the PR and the referenced RFC. - Example: `Status to Accepted, deadline 2019.08.15, RFC 0095-basic-message` - The PR comment should document why the status is being changed. -- The deadline date should be 2 weeks after announcing the proposed status change on an Aries WG call. The PR should also be announced on the [#aries rocketchat channel](https://chat.hyperledger.org/channel/aries). +- The deadline date should be 2 weeks after announcing the proposed status change on an Aries WG call. The PR should also be announced on the [#aries channel](https://chat.hyperledger.org). - Barring negative feedback from the community, the repo's maintainers should merge the PR after the deadline. - The deadline should be moved by two weeks after addressing each substantive change to the RFC made during the status change review period. diff --git a/features/0015-acks/README.md b/features/0015-acks/README.md index 623336fe1..bb272a6eb 100644 --- a/features/0015-acks/README.md +++ b/features/0015-acks/README.md @@ -1,10 +1,9 @@ # Aries RFC 0015: ACKs -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [DEMONSTRATED](/README.md#demonstrated) -- Since: 2019-12-26 -- Status Note: Broadly socialized and beginning to be implemented. Several protocols assume ACK behavior. May be nearing the maturity and uptake appropriate for ACCEPTED status. Note: this RFC -- Supersedes: [Indy HIPE PR #77](https://github.com/hyperledger/indy-hipe/pull/77) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 +- Status Note: Broadly implemented, adopted into many protocols and part of [AIP 1 and 2](../../concepts/0302-aries-interop-profile/README.md). - Start Date: 2018-12-26 - Tags: [feature](/tags.md#feature) @@ -13,9 +12,11 @@ Explains how one party can send acknowledgment messages (ACKs) to confirm receipt and clarify the status of complex processes. -## Change log +## Change Log -- Mar 25, 2020: In the ~thread decorator section of the sample in the [Explicit ACKs section](#explicit-acks), 'myindex' was changed to 'sender_order' and 'lrecs' to 'received_orders'. This is in accordance with the field names as defined in [RFC 0008](https://github.com/hyperledger/aries-rfcs/tree/64e5e55c123b2efaf38f4b0911a71a1c40a7f29d/concepts/0008-message-id-and-threading#threaded-messages). +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. +- 20220322: Clarification that an Ack `Fail` must not be used, and that a [Report Problem](../0035-report-problem/README.md) must be used in its place. Remove Ack `Fail` from the RFC. +- 20200325: In the ~thread decorator section of the sample in the [Explicit ACKs section](#explicit-acks), 'myindex' was changed to 'sender_order' and 'lrecs' to 'received_orders'. This is in accordance with the field names as defined in [RFC 0008](https://github.com/hyperledger/aries-rfcs/tree/64e5e55c123b2efaf38f4b0911a71a1c40a7f29d/concepts/0008-message-id-and-threading#threaded-messages). ## Motivation @@ -72,7 +73,7 @@ this: ``` jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/ack", + "@type": "https://didcomm.org/notification/1.0/ack", "@id": "06d474e0-20d3-4cbf-bea6-6ba7e1891240", "status": "OK", "~thread": { @@ -91,21 +92,27 @@ It may also be appropriate to send an ack at other key points in an interaction As discussed in [0003: Protocols](../../concepts/0003-protocols/README.md), a protocol can [adopt the ack message into its own namespace](../../0000-template-protocol.md#adopted-messages). This allows the type of an ack to change from: - `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/ack` + `https://didcomm.org/notification/1.0/ack` to something like: - `did:sov:protocolOwnersDID;spec/otherProtocol/2.0/ack`. + `https://didcomm.org/otherProtocol/2.0/ack`. Thus, message routing logic can see the ack as part of the other protocol, and send it to the relevant handler--but still have all the standardization of generic acks. ### ack status -The `status` field in an ack tells whether the ack is final or not with respect to -the message being acknowledged. It has 3 predefined values: `OK` (which means an -outcome has occurred, and it was positive); `FAIL` (an outcome has occurred, and -it was negative); and `PENDING`, which acknowledges that no outcome is yet known. -In addition, more advanced usage is possible. See the [details in the Reference -section](#reference). +The `status` field in an ack tells whether the ack is final or not with respect +to the message being acknowledged. It has 2 predefined values: `OK` (which means +an outcome has occurred, and it was positive); and `PENDING`, which acknowledges +that no outcome is yet known. + +There is not an ack `status` of `FAIL`. In the case of a protocol failure a +[Report Problem](../0035-report-problem/README.md) message must be used to +inform the other party(ies). For more details, see the [next +section](#relationship-to-problem-report). + +In addition, more advanced ack usage is possible. See the [details in the +Reference section](#reference). ### Relationship to `problem-report` @@ -120,14 +127,14 @@ arises, best practice is to report it to the sender of the message that triggered the problem. This is the subject of the [problem reporting mechanism](../0035-report-problem/README.md). A `problem_report` is inherently a sort of ACK. In fact, the `ack` message type -and the `problem_report` message type are both members of the same `notification` -message family. Both help a sender learn about status. Therefore, a -requirement for an `ack` can *often* be satisfied by a `problem_report` message. -Where this is truly the case, it is recommended, as it decreases chattiness. - -But notice the hedge word "often." We are hedging for at least two reasons. -First, some `ack`s may be sent before a final outcome, so a final `problem_report` -may not be enough. Second, an ack request may be sent after a previous +and the `problem_report` message type are both members of the same +`notification` message family. Both help a sender learn about status. Therefore, +a requirement for an `ack` is that a status of `FAIL` be satisfied by a +`problem_report` message. + +However, there is some subtlety in the use of the two types of messages. +Some `ack`s may be sent before a final outcome, so a final `problem_report` +may not be enough. As well, an ack request may be sent after a previous `ack` or `problem_report` was lost in transit. Because of these caveats, developers whose code creates or consumes acks should be thoughtful about where the two message types overlap, and where they do not. Carelessness here is likely to cause subtle, @@ -143,18 +150,13 @@ maybe their own decorators. However, reusing the field names and conventions in this RFC may still be desirable, if there is significant overlap in the concepts. -### Requesting ACKs - -A decorator, `~please_ack`, allows one agent to request an ad hoc ACK from -another agent. This is described in the [0317-please-ack RFC](../0317-please-ack/README.md). - ## Reference ### `ack` message #### __`status`__ -Required. As discussed [above](#ack-status), this tells whether the ack is final +Required, values `OK` or `PENDING`. As discussed [above](#ack-status), this tells whether the ack is final or not with respect to the message being acknowledged. #### __`~thread.thid`__ diff --git a/features/0019-encryption-envelope/README.md b/features/0019-encryption-envelope/README.md index 5fdd18987..08b8eaa9e 100644 --- a/features/0019-encryption-envelope/README.md +++ b/features/0019-encryption-envelope/README.md @@ -1,16 +1,16 @@ # Aries RFC 0019: Encryption Envelope -- Authors: [Kyle Den Hartog](kyle.denhartog@evernym.com), [Stephen Curran](swcurran@gmail.com), [Sam Curren](sam@sovrin.org), [Mike Lodder](mike@sovrin.org) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: [Kyle Den Hartog](mailto:kyle.denhartog@evernym.com), [Stephen Curran](mailto:swcurran@gmail.com), [Sam Curren](mailto:sam@sovrin.org), [Mike Lodder](mailto:mike@sovrin.org) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-05-04 - Status Note: -- Supersedes: [INDY 0028 Wire Level Format](https://github.com/hyperledger/indy-hipe/tree/master/text/0028-wire-message-format) +- Supersedes: [INDY 0028 Wire Level Format](https://github.com/hyperledger/indy-hipe/tree/main/text/0028-wire-message-format) - Start Date: 2018-07-10 (approximate, backdated) - Tags: [feature](/tags.md#feature) ## Summary -There are two layers of messages that combine to enable **interoperable** self-sovereign agent-to-agent communication. At the highest level are [DIDComm Plaintext Messages](../0044-didcomm-file-and-mime-types/README.md#didcomm-messages-dm) - messages sent between identities to accomplish some shared goal (e.g., establishing a connection, issuing a verifiable credential, sharing a chat). DIDComm Plaintext Messages are delivered via the second, lower layer of messaging - DIDComm Encrypted Envelopes. A [DIDComm Encrypted Envelope](../0044-didcomm-file-and-mime-types/README.md#didcomm-encrypted-envelope-dee) is a wrapper (envelope) around a plaintext message to permit secure sending and routing. A plaintext message going from its sender to its receiver passes through many agents, and an encryption envelope is used for each hop of the journey. +There are two layers of messages that combine to enable **interoperable** self-sovereign agent-to-agent communication. At the highest level are [DIDComm Plaintext Messages](../0044-didcomm-file-and-mime-types/README.md#didcomm-v1-messages-dm) - messages sent between identities to accomplish some shared goal (e.g., establishing a connection, issuing a verifiable credential, sharing a chat). DIDComm Plaintext Messages are delivered via the second, lower layer of messaging - DIDComm Encrypted Envelopes. A [DIDComm Encrypted Envelope](../0044-didcomm-file-and-mime-types/README.md#didcomm-v1-encrypted-envelope-dee) is a wrapper (envelope) around a plaintext message to permit secure sending and routing. A plaintext message going from its sender to its receiver passes through many agents, and an encryption envelope is used for each hop of the journey. This RFC describes the DIDComm Encrypted Envelope format and the `pack()` and `unpack()` functions that implement this format. @@ -304,7 +304,7 @@ For a reference unpack implementation, see https://github.com/hyperledger/indy-s ```json { - "message": "{ \"@id\": \"123456780\",\"@type\":\"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/basicmessage/1.0/message\",\"sent_time\": \"2019-01-15 18:42:01Z\",\"content\": \"Your hovercraft is full of eels.\"}", + "message": "{ \"@id\": \"123456780\",\"@type\":\"https://didcomm.org/basicmessage/1.0/message\",\"sent_time\": \"2019-01-15 18:42:01Z\",\"content\": \"Your hovercraft is full of eels.\"}", "recipient_verkey": "HKTAiYM8cE2kKC9KaNMZLYj4GS8uWCYMBxP2i1Y92zum", "sender_verkey": "DWwLsbKCRAbYtfYnQNmzfKV7ofVhMBi6T4o3d2SCxVuX" } @@ -314,7 +314,7 @@ For a reference unpack implementation, see https://github.com/hyperledger/indy-s ```json { - "message": "{ \"@id\": \"123456780\",\"@type\":\"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/basicmessage/1.0/message\",\"sent_time\": \"2019-01-15 18:42:01Z\",\"content\": \"Your hovercraft is full of eels.\"}", + "message": "{ \"@id\": \"123456780\",\"@type\":\"https://didcomm.org/basicmessage/1.0/message\",\"sent_time\": \"2019-01-15 18:42:01Z\",\"content\": \"Your hovercraft is full of eels.\"}", "recipient_verkey": "2GXmuCN2JCxSqMRVftBHLxVJKSL5bXyzM8DsPzGqQoNj" } ``` diff --git a/features/0023-did-exchange/README.md b/features/0023-did-exchange/README.md index 8903843c2..ab63d725f 100644 --- a/features/0023-did-exchange/README.md +++ b/features/0023-did-exchange/README.md @@ -1,12 +1,12 @@ -# Aries RFC 0023: DID Exchange Protocol 1.0 +# Aries RFC 0023: DID Exchange v1 -- Authors: [Ryan West](ryan.west@sovrin.org), [Daniel Bluhm](daniel.bluhm@sovrin.org), Matthew Hailstone, Stephen Curran, [Sam Curren](sam@sovrin.org) -- Status: [DEMONSTRATED](/README.md#demonstrated) -- Since: 2019-05-27 -- Status Note: This RFC is a work in progress designed to replace the [RFC 0160 - Connection Protocol](../../features/0160-connection-protocol/README.md) after all necessary changes have been made. This RFC is likely to change as discussions continue, and should not yet be built into production code. +- Authors: [Ryan West](mailto:ryan.west@sovrin.org), [Daniel Bluhm](mailto:daniel.bluhm@sovrin.org), Matthew Hailstone, [Sam Curren](mailto:sam@sovrin.org), [Stephen Curran](mailto:swcurran@cloudcompass.ca), [George Aristy](mailto:george.aristy@securekey.com) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2021-04-15 +- Status Note: Replaces [RFC 0160 - Connection Protocol](../../features/0160-connection-protocol/README.md) and is a part of [AIP 2.0](../../concepts/0302-aries-interop-profile/README.md). - Supersedes: [RFC 0160 - Connection Protocol](../../features/0160-connection-protocol/README.md) - Start Date: 2018-06-29 -- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) ## Summary @@ -16,69 +16,92 @@ This RFC describes the protocol to exchange DIDs between agents when establishin Aries agent developers want to create agents that are able to establish relationships with each other and exchange secure information using keys and endpoints in DID Documents. For this to happen there must be a clear protocol to exchange DIDs. +## Version Change Log + +### Version 1.1 - Signed Rotations without DID Documents + +Added the optional `did_rotate~attach` attachment for provenance of rotation without an attached DID Document. + ## Tutorial We will explain how DIDs are exchanged, with the roles, states, and messages required. ### Roles -The DID Exchange Protocol uses two roles: __inviter__ and __invitee__. +The DID Exchange Protocol uses two roles: _requester_ and _responder_. -The _inviter_ is the party that initiates the protocol with an `invitation` message. This party -must already have an agent and be capable of creating DIDs and endpoints -at which they are prepared to interact. It is desirable but not strictly required that inviters -have the ability to help the invitee with the process and/or costs associated with acquiring -an agent capable of participating in the ecosystem. For example, inviters may often be sponsoring institutions. The inviter sends a `response` message at the end of the _share_ phase. +The _requester_ is the party that initiates this protocol after receiving an `invitation` message +(using [RFC 0434 Out of Band](../0434-outofband/README.md)) or by using an implied invitation from a public DID. For +example, a verifier might get the DID of the issuer of a credential they are verifying, and use information in the +DIDDoc for that DID as the basis for initiating an instance of this protocol. -The _invitee_ has less preconditions; the only requirement is that this party be capable of -receiving invitations over traditional communication channels of some type, and acting on -it in a way that leads to successful interaction. The invitee sends a `request` message at the beginning of the _share_ phase. +Since the _requester_ receiving an explicit invitation may not have an Aries agent, it is desirable, but not strictly, +required that sender of the invitation (who has the _responder_ role in this protocol) +have the ability to help the _requester_ with the process and/or costs associated with acquiring +an agent capable of participating in the ecosystem. For example, the sender of an invitation may often be sponsoring institutions. -In cases where both parties already possess SSI capabilities, deciding who plays the role of inviter and invitee might be a casual matter of whose phone is handier. +The _responder_, who is the sender of an explicit invitation or the publisher of a DID with an implicit invitation, must have +an agent capable of interacting with other agents via DIDComm. + +In cases where both parties already possess SSI capabilities, deciding who plays the role of _requester_ and _responder_ might be a casual matter of whose phone is handier. ### States -#### null +#### Requester -No exchange exists or is in progress +The _requester_ goes through the following states per the State Machine Tables below -#### invited +* start +* invitation-received +* request-sent +* response-received +* abandoned +* completed -The invitation has been shared with the intended _invitee_(s), and they have not yet sent a _exchange_request_. +#### Responder -#### requested +The _responder_ goes through the following states per the State Machine Tables below -A _exchange_request_ has been sent by the _invitee_ to the _inviter_ based on the information in the _invitation_. +* start +* invitation-sent +* request-received +* response-sent +* abandoned +* completed -#### responded +#### State Machine Tables -A _exchange_response_ has been sent by the _inviter_ to the _invitee_ based on the information in the _exchange_request_. +The following are the _requester_ and _responder_ state machines. -#### complete +The `invitation-sent` and `invitation-received` are technically outside this protocol, but are useful to show in the state machine as the invitation is the trigger to start the protocol and is referenced from the protocol as the parent thread (`pthid`). This is discussed in more detail below. -The exchange has been completed. +The `abandoned` and `completed` states are terminal states and there is no expectation that the protocol can be continued (or even referenced) after reaching those states. -![State Machine Tables](chrome_2019-01-29_07-59-38.png) +[![State Machine Tables](did-exchange-states.png)](https://docs.google.com/spreadsheets/d/1NKfEdyebJWQGinRIAPtpXA1BVm8jgG8_i1RyeoNzzKE/edit?usp=sharing) ### Errors -There are no errors in this protocol during the invitation phase. For the request and response, there are two error messages possible for each phase: one for an active rejection and one for an unknown error. These errors are sent using a **problem_report** message type specific to the DID Exchange Protocol. The following list details `problem-code`s that may be sent: +After receiving an explicit invitation, the _requester_ may send a `problem-report` to the _responder_ using the information in the invitation to either restart the invitation process (returning to the `start` state) or to abandon the protocol. The `problem-report` may be an adopted `Out of Band` protocol message or an adopted `DID Exchange` protocol message, depending on where in the processing of the invitation the error was detected. + +During the `request` / `response` part of the protocol, there are two protocol-specific error messages possible: one for an active rejection and one for an unknown error. These errors are sent using a **problem_report** message type specific to the DID Exchange Protocol. These errors do not transition the protocol to the `abandoned` state. The following list details `problem-code`s that may be sent in these cases: + +**request_not_accepted** - The error indicates that the `request` message has been rejected for a reason listed in the `error_report`. Typical reasons include not accepting the method of the provided DID, unknown endpoint protocols, etc. The `request` can be resent _after_ the appropriate corrections have been made. -**request_not_accepted** - The error indicates that the request has been rejected for a reason listed in the error_report. Typical reasons include not accepting the method of the provided DID, unknown endpoint protocols, etc. The request can be resent _after_ the appropriate corrections have been made. +**request_processing_error** - This error is sent when the _responder_ was processing the request with the intent to accept the request, but some processing error occurred. This error indicates that the `request` should be resent as-is. -**request_processing_error** - This error is sent when the inviter was processing the request with the intent to accept the request, but some processing error occurred. This error indicates that the request should be resent as-is. +**response_not_accepted** - The error indicates that the `response` has been rejected for a reason listed in the `error_report`. Typical reasons include not accepting the method of the provided DID, unknown endpoint protocols, invalid signature, etc. The `response` can be resent _after_ the appropriate corrections have been made. -**response_not_accepted** - The error indicates that the response has been rejected for a reason listed in the error_report. Typical reasons include not accepting the method of the provided DID, unknown endpoint protocols, invalid signature, etc. The response can be resent _after_ the appropriate corrections have been made. +**response_processing_error** - This error is sent when the _requester_ was processing the `response` with the intent to accept the response, but some processing error occurred. This error indicates that the `response` should be resent as-is. -**response_processing_error** - This error is sent when the invitee was processing the response with the intent to accept the response, but some processing error occurred. This error indicates that the response should be resent as-is. +If other errors occur, the corresponding party may send a `problem-report` to inform the other party they are abandoning the protocol. -No errors are sent in timeout situations. If the inviter or invitee wishes to retract the messages they sent, they record so locally and return a `request_not_accepted` or `response_not_accepted` error when the other party sends a request or response . +No errors are sent in timeout situations. If the _requester_ or _responder_ wishes to retract the messages they sent, they record so locally and return a `request_not_accepted` or `response_not_accepted` error when the other party sends a `request` or `response`. #### Error Message Example -``` +``` jsonc { - "@type": "https://didcomm.org/didexchange/1.0/problem_report", + "@type": "https://didcomm.org/didexchange/1.1/problem_report", "@id": "5678876542345", "~thread": { "thid": "<@id of message related to problem>" }, "~l10n": { "locale": "en"}, @@ -97,55 +120,75 @@ No errors are sent in timeout situations. If the inviter or invitee wishes to re ### Flow Overview -The _inviter_ gives provisional information to the _invitee_ using an `invitation` message from the `out-of-band` protocol. -The _invitee_ uses provisional information to send a DID and DID Doc to the _inviter_ in a `request` message. -The _inviter_ uses sent DID Doc information to send a DID and DID Doc to the _invitee_ in a `response` message. -The *invitee* sends the *inviter* a `complete` message that confirms the response was received. +- The _responder_ gives provisional information to the _requester_ using an explicit `invitation` message from the [`out-of-band` protocol](../0434-outofband/README.md) or an implicit invitation in a DID the _responder_ publishes. + - In the `out-of-band` protocol, the _responder_ is called the _sender_, and the _requester_ is called the _receiver_. +- The _requester_ uses the provisional information to send a DID and DID Doc to the _responder_ in a `request` message. +- The _responder_ uses sent DID Doc information to send a DID and DID Doc to the _requester_ in a `response` message. +- The _requester_ sends the _responder_ a `complete` message that confirms the `response` message was received. + +## Implicit and Explicit Invitations -## Out-of-Band Invitation +The DID Exchange Protocol is preceded by +- either knowledge of a resolvable DID (an implicit invitation) +- or by a `out-of-band/%VER/invitation` message from the [Out Of Band Protocols RFC](../0434-outofband/README.md). -The DID Exchange Protocol is proceeded by either knowledge of a resolvable DID, or by a `out-of-band/%VER/invitation` message from the [Out Of Band Protocols RFC](../0434-outofband/README.md). The information from either the resolved DID Document or the `service` attribute of the `invitation` message is used to construct the `request` message to start the protocol. +The information needed to construct the `request` message to start the protocol is used +- either from the resolved DID Document +- or the `service` element of the `handshake_protocols` attribute of the `invitation`. ## 1. Exchange Request -The exchange request message is used to communicate the DID document of the _invitee_ to the _inviter_ using the provisional service information present in the _invitation_ message. +The `request` message is used to communicate the DID document of the _requester_ to the _responder_ using the provisional service information present in the (implicit or explicit) invitation. -The _invitee_ will provision a new DID according to the DID method spec. For a Peer DID, this involves creating a matching peer DID and key. The newly provisioned DID and DID Doc is presented in the exchange_request message as follows: +The _requester_ may provision a new DID according to the DID method spec. For a Peer DID, this involves creating a matching peer DID and key. The newly provisioned DID and DID Doc is presented in the `request` message as follows: -#### Example +### Request Message Example -```json +```jsonc { "@id": "5678876542345", - "@type": "https://didcomm.org/didexchange/1.0/request", + "@type": "https://didcomm.org/didexchange/1.1/request", "~thread": { "thid": "5678876542345", "pthid": "" }, "label": "Bob", + "goal_code": "aries.rel.build", + "goal": "To create a relationship", "did": "B.did@B:A", "did_doc~attach": { - "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", - "jws": { - "header": { - "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" - }, - "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", - "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + "@id": "d2ab6f2b-5646-4de3-8c02-762f553ab804", + "mime-type": "application/json", + "data": { + "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } } } } ``` -#### Attributes +#### Request Message Attributes * The `@type` attribute is a required string value that denotes that the received message is an exchange request. * The [`~thread`](../../concepts/0008-message-id-and-threading/README.md#thread-object) decorator MUST be included: - * It MUST include the ID of the parent thread (`pthid`) such that the `request` can be correlated to the corresponding `invitation`. More on correlation [below](#correlating-requests-to-invitations). - * It MAY include the `thid` property. In doing so, implementations MUST set its value to that of `@id` on the same request message. In other words, the values of `@id` and `~thread.thid` MUST be equal. -* The `label` attribute provides a suggested label for the DID being exchanged. This allows the user to tell multiple exchange requests apart. This is not a trusted attribute. -* The `did` indicates the DID being exchanged. -* The `did_doc~attach` contains the DID Doc associated with the DID as a [signed attachment](../../concepts/0017-attachments/README.md). If the DID method for the presented DID is not a peer method and the DID Doc is resolvable on a ledger, the `did_doc~attach` attribute is optional. + * It MUST include the ID of the parent thread (`pthid`) such that the `request` can be correlated to the corresponding (implicit or explicit) `invitation`. More on correlation [below](#correlating-requests-to-invitations). + * It MAY include the `thid` property. This works according to the [`thid`](../../concepts/0008-message-id-and-threading/README.md#thread-id-thid) property in the thread decorator, meaning that if `thid` is not defined it is implicitly defined as the `@id` on the same `request` message. +* The `label` attribute provides a suggested label for the DID being exchanged. This allows the user to tell multiple exchange requests apart. This is not a trusted attribute. (See note on `label` below) +* The `goal_code` (optional) is a self-attested code the receiver may want to display to the user or use in automatically deciding what to do with the request message. The goal code might be used particularly when the request is sent to a resolvable DID without reference to a specfic invitation. +* The goal (optional) is a self-attested string that the receiver may want to display to the user about the context-specific goal of the request message. +* The `did` attribute MUST be included. It indicates the DID being exchanged. +* The `did_doc~attach` (optional), contains the DIDDoc associated with the `did`, if required. + * If the `did` is resolvable (either an inline `peer:did` or a publicly resolvable DID), the `did_doc~attach` attribute should not be included. + * If the DID is a `did:peer` DID, the DIDDoc must be as outlined in [RFC 0627 Static Peer DIDs](../0627-static-peer-dids/README.md). + + +The `label` property was intended to be declared as an optional property, but was added to the RFC as a required property. If an agent wishes to not use a label in the request, an empty string (`""`) or the set value `Unspecified` may be used to indicate a non-value. This approach ensures existing AIP 2.0 implementations do not break. #### Correlating requests to invitations @@ -158,84 +201,95 @@ When a `request` responds to an explicit invitation, its `~thread.pthid` MUST be When a `request` responds to an implicit invitation, its `~thread.pthid` MUST contain a [DID URL](https://w3c-ccg.github.io/did-spec/#dfn-did-url) that resolves to the specific `service` on a DID document that contains the invitation. -**Example referencing an explicit invitation** +##### Example Referencing an Explicit Invitation -```json +```jsonc { "@id": "a46cdd0f-a2ca-4d12-afbf-2e78a6f1f3ef", - "@type": "https://didcomm.org/didexchange/1.0/request", + "@type": "https://didcomm.org/didexchange/1.1/request", "~thread": { "thid": "a46cdd0f-a2ca-4d12-afbf-2e78a6f1f3ef", "pthid": "032fbd19-f6fd-48c5-9197-ba9a47040470" }, "label": "Bob", + "goal_code": "aries.rel.build", + "goal": "To create a relationship", "did": "B.did@B:A", "did_doc~attach": { - "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", - "jws": { - "header": { - "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" - }, - "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", - "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + "@id": "d2ab6f2b-5646-4de3-8c02-762f553ab804", + "mime-type": "application/json", + "data": { + "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } } } } ``` -**Example referencing an implicit invitation** +##### Example Referencing an Implicit Invitation -```json +```jsonc { "@id": "a46cdd0f-a2ca-4d12-afbf-2e78a6f1f3ef", - "@type": "https://didcomm.org/didexchange/1.0/request", + "@type": "https://didcomm.org/didexchange/1.1/request", "~thread": { "thid": "a46cdd0f-a2ca-4d12-afbf-2e78a6f1f3ef", "pthid": "did:example:21tDAKCERh95uGgKbJNHYp#didcomm" }, "label": "Bob", + "goal_code": "aries.rel.build", + "goal": "To create a relationship", "did": "B.did@B:A", "did_doc~attach": { - "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", - "jws": { - "header": { - "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" - }, - "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", - "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + "@id": "d2ab6f2b-5646-4de3-8c02-762f553ab804", + "mime-type": "application/json", + "data": { + "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } } } } ``` - #### Request Transmission -The Request message is encoded according to the standards of the Encryption Envelope, using the `recipientKeys` present in the invitation. +The `request` message is encoded according to the standards of the Encryption Envelope, using the `recipientKeys` present in the invitation. If the `routingKeys` attribute was present and non-empty in the invitation, each key must be used to wrap the message in a forward request, then encoded in an Encryption Envelope. This processing is in order of the keys in the list, with the last key in the list being the one for which the `serviceEndpoint` possesses the private key. The message is then transmitted to the `serviceEndpoint`. -We are now in the `requested` state. +The _requester_ is in the `request-sent` state. When received, the _responder_ is in the `request-received` state. #### Request processing -After receiving the exchange request, the _inviter_ evaluates the provided DID and DID Doc according to the DID Method Spec. +After receiving the exchange request, the _responder_ evaluates the provided DID and DID Doc according to the DID Method Spec. -The _inviter_ should check the information presented with the keys used in the wire-level message transmission to ensure they match. +The responder should check the information presented with the keys used in the wire-level message transmission to ensure they match. -The _inviter_ MAY look up the corresponding invitation identified in the request's `~thread.pthid` to determine whether it should accept this exchange request. +The responder MAY look up the corresponding invitation identified in the request's `~thread.pthid` to determine whether it should accept this exchange request. -If the _inviter_ wishes to continue the exchange, they will persist the received information in their wallet. They will then either update the provisional service information to rotate the key, or provision a new DID entirely. The choice here will depend on the nature of the DID used in the invitation. +If the responder wishes to continue the exchange, they will persist the received information in their wallet. They will then either update the provisional service information to rotate the key, or provision a new DID entirely. The choice here will depend on the nature of the DID used in the invitation. -The _inviter_ will then craft an exchange response using the newly updated or provisioned information. +The responder will then craft an exchange response using the newly updated or provisioned information. #### Request Errors See [Error Section](#errors) above for message format details. -**request_rejected** +##### Request Rejected Possible reasons: @@ -246,7 +300,7 @@ Possible reasons: - Unsupported endpoint protocol - Missing reference to invitation -**request_processing_error** +##### Request Processing Error - unknown processing error @@ -254,37 +308,57 @@ Possible reasons: The exchange response message is used to complete the exchange. This message is required in the flow, as it updates the provisional information presented in the invitation. -#### Example +### Response Message Example ```json { - "@type": "https://didcomm.org/didexchange/1.0/response", + "@type": "https://didcomm.org/didexchange/1.1/response", "@id": "12345678900987654321", "~thread": { "thid": "" }, "did": "B.did@B:A", "did_doc~attach": { - "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", - "jws": { - "header": { - "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" - }, - "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", - "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + "@id": "d2ab6f2b-5646-4de3-8c02-762f553ab804", + "mime-type": "application/json", + "data": { + "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } + } + }, + "did_rotate~attach": { + "mime-type": "text/string", + "data": { + "base64": "Qi5kaWRAQjpB", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } } } } ``` -The key used in the signed attachment must be verified against the invitation's `recipientKeys` for continuity. +The invitation's `recipientKeys` should be dedicated to envelopes authenticated encryption throughout the exchange. These keys are usually defined in the `KeyAgreement` DID verification relationship. -#### Attributes +#### Response Message Attributes * The `@type` attribute is a required string value that denotes that the received message is an exchange request. -* The `~thread` block contains a `thid` reference to the `@id` of the request message. -* The `did` attribute is a required string value and denotes DID in use by the _inviter_. Note that this may not be the same DID used in the invitation. -* The `did_doc~attach` contains the DID Doc associated with the DID as a [signed attachment](../../concepts/0017-attachments/README.md). If the DID method for the presented DID is not a peer method and the DID Doc is resolvable on a ledger, the `did_doc~attach` attribute is optional. +* The `~thread` decorator MUST be included. It contains a `thid` reference to the `@id` of the request message. +* The `did` attribute MUST be included. It denotes the DID in use by the responder. Note that this MAY NOT be the same DID used in the invitation. +* The `did_doc~attach` optional, contains the DID Doc associated with the `did`, if required. + * If the `did` is resolvable (either an inline `did:peer` or a publicly resolvable DID), the `did_doc~attach` attribute should not be included. + * If the DID is a `did:peer` identifier, the DIDDoc must be as outlined in [RFC 0627 Static Peer DIDs](../0627-static-peer-dids/README.md). +* The `did_rotate~attach` attribute is optional, but SHOULD be included if the `did` attribute is resolvable and the `did_doc~attach` is not included. The value is the Base64url encoded DID, and signed with the key used in the invitation. In addition to a new DID, the associated DID Doc might contain a new endpoint. This new DID and endpoint are to be used going forward in the relationship. @@ -292,17 +366,17 @@ In addition to a new DID, the associated DID Doc might contain a new endpoint. T The message should be packaged in the encrypted envelope format, using the keys from the request, and the new keys presented in the internal did doc. -When the message is transmitted, we are now in the `responded` state. +When the message is sent, the _responder_ are now in the `response-sent` state. On receipt, the _requester_ is in the `response-received` state. #### Response Processing -When the _invitee_ receives the `response` message, they will verify the `change_sig` provided. After validation, they will update their wallet with the new information. If the endpoint was changed, they may wish to execute a Trust Ping to verify that new endpoint. +When the requester receives the `response` message, they will decrypt the authenticated envelope which confirms the source's authenticity. After decryption validation, the signature on the `did_doc~attach` or `did_rotate~attach` MUST be validated, if present. The key used in the signature MUST match the key used in the invitation. After attachment signature validation, they will update their wallet with the new information, and use that information in sending the `complete` message. #### Response Errors See [Error Section](#errors) above for message format details. -**response_rejected** +##### Response Rejected Possible reasons: @@ -313,19 +387,19 @@ Possible reasons: - Unsupported endpoint protocol - Invalid Signature -**response_processing_error** +##### Response Processing Error - unknown processing error ## 3. Exchange Complete -The exchange complete message is used to confirm the exchange to the _inviter_. This message is required in the flow, as it marks the exchange complete. The _inviter_ may then invoke any protocols desired based on the context expressed via the `pthid` in the DID Exchange protocol. +The exchange `complete` message is used to confirm the exchange to the _responder_. This message is **required** in the flow, as it marks the exchange complete. The _responder_ may then invoke any protocols desired based on the context expressed via the `pthid` in the DID Exchange protocol. -#### Example +### Complete Message Example -```json +```jsonc { - "@type": "https://didcomm.org/didexchange/1.0/complete", + "@type": "https://didcomm.org/didexchange/1.1/complete", "@id": "12345678900987654321", "~thread": { "thid": "", @@ -336,15 +410,27 @@ The exchange complete message is used to confirm the exchange to the _inviter_. The `pthid` is required in this message, and must be identical to the `pthid` used in the `request` message. -After a message is sent, the *invitee* in the `complete` state. Receipt of a message puts the *inviter* into the `complete` state. +After a `complete` message is sent, the *requester* is in the `completed` terminal state. Receipt of the message puts the *responder* into the `completed` state. + +#### Complete Errors + +See [Error Section](#errors) above for message format details. + +##### Complete Rejected + +This is unlikely to occur with other than an unknown processing error (covered below), so no possible reasons are listed. As experience is gained with the protocol, possible reasons may be added. + +##### Complete Processing Error + +- unknown processing error -#### Next Steps +## Next Steps -The exchange between the _inviter_ and the _invitee_ is now established. This relationship has no trust associated with it. The next step should be the exchange of proofs to build trust sufficient for the purpose of the relationship. +The exchange between the _requester_ and the _responder_ has been completed. This relationship has no trust associated with it. The next step should be to increase the trust to a sufficient level for the purpose of the relationship, such as through an exchange of proofs. -#### Peer DID Maintenance +## Peer DID Maintenance -When Peer DIDs are used in an exchange, it is likely that both Alice and Bob will want to perform some relationship maintenance such as key rotations. Future RFC updates will add these maintenance features. +When Peer DIDs are used in an exchange, it is likely that both the _requester_ and _responder_ will want to perform some relationship maintenance such as key rotations. Future RFC updates will add these maintenance features. ## Reference @@ -352,10 +438,11 @@ When Peer DIDs are used in an exchange, it is likely that both Alice and Bob wil * [Agent to Agent Communication Video](https://drive.google.com/file/d/1PHAy8dMefZG9JNg87Zi33SfKkZvUvXvx/view) * [Agent to Agent Communication Presentation](https://docs.google.com/presentation/d/1H7KKccqYB-2l8iknnSlGt7T_sBPLb9rfTkL-waSCux0/edit#slide=id.p) * Problem_report message adopted into message family, following form defined by the [Problem Report HIPE](https://github.com/hyperledger/indy-hipe/blob/6a5e4fe2d7e14953cd8e3aed07d886176332e696/text/error-handling/README.md) +* [RFC0519 Goal Codes](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0519-goal-codes/README.md) ## Drawbacks -* + N/A at this time ## Prior art @@ -363,7 +450,7 @@ When Peer DIDs are used in an exchange, it is likely that both Alice and Bob wil ## Unresolved questions -- +- N/A at this time ## Implementations @@ -371,4 +458,4 @@ The following lists the implementations (if any) of this RFC. Please do a pull r Name / Link | Implementation Notes --- | --- -[Streetcred.id](https://streetcred.id/) | Commercial mobile and web app built using Aries Framework - .NET [MISSING test results](/tags.md#test-anomaly) +[Trinsic.id](https://trinsic.id/) | Commercial mobile and web app built using Aries Framework - .NET [MISSING test results](/tags.md#test-anomaly) diff --git a/features/0023-did-exchange/chrome_2019-01-29_07-59-38.png b/features/0023-did-exchange/chrome_2019-01-29_07-59-38.png deleted file mode 100644 index 0db3f85c1..000000000 Binary files a/features/0023-did-exchange/chrome_2019-01-29_07-59-38.png and /dev/null differ diff --git a/features/0023-did-exchange/did-exchange-states.png b/features/0023-did-exchange/did-exchange-states.png new file mode 100644 index 000000000..25b793730 Binary files /dev/null and b/features/0023-did-exchange/did-exchange-states.png differ diff --git a/features/0024-didcomm-over-xmpp/README.md b/features/0024-didcomm-over-xmpp/README.md index 894aab3c5..f6d8feb22 100644 --- a/features/0024-didcomm-over-xmpp/README.md +++ b/features/0024-didcomm-over-xmpp/README.md @@ -1,10 +1,10 @@ # Aries RFC 0024: DIDComm over XMPP -- Authors: [Oskar van Deventer](oskar.vandeventer@tno.nl), [Galit Rahim](galit.rahim@tno.nl), [Alexander Blom](alexander.blom@bloqzone.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-06-14 -- Status Note: , moving from Indy to Aries. -- Supersedes: [Indy DIDComm-over-XMPP](https://github.com/Oskar-van-Deventer/indy-hipe/tree/master/text/didcom-over-xmpp) +- Authors: [Oskar van Deventer](mailto:oskar.vandeventer@tno.nl), [Galit Rahim](mailto:galit.rahim@tno.nl), [Alexander Blom](mailto:alexander.blom@bloqzone.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. +- Supersedes: [Indy DIDComm-over-XMPP](https://github.com/Oskar-van-Deventer/indy-hipe/tree/main/text/didcom-over-xmpp) - Start Date: 2019-04-23 - Tags: [feature](/tags.md#feature) @@ -40,7 +40,7 @@ The DIDComm-over-XMPP feature provides an architecture for the transport of DIDC ### DIDComm -The DIDComm wire message format is specified in [HIPE 0028-wire-message-format](https://github.com/hyperledger/indy-hipe/tree/master/text/0028-wire-message-format). It can carry among others the DIDComm connection protocol, as specified in [Hyperledger Indy Hipe 0031](https://github.com/hyperledger/indy-hipe/tree/master/text/0031-connection-protocol). The purpose of the latter protocol is to set up a trusted electronic relationship between two parties (natural person, legal person, ...). Technically, the trust relationship involves the following +The DIDComm wire message format is specified in [HIPE 0028-wire-message-format](https://github.com/hyperledger/indy-hipe/tree/main/text/0028-wire-message-format). It can carry among others the DIDComm connection protocol, as specified in [Hyperledger Indy Hipe 0031](https://github.com/hyperledger/indy-hipe/tree/main/text/0031-connection-protocol). The purpose of the latter protocol is to set up a trusted electronic relationship between two parties (natural person, legal person, ...). Technically, the trust relationship involves the following - Univocal identification of the parties within the context of the relationship - Secure exchange of keys to encrypt and verify messages between agents of the parties @@ -128,7 +128,7 @@ The disadvantage of this method is that it creates a strong correlation point, w *Editor's note: More advantages or disadvantages?* -A typical application of Method 1 is when there is an ongoing human-to-human (or human-to-bot) chat session that uses XMPP and the two parties what to set up a pairwise DID relationship. One can skip Step 0 "Invitation to Connect" ([HIPE 0031](https://github.com/hyperledger/indy-hipe/tree/master/text/0031-connection-protocol)) and immediately perform Step 1 "Connection Request". +A typical application of Method 1 is when there is an ongoing human-to-human (or human-to-bot) chat session that uses XMPP and the two parties what to set up a pairwise DID relationship. One can skip Step 0 "Invitation to Connect" ([HIPE 0031](https://github.com/hyperledger/indy-hipe/tree/main/text/0031-connection-protocol)) and immediately perform Step 1 "Connection Request". **Method 2: Random userpart** diff --git a/features/0025-didcomm-transports/README.md b/features/0025-didcomm-transports/README.md index b88eaad63..c37883883 100644 --- a/features/0025-didcomm-transports/README.md +++ b/features/0025-didcomm-transports/README.md @@ -1,7 +1,7 @@ # Aries RFC 0025: DIDComm Transports -- Authors: [Sam Curren](sam@sovrin.org) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: [Sam Curren](mailto:sam@sovrin.org) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-12-05 - Status Note: - Supersedes: [INDY PR 94](https://github.com/hyperledger/indy-hipe/pull/94) @@ -22,7 +22,13 @@ Standardized transport methods are detailed here. ### HTTP(S) -HTTP(S) is the first transport for DID Communication that has received heavy attention. +HTTP(S) is the first, and most used transport for DID Communication that has received heavy attention. + +While it is recognized that all DIDComm messages are secured through strong encryption, making HTTPS somewhat redundant, it will likely cause issues with mobile clients because venders (Apple and Google) are limiting application access to the HTTP protocol. For example, on iOS 9 or above where [ATS])(https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity) is in effect, any URLs using HTTP must have an exception hard coded in the application prior to uploading to the iTunes Store. This makes DIDComm unreliable as the agent initiating the the request provides an endpoint for communication that the mobile client must use. If the agent provides a URL using the HTTP protocol it will likely be unusable due to low level operating system limitations. + +As a best practice, when HTTP is used in situations where a mobile client (iOS or Android) may be involved it is highly recommended to use the HTTPS protocol, specifically TLS 1.2 or above. + +Other important notes on the subject of using HTTP(S) include: - Messages are transported via HTTP POST. - The MIME Type for the POST request is `application/didcomm-envelope-enc`; see [RFC 0044: DIDComm File and MIME Types](../0044-didcomm-file-and-mime-types/README.md) for more details. @@ -58,7 +64,7 @@ XMPP is an effective transport for incoming DID-Communication messages directly - Independent of cloud agents and routing agents, as messages arrive directly at the mobile agent. - Well suited for direct consumer-to-consumer SSI transactions, from one mobile agent directly to another mobile agent without any DID-Communication intermediaries. - Simple encapsulation of DIDcom messages, getting trust from the DIDcom Encryption Envelope. -- Specified in [Aries RFC 0024: DIDCom-over-XMPP](https://github.com/hyperledger/aries-rfcs/tree/master/features/0024-didcomm-over-xmpp) +- Specified in [Aries RFC 0024: DIDCom-over-XMPP](https://github.com/hyperledger/aries-rfcs/tree/main/features/0024-didcomm-over-xmpp) #### Known Implementations diff --git a/features/0028-introduce/README.md b/features/0028-introduce/README.md index d6aa2528d..27c68c1e1 100644 --- a/features/0028-introduce/README.md +++ b/features/0028-introduce/README.md @@ -12,6 +12,10 @@ Describes how a go-between can introduce two parties that it already knows, but that do not know each other. +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. + ## Motivation Introductions are a fundamental activity in human relationships. They allow @@ -218,8 +222,7 @@ introducee is the object of the sender's interest: ``` The recipient can choose whether or not to honor it in their own way, on -their own schedule. However, a `~please_ack` decorator could be used to make -it more interactive, and a `problem_report` could be returned if the +their own schedule. However, a `problem_report` could be returned if the recipient chooses not to honor it. ### Advanced Use Cases diff --git a/features/0030-sync-connection/README.md b/features/0030-sync-connection/README.md index 2297b6953..328d67c0c 100644 --- a/features/0030-sync-connection/README.md +++ b/features/0030-sync-connection/README.md @@ -1,9 +1,9 @@ # Aries RFC 0030: Sync Connection Protocol 1.0 -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-07-03 -- Status Note: used by the [peer DID method spec](https://openssi.github.io/peer-did-method-spec). Implementation beginning. +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: [Indy HIPE PR #104](https://github.com/hyperledger/indy-hipe/pull/104) - Start Date: 2018-10-01 - Tags: [feature](/tags.md#feature), [decorator](/tags.md#decorator), [protocol](/tags.md#protocol) @@ -15,6 +15,10 @@ common store of state like a blockchain), whereby parties using [peer DIDs]( https://openssi.github.io/peer-did-method-spec) can synchronize the state of their shared relationship by direct communication with one another. +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. + ## Motivation For Alice and Bob to interact, they must establish and maintain state. @@ -57,7 +61,7 @@ other mechanism besides DIDComm message passing, that is fine. This RFC defines the `sync_connection` protocol, version 1.x, as identified by the following [PIURI](../../concepts/0003-protocols/README.md#piuri): - did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/sync_connection/1.0 + https://didcomm.org/sync_connection/1.0 Of course, subsequent evolutions of the protocol will replace `1.0` with an appropriate update per [semver](../../concepts/0003-protocols/README.md#semver-rules-for-protocols) @@ -91,7 +95,7 @@ sample looks like this: ```JSON { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/sync-connection/1.0/sync_state", + "@type": "https://didcomm.org/sync-connection/1.0/sync_state", "@id": "e61586dd-f50e-4ed5-a389-716a49817207", "for": "did:peer:11-479cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe", "base_hash": "d48f058771956a305e12a3b062a3ac81bd8653d7b1a88dd07db8f663f37bf8e0", diff --git a/features/0030-sync-connection/abandon-connection-protocol/README.md b/features/0030-sync-connection/abandon-connection-protocol/README.md index 0a0dae5d1..dd655a076 100644 --- a/features/0030-sync-connection/abandon-connection-protocol/README.md +++ b/features/0030-sync-connection/abandon-connection-protocol/README.md @@ -18,7 +18,7 @@ This is not strictly required, but it is good hygiene. This RFC defines the `abandon_connection` protocol, version 1.x, as identified by the following [PIURI](../../../concepts/0003-protocols/README.md#piuri): - did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/abandon_connection/1.0 + https://didcomm.org/abandon_connection/1.0 Of course, subsequent evolutions of the protocol will replace `1.0` with an appropriate update per [semver](../../../concepts/0003-protocols/README.md#semver-rules-for-protocols) @@ -27,7 +27,7 @@ rules. ### Roles This is a [classic one-step notification]( -https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0003-protocols/README.md#types-of-protocols), +https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/README.md#types-of-protocols), so it uses the predefined roles of `notifier` and `notified`. ![request-response pattern](../../../concepts/0003-protocols/notification.png) @@ -50,9 +50,8 @@ An `announce` message from Alice to Bob looks like this: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/abandon_connection/1.0/announce", - "@id": "c17147d2-ada6-4d3c-a489-dc1e1bf778ab", - "~please_ack": {} + "@type": "https://didcomm.org/abandon_connection/1.0/announce", + "@id": "c17147d2-ada6-4d3c-a489-dc1e1bf778ab" } ``` @@ -64,20 +63,3 @@ forth. The nature of the relationship, the need for a historical audit trail, re requirements, and many other factors may influence what's appropriate; the protocol simply requires that the message be understood to have permanent termination semantics. -It may be desirable to use the [`~please_ack` decorator](../../0317-please-ack/README.md) -to request acknowledgment that the severance has been processed. The example shows -this, but including it is optional. - -##### `ack` - -The [`ack` message](../../0015-acks/README.md#explicit-acks) is [adopted]( -../../../0000-template-protocol.md#adopted-messages) into this protocol. If an -`announce` message includes the -`~please_ack` decorator and the ack is sent, it looks something like this: - -```json -{ -"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/abandon_connection/1.0/ack", -"~thread": { "thid": "c17147d2-ada6-4d3c-a489-dc1e1bf778ab" } -} -``` diff --git a/features/0030-sync-connection/abandon-connection-protocol/announce.json b/features/0030-sync-connection/abandon-connection-protocol/announce.json index 3caad44df..67ceeff4c 100644 --- a/features/0030-sync-connection/abandon-connection-protocol/announce.json +++ b/features/0030-sync-connection/abandon-connection-protocol/announce.json @@ -1,6 +1,5 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/abandon_connection/1.0/announce", - "@id": "c17147d2-ada6-4d3c-a489-dc1e1bf778ab", - "~please_ack": {} + "@type": "https://didcomm.org/abandon_connection/1.0/announce", + "@id": "c17147d2-ada6-4d3c-a489-dc1e1bf778ab" } diff --git a/features/0030-sync-connection/sync_state.json b/features/0030-sync-connection/sync_state.json index f723b0a9b..fc478384f 100644 --- a/features/0030-sync-connection/sync_state.json +++ b/features/0030-sync-connection/sync_state.json @@ -1,5 +1,5 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/sync-connection/1.0/sync_state", + "@type": "https://didcomm.org/sync-connection/1.0/sync_state", "@id": "e61586dd-f50e-4ed5-a389-716a49817207", "for": "did:peer:11-479cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe", "base_hash": "d48f058771956a305e12a3b062a3ac81bd8653d7b1a88dd07db8f663f37bf8e0", diff --git a/features/0031-discover-features/README.md b/features/0031-discover-features/README.md index 4d1559a9d..18707a18f 100644 --- a/features/0031-discover-features/README.md +++ b/features/0031-discover-features/README.md @@ -1,10 +1,10 @@ # Aries RFC 0031: Discover Features Protocol 1.0 - Authors: Daniel Hardman -- Status: [ACCEPTED](/README.md#accepted) +- Status: [ADOPTED](/README.md#adopted) (may be RETIRED when [v2.0](README.md) of the protocol has enough gravitas) - Since: 2019-05-01 -- Status Note: Reached FCP status in Indy. Implemented in at least two codebases. -- Supersedes: [Indy RFC PR #73](https://github.com/hyperledger/indy-hipe/pull/73) +- Status Note: One of our earliest DIDComm protocols; reached FCP (standards track) status in Indy, and implemented in at least two codebases there. Converted to an Aries RFC Implemented in a handful of Aries codebases. With the advent of DIDComm v2 at DIF, it became clear that we wanted to discover features beyond just protocol support, so this version of the protocol is now superseded by [v2.0 in RFC 0557](../0557-discover-features-v2/README.md). +- Supersedes: [Indy HIPE PR #73](https://github.com/hyperledger/indy-hipe/pull/73). - Start Date: 2018-12-17 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) @@ -27,7 +27,9 @@ This RFC introduces a protocol for discussing the protocols an agent can handle. The identifier for the message family used by this protocol is `discover-features`, and the fully qualified URI for its definition is: - did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0 + https://didcomm.org/discover-features/1.0 + +>This protocol is now superseded by [v2.0 in RFC 0557](../0557-discover-features-v2/README.md). Prefer the new version where practical. ### Roles @@ -50,9 +52,9 @@ A `discover-features/query` message looks like this: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/query", + "@type": "https://didcomm.org/discover-features/1.0/query", "@id": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU", - "query": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tictactoe/1.*", + "query": "https://didcomm.org/tictactoe/1.*", "comment": "I'm wondering if we can play tic-tac-toe..." } ``` @@ -80,11 +82,11 @@ A `discover-features/disclose` message looks like this: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/disclose", + "@type": "https://didcomm.org/discover-features/1.0/disclose", "~thread": { "thid": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU" }, "protocols": [ { - "pid": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tictactoe/1.0", + "pid": "https://didcomm.org/tictactoe/1.0", "roles": ["player"] } ] @@ -94,7 +96,7 @@ A `discover-features/disclose` message looks like this: The `protocols` field is a JSON array of __protocol support descriptor__ objects that match the query. Each descriptor has a `pid` that contains a protocol version (fully qualified message family identifier such as -`did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tictactoe/1.0`), plus a `roles` +`https://didcomm.org/tictactoe/1.0`), plus a `roles` array that enumerates the roles the responding agent can play in the associated protocol. @@ -108,10 +110,10 @@ response is probably just as good: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/disclose", + "@type": "https://didcomm.org/discover-features/1.0/disclose", "~thread": { "thid": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU" }, "protocols": [ - {"pid": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tictactoe/1.0"} + {"pid": "https://didcomm.org/tictactoe/1.0"} ] } ``` diff --git a/features/0031-discover-features/disclose.json b/features/0031-discover-features/disclose.json index c46141329..6508eff07 100644 --- a/features/0031-discover-features/disclose.json +++ b/features/0031-discover-features/disclose.json @@ -1,10 +1,10 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/disclose", + "@type": "https://didcomm.org/discover-features/1.0/disclose", "~thread": { "thid": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU" }, "protocols": [ { - "pid": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tictactoe/1.0", + "pid": "https://didcomm.org/tictactoe/1.0", "roles": ["player"] } ] diff --git a/features/0031-discover-features/query.json b/features/0031-discover-features/query.json index 7a9d600e6..53a867f15 100644 --- a/features/0031-discover-features/query.json +++ b/features/0031-discover-features/query.json @@ -1,8 +1,8 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/query", + "@type": "https://didcomm.org/discover-features/1.0/query", "@id": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU", - "query": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tictactoe/1.*", + "query": "https://didcomm.org/tictactoe/1.*", "comment": "I'm wondering if we can play tic-tac-toe..." } diff --git a/features/0031-discover-features/simpler-response.json b/features/0031-discover-features/simpler-response.json index 33dadb211..1f45b47a4 100644 --- a/features/0031-discover-features/simpler-response.json +++ b/features/0031-discover-features/simpler-response.json @@ -1,9 +1,9 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/discover-features/1.0/disclose", + "@type": "https://didcomm.org/discover-features/1.0/disclose", "~thread": { "thid": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU" }, "protocols": [ - {"pid": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tictactoe/1.0"} + {"pid": "https://didcomm.org/tictactoe/1.0"} ] } diff --git a/features/0032-message-timing/README.md b/features/0032-message-timing/README.md index 687bec12a..626a03df2 100644 --- a/features/0032-message-timing/README.md +++ b/features/0032-message-timing/README.md @@ -1,6 +1,6 @@ # Aries RFC 0032: Message Timing -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [DEMONSTRATED](/README.md#demonstrated) - Since: 2019-05-01 - Status Note: Broadly socialized but not yet implemented. diff --git a/features/0034-message-tracing/README.md b/features/0034-message-tracing/README.md index f3ca3b348..382bddf79 100644 --- a/features/0034-message-tracing/README.md +++ b/features/0034-message-tracing/README.md @@ -60,7 +60,21 @@ Tracing is requested by decorating the JSON plaintext of an DIDComm message (whi and handled at its final destination) with the `~trace` attribute. Here is the simplest possible example: -[![example of ~trace](msg-with-trace.png)](msg-with-trace.json) +``` +{ + "@type": "did:sov:BzCBs...;spec/routing/1.0/forward", + "@id": "abc-def-...", + "msg": "U2Vl...", + "~trace": { + "target": "http://example.com/tracer", + "full_thread": true + } +} +``` + +The `"target"` can refer to a url (as above) or the term `"log"`, which is a request to +append trace information to the standard log file. (Information can then be manually +collated from agents.) This example asks the handler of the message to perform an HTTP POST of a __trace report__ about the message to the URI `http://example.com/tracer`. @@ -85,7 +99,19 @@ even if it is expired or invalid. The rationale for this choice is: The body of the HTTP request (the _trace report_) is a JSON document that looks like this: -[![trace report](trace-report.png)](trace-report.json) +``` +{ + "@type": "did:sov:BzCBs...;spec/1.0/trace_report", + "msg_id": "abc-def-...df", + "thread_id": "hij-klm-nop-...qr", + "handler": "did:sov:1234abcd#3", + "ellapsed_milli": 27, + "traced_type": "did:sov:BzCBs...;spec/routing/1.0/forward", + "str_time": "2018-03-27 18:23:45.123Z", + "timestamp": "1234567890.123456", + "outcome": "OK ..." +} +``` ### Subtleties @@ -97,7 +123,7 @@ connection when the reports are analyzed together. ![tracing unrelated messages](trace-xyz.png) -To solve this problem, traced messages use an ID convention that permits ordering. +To solve this problem, traced messages *may* use an ID convention that permits ordering. Assume that the inner application message has a base ID, _X_. Containing messages (e.g., `forward` messages) have IDs in the form _X_.1, _X_.2, _X_.3, and so forth -- where numbers represent the order in @@ -184,11 +210,12 @@ plaintext of the report, as utf8. ### Trace Report Attributes -* `@type`: Should always be `"did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/tracing/1.0/trace_report"`, +* `@type`: Should always be `"https://didcomm.org/tracing/1.0/trace_report"`, or some evolved version thereof. Required for version control and to support trace sinks that process other HTTP payloads as well. -* `for_id`: The ID of the message that the handler is looking at when it composes the +* `msg_id`: The ID of the message that the handler is looking at when it composes the trace report. Required. +* `thread_id`: The ID of the protocol thread. Required. * `handler`: A string that identifies the handler in a way that's useful for troubleshooting purposes. For example, it might identify a particular agent by DID+keyref, or it might be a friendly string like "iPhone" or "AgentsRUs Cloud Agent, geocaching extension v1.3.7". Optional but @@ -197,9 +224,10 @@ plaintext of the report, as utf8. the trace report? If the same handler emits more than one trace report, how long has it been since the last trace was composed? Optional but encouraged. * `traced_type`: What was the message type of the traced message? Optional but encouraged. -* `report_time`: What was the UTC timestamp of the system clock of the handler +* `str_time`: What was the UTC timestamp of the system clock of the handler when the handler composed the trace report? ISO 8601 format with millisecond precision. Optional but encouraged. +* `timestamp`: Value fo the `str_time` field in milliseconds (UNIX time format). * `outcome`: A string that describes the outcome of the message handling. The string MUST begin with one of the following tokens: `"OK"` (meaning the handler completed its processing successfully; `"ERR"` (the handler failed), or `"PEND"` (the handler is still working on the diff --git a/features/0034-message-tracing/msg-with-trace.json b/features/0034-message-tracing/msg-with-trace.json index 289b02bec..949913ae0 100644 --- a/features/0034-message-tracing/msg-with-trace.json +++ b/features/0034-message-tracing/msg-with-trace.json @@ -1,6 +1,6 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/route/1.0/forward", + "@type": "https://didcomm.org/route/1.0/forward", "@id": "98fd8d72-80f6-4419-abc2-c65ea39d0f38", "msg": "U2VlIHRoZSB3aXJlIG1lc3NhZ2VzIEhJUEUgZm9yIGRldGFpbHMgcGFja2luZyBhbmQgZW5jcnlwdGluZy4=", "~trace": "http://example.com/tracer" diff --git a/features/0034-message-tracing/trace-report.json b/features/0034-message-tracing/trace-report.json index 05852ef9b..f014a5017 100644 --- a/features/0034-message-tracing/trace-report.json +++ b/features/0034-message-tracing/trace-report.json @@ -1,10 +1,10 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/trace/1.0/trace_report", + "@type": "https://didcomm.org/trace/1.0/trace_report", "for_id": "98fd8d72-80f6-4419-abc2-c65ea39d0f38.1", "handler": "did:sov:1234abcd#3", "elapsed_milli": 27, - "traced_type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/route/1.0/forward", + "traced_type": "https://didcomm.org/route/1.0/forward", "report_time": "2018-05-27 18:23:16.123Z", "outcome": "OK (forwarded to did:sov:1234abcd#4)" } diff --git a/features/0035-report-problem/README.md b/features/0035-report-problem/README.md index 77f4d2f82..9e2b3ce91 100644 --- a/features/0035-report-problem/README.md +++ b/features/0035-report-problem/README.md @@ -1,18 +1,22 @@ # Aries RFC 0035: Report Problem Protocol 1.0 -- Authors: [Stephen Curran](swcurran@cloudcompass.ca), [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [DEMONSTRATED](/README.md#demonstrated) -- Since: 2019-04-01 -- Status Note: Implemented in several codebases. Not yet fully harmonized. +- Authors: [Stephen Curran](mailto:swcurran@cloudcompass.ca), [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 +- Status Note: Implemented in multiple codebases. - Supersedes: [Indy HIPE PR #65]( https://github.com/hyperledger/indy-hipe/pull/65) - Start Date: 2018-11-26 -- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) ## Summary Describes how to report errors and warnings in a powerful, interoperable way. All implementations of SSI agent or hub technology SHOULD implement this RFC. +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. + ## Motivation Effective reporting of errors and warnings is difficult in any system, and particularly so in @@ -113,15 +117,10 @@ Reporting problems uses a simple one-step [notification protocol]( ../../concepts/0003-protocols/README.md#types-of-protocols). Its official [PIURI]( ../../concepts/0003-protocols/README.md#piuri) is: - did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/report-problem/1.0 + https://didcomm.org/report-problem/1.0 The protocol includes the standard `notifier` and `notified` roles. It defines a single message type `problem-report`, introduced here. -It also [adopts](../../0000-template-protocol.md#adopted-messages) the -`ack` message from the [`ACK 1.0` protocol](../0015-acks/README.md), -to accommodate the possibility that the [`~please_ack`](../0317-please-ack/README.md) -[decorator]( ../../concepts/0011-decorators/README.md) may be used on the - notification. A `problem-report` communicates about a problem when an agent-to-agent message is possible and a recipient for the problem report is known. This covers, for example, @@ -139,7 +138,7 @@ of the following: ```jsonc { - "@type" : "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/report-problem/1.0/problem-report", + "@type" : "https://didcomm.org/report-problem/1.0/problem-report", "@id" : "an identifier that can be used to discuss this error message", "~thread" : "info about the threading context in which the error occurred (if any)", "description" : { "en": "localized message", "code": "symbolic-name-for-error" }, @@ -172,6 +171,8 @@ to a message, the thread decorator is mostly redundant, as `~thread.thid` must e **description**: Contains human-readable, localized alternative string(s) that explain the problem. It is highly recommended that the message follow use the guidance in [the l10n RFC](../0043-l10n/README.md), allowing the error to be searched on the web and documented formally. +**description.code**: Required. Contains the code that indicates the problem being communicated. Codes are described in protocol RFCs and other relevant places. New Codes SHOULD follow the [Problem Code](https://identity.foundation/didcomm-messaging/spec/#problem-codes) naming convention detailed in the DIDComm v2 spec. + **problem_items**: A list of one or more key/value pairs that are parameters about the problem. Some examples might be: - a list of arguments that didn’t pass input validation @@ -215,13 +216,13 @@ Each item in the list must be a tagged pair (a JSON {key:value}, where the key n ``` jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/problem-report", + "@type": "https://didcomm.org/notification/1.0/problem-report", "@id": "7c9de639-c51c-4d60-ab95-103fa613c805", "~thread": { "pthid": "1e513ad4-48c9-444e-9e7e-5b8b45c5e325", "sender_order": 1 }, - "~l10n" : {"catalog": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/error-codes"}, + "~l10n" : {"catalog": "https://didcomm.org/error-codes"}, "description" : "Unable to find a route to the specified recipient.", "description~l10n" : {"code": "cant-find-route" }, "problem_items" : [ @@ -237,6 +238,12 @@ Each item in the list must be a tagged pair (a JSON {key:value}, where the key n The following is a categorization of a number of examples of errors and (current) Best Practice handling for those types of errors. The new `problem-report` message type is used for some of these categories, but not all. +### Unknown Error + +Errors of a known error code will be processed according to the understanding of what the code means. Support of a protocol includes support and proper processing of the error codes detailed within that protocol. + +Any unknown error code that starts with `w.` in the DIDComm v2 style may be considered a warning, and the flow of the active protocol SHOULD continue. All other unknown error codes SHOULD be considered to be an end to the active protocol. + ### Error While Processing a Received Message An Agent Message sent by a Sender and received by its intended Recipient cannot be processed. @@ -331,6 +338,20 @@ If the decision is to retry, it would be good to have support in areas covered b Excessive retrying can exacerbate an existing system issue. If the reason for the timeout is because there is a "too many messages to be processed" situation, then sending retries simply makes the problem worse. As such, a reasonable backoff strategy should be used (e.g. exponentially increasing times between retries). As well, a [strategy used at Uber](https://eng.uber.com/reliable-reprocessing/) is to flag and handle retries differently from regular messages. The analogy with Uber is not pure - that is a single-vendor system - but the notion of flagging retries such that retry messages can be handled differently is a good approach. +### Caveat: Problem Report Loops + +Implementers should consider and mitigate the risk of an endless loop of error messages. For example: + +- Alice sends a message to Bob that Bob doesn't recognize. Bob sends a `Problem Report` message to Alice. +- Alice doesn't understand the message from Bob and sends a `Problem Report` to Bob. +- Bob doesn't understand the message from Alice and sends a `Problem Report` to Alice. And so on... + +#### Recommended Handling + +How agents mitigate the risk of this problem is implementation specific, balancing loop-tracking overhead versus the likelihood of occurrence. +For example, an agent implementation might have a counter on a connection object that is incremented when certain types of `Problem Report` messages are sent on that connection, +and reset when any other message is sent. The agent could stop sending those types of `Problem Report` messages after the counter reaches a given value. + ## Reference TBD @@ -363,6 +384,6 @@ The following lists the implementations (if any) of this RFC. Please do a pull r Name / Link | Implementation Notes --- | --- -[RFC 0036: Issue Credential Protocol](../0036-issue-credential/README.md) | The `problem-report` message is [adopted](../../0000-template-protocol.md#adopted-messages) by this protocol. -[RFC 0037: Present Proof Protocol](../0037-present-proof/README.md) | The `problem-report` message is [adopted](../../0000-template-protocol.md#adopted-messages) by this protocol. -[Streetcred.id](https://streetcred.id/) | Commercial mobile and web app built using Aries Framework - .NET +[RFC 0036: Issue Credential Protocol](../0036-issue-credential/README.md) | The `problem-report` message is [adopted](../../0000-template-protocol.md#adopted-messages) by this protocol. [MISSING test results](/tags.md#test-anomaly) +[RFC 0037: Present Proof Protocol](../0037-present-proof/README.md) | The `problem-report` message is [adopted](../../0000-template-protocol.md#adopted-messages) by this protocol. [MISSING test results](/tags.md#test-anomaly) +[Trinsic.id](https://trinsic.id/) | Commercial mobile and web app built using Aries Framework - .NET [MISSING test results](/tags.md#test-anomaly) diff --git a/features/0036-issue-credential/README.md b/features/0036-issue-credential/README.md index 1ae98f408..554ff4dce 100644 --- a/features/0036-issue-credential/README.md +++ b/features/0036-issue-credential/README.md @@ -1,7 +1,7 @@ # Aries RFC 0036: Issue Credential Protocol 1.0 - Authors: Nikita Khateev -- Status: [ACCEPTED](/README.md#accepted) +- Status: [ADOPTED](/README.md#adopted) (But should move to deprecated) - Since: 2019-05-28 - Status Note: See [RFC 0037](../0037-present-proof/README.md) for the presentation part of using credentials. - Supersedes: [Indy HIPE PR #89]( https://github.com/hyperledger/indy-hipe/blob/2e85595e9a948a2fbfd58400191d112caff5a14b/text/credential-exchange-message-family/README.md); also [Credential Exchange 0.1 -- IIW 2019](https://hackmd.io/@QNKW9ANJRy6t81D7IfgiZQ/HkklVzww4?type=view) @@ -99,7 +99,7 @@ An optional message sent by the potential Holder to the Issuer to initiate the p ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/1.1/propose-credential", + "@type": "https://didcomm.org/issue-credential/1.1/propose-credential", "@id": "", "comment": "some comment", "credential_proposal": , @@ -131,7 +131,7 @@ Schema: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/1.0/offer-credential", + "@type": "https://didcomm.org/issue-credential/1.0/offer-credential", "@id": "", "comment": "some comment", "credential_preview": , @@ -152,7 +152,7 @@ Description of fields: * `comment` -- an optional field that provides human readable information about this Credential Offer, so the offer can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). * `credential_preview` -- a JSON-LD object that represents the credential data that Issuer is willing to issue. It matches the schema of [Credential Preview](#preview-credential); * `offers~attach` -- an array of attachments that further define the credential being offered. This might be used to clarify which formats or format versions will be issued. - * For Indy, the attachment includes a nonce and key correctness proof to facilitate integrity checks. It is a base64-encoded version of the data returned from [`indy_issuer_create_credential_offer()`](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L280). + * For Indy, the attachment includes a nonce and key correctness proof to facilitate integrity checks. It is a base64url-encoded version of the data returned from [`indy_issuer_create_credential_offer()`](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L280). The Issuer may add a [`~payment-request` decorator](../0075-payment-decorators/README.md#payment_request) to this message to convey the need for payment before issuance. See the [payment section below](#payments-during-credential-exchange) for more details. @@ -166,7 +166,7 @@ Schema: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/1.0/request-credential", + "@type": "https://didcomm.org/issue-credential/1.0/request-credential", "@id": "", "comment": "some comment", "requests~attach": [ @@ -185,7 +185,7 @@ Description of Fields: * `comment` -- an optional field that provides human readable information about this Credential Request, so it can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). * `requests~attach` -- an array of [attachments](../../concepts/0017-attachments/README.md) defining the requested formats for the credential. - * For Indy, the attachment is a base64-encoded version of the data returned from [`indy_prover_create_credential_req()`](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L658). + * For Indy, the attachment is a base64url-encoded version of the data returned from [`indy_prover_create_credential_req()`](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L658). This message may have a [`~payment-receipt` decorator](../0075-payment-decorators/README.md#payment_receipt) to prove to the Issuer that the potential Holder has satisfied a payment requirement. See the [payment section below](#payments-during-credential-exchange). @@ -197,7 +197,7 @@ Schema: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/1.0/issue-credential", + "@type": "https://didcomm.org/issue-credential/1.0/issue-credential", "@id": "", "comment": "some comment", "credentials~attach": [ @@ -216,7 +216,7 @@ Description of fields: * `comment` -- an optional field that provides human readable information about the issued credential, so it can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). * `credentials~attach` -- an array of attachments containing the issued credentials. - * For Indy, the attachment contains data from libindy about credential to be issued, base64-encoded, as returned from `libindy`. For more information see the [Libindy API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L338). + * For Indy, the attachment contains data from libindy about credential to be issued, base64url-encoded, as returned from `libindy`. For more information see the [Libindy API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L338). If the issuer wants an acknowledgement that the issued credential was accepted, this message must be decorated with `~please-ack`, and it is then best practice for the new Holder to respond with an explicit `ack` message as described in [0317: Please ACK Decorator](../0317-please-ack/README.md). @@ -244,7 +244,7 @@ This is not a message but an inner object for other messages in this protocol. I ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/1.0/credential-preview", + "@type": "https://didcomm.org/issue-credential/1.0/credential-preview", "attributes": [ { "name": "", @@ -269,7 +269,7 @@ The optional `mime-type` advises the issuer how to render a binary attribute, to The mandatory `value` holds the attribute value: * if `mime-type` is missing (null), then `value` is a string. In other words, implementations interpret it the same as any other key+value pair in JSON -* if `mime-type` is not null, then `value` is always a base64-encoded string that represents a binary BLOB, and `mime-type` tells how to interpret the BLOB after base64-decoding. +* if `mime-type` is not null, then `value` is always a base64url-encoded string that represents a binary BLOB, and `mime-type` tells how to interpret the BLOB after base64url-decoding. ## Threading diff --git a/features/0037-present-proof/README.md b/features/0037-present-proof/README.md index 3c4ad5e01..a9da30713 100644 --- a/features/0037-present-proof/README.md +++ b/features/0037-present-proof/README.md @@ -1,7 +1,7 @@ # Aries RFC 0037: Present Proof Protocol 1.0 - Authors: Nikita Khateev -- Status: [ACCEPTED](/README.md#accepted) +- Status: [ADOPTED](/README.md#adopted) (But should move to deprecated) - Since: 2019-05-28 - Status Note: This v1.x version of the protocol will be replaced by version v2 defined in [RFC 454](../0454-present-proof-v2/README.md). - Supersedes: [Indy HIPE PR #89](https://github.com/hyperledger/indy-hipe/blob/2e85595e9a948a2fbfd58400191d112caff5a14b/text/credential-exchange-message-family/README.md); also [Credential Exchange 0.1 -- IIW 2019](https://hackmd.io/@QNKW9ANJRy6t81D7IfgiZQ/HkklVzww4?type=view) @@ -71,7 +71,7 @@ An optional message sent by the Prover to the verifier to initiate a proof prese ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/propose-presentation", + "@type": "https://didcomm.org/present-proof/1.0/propose-presentation", "@id": "", "comment": "some comment", "presentation_proposal": @@ -89,7 +89,7 @@ From a verifier to a prover, the `request-presentation` message describes values ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", + "@type": "https://didcomm.org/present-proof/1.0/request-presentation", "@id": "", "comment": "some comment", "request_presentations~attach": [ @@ -108,7 +108,7 @@ Description of fields: * `comment` -- a field that provides some human readable information about this request for a presentation. * `request_presentations~attach` -- an array of attachments defining the acceptable formats for the presentation. - * For Indy, the attachment contains data from libindy about the presentation request, base64-encoded, as returned from `libindy`. For more information see the [Libindy API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1214). + * For Indy, the attachment contains data from libindy about the presentation request, base64url-encoded, as returned from `libindy`. For more information see the [Libindy API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1214). ### Presentation @@ -116,7 +116,7 @@ This message is a response to a Presentation Request message and contains signed ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/presentation", + "@type": "https://didcomm.org/present-proof/1.0/presentation", "@id": "", "comment": "some comment", "presentations~attach": [ @@ -135,7 +135,7 @@ Description of fields: * `comment` -- a field that provides some human readable information about this presentation. * `presentations~attach` -- an array of attachments containing the presentation in the requested format(s). - * For Indy, the attachment contains data from libindy that is the presentation, base64-encoded, as returned from `libindy`. For more information see the [Libindy API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1404). + * For Indy, the attachment contains data from libindy that is the presentation, base64url-encoded, as returned from `libindy`. For more information see the [Libindy API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1404). #### Verifying Claims of Indy-based Verifiable Credentials @@ -161,7 +161,7 @@ This is not a message but an inner object for other messages in this protocol. I ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/presentation-preview", + "@type": "https://didcomm.org/present-proof/1.0/presentation-preview", "attributes": [ { "name": "", @@ -207,7 +207,7 @@ The optional `mime-type` advises the verifier how to render a binary attribute, The optional `value`, when present, holds the value of the attribute to reveal in presentation: * if `mime-type` is missing (null), then `value` is a string. In other words, implementations interpret it the same as any other key+value pair in JSON -* if `mime-type` is not null, then `value` is always a base64-encoded string that represents a binary BLOB, and `mime-type` tells how to interpret the BLOB after base64-decoding. +* if `mime-type` is not null, then `value` is always a base64url-encoded string that represents a binary BLOB, and `mime-type` tells how to interpret the BLOB after base64-decoding. An attribute specification must specify a `value`, a `cred_def_id`, or both: @@ -226,7 +226,7 @@ For example, a holder with multiple account credentials could use a presentation ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/presentation-preview", + "@type": "https://didcomm.org/present-proof/1.0/presentation-preview", "attributes": [ { "name": "account", diff --git a/features/0042-lox/README.md b/features/0042-lox/README.md index 036b04e31..21e70d965 100644 --- a/features/0042-lox/README.md +++ b/features/0042-lox/README.md @@ -1,6 +1,6 @@ # Aries RFC 0042: LOX -- A more secure pluggable framework for protecting wallet keys -- Authors: [Michael Lodder](mike@sovrin.org) +- Authors: [Michael Lodder](mailto:mike@sovrin.org) - Status: [DEMONSTRATED](/README.md#demonstrated) - Since: 2019-05-30 - Start Date: 2019-05-30 @@ -50,7 +50,7 @@ Some systems back keyrings with hardware to increase security. The following flo ### Secure Enclaves Secure enclaves are used to describe HSMs, TPMs, and TEEs. -An explaination of how secure enclaves work is detailed [here](https://github.com/hyperledger/indy-hipe/tree/master/text/0013-wallets#enclave-wrapping). +An explaination of how secure enclaves work is detailed [here](https://github.com/hyperledger/indy-hipe/tree/main/text/0013-wallets#enclave-wrapping). ### Details @@ -126,7 +126,7 @@ Trying to account for all of these will be difficult and may require changes to ## Prior art -A brief overview of enclaves and their services have been discussed in the [Indy wallet HIPE](https://github.com/hyperledger/indy-hipe/tree/master/text/0013-wallets). +A brief overview of enclaves and their services have been discussed in the [Indy wallet HIPE](https://github.com/hyperledger/indy-hipe/tree/main/text/0013-wallets). ## Unresolved questions @@ -138,4 +138,4 @@ The following lists the implementations (if any) of this RFC. Please do a pull r Name / Link | Implementation Notes --- | --- -[Reference Code](https://github.com/hyperledger/aries-rfcs/tree/master/features/0042-lox/reference_code) | Example rust code that implements Lox using OS keychains +[Reference Code](https://github.com/hyperledger/aries-rfcs/tree/main/features/0042-lox/reference_code) | Example rust code that implements Lox using OS keychains diff --git a/features/0043-l10n/with-code.json b/features/0043-l10n/with-code.json index ce8b9b846..004f2cf12 100644 --- a/features/0043-l10n/with-code.json +++ b/features/0043-l10n/with-code.json @@ -1,6 +1,6 @@ { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/problem-report", + "@type": "https://didcomm.org/notification/1.0/problem-report", "explain": "Unable to route to specified agent", "explain~l10n": { "code": "cant-route-to-agent", diff --git a/features/0044-didcomm-file-and-mime-types/README.md b/features/0044-didcomm-file-and-mime-types/README.md index f42f59830..2bbd56cc7 100644 --- a/features/0044-didcomm-file-and-mime-types/README.md +++ b/features/0044-didcomm-file-and-mime-types/README.md @@ -1,21 +1,15 @@ # Aries RFC 0044: DIDComm File and MIME Types - Authors: Daniel Hardman, Kyle Den Hartog -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-05-28 -- Status Note: Socialized and accepted within Indy community, and used in several implementations of protocols that want to associate a MIME type with an HTTP payload. However, this version of the spec changes the type names of types slightly to genericize, so we're resetting the status. -- Supersedes: [Indy HIPE 0026]( https://github.com/hyperledger/indy-hipe/blob/master/text/0026-agent-file-format/README.md) +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2021-04-15 +- Status Note: Revised as part of [AIP 2.0](../../concepts/0302-aries-interop-profile/README.md) to ease the upcoming transition from DIDComm v1 to [DIDComm v2](https://identity.foundation/didcomm-messaging/spec/). - Start Date: 2018-11-13 - Tags: [feature](/tags.md#feature) -[![message in envelope](small-msg-in-envelope.png)](msg-in-envelope.png) - ## Summary -Define a file format and MIME type that holds [DIDComm]( - ../../concepts/0005-didcomm/README.md) -content--messages--as well as the encrypted and signed -envelopes that contain them. +Defines the media (MIME) types and file types that hold [DIDComm]( ../../concepts/0005-didcomm/README.md) messages in encrypted, signed, and plaintext forms. Covers DIDComm V1, plus a little of [V2](https://identity.foundation/didcomm-messaging/spec/) to clarify [how DIDComm versions are detected](#detecting-didcomm-versions). ## Motivation @@ -30,12 +24,16 @@ distributed file systems like IPFS, can be inserted in an object store or in content-addressable storage, can be viewed and modified in editors, and support a million other uses. -We need to define how files can contain DIDComm messages, and what the +We need to define how files and attachments can contain DIDComm messages, and what the semantics of processing such files will be. ## Tutorial -### DIDComm Encrypted Envelope (*.dee) +### Media Types + + Media types are based on the conventions of [RFC6838](https://tools.ietf.org/html/rfc6838). Similar to [RFC7515](https://tools.ietf.org/html/rfc7515#section-4.1.9), the `application/` prefix MAY be omitted and the recipient MUST treat media types not containing `/` as having the `application/` prefix present. + +### DIDComm v1 Encrypted Envelope (*.dee) [![dee icon](dee-small.png)](dee-big.png) @@ -47,31 +45,34 @@ its type reliably. The file extension associated with this filetype is `dee`, giving a globbing pattern of `*.dee`; this should be be read as "STAR DOT D E E" or as "D E E" files. -If a format evolution takes place, a subsequent version could be -noted by appending a digit, as in `*.dee2` for second-generation `dee` files. - -The name of this file format is "DIDComm Encrypted Envelope." We expect people to say, -"I am looking at a DIDComm Encrypted Envelope", or "This file is in DIDComm Encrypted Envelope format", or -"Does my editor have a DIDComm Encrypted Envelope plugin?" + +The name of this file format is "DIDComm V1 Encrypted Envelope." We expect people to say, +"I am looking at a DIDComm V1 Encrypted Envelope", or "This file is in DIDComm V1 Encrypted Envelope format", or +"Does my editor have a DIDComm V1 Encrypted Envelope plugin?" Although the format of encrypted envelopes is derived from JSON and the JWT/JWE family of specs, no useful processing of these files will take place by viewing them as JSON, and viewing them as generic JWEs will greatly constrain which semantics are applied. Therefore, the recommended MIME type for *.dee files is -`application/didcomm-enc-env`, with `application/jwe` as a fallback, and +`application/didcomm-envelope-enc`, with `application/jwe` as a fallback, and `application/json` as an even less desirable fallback. (In this, we are making a choice similar to the one that views `*.docx` files primarily as `application/msword` instead of `application/xml`.) If format evolution takes place, the version could become a parameter as [described in RFC 1341](https://www.w3.org/Protocols/rfc1341/4_Content-Type.html): -`application/didcomm-enc-env;v=2`. +`application/didcomm-envelope-enc;v=2`. + +A recipient using the media type value MUST treat it as if `“application/”` were prepended to any `"typ"` or `"cty"` value not containing a ‘/’ in compliance +with the [JWE](https://tools.ietf.org/html/rfc7516) /[JWS](https://tools.ietf.org/html/rfc7515) family of specs. -The default action for DIDComm Encrypted Envelopes (what happens when a user double-clicks one) +The default action for DIDComm V1 Encrypted Envelopes (what happens when a user double-clicks one) should be `Handle` (that is, process the message as if it had just arrived by some other transport), if the software handling the message is an agent. In other types of software, the default action might be to view the file. Other useful actions might include `Send`, `Attach` (to email, chat, etc), `Open with agent`, and `Decrypt to *.dp`. -### DIDComm Signed Envelopes (*.dse) +>NOTE: The analog to this content type in DIDComm v2 is called a "DIDComm Encrypted Message." Its format is slightly different. For more info, see [Detecting DIDComm Versions](#detecting-didcomm-versions) below. + +### DIDComm V1 Signed Envelopes (*.dse) [![dse icon](dse-small.png)](dse-big.png) @@ -86,22 +87,25 @@ in combination with signing, the DSE goes inside the DEE. The file extension associated with this filetype is `dse`, giving a globbing pattern of `*.dse`; this should be be read as "STAR DOT D S E" or as "D S E" files. -Format evolution can add digits as with *.dee files. -The name of this file format is "DIDComm Signed Envelope." We expect people to say, -"I am looking at a DIDComm Signed Envelope", or "This file is in DIDComm Signed Envelope format", or -"Does my editor have a DIDComm Signed Envelope plugin?" +The name of this file format is "DIDComm V1 Signed Envelope." We expect people to say, +"I am looking at a DIDComm V1 Signed Envelope", or "This file is in DIDComm V1 Signed Envelope format", or +"Does my editor have a DIDComm V1 Signed Envelope plugin?" As with *.dee files, the best way to hande *.dse files is to map them to a custom MIME type. The recommendation is `application/didcomm-sig-env`, with `application/jws` as a fallback, and `application/json` as an even less desirable fallback. -The default action for DIDComm Signed Envelopes (what happens when a user double-clicks one) +A recipient using the media type value MUST treat it as if `“application/”` were prepended to any `"typ"` or `"cty"` value not containing a ‘/’ in compliance +with the [JWE](https://tools.ietf.org/html/rfc7516) /[JWS](https://tools.ietf.org/html/rfc7515) family of specs. + +The default action for DIDComm V1 Signed Envelopes (what happens when a user double-clicks one) should be `Validate` (that is, process the signature to see if it is valid. +>NOTE: The analog to this content type in DIDComm v2 is called a "DIDComm Signed Message." Its format is slightly different. For more info, see [Detecting DIDComm Versions](#detecting-didcomm-versions) below. -### DIDComm Messages (*.dm) +### DIDComm V1 Messages (*.dm) [![dm icon](dm-small.png)](dm-big.png) @@ -123,20 +127,23 @@ The file extension associated with this filetype is `*.dm`, and should be read a "STAR DOT D M" or "D M" files. If a format evolution takes place, a subsequent version could be noted by appending a digit, as in `*.dm2` for second-generation `dm` files. -The name of this file format is "DIDComm Message." We expect people to say, -"I am looking at a DIDComm Message", or "This file is in DIDComm Message", or -"Does my editor have a DIDComm Message plugin?" For extra clarity, it is acceptable -to add the adjective "plaintext", as in "DIDComm Plaintext Message." +The name of this file format is "DIDComm V1 Message." We expect people to say, +"I am looking at a DIDComm V1 Message", or "This file is in DIDComm V1 Message format", or +"Does my editor have a DIDComm V1 Message plugin?" For extra clarity, it is acceptable +to add the adjective "plaintext", as in "DIDComm V1 Plaintext Message." + +The most specific MIME type of *.dm files is `application/json;flavor=didcomm-msg`--or, if more generic handling is appropriate, just +`application/json`. -The MIME type of *.dm files is `application/json`--or, if further discrimination is needed, -`application/json;flavor=didcomm-msg`. If format evolution takes place, the version could -become a parameter as [described in RFC 1341](https://www.w3.org/Protocols/rfc1341/4_Content-Type.html): -`application/json;flavor=didcomm-msg;v=2`. +A recipient using the media type value MUST treat it as if `“application/”` were prepended to any `"typ"` or `"cty"` value not containing a ‘/’ in compliance +with the [JWE](https://tools.ietf.org/html/rfc7516) /[JWS](https://tools.ietf.org/html/rfc7515) family of specs. -The default action for DIDComm Messages should be to +The default action for DIDComm V1 Messages should be to `View` or `Validate` them. Other interesting actions might be `Encrypt to *.dee`, `Sign to *.dse`, and `Find definition of protocol`. +>NOTE: The analog to this content type in DIDComm v2 is called a "DIDComm Plaintext Message." Its format is slightly different. For more info, see [Detecting DIDComm Versions](#detecting-didcomm-versions) below. + As a general rule, DIDComm messages that are being sent in production use cases of DID communication should be stored in encrypted form (`*.dee`) at rest. There are cases where this might not be preferred, e.g., providing documentation of the format of message or during a debugging scenario using @@ -158,12 +165,58 @@ Object format might be a bean. In C++, it might be a `std::mapDIDComm V1 Encrypted Envelope
*.dee | `application/didcomm-encrypted+json`
DIDComm Encrypted Message
*.dcem +signed| `application/didcomm-sig-env`
DIDComm V1 Signed Envelope
*.dse | `application/didcomm-signed+json`
DIDComm Signed Message
*.dcsm +plaintext| `application/json;flavor=didcomm-msg`
DIDComm V1 Message
*.dm | `application/didcomm-plain+json`
DIDComm Plaintext Message
*.dcpm + +It is also recommended that agents implementing [Discover Features Protocol v2](../0557-discover-features-v2/README.md) respond to [queries about supported DIDComm versions](../0557-discover-features-v2/README.md#queries-message-type) using the `didcomm-version` feature name. This allows queries about what an agent is willing to support, whereas the media type mechanism describes what is in active use. The values that should be returned from such a query are URIs that tell where DIDComm versions are developed: + +Version | URI +--- | --- +V1 | https://github.com/hyperledger/aries-rfcs +V2 | https://github.com/decentralized-identity/didcomm-messaging + +### What it means to "implement" this RFC + +For the purposes of [Aries Interop Profiles](../../concepts/0302-aries-interop-profile/README.md), an agent "implements" this RFC when: + +* If it encounters references to DIDComm V1 media types (e.g., in HTTP headers, in attachments, or in the fields of DIDComm messages where a media type is expected), it imputes the meaning documented here. +* If it characterizes DIDComm V1 content in its own outbound communication or UI, it does so with the media type strings, friendly names, and file extensions documented here. ## Reference The file extensions and MIME types described here are also accompanied by suggested graphics. -[Vector forms of these graphics are available as well]( +[Vector forms of these graphics are available]( https://docs.google.com/presentation/d/1QmKxuMz8KnqYbdGUEOaNqLtZSCZryQrwj9RRXMN4uAk/edit#slide=id.p). ## Implementations diff --git a/features/0048-trust-ping/README.md b/features/0048-trust-ping/README.md index 0a889a616..e15cd6790 100644 --- a/features/0048-trust-ping/README.md +++ b/features/0048-trust-ping/README.md @@ -1,10 +1,10 @@ # Aries RFC 0048: Trust Ping Protocol 1.0 -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-02-01 - Status Note: Numerous implementations. -- Supersedes: [Indy HIPE 0032](https://github.com/hyperledger/indy-hipe/tree/master/text/0032-trust-ping) +- Supersedes: [Indy HIPE 0032](https://github.com/hyperledger/indy-hipe/tree/main/text/0032-trust-ping) - Start Date: 2018-12-11 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) @@ -48,7 +48,7 @@ creates a `ping` message like this: ```JSON { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/trust_ping/1.0/ping", + "@type": "https://didcomm.org/trust_ping/1.0/ping", "@id": "518be002-de8e-456e-b3d5-8fe472477a86", "~timing": { "out_time": "2018-12-15 04:29:23Z", @@ -86,7 +86,7 @@ is not `false`, the receiver should reply as quickly as possible with a ```JSON { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/trust_ping/1.0/ping_response", + "@type": "https://didcomm.org/trust_ping/1.0/ping_response", "@id": "e002518b-456e-b3d5-de8e-7a86fe472847", "~thread": { "thid": "518be002-de8e-456e-b3d5-8fe472477a86" }, "~timing": { "in_time": "2018-12-15 04:29:28Z", "out_time": "2018-12-15 04:31:00Z"}, @@ -110,7 +110,7 @@ messages are encrypted with suitable algorithms and keys. 2. Messages may be targeted at any known agent in the other party's sovereign domain, using [cross-domain routing conventions]( -https://github.com/hyperledger/indy-hipe/blob/master/text/0022-cross-domain-messaging/README.md), +https://github.com/hyperledger/indy-hipe/blob/main/text/0022-cross-domain-messaging/README.md), and may be encrypted and packaged to expose exactly and only the information desired, at each hop along the way. This allows two parties to evaluate the completeness of diff --git a/features/0056-service-decorator/README.md b/features/0056-service-decorator/README.md index 3b56fc44a..b7e5de431 100644 --- a/features/0056-service-decorator/README.md +++ b/features/0056-service-decorator/README.md @@ -1,6 +1,6 @@ # Aries RFC 0056: Service Decorator -- Authors: [Sam Curren](sam@sovrin.org), Tobias Looker +- Authors: [Sam Curren](mailto:sam@sovrin.org), Tobias Looker - Status: [PROPOSED](/README.md#proposed) - Since: 2019-06-03 - Status Note: Needs refinement and validation, will be useful in any connectionless communication. @@ -23,7 +23,7 @@ The `~service` decorator on a message contains the service definition that you m Usage looks like this, with the contents defined the [Service Endpoint section of the DID Spec](https://w3c-ccg.github.io/did-spec/#service-endpoints): -```json= +```json { "@type": "somemessagetype", "~service": { @@ -34,11 +34,9 @@ Usage looks like this, with the contents defined the [Service Endpoint section o } ``` - - ## Reference -The contents of the `~service` decorator are defined by the [Service Endpoint section of the DID Spec](https://w3c-ccg.github.io/did-spec/#service-endpoints). +The contents of the `~service` decorator are defined by the [Service Endpoint section of the DID Spec](https://w3c-ccg.github.io/did-spec/#service-endpoints). The decorator should not be used when the message recipient already has a service endpoint. @@ -65,6 +63,6 @@ The Connect Protocol had previously included this same information as an attribu The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -Name / Link | Implementation Notes ---- | --- - | | +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0066-non-repudiable-cryptographic-envelope/README.md b/features/0066-non-repudiable-cryptographic-envelope/README.md index d1b545630..4d1cab72e 100644 --- a/features/0066-non-repudiable-cryptographic-envelope/README.md +++ b/features/0066-non-repudiable-cryptographic-envelope/README.md @@ -1,6 +1,6 @@ # Aries RFC 0066: Non-Repudiable Signature for Cryptographic Envelope -- Authors: [Kyle Den Hartog](indy@kyledenhartog.com) +- Authors: [Kyle Den Hartog](mailto:indy@kyledenhartog.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-04-15 - Status Note: This is a second attempt to integrate non-repudiable digital signatures based on learnings and discussions over the past few months. This focuses only on the signing of entire messages. Signature Decorators will be handled seperately. @@ -57,7 +57,7 @@ Starting with an initial `connections/1.0/invitation` message like this: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", + "@type": "https://didcomm.org/connections/1.0/invitation", "@id": "12345678900987654321", "label": "Alice", "recipientKeys": ["8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"], @@ -130,7 +130,7 @@ Next we'll take our content layer message which as an example is the JSON provid ```json { "@id": "123456780", - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/basicmessage/1.0/message", + "@type": "https://didcomm.org/basicmessage/1.0/message", "~l10n": { "locale": "en" }, "sent_time": "2019-01-15 18:42:01Z", "content": "Your hovercraft is full of eels." @@ -209,7 +209,7 @@ Now Base64URL decode that section and you'll get the original message: { "content": "Your hovercraft is full of eels.", "sent_time": "2019-01-15 18:42:01Z", - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/basicmessage/1.0/message", + "@type": "https://didcomm.org/basicmessage/1.0/message", "@id": "123456780", "~l10n": {"locale": "en"} } diff --git a/features/0066-non-repudiable-cryptographic-envelope/demo.py b/features/0066-non-repudiable-cryptographic-envelope/demo.py index 741b7a9ca..0747df832 100644 --- a/features/0066-non-repudiable-cryptographic-envelope/demo.py +++ b/features/0066-non-repudiable-cryptographic-envelope/demo.py @@ -51,7 +51,7 @@ async def run(): # build payload json structure payload = {} payload['@id'] = "123456780" - payload['@type'] = "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/basicmessage/1.0/message" + payload['@type'] = "https://didcomm.org/basicmessage/1.0/message" payload['~l10n'] = {"locale": "en"} payload['sent_time'] = "2019-01-15 18:42:01Z" payload['content'] = "Your hovercraft is full of eels." diff --git a/features/0067-didcomm-diddoc-conventions/README.md b/features/0067-didcomm-diddoc-conventions/README.md index a46451c76..42872fef3 100644 --- a/features/0067-didcomm-diddoc-conventions/README.md +++ b/features/0067-didcomm-diddoc-conventions/README.md @@ -1,6 +1,6 @@ # Aries RFC 0067: DIDComm DID document conventions -- Authors: [Tobias Looker](tobias.looker@mattr.global), [Stephen Curran](swcurran@gmail.com) +- Authors: [Tobias Looker](mailto:tobias.looker@mattr.global), [Stephen Curran](mailto:swcurran@gmail.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-06-10 - Status Note: This revises the former [INDY HIPE](https://github.com/hyperledger/indy-hipe/pull/92) @@ -37,6 +37,10 @@ When a DID document wishes to express support for DID communications, the follow "priority" : 0, "recipientKeys" : [ "did:example:123456789abcdefghi#1" ], "routingKeys" : [ "did:example:123456789abcdefghi#1" ], + "accept": [ + "didcomm/aip2;env=rfc587", + "didcomm/aip2;env=rfc19" + ], "serviceEndpoint": "https://agent.example.com/" }] } @@ -47,6 +51,9 @@ When a DID document wishes to express support for DID communications, the follow - priority : This represents the priority of the service endpoint, used for distinction when multiple `did-communication` service endpoints are present in a single DID document. It is mandatory that this field is set to an unsigned integer with the default value of `0`. - recipientKeys : This is an array of [did key references](https://w3c-ccg.github.io/did-spec/#public-keys) used to denote the default recipients of an endpoint. (*note-1*) - routingKeys: This is an array of [did key references](https://w3c-ccg.github.io/did-spec/#public-keys), ordered from most destward to most srcward, used to denote the individual routing hops in between the sender and recipients. See [TBC]() for more information on how routing is intended to operate. +- `accept` - [optional] an array of media types in the order of preference for sending a message to the endpoint. + If `accept` is not specified, the sender uses its preferred choice for sending a message to the endpoint. + [RFC 0044](../0044-didcomm-file-and-mime-types/README.md) provides a general discussion of media types. - serviceEndpoint : Required by the [Service Endpoints Spec](https://w3c-ccg.github.io/did-spec/#service-endpoints). This URL based endpoint is used to declare how the message should be sent. DID communication is transport agnostic, and therefore leverages existing application level transport protocols. However for each transport defined, which is identified by the URL scheme e.g `http`, a set of transport specific considerations are defined see [transports](../0025-didcomm-transports/README.md) for more details. >Notes @@ -156,7 +163,7 @@ Alices agent goes to prepare a message `desired_msg` for Bob. 1. Alices agent resolves the above DID document `did:example:1234abcd` for Bob and resolves the `did-communication` service definition. 2. Alices agent then packs `desired_msg` in an encrypted envelope message to the resolved keys defined in the `recipientKeys` array. -3. Because the the `routingKeys` array is not empty, a content level message of type `forward` is prepared where the `to` field of the forward message is set to the resolved keys and the `msg` field of the forward message is set to the encrypted envelope from the previous step. +3. Because the `routingKeys` array is not empty, a content level message of type `forward` is prepared where the `to` field of the forward message is set to the resolved keys and the `msg` field of the forward message is set to the encrypted envelope from the previous step. 4. The resulting forward message from the previous step is then packed inside another encrypted envelope for the first and only key in the `routingKeys` array. 5. Inspection of the service endpoint, reveals it is a did url and leads to resolving another `did-communication` service definition, this time owned and controlled by `agents-r-us`. 6. Because in the `agents-r-us` service definition there is a recipient key. A content level message of type `forward` is prepared where the `to` field of the forward message is set to the recipient key and the `msg` field of the forward message is set to the encrypted envelope from the previous step. diff --git a/features/0075-payment-decorators/README.md b/features/0075-payment-decorators/README.md index b3fe12c6f..6c2ff22ac 100644 --- a/features/0075-payment-decorators/README.md +++ b/features/0075-payment-decorators/README.md @@ -1,9 +1,9 @@ # Aries RFC 0075: Payment Decorators -- Authors: [Sam Curren](sam@sovrin.org), [Daniel Hardman](daniel.hardman@gmail.com), Tomislav Markovski -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-06-11 -- Status Note: Still being studied. +- Authors: [Sam Curren](mailto:sam@sovrin.org), [Daniel Hardman](mailto:daniel.hardman@gmail.com), Tomislav Markovski +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: [Indy HIPE PR #129]( https://github.com/hyperledger/indy-hipe/pull/129) - Start Date: 2019-04-22 - Tags: [feature](/tags.md#feature), [decorator](/tags.md#decorator) @@ -237,7 +237,7 @@ this (note the snake_case since we are not matching a W3C spec): and that the transfer relates to this payment request instead of another. This might be a ledger's transaction ID, for example. -**proof**: Optional. A base64-encoded blob that contains directly verifiable proof that the +**proof**: Optional. A base64url-encoded blob that contains directly verifiable proof that the transaction took place. This might be useful for payments enacted by a [triple-signed receipt]( http://opentransactions.org/wiki/index.php/Triple-Signed_Receipts) mechanism, for example. When this is present, `transaction_id` becomes optional. For ledgers @@ -257,7 +257,7 @@ credential under discussion. ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue_credential/1.0/offer_credential", + "@type": "https://didcomm.org/issue_credential/1.0/offer_credential", "@id": "5bc1989d-f5c1-4eb1-89dd-21fd47093d96", "cred_def_id": "KTwaKJkvyjKKf55uc6U8ZB:3:CL:59:tag1", "~payment_request": { @@ -294,7 +294,7 @@ This Credential Request is sent to the issuer, indicating that they have paid th ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue_credential/1.0/request_credential", + "@type": "https://didcomm.org/issue_credential/1.0/request_credential", "@id": "94af9be9-5248-4a65-ad14-3e7a6c3489b6", "~thread": { "thid": "5bc1989d-f5c1-4eb1-89dd-21fd47093d96" }, "cred_def_id": "KTwaKJkvyjKKf55uc6U8ZB:3:CL:59:tag1", diff --git a/features/0092-transport-return-route/README.md b/features/0092-transport-return-route/README.md index b121e2371..7018151ea 100644 --- a/features/0092-transport-return-route/README.md +++ b/features/0092-transport-return-route/README.md @@ -1,8 +1,8 @@ # Aries RFC 0092: Transports Return Route -- Authors: [Sam Curren](sam@sovrin.org) -- Status: [ACCEPTED](/README.md#accepted) -- Since: 2019-12-06 +- Authors: [Sam Curren](mailto:sam@sovrin.org) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 - Status Note: - Supersedes: [INDY HIPE PR 116](https://github.com/hyperledger/indy-hipe/pull/116) - Start Date: 2019-03-04 diff --git a/features/0095-basic-message/README.md b/features/0095-basic-message/README.md index 011fad1de..953a040e8 100644 --- a/features/0095-basic-message/README.md +++ b/features/0095-basic-message/README.md @@ -1,7 +1,7 @@ # Aries RFC 0095: Basic Message Protocol 1.0 - Authors: Sam Curren -- Status: [ACCEPTED](/README.md#accepted) +- Status: [ADOPTED](/README.md#adopted) - Since: 2019-08-06 - Status Note: - Supersedes: [Indy 0033](https://github.com/hyperledger/indy-hipe/edit/master/text/0033-basic-message/README.md) @@ -39,7 +39,7 @@ There are many useful features of user messaging systems that we will not be add ## Reference -**Protocol**: did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/basicmessage/1.0/ +**Protocol**: https://didcomm.org/basicmessage/1.0/ **message** @@ -52,7 +52,7 @@ Example: ```json { "@id": "123456780", - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/basicmessage/1.0/message", + "@type": "https://didcomm.org/basicmessage/1.0/message", "~l10n": { "locale": "en" }, "sent_time": "2019-01-15 18:42:01Z", "content": "Your hovercraft is full of eels." diff --git a/features/0113-question-answer/README.md b/features/0113-question-answer/README.md index 82d8a7819..249eb339d 100644 --- a/features/0113-question-answer/README.md +++ b/features/0113-question-answer/README.md @@ -1,6 +1,6 @@ # Aries RFC 0113: Question Answer Protocol 0.9 -- Authors: [Douglas Wightman](douglas.wightman@evernym.com) +- Authors: [Douglas Wightman](mailto:douglas.wightman@evernym.com) - Status: [DEMONSTRATED](/README.md#demonstrated) - Since: 2019-07-05 - Start Date: 2019-02-07 @@ -38,13 +38,13 @@ In this tutorial Alice (the responder) receives the packet and must respond to t All messages in this protocol are part of the "Question/Answer 1.0" message family uniquely identified by this DID reference: - did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/questionanswer/1.0 + https://didcomm.org/questionanswer/1.0 The protocol begins when the questioner sends a `questionanswer` message to the responder: ```JSON { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/questionanswer/1.0/question", + "@type": "https://didcomm.org/questionanswer/1.0/question", "@id": "518be002-de8e-456e-b3d5-8fe472477a86", "question_text": "Alice, are you on the phone with Bob from Faber Bank right now?", "question_detail": "This is optional fine-print giving context to the question and its various answers.", @@ -69,13 +69,13 @@ The response message is then sent using the ~sig message decorator: ```JSON { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/questionanswer/1.0/answer", + "@type": "https://didcomm.org/questionanswer/1.0/answer", "~thread": { "thid": "518be002-de8e-456e-b3d5-8fe472477a86", "seqnum": 0 }, "response": "Yes, it's me", "response~sig": { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/signature/1.0/ed25519Sha512_single" + "@type": "https://didcomm.org/signature/1.0/ed25519Sha512_single" "signature": "", - "sig_data": ""))>", + "sig_data": ""))>", "signers": [""], } "~timing": { diff --git a/features/0114-predefined-identities/README.md b/features/0114-predefined-identities/README.md index 3f4851889..6d3ac98c5 100644 --- a/features/0114-predefined-identities/README.md +++ b/features/0114-predefined-identities/README.md @@ -1,9 +1,9 @@ # Aries RFC 0114: Predefined Identities - Authors: Daniel Hardman -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-07-10 -- Status Note: (explanation of current status; if adopted, links to impls or derivative ideas; if superseded, link to replacement) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Start Date: 2019-07-10 - Tags: [feature](/tags.md#feature) diff --git a/features/0116-evidence-exchange/README.md b/features/0116-evidence-exchange/README.md index ce67cbcb0..3b29fd35d 100644 --- a/features/0116-evidence-exchange/README.md +++ b/features/0116-evidence-exchange/README.md @@ -1,9 +1,9 @@ # Aries RFC 0116: Evidence Exchange Protocol 0.9 - Authors: [Dan Gisolfi](mailto:dan.gisolfi@gmail.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-07-26 -- Status Note: Revised to address both physical and digital identity proofing methods and NIST assurance levels. +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Start Date: 2019-07-05 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) @@ -13,7 +13,7 @@ The goal of this protocol is to allow Holders to provider an inquiring Verifier ## Motivation -During the identity verification process, an entity *may* require access to the genesis documents used to establish digital credentials issued by a credential issuing entity or [Credential Service Provider (CSP)](./eep_glossary.md). In support of the transition from existing business verification processes to emerging business processes that rely on digitally verified credentials using protocols such as [0036-issue-credential](https://github.com/hyperledger/aries-rfcs/tree/master/features/0036-issue-credential) and [0037-present-proof](https://github.com/hyperledger/aries-rfcs/tree/master/features/0037-present-proof), we need to establish a protocol that allow entities to make this transition while remaining compliant with business and regulatory requirements. Therefore, **we need a mechanism for Verifiers to obtain access to vetted evidence (physical or digital information or documentation) without requiring a relationship or interaction with the Issuer**. +During the identity verification process, an entity *may* require access to the genesis documents used to establish digital credentials issued by a credential issuing entity or [Credential Service Provider (CSP)](./eep_glossary.md). In support of the transition from existing business verification processes to emerging business processes that rely on digitally verified credentials using protocols such as [0036-issue-credential](https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential) and [0037-present-proof](https://github.com/hyperledger/aries-rfcs/tree/main/features/0037-present-proof), we need to establish a protocol that allow entities to make this transition while remaining compliant with business and regulatory requirements. Therefore, **we need a mechanism for Verifiers to obtain access to vetted evidence (physical or digital information or documentation) without requiring a relationship or interaction with the Issuer**. >While this protocol *should* be supported by all persona, its relevance to decentralized identity ecosystems is highly dependent on the business policies of a market segment of Verifiers. For more details see the [Persona](#persona) section. @@ -180,7 +180,7 @@ These forms of *Identity Evidence* are examples of trusted credentials that an E ## Tutorial -The evidence exchange protocol builds on the attachment decorator within DIDComm using the the [Inlining Method](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0017-attachments/README.md#inlining) for *Digital Assertions* and the [Appending Method](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0017-attachments/README.md#appending) for *Original Documents*. +The evidence exchange protocol builds on the attachment decorator within DIDComm using the the [Inlining Method](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#inlining) for *Digital Assertions* and the [Appending Method](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#appending) for *Original Documents*. The protocol is comprised of the following messages and associated actions: @@ -195,11 +195,11 @@ The protocol is comprised of the following messages and associated actions: ### Request Evidence Message -This message should be used as an accompaniment to an [issue credential message](https://github.com/hyperledger/aries-rfcs/tree/master/features/0036-issue-credential#issue-credential). Upon receipt and storage of a credential the Holder should compose an ```evidence_request``` for each credential received from the Issuer. The Holder may use this message to get an update for new and existing credentials from the Issuer. +This message should be used as an accompaniment to an [issue credential message](https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential#issue-credential). Upon receipt and storage of a credential the Holder should compose an ```evidence_request``` for each credential received from the Issuer. The Holder may use this message to get an update for new and existing credentials from the Issuer. ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/evidence_exchange/1.0/evidence_request", + "@type": "https://didcomm.org/evidence_exchange/1.0/evidence_request", "@id": "6a4986dd-f50e-4ed5-a389-718e61517207", "for": "did:peer:1-F1220479cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe", "as_of_time": "2019-07-23 18:05:06.123Z", @@ -221,7 +221,7 @@ This message is required for an Issuer Agent in response to an ```evidence_reque ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/evidence_exchange/1.0/evidence_response", + "@type": "https://didcomm.org/evidence_exchange/1.0/evidence_response", "@id": "1517207d-f50e-4ed5-a389-6a4986d718e6", "~thread": { "thid": "6a4986dd-f50e-4ed5-a389-718e61517207" }, "for": "did:peer:1-F1220479cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe", @@ -271,7 +271,7 @@ Description of attributes: "technology": "api" }, "ipsp_did": "~3d5nh7900fn4", - "ipsp_claim": , + "ipsp_claim": , "ipsp_claim_sig": "3vvvb68b53d5nh7900fn499040cd9e89fg3kkh0f099c0021233728cf67945faf", "examinerSignature": "f67945faf9e89fg3kkh3vvvb68b53d5nh7900fn499040cd3728c0f099c002123" } @@ -306,7 +306,7 @@ Description of attributes: "technology": "barcode" }, "data": { - "base64": + "base64": }, "examinerSignature": "f67945faf9e89fg3kkh3vvvb68b53d5nh7900fn499040cd3728c0f099c002123" }, @@ -321,7 +321,7 @@ Description of attributes: "technology": "human-visual" }, "data": { - "base64": + "base64": }, "examinerSignature": "945faf9e8999040cd3728c0f099c002123f67fg3kkh3vvvb68b53d5nh7900fn4" }, @@ -337,7 +337,7 @@ Description of attributes: }, "data": { "sha256": "1d9eb668b53d99c002123f1ffa4db0cd3728c0f0945faf525c5ee4a2d4289904", - "base64": + "base64": }, "examinerSignature": "5nh7900fn499040cd3728c0f0945faf9e89kkh3vvvb68b53d99c002123f67fg3" } @@ -345,7 +345,7 @@ Description of attributes: } ``` -This message adheres to the attribute [content formats outlined in the Aries Attachments RFC ](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0017-attachments/README.md#base64) with the following additions: +This message adheres to the attribute [content formats outlined in the Aries Attachments RFC ](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#base64) with the following additions: * `mime-type`: Describes the MIME type of the attached content. Optional but recommended. * `filename`: A hint about the name that might be used if this attachment is persisted as a file. It is not required, and need not be unique. If this field is present and mime-type is not, the extension on the filename may be used to infer a MIME type. @@ -424,7 +424,7 @@ This message adheres to the attribute [content formats outlined in the Aries Att } ``` -This message adheres to the attribute [content formats outlined in the Aries Attachments RFC ](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0017-attachments/README.md#base64) and builds on the [By Value Attachments](#by-value-attachments) with the following additions: +This message adheres to the attribute [content formats outlined in the Aries Attachments RFC ](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#base64) and builds on the [By Value Attachments](#by-value-attachments) with the following additions: * `links`: A list of zero or more locations at which the content may be fetched. * `url`: Link to the external document. @@ -434,11 +434,11 @@ Upon completion of the Evidence Request and Response exchange, the Holder's Agen ### Evidence Access Request Message -Upon the successful processing of a [credential proof presentation message](https://github.com/hyperledger/aries-rfcs/tree/master/features/0037-present-proof#presentation), a Verifier may desire to request supporting evidence for the processed credential. This ```evidence_access_request``` message is built by the Verifier and sent to the Holder's agent. Similar to the ```request_evidence``` message, the Verifier may use this message to get an update for new and existing credentials associated with the Holder. The intent of this message is for the Verifier to establish trust by obtaining a copy of the available evidence and performing the necessary content validation. +Upon the successful processing of a [credential proof presentation message](https://github.com/hyperledger/aries-rfcs/tree/main/features/0037-present-proof#presentation), a Verifier may desire to request supporting evidence for the processed credential. This ```evidence_access_request``` message is built by the Verifier and sent to the Holder's agent. Similar to the ```request_evidence``` message, the Verifier may use this message to get an update for new and existing credentials associated with the Holder. The intent of this message is for the Verifier to establish trust by obtaining a copy of the available evidence and performing the necessary content validation. ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/evidence_exchange/1.0/evidence_access_request", + "@type": "https://didcomm.org/evidence_exchange/1.0/evidence_access_request", "@id": "7c3f991836-4ed5-f50e-7207-718e6151a389", "for": "did:peer:1-F1220479cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe", "as_of_time": "2019-07-23 18:05:06.123Z", @@ -457,7 +457,7 @@ Description of attributes: ![verify-workflow](./img/verify_cred_flow.png) -This protocol is intended to be flexible and applicable to a variety of use cases. While our discussion has circulated around the use of the protocol as follow-up to the processing of a credential proof presentment flow, the fact is that the protocol can be used at any point after a Pair-wise DID Exchange has been successfully established and is therefore in the [complete state](https://github.com/hyperledger/aries-rfcs/tree/master/features/0023-did-exchange#complete) as defined by the DID Exchange Protocol. An `IssuerDID` (or DID of the an entity that is one of the two parties in a private pair-wise relationship) is assumed to be known under all possible conditions once the relationship is in the complete state. +This protocol is intended to be flexible and applicable to a variety of use cases. While our discussion has circulated around the use of the protocol as follow-up to the processing of a credential proof presentment flow, the fact is that the protocol can be used at any point after a Pair-wise DID Exchange has been successfully established and is therefore in the [complete state](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange#complete) as defined by the DID Exchange Protocol. An `IssuerDID` (or DID of the an entity that is one of the two parties in a private pair-wise relationship) is assumed to be known under all possible conditions once the relationship is in the complete state. ### Evidence Access Response Message @@ -465,7 +465,7 @@ This message is required for a Holder Agent in response to an ```evidence_access ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/evidence_exchange/1.0/evidence_access_response", + "@type": "https://didcomm.org/evidence_exchange/1.0/evidence_access_response", "@id": "1517207d-f50e-4ed5-a389-6a4986d718e6", "~thread": { "thid": "7c3f991836-4ed5-f50e-7207-718e6151a389" }, "for": "did:peer:1-F1220479cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe", @@ -492,7 +492,7 @@ This message is required for a Holder Agent in response to an ```evidence_access } ``` -This message adheres to the attribute [content formats outlined in the Aries Attachments RFC ](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0017-attachments/README.md#base64) and leverages the same [Evidence Response Message](#evidence-response-message) attribute descriptions. +This message adheres to the attribute [content formats outlined in the Aries Attachments RFC ](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#base64) and leverages the same [Evidence Response Message](#evidence-response-message) attribute descriptions. ## Reference @@ -517,7 +517,7 @@ As noted in the [references](#reference) section, there are a number of trending ## Prior art -This protocol builds on the foundational capabilities of DIDComm messages, most notable being the [attachment decorator](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0017-attachments/README.md) within DIDComm. +This protocol builds on the foundational capabilities of DIDComm messages, most notable being the [attachment decorator](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md) within DIDComm. ## Unresolved questions diff --git a/features/0124-did-resolution-protocol/README.md b/features/0124-did-resolution-protocol/README.md index c36e176e9..77bf03ec7 100644 --- a/features/0124-did-resolution-protocol/README.md +++ b/features/0124-did-resolution-protocol/README.md @@ -1,6 +1,6 @@ # Aries RFC 0124: DID Resolution Protocol 0.9 -- Authors: [Markus Sabadello](markus@danubetech.com) +- Authors: [Markus Sabadello](mailto:markus@danubetech.com), [Luis Gómez Alonso](mailto:luis.gomezalonso@sicpa.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-07-13 - Status Note: Not implemented, but has been discussed as part of the [Aries DID Resolution](https://github.com/hyperledger/aries-rfcs/issues/101) work. @@ -15,10 +15,10 @@ to resolve DIDs and dereference DID URLs. ## Motivation DID Resolution is an important feature of Aries. It is a prerequisite for the `unpack()` function in -[DIDComm](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0005-didcomm), especially in +[DIDComm](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0005-didcomm), especially in [Cross-Domain Messaging](../../concepts/0094-cross-domain-messaging/README.md), since cryptographic keys must be discovered from DIDs in order to enable trusted communication between the -[agents](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0004-agents) associated with DIDs. +[agents](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0004-agents) associated with DIDs. DID Resolution is also required for other operations, e.g. for verifying credentials or for discovering [DIDComm service endpoints](../../features/0067-didcomm-diddoc-conventions/README.md). @@ -42,9 +42,9 @@ invokes another DID Resolver via a "remote" binding (such as HTTP(S) or DIDComm) ### Name and Version This defines the `did_resolution` protocol, version 0.1, as identified by the -following [PIURI](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0003-protocols/uris.md#piuri): +following [PIURI](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/uris.md#piuri): - did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/did_resolution/0.1 + https://didcomm.org/did_resolution/0.1 ### Key Concepts @@ -84,10 +84,30 @@ resolving DIDs for at least one DID method. | resolving | | *new interaction* | transition to "done" | | done | | | | + +##### States for `requester` role in a failure scenario + +| | EVENTS: | send `resolve` | receive `resolve_result` | +| -------------------- | --------------- | ------------------------------------ | -------------------------- | +| **STATES** | | | | +| preparing-request | | transition to "awaiting-response" | *different interaction* | +| awaiting-response | | *impossible* | error reporting | +| problem reported | | | | + + +##### States for `resolver` role in a failure scenario + +| | EVENTS: | receive `resolve` | send `resolve_result` | +| -------------------- | --------------- | ------------------------------------ | -------------------------- | +| **STATES** | | | | +| awaiting-request | | transition to "resolving" | *impossible* | +| resolving | | *new interaction* | error reporting | +| problem reported | | | | + ### Messages All messages in this protocol are part of the "did_resolution 0.1" message -family uniquely identified by this DID reference: `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/did_resolution/0.1` +family uniquely identified by this DID reference: `https://didcomm.org/did_resolution/0.1` ##### `resolve` message @@ -95,7 +115,7 @@ The protocol begins when the `requester` sends a `resolve` message to the `resolver`. It looks like this: { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/did_resolution/0.1/resolve", + "@type": "https://didcomm.org/did_resolution/0.1/resolve", "@id": "xhqMoTXfqhvAgtYxUSfaxbSiqWke9t", "did": "did:sov:WRfXPg8dantKVubE3HX8pw", "input_options": { @@ -122,7 +142,7 @@ It represents the result of the [DID Resolution](https://w3c-ccg.github.io/did-r It looks like this: { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/did_resolution/0.1/resolve_result", + "@type": "https://didcomm.org/did_resolution/0.1/resolve_result", "~thread": { "thid": "xhqMoTXfqhvAgtYxUSfaxbSiqWke9t" }, "did_document": { "@context": "https://w3id.org/did/v0.11", @@ -145,7 +165,7 @@ If the `input_options` field of the `resolve` message contains an entry `result_ which includes a DID Document plus additional metadata: { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/did_resolution/0.1/resolve_result", + "@type": "https://didcomm.org/did_resolution/0.1/resolve_result", "~thread": { "thid": "xhqMoTXfqhvAgtYxUSfaxbSiqWke9t" }, "did_document": { "@context": "https://w3id.org/did/v0.11", @@ -172,6 +192,19 @@ which includes a DID Document plus additional metadata: "attrResponse": { ... } } } +##### `problem-report` failure message + +The `resolve_result` will also report failure messages in case of impossibility to resolve a DID. +It represents the problem report indicating that the resolver could not resolve the DID, and the reason of the failure. +It looks like this: + + { + "@type": "https://didcomm.org/did_resolution/0.1/resolve_result", + "~thread": { "thid": "xhqMoTXfqhvAgtYxUSfaxbSiqWke9t" }, + "explain_ltxt": "Could not resolve DID did:sov:WRfXPg8dantKVubE3HX8pw not found by resolver xxx", + ... + } + ## Reference diff --git a/features/0160-connection-protocol/README.md b/features/0160-connection-protocol/README.md index 743748f8a..1fdf072ac 100644 --- a/features/0160-connection-protocol/README.md +++ b/features/0160-connection-protocol/README.md @@ -1,9 +1,9 @@ # 0160: Connection Protocol -- Authors: [Ryan West](ryan.west@sovrin.org), [Daniel Bluhm](daniel.bluhm@sovrin.org), Matthew Hailstone, Stephen Curran, [Sam Curren](sam@sovrin.org) -- Status: [ACCEPTED](/README.md#accepted) +- Authors: [Ryan West](mailto:ryan.west@sovrin.org), [Daniel Bluhm](mailto:daniel.bluhm@sovrin.org), Matthew Hailstone, Stephen Curran, [Sam Curren](mailto:sam@sovrin.org) +- Status: [ADOPTED](/README.md#adopted) (But should move to deprecated) - Since: 2019-08-06 - Status Note: This is the protocol with existing uses. It is expected that [RFC 0023 DID Exchange](../../features/0023-did-exchange/README.md) will replace this protocol. -- Supersedes: [HIPE 0031 - Connection Protocol](https://github.com/hyperledger/indy-hipe/tree/master/text/0031-connection-protocol) +- Supersedes: [HIPE 0031 - Connection Protocol](https://github.com/hyperledger/indy-hipe/tree/main/text/0031-connection-protocol) - Start Date: 2018-06-29 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) @@ -79,7 +79,7 @@ No errors are sent in timeout situations. If the inviter or invitee wishes to re ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/problem_report", + "@type": "https://didcomm.org/connections/1.0/problem_report", "@id": "5678876542345", "~thread": { "thid": "<@id of message related to problem>" }, "~i10n": { "locale": "en"}, @@ -107,6 +107,8 @@ The *invitee* sends the *inviter* an ack or any other message that confirms the [0-invitation]: #0-invitation +> Note: This Invitation message is deprecated, and should use an invitation message from the [Out Of Band Protocol](../0434-outofband/README.md) + An invitation to connect may be transferred using any method that can reliably transmit text. The result must be the essential data necessary to initiate a [Connection Request](#1-connection-request) message. A connection invitation is an agent message with agent plaintext format, but is an **out-of-band communication** and therefore not communicated using wire level encoding or encryption. The necessary data that an invitation to connect must result in is: - suggested label @@ -135,7 +137,7 @@ Invitation Message with Public Invitation DID: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", + "@type": "https://didcomm.org/connections/1.0/invitation", "@id": "12345678900987654321", "label": "Alice", "did": "did:sov:QmWbsNYhMrjHiqZDTUTEJs" @@ -146,7 +148,7 @@ Invitation Message with Keys and URL endpoint: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", + "@type": "https://didcomm.org/connections/1.0/invitation", "@id": "12345678900987654321", "label": "Alice", "recipientKeys": ["8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"], @@ -159,7 +161,7 @@ Invitation Message with Keys and DID Service Endpoint Reference: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", + "@type": "https://didcomm.org/connections/1.0/invitation", "label": "Alice", "recipientKeys": ["8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"], "serviceEndpoint": "did:sov:A2wBhNYhMrjHiqZDTUYH7u;routeid", @@ -209,7 +211,7 @@ Invitation: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", + "@type": "https://didcomm.org/connections/1.0/invitation", "@id": "12345678900987654321", "label": "Alice", "recipientKeys": ["8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"], @@ -267,7 +269,7 @@ The _invitee_ will provision a new DID according to the DID method spec. For a P ```jsonc { "@id": "5678876542345", - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/request", + "@type": "https://didcomm.org/connections/1.0/request", "label": "Bob", "connection": { "DID": "B.did@B:A", @@ -371,7 +373,7 @@ The connection response message is used to complete the connection. This message ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/response", + "@type": "https://didcomm.org/connections/1.0/response", "@id": "12345678900987654321", "~thread": { "thid": "<@id of request message>" @@ -390,16 +392,16 @@ The above message is required to be signed as described in [RFC 0234 Signature D ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/response", + "@type": "https://didcomm.org/connections/1.0/response", "@id": "12345678900987654321", "~thread": { "thid": "<@id of request message>" }, "connection~sig": { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/signature/1.0/ed25519Sha512_single", + "@type": "https://didcomm.org/signature/1.0/ed25519Sha512_single", "signature": "", "sig_data": "", - "signers": "" + "signer": "" } } ``` @@ -502,4 +504,4 @@ Name / Link | Implementation Notes [Aries Cloud Agent - Python](https://github.com/hyperledger/aries-cloudagent-python) | ported from VON codebase that passed agent connectathon tests, Feb 2019; [MISSING test results](/tags.md#test-anomaly) [Aries Static Agent - Python](https://github.com/hyperledger/aries-staticagent-python) | implemented July 2019; [MISSING test results](/tags.md#test-anomaly) [Aries Protocol Test Suite](https://github.com/hyperledger/aries-protocol-test-suite) | ported from Indy Agent codebase that provided agent connectathon tests, Feb 2019; [MISSING test results](/tags.md#test-anomaly) -[Indy Cloud Agent - Python](https://github.com/hyperledger/indy-agent/python) | passed agent connectathon tests, Feb 2019; [MISSING test results](/tags.md#test-anomaly) \ No newline at end of file +[Indy Cloud Agent - Python](https://github.com/hyperledger/indy-agent/python) | passed agent connectathon tests, Feb 2019; [MISSING test results](/tags.md#test-anomaly) diff --git a/features/0183-revocation-notification/README.md b/features/0183-revocation-notification/README.md index 5a905f713..dab004c3b 100644 --- a/features/0183-revocation-notification/README.md +++ b/features/0183-revocation-notification/README.md @@ -1,7 +1,7 @@ # Aries RFC 0183: Revocation Notification 1.0 -- Authors: [Keith Smith] -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-08-12 +- Authors: Keith Smith +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2024-05-01 - Status Note: Initial proposal after discussion on rocketchat - Supersedes: - Start Date: 2018-08-12 @@ -11,6 +11,10 @@ This RFC defines the message format which an issuer uses to notify a holder that a previously issued credential has been revoked. +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. + ## Motivation We need a standard protocol for an issuer to notify a holder that a previously issued credential has been revoked. @@ -27,7 +31,7 @@ The Revocation Notification protocol is a very simple protocol consisting of a s This simple protocol allows an issuer to choose to notify a holder that a previously issued credential has been revoked. -It is the issuer's prerogative whether or not to notify the holder that a credential has been revoked. +It is the issuer's prerogative whether or not to notify the holder that a credential has been revoked. It is not a security risk if the issuer does not notify the holder that the credential has been revoked, nor if the message is lost. The holder will still be unable to use a revoked credential without this notification. ### Roles @@ -40,21 +44,24 @@ The `revoke` message sent by the `issuer` to the `holder` is as follows: ```JSON { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/revocation_notification/1.0/revoke", + "@type": "https://didcomm.org/revocation_notification/1.0/revoke", "@id": "", - "credential_id": "", + "thread_id": "", "comment": "Some comment" } ``` Description of fields: -* `credential_id` -- identifies the credential which is being revoked. This is the value as sent in the [issue-credential](https://github.com/hyperledger/aries-rfcs/tree/master/features/0036-issue-credential#issue-credential) message. -* `comment` -- a field that provides some human readable information about the revocation notification. This is typically the reason for the revocation as deemed appropriate by the issuer. +* `thread_id` (required) -- the [thread ID](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0008-message-id-and-threading#thread-id-thid) of the [issue-credential-v2](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2) protocol which was used to issue one or more credentials that have been revoked by the issuer. If multiple credentials were issued, each credential has a different credential format but contains the same claims as described [here](https://github.com/hyperledger/aries-rfcs/tree/b982c24b9083dd5dddff6343dbf534cd1cfe36a6/features/0453-issue-credential-v2#message-attachments); therefore, this message notifies the holder that all of these credentials have been revoked. + +* `comment` (optional) -- a field that provides some human readable information about the revocation notification. This is typically the reason for the revocation as deemed appropriate by the issuer. ## Reference -* See the [issue-credential](https://github.com/hyperledger/aries-rfcs/tree/master/features/0036-issue-credential#issue-credential) protocol. +* See the [issue-credential-v2](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2) protocol. +* See the [thread ID](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0008-message-id-and-threading#thread-id-thid) description. +* See the [Please ACK Decorator RFC](https://github.com/hyperledger/aries-rfcs/tree/main/features/0317-please-ack). ## Drawbacks diff --git a/features/0193-coin-flip/README.md b/features/0193-coin-flip/README.md index 1a0960fc5..ebe7ea29f 100644 --- a/features/0193-coin-flip/README.md +++ b/features/0193-coin-flip/README.md @@ -1,9 +1,9 @@ # Aries RFC 0193: Coin Flip Protocol 1.0 -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-08-19 -- Status Note: recently proposed +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com), [Patrick Stürmlinger](mailto:patrick@mindf.org) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Start Date: 2019-08-19 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) @@ -11,16 +11,20 @@ Specifies a safe way for two parties who are remote from one another and who do not trust one another to pick a random, binary outcome that neither can manipulate. +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. + ## Motivation -To guarantee fairness, it is often important to pick one party in a protocol to make a choice about what to do next. We need a way to do this that more or less mirrors the randomness of flipping a coin. +To guarantee fairness, it is often important to pick one party in a protocol to make a choice about what to do next. We need a way to do this that it more or less mirrors the randomness of flipping a coin. ## Tutorial ### Name and Version This defines the `coinflip` protocol, version 1.x, as identified by the -following [PIURI](https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0003-protocols/uris.md#piuri): +following [PIURI](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0003-protocols/uris.md#piuri): https://github.com/hyperledger/aries-rfcs/features/0193-coin-flip/1.0 @@ -30,19 +34,15 @@ There are 2 roles in the protocol: __Recorder__ and __Caller__. These role names ### Algorithm -Before describing the messages, let's review the algorithm that will be used. This algorithm is not new; it is a simple commitment scheme [described on wikipedia](https://en.wikipedia.org/wiki/Coin_flipping#Telecommunications) and implemented in various places. The RFC merely formalizes the algorithm for DIDComm. - -1. Caller chooses a random [UUID](https://tools.ietf.org/html/rfc4122) and sends it to Recorder using the [`propose` message described below](#propose). A [version 4 UUID](https://tools.ietf.org/html/rfc4122#section-4.4) is recommended, though any UUID version should be accepted. Note that the UUID is represented in lower case, with hyphens, and without enclosing curly braces. Suppose this value is `01bf7abd-aa80-4389-bf8c-dba0f250bb1b`. +Before describing the messages, let's review the algorithm that will be used. This algorithm is not new; it is a simple commitment scheme [described on wikipedia](https://en.wikipedia.org/wiki/Commitment_scheme) and implemented in various places. The RFC merely formalizes a simple commitment scheme for DIDComm in a way that the Caller chooses a side without knowing whether it's `win` or `lose`. -2. Recorder chooses a cooresponding random UUID -- say, `d96dfb58-60ba-4fcd-9ca0-a2be41181d6f`. +1. Recorder chooses a random [UUID](https://tools.ietf.org/html/rfc4122). A [version 4 UUID](https://tools.ietf.org/html/rfc4122#section-4.4) is recommended, though any UUID version should be accepted. Note that the UUID is represented in lower case, with hyphens, and without enclosing curly braces. Suppose this value is `01bf7abd-aa80-4389-bf8c-dba0f250bb1b`. This UUID is called __salt__. -3. Recorder captures an outcome for an imaginary coin flip -- either the string `heads` or the string `tails`. Suppose Recorder captures `tails`. +2. Recorder builds two __side strings__ by salting `win` and `lose` with the _salt_ -- i.e., `win01bf7abd-aa80-4389-bf8c-dba0f250bb1b` and `lose01bf7abd-aa80-4389-bf8c-dba0f250bb1b`. Recorder then computes a SHA256 hash of each side string, which are `0C192E004440D8D6D6AF06A7A03A2B182903E9F048D4E7320DF6301DF0C135A5` and `C587E50CB48B1B0A3B5136BA9D238B739A6CD599EE2D16994537B75CA595C091` for our example, and randomly selects one _side string_ as side1 and the other one as side2. Recorder sends them to Caller using the [`propose` message described below](#propose). Those hashes do commit Recorder to all inputs, without revealing which one is `win` or `lose`, and it's the Recorder's way of posing the Caller the question, "underside or topside"? -4. Recorder builds a __flip string__. This is single-space-separated concatenation of 3 inputs: `recorder-captured-state recorder-uuid caller-uuid`. Given the random numbers and tails state in our example, this string would be `tails d96dfb58-60ba-4fcd-9ca0-a2be41181d6f 01bf7abd-aa80-4389-bf8c-dba0f250bb1b`. Recorder then computes a SHA256 hash of the flip string, which is `B78DC2D94F6E92B69491F13DC8C866C0A31F896069D3DD69472D0D7740967011` for our example, and sends it to Caller using the [`flip` message described below](#flip). This hash commits Recorder to all inputs, without revealing Recorder's UUID, and it is the Recorder's way of posing to the Caller the question, "heads or tails?" +3. Caller announces their committed choice -- for instance, `side2`, using the ['call' message described below](#call). This commits Caller to a particular side of the virtual coin. -5. Caller announces their committed choice -- for instance, "heads", using the ['call' message described below](#call). This commits Caller to a particular prediction about the state of the virtual coin. - -6. Recorder uses a ['reveal' message](#reveal) to reveal _flip string_. Both parties discover who won the coin flip. If Caller predicted the state correctly, the state at the beginning of _flip string_ will match the Caller's choice in step 6, and Caller wins. Otherwise, Recorder wins. Neither party is able to manipulate the outcome. This is guaranteed by both parties checking to see that their UUIDs appear in the correct position in _flip string_, and that _flip string_ does indeed hash to the value computed in step 4. +4. Recorder uses a ['reveal' message](#reveal) to reveal the _salt_. Caller is now able to rebuild both _side strings_ and both parties discover whether Caller guessed the `win` side or not. If Caller guessed the `win` side, Caller won. Otherwise Recorder won. Neither party is able to manipulate the outcome. This is guaranteed by Caller being able to verify that Recorder proposed two valid options, i.e. one side winning and one side losing, and Recorder knowing not to reveal any disclosed information before Caller made their choice. ### States @@ -76,8 +76,9 @@ The protocol begins when Caller sends to Recorder a `propose` message that embod { "@type": "https://github.com/hyperledger/aries-rfcs/features/0193-coin-flip/1.0/propose", "@id": "518be002-de8e-456e-b3d5-8fe472477a86", - "caller-uuid": "d96dfb58-60ba-4fcd-9ca0-a2be41181d6f", - "comment": "Let's flip to see who goes first.", + "side1": "C587E50CB48B1B0A3B5136BA9D238B739A6CD599EE2D16994537B75CA595C091", + "side2": "0C192E004440D8D6D6AF06A7A03A2B182903E9F048D4E7320DF6301DF0C135A5", + "comment": "Make your choice and let's who goes first.", "choice-id": "did:sov:SLfEi9esrjzybysFxQZbfq;spec/tictactoe/1.0/who-goes-first", "caller-wins": "did:example:abc123", // Meaning of value defined in superprotocol "recorder-wins": "did:example:xyz456", // Meaning of value defined in superprotocol @@ -88,7 +89,7 @@ The protocol begins when Caller sends to Recorder a `propose` message that embod } ``` -The `@type` and `@id` fields are standard for DIDComm. The `caller-uuid` field conveys the data required by Step 1 of the algorithm. The optional `comment` field follows [localization conventions](../0043-l10n/README.md) and is irrelevant unless the coin flip intends to invite human participation. The `~thread.pthid` [decorator](../../concepts/0011-decorators/README.md) is optional but should be common; it [identifies the thread of the parent interaction](../../concepts/0008-message-id-and-threading/README.md#threaded-messages) (the [superprotocol](../../concepts/0003-protocols/README.md#composable)). +The `@type` and `@id` fields are standard for DIDComm. The `side1` and `side2` fields convey the data required by Step 2 of the algorithm. The optional `comment` field follows [localization conventions](../0043-l10n/README.md) and is irrelevant unless the coin flip intends to invite human participation. The `~thread.pthid` [decorator](../../concepts/0011-decorators/README.md) is optional but should be common; it [identifies the thread of the parent interaction](../../concepts/0008-message-id-and-threading/README.md#threaded-messages) (the [superprotocol](../../concepts/0003-protocols/README.md#composable)). The `choice-id` field formally names a choice that a superprotocol has defined, and tells how the string values of the `caller-wins` and `recorder-wins` fields will be interpreted. In the example above, the choice is defined in the [Tic-Tac-Toe Protocol](../../concepts/0003-protocols/tictactoe/README.md#key-concepts), which also specifies that `caller-wins` and `recorder-wins` will contain DIDs of the parties playing the game. Some other combinations that might make sense include: @@ -98,39 +99,18 @@ The `choice-id` field formally names a choice that a superprotocol has defined, * In a protocol that models radioactive halflife, the decay of a particular neutron might use `choice-id` of `prefix/halflife/1.0/should-decay`, and the `*-wins` fields might be the strings "yes" and "no". -The [`~timing.expires_time` decorator](../0032-message-timing/README.md#tutorial) may be used to impose a time limit on the processing of this message. If used, the protocol must restart if the subsequent `flip` message is not received by this time limit. - -#### `flip` - -This message is sent from Recorder to Caller. It embodies Step 2-5 of [the algorithm](#algorithm). It looks like this: - -```jsonc -{ - "@type": "https://github.com/hyperledger/aries-rfcs/features/0193-coin-flip/1.0/flip", - "@id": "7a86e002-8dee-b3d5-456e-8fe47247518b", - "commitment": "B78DC2D94F6E92B69491F13DC8C866C0A31F896069D3DD69472D0D7740967011", - "comment": "Here you go. Do you pick heads or tails?", - "~thread": { - "thid": "518be002-de8e-456e-b3d5-8fe472477a86", - "sender_order": 0 - } -} -``` - -Note the use of `~thread.thid` to connect this `flip` to the preceding `propose`. As before, `comment` is optional and only relevant for cases that involve human interaction. - The [`~timing.expires_time` decorator](../0032-message-timing/README.md#tutorial) may be used to impose a time limit on the processing of this message. If used, the protocol must restart if the subsequent `call` message is not received by this time limit. #### `call` -This message is sent from Caller to Recorder, and embodies Step 6 of [the algorithm](#algorithm). It looks like this: +This message is sent from Caller to Recorder, and embodies Step 3 of [the algorithm](#algorithm). It looks like this: ```jsonc { "@type": "https://github.com/hyperledger/aries-rfcs/features/0193-coin-flip/1.0/call", "@id": "1173fe5f-86c9-47d7-911b-b8eac7d5f2ad", - "called": "tails", - "comment": "I pick tails.", + "choice": "side2", + "comment": "I pick side 2.", "~thread": { "thid": "518be002-de8e-456e-b3d5-8fe472477a86", "sender_order": 1 @@ -138,22 +118,21 @@ This message is sent from Caller to Recorder, and embodies Step 6 of [the algori } ``` -Note the use of `~thread.thid` and `sender_order: 1` to connect this `call` to the preceding `flip`. +Note the use of `~thread.thid` and `sender_order: 1` to connect this `call` to the preceding `propose`. The [`~timing.expires_time` decorator](../0032-message-timing/README.md#tutorial) may be used to impose a time limit on the processing of this message. If used, the protocol must restart if the subsequent `reveal` message is not received by this time limit. #### `reveal` -This message is sent from Recorder to Caller, and embodies Step 7 of [the algorithm](#algorithm). It looks like this: +This message is sent from Recorder to Caller, and embodies Step 4 of [the algorithm](#algorithm). It looks like this: ```jsonc { "@type": "https://github.com/hyperledger/aries-rfcs/features/0193-coin-flip/1.0/reveal", "@id": "e2a9454d-783d-4663-874e-29ad10776115", - "flip_string": "tails d96dfb58-60ba-4fcd-9ca0-a2be41181d6f 01bf7abd-aa80-4389-bf8c-dba0f250bb1b", + "salt": "01bf7abd-aa80-4389-bf8c-dba0f250bb1b", "winner": "caller", "comment": "You win.", - "~please_ack": {}, "~thread": { "thid": "518be002-de8e-456e-b3d5-8fe472477a86", "sender_order": 1 @@ -165,13 +144,9 @@ Note the use of `~thread.thid` and `sender_order: 1` to connect this `reveal` to The Caller should validate this message as follows: -* Confirm that `flip_string` is a correctly formatted string consisting of 3 fields with no leading or trailing spaces, having exactly 1 space delimiter between each field, where the first field is the case-sensitive value "heads" or "tails", and the other two fields are correctly formatted UUIDs. This check is important because it eliminates the possibility that the Recorder could introduce variation to the commitment. -* Confirm that the third field in `flip_string` equals `caller-uuid` from the `propose` message. -* Confirm that `flip_string_hash` from the preceding `flip` equals the SHA256 hash of `flip_string`. - -Having validated the message thus far, Caller determines the winner by checking to see if the value of the first field in `flip_string` equals the value of `called` from the preceding `call` message. If yes, then the value of the `winner` field must be `caller`; if no, then it must be `recorder`. The `winner` field must be present in the message, and its value must be correct, for the `reveal` message to be deemed fully valid. This confirms that both parties understand the outcome, and it prevents a Recorder from asserting a false outcome that is accepted by careless validation logic on the Caller side. +* Confirm that SHA256 hashes of `win` and `lose` salted with _salt_ results in the two _side strings_ from the `propose` message. This check is important because it eliminates the possibility that the Recorder could introduce variation to the commitment. -The [`~please_ack` decorator](../0317-please-ack/README.md) is optional. If a superprotocol specifies the next step after a Coin Flip with sufficient precision, it may be unnecessary. However, it should be supported by implementations. The resulting `ack` message, if sent, is hereby [adopted into the Coin Flip protocol](../0015-acks/README.md#adopting-acks). +Having validated the message thus far, Caller determines the winner by checking if the self computed hash of `win` equals the given hash at the `propose` message at the position chosen with the `call` message or not. If yes, then the value of the `winner` field must be `caller`; if not, then it must be `recorder`. The `winner` field must be present in the message, and its value must be correct, for the `reveal` message to be deemed fully valid. This confirms that both parties understand the outcome, and it prevents a Recorder from asserting a false outcome that is accepted by careless validation logic on the Caller side. The [`~timing.expires_time` decorator](../0032-message-timing/README.md#tutorial) may be used to impose a time limit on the processing of this message. If used, the protocol must restart if the subsequent `ack` or the next message in the superprotocol is not received before the time limit. @@ -181,7 +156,7 @@ The protocol is a bit chatty. ## Rationale and alternatives -It may be desirable to pick among more than 2 alternatives. A separate protocol needs to be designed for that. +It may be desirable to pick among more than 2 alternatives. This RFC could be extended easily to provide more options than win and lose. The algorithm itself would not change. ## Prior art @@ -195,7 +170,7 @@ As mentioned in the introduction, the algorithm used in this protocol is a simpl The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -Name / Link | Implementation Notes ---- | --- - | | +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0193-coin-flip/coin-flip.html b/features/0193-coin-flip/coin-flip.html index c1560dcd9..e90296ad2 100644 --- a/features/0193-coin-flip/coin-flip.html +++ b/features/0193-coin-flip/coin-flip.html @@ -6,7 +6,7 @@ -
- +
+ diff --git a/features/0193-coin-flip/coin-flip.png b/features/0193-coin-flip/coin-flip.png index dd8e57f72..be98a7213 100644 Binary files a/features/0193-coin-flip/coin-flip.png and b/features/0193-coin-flip/coin-flip.png differ diff --git a/features/0211-route-coordination/README.md b/features/0211-route-coordination/README.md index ed4ad72ec..d4dc29dca 100644 --- a/features/0211-route-coordination/README.md +++ b/features/0211-route-coordination/README.md @@ -1,10 +1,10 @@ # 0211: Mediator Coordination Protocol -- Authors: [Sam Curren](telegramsam@gmail.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-09-03 -- Status Note: Initial version, still under discussion. Previously named `Route Coordination Protocol`. +- Authors: [Sam Curren](mailto:telegramsam@gmail.com), [Daniel Bluhm](mailto:daniel@indicio.tech), [Adam Burdett](mailto:burdettadam@gmail.com) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 +- Status Note: Discussed and implemented and part of AIP 2.0. - Start Date: 2019-09-03 -- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) ## Summary @@ -12,7 +12,7 @@ A protocol to coordinate mediation configuration between a mediating agent and t ## Application Scope -This protocol is needed when using an edge agent and a mediator agent from different vendors. Edge agents and mediator agents from the same vendor may use whatever protocol they wish without sacrificing interoperability. +This protocol is needed when using an edge agent and a mediator agent from different vendors. Edge agents and mediator agents from the same vendor may use whatever protocol they wish without sacrificing interoperability. ## Motivation @@ -20,11 +20,11 @@ Use of the forward message in the Routing Protocol requires an exchange of infor ## Protocol -**Name**: coordinatemediation +**Name**: coordinate-mediation **Version**: 1.0 -**Base URI**: `https://didcomm.org/coordinatemediation/1.0/` +**Base URI**: `https://didcomm.org/coordinate-mediation/1.0/` ### Roles @@ -32,151 +32,172 @@ Use of the forward message in the Routing Protocol requires an exchange of infor **recipient** - The agent for whom the `forward` message payload is intended. ### Flow -A recipient may discover an agent capable of routing using the Feature Discovery Protocol. If protocol is supported with the _mediator_ role, a _recipient_ may send a `route_request` to initiate a routing relationship. +A recipient may discover an agent capable of routing using the Feature Discovery Protocol. If protocol is supported with the _mediator_ role, a _recipient_ may send a `mediate-request` to initiate a routing relationship. -First, the _recipient_ sends a `route_request` message to the _mediator_. If the _mediator_ is willing to route messages, it will respond with a `route_grant` message. The _recipient_ will share the routing information in the grant message with other contacts. +First, the _recipient_ sends a `mediate-request` message to the _mediator_. If the _mediator_ is willing to route messages, it will respond with a `mediate-grant` message. The _recipient_ will share the routing information in the grant message with other contacts. -When a new key is used by the _recipient_, it must be registered with the _mediator_ to enable route identification. This is done with a `keylist_update` message. +When a new key is used by the _recipient_, it must be registered with the _mediator_ to enable route identification. This is done with a `keylist-update` message. -The `keylist_update` and `keylist_query` methods are used over time to identify and remove keys that are no longer in use by the _recipient_. +The `keylist-update` and `keylist-query` methods are used over time to identify and remove keys that are no longer in use by the _recipient_. -### Terms - -The protocol allows for term agreement between the _mediator_ and _recipient_. - -**mediator_terms** indicate terms that the _mediator_ requires the _recipient_ to agree to. - -**recipient_terms** indicate terms that the _recipient_ requires the _mediator_ to agree to. +## Reference -If the _mediator_ requires the _recipient_ to agree to terms prior to service, a `mediate_deny` message will be returned listing the URIs of terms that the user must agree to. Term agreement is indicated by including the same URIs in the `mediator_terms` attribute of the `route_request` message. The *mediator* may indicate which user terms they support in the `recipient_terms` attribute of the `mediate_deny` message. +> **Note on terms:** Early versions of this protocol included the concept of +> terms for mediation. This concept has been removed from this version due to a +> need for further discussion on representing terms in DIDComm in general and +> lack of use of these terms in current implementations. -## Reference ### Mediation Request This message serves as a request from the _recipient_ to the _mediator_, asking for the permission (and routing information) to publish the endpoint as a mediator. + ```jsonc { "@id": "123456781", "@type": "/mediate-request", - "mediator_terms": [], - "recipient_terms": [] } ``` ### Mediation Deny -A mediator may require agreements prior to granting route coordination. If the agreements present in the request are not sufficient, a route deny message may be used to indicate which agreements are required. +This message serves as notification of the mediator denying the recipient's +request for mediation. ```jsonc { "@id": "123456781", "@type": "/mediate-deny", - "mediator_terms": [], - "recipient_terms": [] } ``` ### Mediation Grant A route grant message is a signal from the mediator to the recipient that permission is given to distribute the included information as an inbound route. + ```jsonc { "@id": "123456781", "@type": "/mediate-grant", - "endpoint": "", - "routing_keys": [] - + "endpoint": "http://mediators-r-us.com", + "routing_keys": ["did:key:z6Mkfriq1MqLBoPWecGoDLjguo1sB9brj6wT3qZ5BxkKpuP6"] } ``` -Questions: -- What about multiple endpoint options? http and ws? + +`endpoint`: The endpoint reported to mediation client connections. + +`routing_keys`: List of keys in intended routing order. Key used as recipient of forward messages. + ### Keylist Update + Used to notify the _mediator_ of keys in use by the _recipient_. + ```jsonc { "@id": "123456781", - "@type": "/keylist_update", + "@type": "/keylist-update", "updates":[ { - "recipient_key": "", - "action": "" // "add" or "remove" + "recipient_key": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH", + "action": "add" } ] } ``` + +`recipient_key`: Key subject of the update. + +`action`: One of `add` or `remove`. + ### Keylist Update Response + Confirmation of requested keylist updates. + ```jsonc { "@id": "123456781", - "@type": "/keylist_update_response", + "@type": "/keylist-update-response", "updated": [ { - "recipient_key": "", + "recipient_key": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH", "action": "" // "add" or "remove" "result": "" // [client_error | server_error | no_change | success] } ] } ``` -Questions: -- What types of errors are possible here? + +`recipient_key`: Key subject of the update. + +`action`: One of `add` or `remove`. + +`result`: One of `client_error`, `server_error`, `no_change`, `success`; describes the resulting state of the keylist update. + ### Key List Query +Query mediator for a list of keys registered for this connection. + ```jsonc { "@id": "123456781", - "@type": "/key_list_query", - "filter":{ - "": ["",""] - } + "@type": "/keylist-query", "paginate": { "limit": 30, "offset": 0 } } ``` -Questions: -- Filters feels odd here. Asking to see if a key is registered makes sense, but what else to filter on? + +`paginate` is optional. ### Key List +Response to key list query, containing retrieved keys. + ```jsonc { "@id": "123456781", - "@type": "/key_list", + "@type": "/keylist", "keys": [ { - "recipient_key": "" + "recipient_key": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH" } - ] + ], "pagination": { - + "count": 30, + "offset": 30, + "remaining": 100 } - } ``` -## Prior art +`pagination` is optional. -There was an Indy HIPE that never made it past the PR process that described a similar approach. That HIPE led to a partial implementation of this inside the Aries Cloud Agent Python +### Encoding of keys +All keys are encoded using the [`did:key`](https://w3c-ccg.github.io/did-method-key/) method as per +[RFC0360](../0360-use-did-key/README.md). +## Prior art -## Unresolved questions +There was an Indy HIPE that never made it past the PR process that described a similar approach. That HIPE led to a partial implementation of this inside the Aries Cloud Agent Python -- Still considering alternatives to convey the right meaning. +## Future Considerations - Should we allow listing keys by date? You could query keys in use by date? -- How might payment be coordinated? -- Should key ownership be proved when registered? Is there a risk of people requesting other people's keys? - We are missing a way to check a single key (or a few keys) without doing a full list. -- Additional questions in each section - +- Mediation grant supports only one endpoint. What can be done to support multiple endpoint options i.e. http, ws, etc. +- Requiring proof of key ownership (with a signature) would prevent an edge case where a malicious party registers a key for another party at the same mediator, and before the other party. +- How do we express terms and conditions for mediation? + +## Unresolved questions + +- None + ## Implementations The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. Name / Link | Implementation Notes --- | --- - | | +[Aries Cloud Agent - Python](https://github.com/hyperledger/aries-cloudagent-python/blob/main/Mediation.md) | Added in ACA-Py 0.6.0 [MISSING test results](/tags.md#test-anomaly)**** +[DIDComm mediator](https://github.com/Sirius-social/didcomm-mediator) | Open source cloud-based mediator. diff --git a/features/0212-pickup/README.md b/features/0212-pickup/README.md index 63f753fd6..3c8fd18a0 100644 --- a/features/0212-pickup/README.md +++ b/features/0212-pickup/README.md @@ -1,5 +1,6 @@ # 0212: Pickup Protocol -- Authors: [Sam Curren](telegramsam@gmail.com) + +- Authors: [Sam Curren](mailto:telegramsam@gmail.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-09-03 - Status Note: Initial version @@ -32,41 +33,52 @@ batch retrieval can be executed when many messages ... ## Reference ### StatusRequest + Sent by the _recipient_ to the _message_holder_ to request a `status` message. -```json= + +```json { - "@id": "123456781", - "@type": "https://didcomm.org/messagepickup/1.0/status-request" + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/1.0/status-request" } ``` + ### Status + Status details about pending messages -```json= + +```json { - "@id": "123456781", - "@type": "https://didcomm.org/messagepickup/1.0/status", - "message_count": 7, - "duration_waited": 3600, - "last_added_time": "2019-05-01 12:00:00Z", - "last_delivered_time": "2019-05-01 12:00:01Z", - "last_removed_time": "2019-05-01 12:00:01Z", - "total_size": 8096 + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/1.0/status", + "message_count": 7, + "duration_waited": 3600, + "last_added_time": "2019-05-01 12:00:00Z", + "last_delivered_time": "2019-05-01 12:00:01Z", + "last_removed_time": "2019-05-01 12:00:01Z", + "total_size": 8096 } ``` + `message_count` is the only required attribute. The others may be present if offered by the _message_holder_. + ### Batch Pickup + A request to have multiple waiting messages sent inside a `batch` message. -```json= + +```json { - "@id": "123456781", - "@type": "https://didcomm.org/messagepickup/1.0/batch-pickup", - "batch_size": 10 + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/1.0/batch-pickup", + "batch_size": 10 } ``` ### Batch + A message that contains multiple waiting messages. -```json= + +```json { "@id": "123456781", "@type": "https://didcomm.org/messagepickup/1.0/batch", @@ -87,22 +99,29 @@ A message that contains multiple waiting messages. ] } ``` + ### Message Query With Message Id List + A request to read single or multiple messages with a message message id array. -```json= + +```json { - "@id": "123456781", - "@type": "https://didcomm.org/messagepickup/1.0/list-pickup", - "message_ids": [ - "06ca25f6-d3c5-48ac-8eee-1a9e29120c31", - "344a51cf-379f-40ab-ab2c-711dab3f53a9a" - ] + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/1.0/list-pickup", + "message_ids": [ + "06ca25f6-d3c5-48ac-8eee-1a9e29120c31", + "344a51cf-379f-40ab-ab2c-711dab3f53a9a" + ] } ``` + `message_ids` message id array for picking up messages. Any message id in `message_ids` could be delivered via several ways to the recipient (Push notification or with an envoloped message). + ### Message List Query Response + A response to query with message id list. -```json= + +```json { "@type": "https://didcomm.org/messagepickup/1.0/list-response", "messages~attach": [ @@ -121,16 +140,18 @@ A response to query with message id list. ] } ``` + ### Noop + Used to receive another message implicitly. This message has no expected behavior when received. -```json= + +```json { - "@id": "123456781", - "@type": "https://didcomm.org/messagepickup/1.0/noop" + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/1.0/noop" } ``` - ## Prior art Concepts here borrow heavily from a [document](https://hackmd.io/@8VtAqKThQ6mKa9T7JgzIaw/SJw9Ead2N?type=view) written by Andrew Whitehead of BCGov. @@ -143,6 +164,6 @@ Concepts here borrow heavily from a [document](https://hackmd.io/@8VtAqKThQ6mKa9 The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -Name / Link | Implementation Notes ---- | --- - | | +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0213-transfer-policy/README.md b/features/0213-transfer-policy/README.md index 86d8e5902..6e440b147 100644 --- a/features/0213-transfer-policy/README.md +++ b/features/0213-transfer-policy/README.md @@ -1,8 +1,9 @@ # 0213: Transfer Policy Protocol -- Authors: [Sam Curren](telegramsam@gmail.com) + +- Authors: [Sam Curren](mailto:telegramsam@gmail.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-09-03 -- Status Note: Initial version +- Status Note: Initial version - Start Date: 2019-09-03 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) @@ -24,65 +25,70 @@ Explicit Policy Enables clear expectations. ## Reference ### Policy Publish + Used to share current policy by policy holder. This can be sent unsolicited or in response to a `policy_share_request`. -```json= + +```json { - "@id": "123456781", - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/transferpolicy/1.0/policy", - "queue_max_duration": 86400, - "message_count_limit": 1000, - "message_size_limit": 65536, - "queue_size_limit": 65536000, - "pickup_allowed": true, - "delivery_retry_count_limit":5, - "delivery_retry_count_seconds":86400, - "delivery_retry_backoff": "exponential" + "@id": "123456781", + "@type": "https://didcomm.org/transferpolicy/1.0/policy", + "queue_max_duration": 86400, + "message_count_limit": 1000, + "message_size_limit": 65536, + "queue_size_limit": 65536000, + "pickup_allowed": true, + "delivery_retry_count_limit": 5, + "delivery_retry_count_seconds": 86400, + "delivery_retry_backoff": "exponential" } ``` + ### Policy Share Request + Used to ask for a `policy` message to be sent. -```json= +```json { - "@id": "123456781", - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/transferpolicy/1.0/policy_share_request" + "@id": "123456781", + "@type": "https://didcomm.org/transferpolicy/1.0/policy_share_request" } ``` ### Policy Change Request -Sent to request a policy change. The expected response is a `policy` message. -```json= +Sent to request a policy change. The expected response is a `policy` message. +```json { - "@id": "123456781", - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/transferpolicy/1.0/policy_change_request", - "queue_max_duration": 86400, - "message_count_limit": 1000, - "message_size_limit": 65536, - "queue_size_limit": 65536000, - "pickup_allowed": true, - "delivery_retry_count_limit":5, - "delivery_retry_count_seconds":86400, - "delivery_retry_backoff": "exponential" + "@id": "123456781", + "@type": "https://didcomm.org/transferpolicy/1.0/policy_change_request", + "queue_max_duration": 86400, + "message_count_limit": 1000, + "message_size_limit": 65536, + "queue_size_limit": 65536000, + "pickup_allowed": true, + "delivery_retry_count_limit": 5, + "delivery_retry_count_seconds": 86400, + "delivery_retry_backoff": "exponential" } ``` -Only attributes that you desire to change need to be included. +Only attributes that you desire to change need to be included. ## Prior art + Concepts here borrow heavily from a [document](https://hackmd.io/@8VtAqKThQ6mKa9T7JgzIaw/SJw9Ead2N?type=view) written by Andrew Whitehead of BCGov. ## Unresolved questions - Is the attribute list too extensive for a first pass? - Which policy attributes should be required? Which optional? - + ## Implementations The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -Name / Link | Implementation Notes ---- | --- - | | +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0214-help-me-discover/README.md b/features/0214-help-me-discover/README.md index 299e87b01..322e39bee 100644 --- a/features/0214-help-me-discover/README.md +++ b/features/0214-help-me-discover/README.md @@ -1,8 +1,8 @@ # Aries RFC 0214: "Help Me Discover" Protocol -- Authors: [George Aristy](george.aristy@securekey.com), [Daniel Hardman](daniel.hardman@gmail.com) +- Authors: [George Aristy](mailto:george.aristy@securekey.com), [Daniel Hardman](mailto:daniel.hardman@gmail.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-09-10 -- Status Note: implementation is being explored by SecureKey +- Status Note: implementation is being explored by SecureKey - Start Date: 2018-08-20 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) @@ -43,7 +43,7 @@ The following requirements do not change this simple framework, but they introdu * It is desirable that criteria should be expressed in a way that harmonizes with proof requests, which also need a criteria language. * It must be possible for the responder to give partial answers: "I do know a good mechanic, but not one that lives close to you." * It must be possible for the responder to give compound answers: "Here's an item that satisfies critiera 1 and 3, and here's a different itme that satisfies criteria 2 and 4." -* It must be possible for this protocol to precede another protocol (e.g., [RFC 0028 Introduce Protocol](https://github.com/hyperledger/aries-rfcs/blob/master/features/0028-introduce/README.md)) in such a way that what follows can refer back to items in this protocol in an unambiguous way, as in "Here's an introduction to the party that I just told you about, that satisfies criteria 3 and 4 from the 'Help Me Discover' request you recently made." +* It must be possible for this protocol to precede another protocol (e.g., [RFC 0028 Introduce Protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0028-introduce/README.md)) in such a way that what follows can refer back to items in this protocol in an unambiguous way, as in "Here's an introduction to the party that I just told you about, that satisfies criteria 3 and 4 from the 'Help Me Discover' request you recently made." ### Messages diff --git a/features/0234-signature-decorator/README.md b/features/0234-signature-decorator/README.md index ab843fb42..6c8345ab3 100644 --- a/features/0234-signature-decorator/README.md +++ b/features/0234-signature-decorator/README.md @@ -1,12 +1,20 @@ # Aries RFC 0234: Signature Decorator -- Authors: [Kyle Den Hartog](kyle.denhartog@evernym.com) -- Status: [DEMONSTRATED](/README.md#demonstrated) -- Since: 2019-09-27 -- Status Note: Retroactive port of [this HIPE](https://github.com/kdenhartog/indy-hipe/blob/d421fc77bae87c780aad346d15c0c49939adc281/text/digital-signatures/README.md) (never merged) on which the `connection` protocol depends +- Authors: [Kyle Den Hartog](mailto:kyle.denhartog@evernym.com) +- Status: [RETIRED](/README.md#retired) +- Since: 2020-10-14 +- Status Note: This decorator is retired, replaced with the use of the signed form of the attachment decorator +([RFC 0017](../../concepts/0017-attachments/README.md#signing-attachments)) - Supersedes: [this HIPE](https://github.com/kdenhartog/indy-hipe/blob/d421fc77bae87c780aad346d15c0c49939adc281/text/digital-signatures/README.md) (never merged) - Start Date: 2019-01-07 - Tags: [feature](/tags.md#feature), [decorator](/tags.md#decorator) +## RFC ARCHIVED + +DO NOT USE THIS RFC. + +Use the signed form of the attachment decorator ([RFC 0017](../concepts/../../concepts/0017-attachments/README.md#signing-attachments)) +instead of this decorator. + ## Summary The `~sig` [field-level decorator](../../concepts/0011-decorators/README.md#decorator-scope) enables [non-repudiation](../../concepts/0049-repudiation/README.md) by allowing an Agent to add a digital signature over a portion of a DIDComm message. @@ -27,7 +35,7 @@ We'll use the following message as an example: ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/example/1.0/test_message", + "@type": "https://didcomm.org/example/1.0/test_message", "@id": "df3b699d-3aa9-4fd0-bb67-49594da545bd", "msg": { "text": "Hello World!", @@ -40,10 +48,10 @@ Digitally signing the `msg` object with the `ed25519sha256_single` scheme result ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/example/1.0/test_message", + "@type": "https://didcomm.org/example/1.0/test_message", "@id": "df3b699d-3aa9-4fd0-bb67-49594da545bd", "msg~sig": { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/signature/1.0/ed25519Sha512_single", + "@type": "https://didcomm.org/signature/1.0/ed25519Sha512_single", "sig_data": "base64URL(64bit_integer_from_unix_epoch|msg_object)", "signature": "base64URL(digital signature function output)", "signer": "base64URL(inlined_signing_verkey)" diff --git a/features/0234-signature-decorator/ed25519sha256_single.md b/features/0234-signature-decorator/ed25519sha256_single.md index 0c472fa86..bb6b4ad30 100644 --- a/features/0234-signature-decorator/ed25519sha256_single.md +++ b/features/0234-signature-decorator/ed25519sha256_single.md @@ -8,14 +8,14 @@ This scheme computes a single [ed25519](https://ed25519.cr.yp.to/) digital signa ```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/signature/1.0/ed25519Sha512_single", + "@type": "https://didcomm.org/signature/1.0/ed25519Sha512_single", "sig_data": "base64URL(64bit_integer_from_unix_epoch|msg)", "signature": "base64URL(ed25519 signature)", "signer": "base64URL(inlined_ed25519_signing_verkey)" } ``` -* `@type` MUST be `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/signature/1.0/ed25519Sha512_single` +* `@type` MUST be `https://didcomm.org/signature/1.0/ed25519Sha512_single` * `sig_data` MUST be the base64URL encoding of a 64-bit integer prepended to the message * `signature` MUST be the base64URL encoding of the resulting ed25519 digital signature over `sig_data` * `signer` MUST be the base64URL encoding of the corresponding ed25519 public key used to sign `sig_data` diff --git a/features/0249-rich-schema-contexts/README.md b/features/0249-rich-schema-contexts/README.md index 04bf8ca33..6b7719957 100644 --- a/features/0249-rich-schema-contexts/README.md +++ b/features/0249-rich-schema-contexts/README.md @@ -1,8 +1,8 @@ # Aries RFC 0249: Aries Rich Schema Contexts - Authors: [Brent Zundel](mailto:brent.zundel@evernym.com), [Ken Ebert](mailto:ken@sovrin.org), [Alexander Shcherbakov](mailto:alexander.shcherbakov@evernym.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-10-08 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-06-07 - Tags: [feature](/tags.md#feature), [rich-schemas](/tags.md#rich-schemas) @@ -16,7 +16,7 @@ meaning among rich schema objects. Context objects are processed in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common). ## Motivation [motivation]: #motivation @@ -62,11 +62,11 @@ Aries will provide a means for writing contexts to and reading contexts from a verifiable data registry (such as a distributed ledger). `@context` will be written to the ledger in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). ### Aries Data Registry Interface Aries Data Registry Interface methods for adding and retrieving `@context` from the -ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#aries-data-registry-interface). +ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#aries-data-registry-interface). This means the following methods can be used: - `write_rich_schema_object` @@ -84,8 +84,8 @@ More information on `@context` from the JSON-LD specification may be found [here](https://w3c.github.io/json-ld-syntax/#the-context) and [here](https://w3c.github.io/json-ld-syntax/#advanced-context-usage). -- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common) +- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common) ## Drawbacks diff --git a/features/0281-rich-schemas/README.md b/features/0281-rich-schemas/README.md index 1a0413c0f..e91d923da 100644 --- a/features/0281-rich-schemas/README.md +++ b/features/0281-rich-schemas/README.md @@ -1,8 +1,8 @@ # Aries RFC 0281: Aries Rich Schemas - Authors: [Brent Zundel](mailto:brent.zundel@evernym.com), [Ken Ebert](mailto:ken@sovrin.org), [Alexander Shcherbakov](mailto:alexander.shcherbakov@evernym.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-10-30 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-06-07 - Tags: [feature](/tags.md#feature), [rich-schemas](/tags.md#rich-schemas) @@ -19,7 +19,7 @@ additional properties. For example a schema for "employee" may inherit from the schema for "person." Schema objects are processed in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common). ## Motivation [motivation]: #motivation @@ -101,13 +101,13 @@ Schema, OWL, etc. ### Properties Rich Schema properties follow the generic template defined in -[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). Rich Schema's `content` field is a JSON-LD-serialized string with the following fields: #### @id A rich schema must have an `@id` property. The value of this property must -be equal to the `id` field which is a DID (see [Identification of Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#identification-of-rich-schema-objects)). +be equal to the `id` field which is a DID (see [Identification of Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#identification-of-rich-schema-objects)). A [rich schema](README.md) may refer to the `@id` of another rich schema to define a parent schema. A property of a rich schema may use the `@id` of @@ -227,12 +227,12 @@ Aries will provide a means for writing contexts to and reading contexts from a verifiable data registry (such as a distributed ledger). A Schema will be written to the ledger in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). ### Aries Data Registry Interface Aries Data Registry Interface methods for adding and retrieving a Schema from the -ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#aries-data-registry-interface). +ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#aries-data-registry-interface). This means the following methods can be used: - `write_rich_schema_object` @@ -245,8 +245,8 @@ This means the following methods can be used: More information on the Verifiable Credential data model use of `schemas` may be found [here](https://w3c.github.io/vc-data-model/#data-schemas). -- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common) +- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common) ## Drawbacks diff --git a/features/0303-v01-credential-exchange/README.md b/features/0303-v01-credential-exchange/README.md index d6cd82fa6..adc128dd1 100644 --- a/features/0303-v01-credential-exchange/README.md +++ b/features/0303-v01-credential-exchange/README.md @@ -6,7 +6,7 @@ - Status Note: Deprecated, but in common use in existing deployments of Aries agents. See [Implementations](#implementations) - Supersedes: [HackMD Document](https://hackmd.io/oWSw18DLTYCmHi_ty_gYvg?view) - Start Date: 2019-03-13 -- Tags: feature, protocol +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) ## Summary @@ -47,7 +47,7 @@ Acknowledgments and Errors should be signalled via adopting the standard `ack` a ```jsonld { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-issuance/0.1/credential-offer", + "@type": "https://didcomm.org/credential-issuance/0.1/credential-offer", "@id": "", "comment": "some comment", "credential_preview": , @@ -59,7 +59,7 @@ Acknowledgments and Errors should be signalled via adopting the standard `ack` a ```jsonld { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-issuance/0.1/credential-request", + "@type": "https://didcomm.org/credential-issuance/0.1/credential-request", "@id": "", "comment": "some comment", "request": @@ -70,7 +70,7 @@ Acknowledgments and Errors should be signalled via adopting the standard `ack` a ``` jsonld { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-issuance/0.1/credential-issue", + "@type": "https://didcomm.org/credential-issuance/0.1/credential-issue", "@id": "", "issue": } @@ -84,7 +84,7 @@ The message family to initiate a presentation. The verifier initiates the proces ```jsonld { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-presentation/0.1/presentation-request", + "@type": "https://didcomm.org/credential-presentation/0.1/presentation-request", "@id": "", "comment": "some comment", "request": @@ -95,7 +95,7 @@ The message family to initiate a presentation. The verifier initiates the proces ```jsonld { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/credential-presentation/0.1/credential-presentation", + "@type": "https://didcomm.org/credential-presentation/0.1/credential-presentation", "@id": "", "comment": "some comment", "presentation": diff --git a/features/0309-didauthz/README.md b/features/0309-didauthz/README.md index 2b5047544..86a981c60 100644 --- a/features/0309-didauthz/README.md +++ b/features/0309-didauthz/README.md @@ -1,11 +1,11 @@ # Aries RFC 0309: DIDAuthZ -- Authors: [George Aristy](george.aristy@gmail.com) SecureKey Technologies -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-11-14 -- Status Note: This RFC is under development. +- Authors: [George Aristy](mailto:george.aristy@gmail.com) SecureKey Technologies +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-09-27 -- Tags: feature, credentials +- Tags: [feature](/tags.md#feature), [credentials](/tags.md#credentials) ## Summary diff --git a/features/0317-please-ack/README.md b/features/0317-please-ack/README.md index 9b66edd8f..26d238cf2 100644 --- a/features/0317-please-ack/README.md +++ b/features/0317-please-ack/README.md @@ -1,21 +1,37 @@ # Aries RFC 0317: Please ACK Decorator -- Authors: [Daniel Hardman](daniel.hardman@gmail.com) -- Status: [PROPOSED](/README.md#proposed) +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com), [Timo Glastra](mailto:timo@animo.id) +- Status: [RETIRED](/README.md#retired) - Since: 2019-12-26 -- Status Note: Separated from the ACK protocol -- Supersedes: [0015-ACKs](https://github.com/hyperledger/aries-rfcs/tree/527849ec3aa2a8fd47a7bb6c57f918ff8bcb5e8c/features/0015-acks) +- Status Note: Attempts at implementation demonstrate that a general purpose `~please_ack` capability is not practical, and needs to be implemented on a per protocol basis, for protocols where the functionality makes sense. - Start Date: 2018-12-26 - Tags: [feature](/tags.md#feature), [decorator](/tags.md#decorator) +## Retirement of `~please_ack` + +The `please_ack` decorator was initially added to [Aries Interop Protocol 2.0]. However, this was done prior to attempts at an implementation. When such an attempt was made, it was found that the decorator is not practical as a general purpose mechanism. The capability assumed that the feature would be general purpose and could be applied outside of the protocols with which it was used. That assumption proved impossible to implement. The inclusion of the `~please_ack` decorator cannot be implemented without altering any protocol with which it is used, and so it is not practical. Instead, any protocols that can benefit from such a feature can be extended to explicitly support the feature. + +For the `"on": ["OUTCOME"]` type of ACK, the problem manifests in two ways. First, the definition of `OUTCOME` is protocol (and in fact, protocol message) specific. The definition of "complete" for each message is specific to each message, so there is no "general purpose" way to know when an `OUTCOME` ACK is to be sent. Second, the addition of a `~please_ack` decorator changes the protocol state machine for a given protocol, introducing additional states, and hence, additional state handling. Supporting `"on": ["OUTCOME"]` processing requires making changes to all protocols, which would be better handled on a per protocol basis, and where useful (which, it was found, is rare), adding messages and states. For example, what is the point of an extra `ACK` message on an `OUTCOME` in the middle of a protocol that itself results in the sending of the response message? + +Our experimentation found that it would be easier to achieve a general purpose `"on": ["RECEIPT"]` capability, but even then there were problems. Most notably, the capability is most useful when added to the last message of a protocol, where the message sender would like confirmation that the recipient got the message. However, it is precisely that use of the feature that also introduces breaking changes to the protocol state machine for the protocols to which it applies, requiring per protocol updates. So while the feature would be marginally useful in some cases, the complexity cost of the capability -- and the lack of demand for its creation -- led us to retire the entire RFC. + +For more details on the great work done by [Alexander Sukhachev @alexsdsr](https://github.com/alexsdsr), please see these pull requests, including both the changes proposed in the PRs, and the subsequent conversations about the features. + +- [Aries Cloud Agent Python PR 2540 - PleaseAck.md document](https://github.com/hyperledger/aries-cloudagent-python/pull/2540) +- [Aries Cloud Agent Python PR 2546 - DRAFT: please_ack support PoC for the 0453-issue-credential-v2 protocol](https://github.com/hyperledger/aries-cloudagent-python/pull/2546) +- [Aries RFCs - Update the 'unresolved questions' section of the 0317-please-ack RFC](https://github.com/hyperledger/aries-rfcs/pull/801) + +Much thanks for Alexander for the effort he put into trying to implement this capability. + +[Aries Interop Protocol 2.0]: https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0302-aries-interop-profile#aries-interop-profile-version-20 + ## Summary -Explains how one party can request an acknowledgment -to and clarify the status of complex processes. +Explains how one party can request an acknowledgment to and clarify the status of processes. ## Motivation -An __acknowledgment__ or __ACK__ is one of the most common procedures in protocols +An **acknowledgment** or **ACK** is one of the most common procedures in protocols of all types. The ACK message is defined in Aries RFC [0015-acks](../0015-acks/README.md) and is adopted into other protocols for use at explicit points in the execution of a protocol. In addition to receiving ACKs at predefined places in a protocol, agents also need the ability to request additional ACKs at other points in an instance of a protocol. Such requests may or may not be answered by the other party, hence the "please" in the name of decorator. ## Tutorial @@ -28,7 +44,7 @@ messages to arrive as sent, and to be processed as expected, a vital tool in the agent communication repertoire is the ability to request and receive acknowledgments to confirm a shared understanding. -#### Requesting an ack (`~please_ack`) +### Requesting an ack (`~please_ack`) A protocol may stipulate that an ack is always necessary in certain circumstances. Launch mechanics for spacecraft do this, because the stakes for a miscommunication @@ -47,261 +63,83 @@ organically to see the effect. But if she's bidding on a high-value item and is about to put her phone in airplane mode because her plane's ready to take off, she may want an immediate ACK that the bid was accepted. -The dynamic need for acks is expressed with the `~please_ack` message [decorator]( -../../concepts/0011-decorators/README.md). In its simplest form, it looks -like this: - -``` jsonc -"~please_ack": {} -``` - -This says, "Please send me an ack as soon as you receive this message." - -#### Advanced Features (experimental) - -
-(The features in this section are part of the 1.0 spec, but are not required to -be implemented to achieve 1.0 compliance. We describe them to show what may -be possible in the future.) -
+The dynamic need for acks is expressed with the `~please_ack` message [decorator](../../concepts/0011-decorators/README.md). An example of the decorator looks like this: -A fancier version of `~please_ack` might look like this: - -``` jsonc +```json { "~please_ack": { - "message_id": "b271c889-a306-4737-81e6-6b2f2f8062ae", - "on": [ - "RECEIPT", - "6h", - "OUTCOME" - ] + "on": ["RECEIPT"] } } ``` -This says, "For the message that I already sent you, with -@id=b271c889-a306-4737-81e6-6b2f2f8062ae, -please acknowledge that you've seen it as soon as you get this new message, and -please send me a new ack every 6 hours as long as status is still pending. Then -send me a final ack clarifying the outcome of the message once its outcome is -known." - -This sort of `~please_ack` might make sense when Alice expected a quick resolution, -but got silence from Bob. She refers back to the message that she thought would -finalize their interaction, and she asks for ongoing status every 6 hours until -there's closure. A `message_id` is optional; normally it's omitted since the message -needing an ack is the same message where ack is requested. But including `message_id` -allows Alice to change her mind about an ack after she's sent a message. - -The concept of "outcome" is relevant for interactions with a meaningful -delay between the final actions of one actor, and the time when the product of -those actions is known. Imagine Alice uses A2A messages to make an offer on a -house, and Bob, the homeowner, has 72 hours to accept or reject. The default ack -event, *message processing*, happens when Alice's offer arrives. The *outcome* -event for Alice's offer happens when the offer is accepted or rejected, and may -be delayed up to 72 hours. Similar situations apply to protocols where an -application is submitted, and probably to many other use cases. - -The notion of "on receipt" matters if the message requesting the ack is not the same -as the message that needs acknowledgment. This type of ack may help compensate for -transmission errors, among other things. - -### When an ack doesn't come - -All ack behaviors are best effort unless a protocol stipulates otherwise. This is -why the decorator name begins with `please`. A party that requests an explicit ack -cannot reason strongly about status when the ack doesn't come. The other party may -be offline, may be unable or unwilling to support fancy acks (or even simple ones), -or may be communicating through a channel that's unreliable. - -However, a party that receives a `~please_ack` can, in an `ack` response, indicate that -it is not going to comply with everything that was requested. This is best practice if -a misalignment is known in advance, as it allows the ack requester to adjust -expectations. For example, the fancier `~please_ack` shown above could trigger the -following ack on receipt: - -``` jsonc -{ - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/ack", - "@id": "06d474e0-20d3-4cbf-bea6-6ba7e1891240", - "status": "PENDING", - "deny": ["6h"], - "~thread": { - "thid": "b271c889-a306-4737-81e6-6b2f2f8062ae", - "myindex": 4, - "lrecs": {"2fQvCXfgvxz4dtBDDwcj2PJdG5qDrEsrQVjvWRhg9uhd": 3} - } -} -``` - -Here, `deny` tells the recipient that, although the `receipt` request in the -previous `~please_ack.on` was honored, and the `outcome` request will probably be -honored as well, the recipient cannot expect an ack every 6 hours. (The sender may -still send acks at their discretion; the denial just says that this behavior can't -be counted on.) - -## Reference - -### `~please_ack` decorator - -#### __`message_id`__ - -Asks for an acknowledgment of a message other than the one -that's decorated. Usually omitted, since most requests for an -ACK happen in the same message that wants acknowledgment. - -#### __`on`__ - -Describes the circumstances under which an ack is desired. Possible -values in this array include `RECEIPT`, `OUTCOME`, and strings that express a -time interval, as [documented in the RFC that discusses date- and time-related conventions]( -../../concepts/0074-didcomm-best-practices/README.md#_dur). -Support for acks on a time interval is an advanced feature and should not be -depended upon in the general case. - -In addition, it is possible to name protocol states in this array. To understand this, let's -return to the example of Alice making an offer on a house. Suppose that the `home-buy` -protocol names and defines the following states for the owner who receives an offer: -`waiting-for-other-offers`, `evaluating-all-offers`, `picking-best-offer`. All of -these states would be passed through by Bob after Alice sends her message, and -she could request an ack to be sent with each state, or with just some of them: - -``` jsonc -"on": ["evaluating-all-offers", "OUTCOME"] -``` - -The order of items in the `on` array is not significant, and any unrecognized -values in it should be ignored. +This says, "Please send me an ack as soon as you receive this message." ### Examples Suppose AliceCorp and Bob are involved in credential issuance. Alice is an issuer; Bob wants to hold the issued credential. -#### Happy Path +#### On Receipt In the final required message of the `issue-credential` protocol, AliceCorp sends the credential to Bob. But AliceCorp wants to know for sure that Bob has received it, for its own accounting purposes. So it decorates the final message with an ack request: -```JSON -"~please_ack: {}" -``` - -Bob honors this request and returns an `ack` as soon as he receives it and stores its -payload. The interesting field is `status`, which look like this: `"status": "OK"` (or, -if the `issue-credential` protocol defines a final state for the holder called -`now-holding`, Bob could be more explicit and send '"status": "now-holding"'. - -#### Delayed Issuance - -Suppose instead that partway through the issuance protocol, a message gets -dropped or delayed. Bob has sent his `credential-request` message with `@id:abc123`, -but he's been waiting for a response for AliceCorp for a long time. He now sends -a new message, requesting an ack. The message type is `problem-report` and the -severity is `WARN`, because Bob is unsure what the slow response means. `~thread.thid` -points back to the message that began the issuance protocol, which was probably -AliceCorp's `credential-offer`. `~thread.myindex` shows that this is the second -message Bob is sending on the thread, not the first--and that Bob has seen only -one message from AliceCorp on the thread, which was the offer to issue. This -should help AliceCorp recognize that it's missed a `credential-request` from Bob, -or if Bob has missed AliceCorp's response instead. Most importantly, this new -message from Bob is decorated with `~please_ack`: - -``` jsonc +```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/problem-report", - "@id": "06d474e0-20d3-4cbf-bea6-6ba7e1891240", - "~thread": { - "thid": "abc123", - "pthid": "xyz234", - "sender_order": 1, - "received_orders": [{"": -1}] - }, - "~please_ack": { "message_id": "abc123" } + "~please_ack": { + "on": ["RECEIPT"] + } } ``` -[TODO: How does Bob say that he hasn't seen any response to abc123 on the xyz234 thread, -instead of saying that he hasn't seen any response to abc123 on the abc123 thread?] +Bob honors this request and returns an `ack` as soon as he receives it and stores its payload. + +#### On Outcome -If AliceCorp saw Bob's `credential-request` but has simply been slow to respond, then -one possible response is to send Bob a message that says, "Yes, I know you asked for a -credential. I'm working on it." Such an `ack` would look like this: +Same as with the previous example, AliceCorp wants an acknowledgement from Bob. However, in contrast to the previous example that just requests an acknowledgement on receipt of message, this time AliceCorp wants to know for sure Bob verified the validity of the credential. To do this AliceCorp decorates the `issue-credential` message with an ack request for the `OUTCOME`. -``` jsonc +```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/ack", - "@id": "a7e174e0-032d-bf4c-a6eb-9126b84006d4", - "status": "PENDING", - "~thread": { - "thid": "abc123", - "pthid": "xyz234", - "sender_order": 0, - "received_orders": [{"": 0}] + "~please_ack": { + "on": ["OUTCOME"] } } ``` -Notice that `~thread.thid` has changed; the topic is now the missing message, not the -larger interaction. +Bob honors this request and returns an `ack` as soon as he has verified the validity of the issued credential. -If, on the other hand, AliceCorp is ready to issue the credential by the time the ack -request arrives, it could respond with a credential. As long as the credential -reply contains `~thread.received_orders: { : 1 }`, then it is an implicit -ACK because it tells Bob that the ack request was seen, and Bob can discover the status. +## Reference -If AliceCorp has never seen Bob's `credential-request`, then AliceCorp can reply with -a `problem-report` where the `~thread` object looks like this: +### `~please_ack` decorator -``` jsonc -{ - "thid": "abc123", - "received_orders": [{"": -1}] -} -``` +#### **`on`** -This says, "I'm sorry, Bob. I haven't seen any message from you on a thread with that -`@id`. (The code and comment in the `problem-report` message would probably clarify that -as well, but it is the `-1` in `~thread.received_orders` that tells Bob what he needs to know.) -Bob can now fix the problem by resending his `credential_request`. [TODO: what does the -resend look like? Does it have a `replaces_myindex` property in `~thread` that clarifies -how it is plugging the gap?] +The only field for the please ack decorator. Required array. Describes the circumstances under which an ack is desired. Possible values in this array include `RECEIPT` and `OUTCOME`. -If AliceCorp has already issued the credential to Bob, it can reply with an `ack` that -documents the outcome as far as it is concerned: +If both values are present, it means an acknowledgement is requested for both the receipt and outcome of the message -``` jsonc -{ - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/ack", - "@id": "a7e174e0-032d-bf4c-a6eb-9126b84006d4", - "status": "OK", - "~thread": { - "thid": "xyz234", - "sender_order": 2, - "received_orders": [{"": 1}] - } -} -``` +##### `RECEIPT` -Because `status` is OK, Bob knows that AliceCorp thinks the interaction associated -with his message "abc123", is over. Because `~thread.sender_order` is 2 instead of 1, Bob -knows that this `ack` is the 3rd message in the interaction (credential-offer=0, -credential=1, ack=2). Bob can now ask AliceCorp to resend. [TODO: how is this done?] +The `RECEIPT` acknowledgement is the easiest ack mechanism and requests that an ack is sent on receipt of the message. This way of requesting an ack is to verify whether the other agent successfully received the message. It implicitly means the agent was able to unpack the message, to see -## Drawbacks and Alternatives +##### `OUTCOME` + +The `OUTCOME` acknowledgement is the more advanced ack mechanism and requests that an ack is sent on outcome of the message. By default outcome means the message has been handled and processed without business logic playing a role in the decision. + +In the context of the issue credential protocol, by default, this would mean an ack is requested as soon as the received credentials is verified to be valid. It doesn't mean the actual contents of the credential are acknowledged. For the issue credential protocol it makes more sense to send the acknowledgement after the contents of the credential have also been verified. + +Therefore protocols can override the definition of outcome in the context of that protocol. Examples of protocols overriding this behavior are [Issue Credential Protocol 2.0](../0453-issue-credential-v2/README.md), [Present Proof Protocol 2.0](../0454-present-proof-v2/README.md) and [Revocation Notification Protocol 1.0](../0183-revocation-notification/README.md) + +## Drawbacks + +None specified. -This mechanism is more complex than what developers might assume -at first glance. Isn't it enough for the ~please_ack to be just the simple version? +## Rationale and alternatives -It could be. However, if we left it that simple, then we would not have a -standard way to ask for fancier ACK semantics. This would probably not -be fatal to the ecosystem, but it would lead to a proliferation of message -types that all do more or less the same thing. A [pattern would be -ungeneralized](https://codecraft.co/2015/09/02/on-forests-and-trees/), -causing lots of wasted code and documentation and learning time. +The first version of this RFC was a lot more advanced, but also introduced a lot of complexities. A lot of complex features have been removed so it could be included in AIP 2.0 in a simpler form. More advanced features [from the initial RFC](https://github.com/hyperledger/aries-rfcs/blob/2e6007b224f6888aec79b20bbddea3c4d533042a/features/0317-please-ack/README.md) can be added back in when needed. ## Prior art @@ -309,8 +147,7 @@ None specified. ## Unresolved questions -- Security and privacy implications of `~please_ack` decorators. Could they be used to mount -a denial-of-service attack or to sniff info that's undesirable? +- Security and privacy implications of `~please_ack` decorators. Could they be used to mount a denial-of-service attack or to sniff info that's undesirable? - Signed (Non-repudiable) acks. How do you ask for an ACK that commits its sender to the acknowledgment in a way that's provable to third parties? - Multiplexed acks. How do you ask for, and supply, an ACK to all of Alice's agents instead of just to the one who sent the ACK? Does each agent need to request the ACK separately? Are there denial-of-service or other security issues? @@ -318,6 +155,6 @@ a denial-of-service attack or to sniff info that's undesirable? The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -Name / Link | Implementation Notes ---- | --- - | +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0327-crypto-service/README.md b/features/0327-crypto-service/README.md index b61f42581..b47f77cd8 100644 --- a/features/0327-crypto-service/README.md +++ b/features/0327-crypto-service/README.md @@ -1,12 +1,12 @@ # Aries RFC 0327: Crypto service Protocol 1.0 - Authors: Robert Mitwicki, Wolfgang Lamot -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-11-20 (date you submit your PR) -- Status Note: RFC under development +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-11-01 -- Tags: feature, protocol +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) ## Summary diff --git a/features/0334-jwe-envelope/README.md b/features/0334-jwe-envelope/README.md index 218c56946..fbe2cba41 100644 --- a/features/0334-jwe-envelope/README.md +++ b/features/0334-jwe-envelope/README.md @@ -1,9 +1,9 @@ # Aries RFC 0334: JWE envelope 1.0 - Authors: [Baha A. Shaaban](mailto:baha.shaaban@securekey.com) (SecureKey Technologies Inc.), [Troy Ronda](mailto:troy.ronda@securekey.com) (SecureKey Technologies Inc.) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-11-28 -- Status Note: RFC under development +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-11-01 - Tags: [feature](/tags.md#feature) @@ -14,7 +14,7 @@ Agents need to use a common set of algorithms when exchanging and persisting dat ## Motivation -The goal of this RFC is define ciphersuites for Anoncrypt and Authcrypt such that we can achieve better compatability with JOSE. We also aim to supply both a compliant suite and a constrained device suite. The compliant suite is suitable for implementations that contain AES hardware acceleration or desire to use NIST / FIPS algorithms (where possible). +The goal of this RFC is to define cipher suites for Anoncrypt and Authcrypt such that we can achieve better compatibility with JOSE. We also aim to supply both a compliant suite and a constrained device suite. The compliant suite is suitable for implementations that contain AES hardware acceleration or desire to use NIST / FIPS algorithms (where possible). ## Encryption Algorithms @@ -24,10 +24,11 @@ The next two sub-sections describe the encryption algorithms that must be suppor The following table defines the supported content encryption algorithms for DIDComm JWE envelopes: - Content Encryption | Encryption Algorithm identifier - :------------------ | :------------------- - AES-GCM (256 bit) | A256GCM - XChacha20Poly1305 | XC20P + Content Encryption | Encryption Algorithm identifier | Authcrypt/Anoncrypt | Reference | + :--------------------- | :------------------------------ | :----------------- | :--------- | + A256CBC-HS512 (512 bit) | AES_256_CBC_HMAC_SHA_512 | Authcrypt/Anoncrypt | [ECDH-1PU section 2.1](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04#section-2.1) and [RFC 7518 section 5.2.5](https://datatracker.ietf.org/doc/html/rfc7518#section-5.2.5) | + AES-GCM (256 bit) | A256GCM | Anoncrypt | [RFC7518 section 5.1](https://tools.ietf.org/html/rfc7518#section-5.1) and more specifically [RFC7518 section 5.3](https://tools.ietf.org/html/rfc7518#section-5.3) | + XChacha20Poly1305 | XC20P | Anoncrypt | [xchacha draft 03](https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03) | ### Key Encryption Algorithms @@ -47,12 +48,14 @@ The following curves are supported: :--------------------------------------------------------- | :----------------- X25519 (aka Curve25519) | X25519 (default) NIST P256 (aka SECG secp256r1 and ANSI X9.62 prime256v1, ref [here](https://tools.ietf.org/search/rfc4492#appendix-A)) | P-256 + NIST P384 (aka SECG secp384r1, ref [here](https://tools.ietf.org/search/rfc4492#appendix-A)) | P-384 + NIST P521 (aka SECG secp521r1, ref [here](https://tools.ietf.org/search/rfc4492#appendix-A)) | P-521 Other curves are optional. #### Security Consideration for Curves -As noted in the ECDH-1PU [IETF draft](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03#section-4) security considerations section, all implementations must ensure the following: +As noted in the ECDH-1PU [IETF draft](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04#section-4) security considerations section, all implementations must ensure the following: ```text When performing an ECDH key agreement between a static private key and any untrusted public key, care should be taken to ensure that the @@ -76,6 +79,8 @@ The Proposed [JWE Formats](#jwe-formats) below lists a combination of content en - All new algorithm identifiers should be registered at IANA. - XC20P - ECDH-1PU+A256KW (already in IETF draft) + - ECDH-ES+XC20PKW + - ECDH-1PU+XC20PKW - Security Considerations of [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) (Section 4) - X25519 is not yet part of SP 800-56A. See [NIST post](https://csrc.nist.gov/News/2017/Transition-Plans-for-Key-Establishment-Schemes) for more information. @@ -100,26 +105,27 @@ Another prior effort towards enhancing JWE compliance is to use XChacha20Poly130 "recipients": [ { "header": { - "kid": base64url(recipient KID), // e.g: base64url("urn:123") + "kid": base64url(recipient KID), // e.g: base64url("urn:123") or base64url(jwk thumbprint as KID) "alg": "ECDH-ES+A256KW", - "epk": { // defining X25519 key as an example JWK, but this can be AES-GCM 256-bit key as well + "epk": { // defining X25519 key as an example JWK, but this can be EC key as well "kty": "OKP", "crv": "X25519", - "x": "-3bLMSHYDG3_LVNh-MJvoYs_a2sAEPr4jwFfFjTrmUo" // sender's ephemeral public key value base64url encoded + "x": "-3bLMSHYDG3_LVNh-MJvoYs_a2sAEPr4jwFfFjTrmUo" // sender's ephemeral public key value raw (no padding) base64url encoded }, - "apu": epk.x value above, - "apv": base64url(recipient.kid) + "apu": base64url(epk.x value above), + "apv": base64url(recipients[*].header.kid) }, "encrypted_key": "Sls6zrMW335GJsJe0gJU4x1HYC4TRBZS1kTS1GATEHfH_xGpNbrYLg" } ], + "aad": "base64url(sha256(concat('.',sort([recipients[0].kid, ..., recipients[n].kid])))))", "iv": "K0PfgxVxLiW0Dslx", "ciphertext": "Sg", "tag": "PP31yGbQGBz9zgq9kAxhCA" } ``` -`typ` header field is the DIDComm Transports value as mentioned in [RFC-0025](https://github.com/hyperledger/aries-rfcs/tree/master/features/0025-didcomm-transports#reference). This RFC states the prefix `application/` but according to [IANA Media types](https://www.iana.org/assignments/media-types/media-types.xhtml#application) the prefix is implied therefore not needed here. +`typ` header field is the DIDComm Transports value as mentioned in [RFC-0025](https://github.com/hyperledger/aries-rfcs/tree/main/features/0025-didcomm-transports#reference). This RFC states the prefix `application/` but according to [IANA Media types](https://www.iana.org/assignments/media-types/media-types.xhtml#application) the prefix is implied therefore not needed here. ### Anoncrypt using ECDH-ES key wrapping mode and A256GCM content encryption @@ -133,25 +139,26 @@ Another prior effort towards enhancing JWE compliance is to use XChacha20Poly130 { "header": { "kid": base64url(recipient KID), - "alg": "ECDH-ES+A256KW", + "alg": "ECDH-ES+XC20PKW", // or "ECDH-ES+A256KW" with "epk" as EC key "epk": { "kty": "OKP", "crv": "X25519", - "x": "aOH-76BRwkHf0nbGokaBsO6shW9McEs6jqVXaF0GNn4" // sender's ephemeral public key value base64url encoded + "x": "aOH-76BRwkHf0nbGokaBsO6shW9McEs6jqVXaF0GNn4" // sender's ephemeral public key value raw (no padding) base64url encoded }, - "apu": epk.x value above, - "apv": base64url(recipient.kid) + "apu": base64url(epk.x value above), + "apv": base64url(recipients[*].header.kid) }, "encrypted_key": "wXzKi-XXb6fj_KSY5BR5hTUsZIiAQKrxblTo3d50B1KIeFwBR98fzQ" } ], + "aad": "base64url(sha256(concat('.',sort([recipients[0].kid, ..., recipients[n].kid])))))", "iv": "9yjR8zvgeQDZFbIS", "ciphertext": "EvIk_Rr6Nd-0PqQ1LGimSqbKyx_qZjGnmt6nBDdCWUcd15yp9GTeYqN_q_FfG7hsO8c", "tag": "9wP3dtNyJERoR7FGBmyF-w" } ``` -In the above two examples, `apu` is the encode ephemeral key used to encrypt the cek stored in `encrypted_key` and `apv` is the key id of the static public key of the recipient. Both are base64Url encoded. +In the above two examples, `apu` is the encoded ephemeral key used to encrypt the cek stored in `encrypted_key` and `apv` is the encoded key id of the static public key of the recipient. Both are raw (no padding) base64Url encoded. `kid` is the value of a key ID in a DID document that should be resolvable to fetch the raw public key used. ### Authcrypt using ECDH-1PU key wrapping mode @@ -160,24 +167,24 @@ In the above two examples, `apu` is the encode ephemeral key used to encrypt the { "protected": base64url({ "typ": "didcomm-envelope-enc", - "enc":"XC20P", // or "A256GCM" + "enc":"A256CBC-HS512", // or one of: "A128CBC-HS256", "A192CBC-HS384" "skid": base64url(sender KID), + "alg": "ECDH-1PU+A256KW", // or "ECDH-1PU+XC20P" with "epk" as X25519 key + "apu": base64url("skid" header value), + "apv": base64url(sha256(concat('.',sort([recipients[0].kid, ..., recipients[n].kid]))))), + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "gfdM68LgZWhHwdVyMAPh1oWqV_NcYGR4k7Bjk8uBGx8", + "y": "Gwtgz-Bl_2BQYdh4f8rd7y85LE7fyfdnb0cWyYCrAb4" + } }), "recipients": [ { - "encrypted_key": "base64url(encrypted CEK)", "header": { - "kid": base64url(recipient KID), - "alg": "ECDH-1PU+A256KW", - "enc": "A256GCM", - "apu": base64url(senderID), - "apv": base64url(recipientID), - "epk": { - "kty": "OKP", - "crv": "X25519", - "x": "aOH-76BRwkHf0nbGokaBsO6shW9McEs6jqVXaF0GNn4" - }, - } + "kid": base64url(recipient KID) + }, + "encrypted_key": "base64url(encrypted CEK)" }, ... ], @@ -188,13 +195,17 @@ In the above two examples, `apu` is the encode ephemeral key used to encrypt the } ``` -With the recipients headers representing an ephemeral key that can be used to derive the key to be used for AEAD decryption of the CEK following the [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) encryption scheme. +With the recipients headers representing an ephemeral key that can be used to derive the key to be used for AEAD decryption of the CEK following the [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04) encryption scheme. + +The function `XC20P` in the example above is defined as the XChahcha20Poly1035 cipher function. This can be replaced by the AES-CBC+HMAC_SHA family of cipher functions for authcrypt or AES-GCM cipher function for anoncrypt. -The function `XC20P` in the example above is defined as the XChahcha20Poly1035 cipher function. This can be replaced by the A256GCM cipher function. +### Concrete examples + +See concrete [anoncrypt](anoncrypt-examples.md) and [authcrypt](authcrypt-examples.md) examples ## JWE detached mode nested envelopes -There are situations in DIDComm messaging where an envelope could be nested inside another envelope -- particularly [RFC 46: Mediators and Relays](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0046-mediators-and-relays). Normally nesting envelopes implies that the envelope payloads will incur additional encryption and encoding operations at each parent level in the nesting. This section describes a mechanism to extract the nested payloads outside the nesting structure to avoid these additional operations. +There are situations in DIDComm messaging where an envelope could be nested inside another envelope -- particularly [RFC 46: Mediators and Relays](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0046-mediators-and-relays). Normally nesting envelopes implies that the envelope payloads will incur additional encryption and encoding operations at each parent level in the nesting. This section describes a mechanism to extract the nested payloads outside the nesting structure to avoid these additional operations. ### Detached mode @@ -238,7 +249,7 @@ This solution has the following characteristics: The extracted ciphertext serialization format should have additional thought for both compact and JSON modes. As a starting point: -- Compact mode: Each extracted ciphertext is appended to the end of the serialized "final" JWE (using dot seperation). These extracted cipher texts are ordered according to the nesting (from innermost to outermost). +- Compact mode: Each extracted ciphertext is appended to the end of the serialized "final" JWE (using dot separation). These extracted cipher texts are ordered according to the nesting (from innermost to outermost). - JSON mode: The extracted ciphertext are placed into a JSON array. These extracted cipher texts are ordered according to the nesting (from innermost to outermost). The array is appended to the "final" JWE object as the `detached_ciphertext` field. For illustration, the following compact serialization represents nesting due to two mediators (the second mediator being closest to the Receiver). @@ -264,7 +275,7 @@ Second Mediator receives: BASE64URL(JWE Ciphertext for Receiver) ``` -Finally the Receiver has a normal JWE (as usual): +Finally, the Receiver has a normal JWE (as usual): ``` BASE64URL(UTF8(JWE Protected Header for Receiver)) || '.' || BASE64URL(JWE Encrypted Key for Receiver) || '.' || @@ -278,8 +289,8 @@ This illustration extends the serialization shown in [RFC 7516](https://tools.ie ## Prior art - The [JWE](https://tools.ietf.org/html/rfc7518) family of encryption methods. -- [Aries RFC 0019-encryption-envelope](https://github.com/hyperledger/aries-rfcs/tree/master/features/0019-encryption-envelope) suggested envelope formats will be superseded by this RFC. -- [Aries RFC 0025-didcomm-transports](https://github.com/hyperledger/aries-rfcs/tree/master/features/0025-didcomm-transports#reference) for the content type used in the proposed envelopes. +- [Aries RFC 0019-encryption-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0019-encryption-envelope) suggested envelope formats will be superseded by this RFC. +- [Aries RFC 0025-didcomm-transports](https://github.com/hyperledger/aries-rfcs/tree/main/features/0025-didcomm-transports#reference) for the content type used in the proposed envelopes. - [minimal-cipher](https://github.com/digitalbazaar/minimal-cipher) implementation - [Aries-Framework-Go](https://github.com/hyperledger/aries-framework-go/) has an experimental (X)Chacha20Poly1305 Packer implementation based on Aries-RFCs [issue-133](https://github.com/hyperledger/aries-rfcs/issues/133#issuecomment-535199768) - [IANA Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml#application) @@ -290,7 +301,12 @@ This illustration extends the serialization shown in [RFC 7516](https://tools.ie ## Unresolved questions - What fields should Key identifiers in ES and 1PU key wrapping modes use? `kid` vs `id` (vs `skid` introduced in [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) IETF document) or any other combination of fields. There is a discussion about this [here](https://github.com/w3c/did-core/issues/131). -- What kind of keys to include in the JWE envelope? `Encryption` or `signing` keys? Currently the existing Aries agents include `signing` keys for the sender and recipients and convert them to encryption keys for encryption/decryption operations only. The drawback is the envelope transmitted by the agent contains signing keys. The aries-framework-go repo includes (an experimental) JWE implementation that expects `signing` keys from the API user and then fetches the corresponding `encryption` keys from the wallet (KMS) to build the envelope. `Signing` keys are not included in the envelope in this implementation. There is a need to separate them from `encryption` keys in the current Aries implementations as well. + - **Update**: + The answer to this question is to keep `kid` definition as per the JWE/JWS family of specification definitions and use `skid` in the JWE protected header as defined in [ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) to represent a resolvable sender key id. + +- What kind of keys to include in the JWE envelope? `Encryption` or `signing` keys? Currently, the existing Aries agents include `signing` (ED25519) keys for the sender and recipients and convert them to encryption (X25519) keys for encryption/decryption operations only. The drawback of this approach is the envelope transmitted by the agent contains signing public keys. There is a need to separate them from `encryption` keys. + - **Update**: + The best way to separate the two keys is to use the DID document's [KeyAgreement](https://www.w3.org/TR/did-core/#key-agreement) verification method in full description to store the `encryption` key so that it can be sent in the JWE envelope independently of the signing (DID authentication) key. ## Implementations @@ -300,4 +316,4 @@ The following lists the implementations (if any) of this RFC. Please do a pull r | ----------- | -------------------- | | | | -Note: [Aries Framework - Go](https://github.com/hyperledger/aries-framework-go) will soon work on a first draft implementation of this RFC. +Note: [Aries Framework - Go](https://github.com/hyperledger/aries-framework-go) is almost done with a first draft implementation of this RFC. diff --git a/features/0334-jwe-envelope/anoncrypt-examples.md b/features/0334-jwe-envelope/anoncrypt-examples.md new file mode 100644 index 000000000..1c1fda63b --- /dev/null +++ b/features/0334-jwe-envelope/anoncrypt-examples.md @@ -0,0 +1,1150 @@ +Table of Contents +================= + +* [Anoncrypt JWE Concrete examples](#anoncrypt-jwe-concrete-examples) + * [Notes](#notes) + * [1 A256GCM Content Encryption](#1-a256gcm-content-encryption) + * [1.1 Multi recipients JWEs](#11-multi-recipients-jwes) + * [1.1.1 NIST P-256 keys](#111-nist-p-256-keys) + * [1.1.2 NIST P-384 keys](#112-nist-p-384-keys) + * [1.1.3 NIST P-521 keys](#113-nist-p-521-keys) + * [1.1.4 X25519 keys](#114-x25519-keys) + * [1.2 Single Recipient JWEs](#12-single-recipient-jwes) + * [1.2.1 NIST P-256 key](#121-nist-p-256-key) + * [1.2.2 NIST P-384 key](#122-nist-p-384-key) + * [1.2.3 NIST P-521 key](#123-nist-p-521-key) + * [1.2.4 X25519 key](#124-x25519-key) + * [2 XC20P content encryption](#2-xc20p-content-encryption) + * [2.1 Multi recipients JWEs](#21-multi-recipients-jwes) + * [2.1.1 NIST P-256 keys](#211-nist-p-256-keys) + * [2.1.2 NIST P-384 keys](#212-nist-p-384-keys) + * [2.1.3 NIST P-521 keys](#213-nist-p-521-keys) + * [2.1.4 X25519 keys](#214-x25519-keys) + * [2.2 Single Recipient JWEs](#22-single-recipient-jwes) + * [2.2.1 NIST P-256 key](#221-nist-p-256-key) + * [2.2.2 NIST P-384 key](#222-nist-p-384-key) + * [2.2.3 NIST P-521 key](#223-nist-p-521-key) + * [2.2.4 X25519 key](#224-x25519-key) + +Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc) + +# Anoncrypt JWE Concrete examples + +The following examples are for JWE **anoncrypt** packer for encrypting the payload `secret message` and aad value set as the concatenation of recipients' KIDs (ASCII sorted) joined by `.` for non-compact serializations (JWE Compact serializations [don't have AAD](https://tools.ietf.org/html/rfc7516#section-7.1)). + +### Notes +- all `x` and `y` key coordinates values below are raw (no padding) base64URL encoded. +- JWE envelopes with multi recipients use the [General JWE JSON Serialization](https://tools.ietf.org/html/rfc7516#section-7.2.1) format. +- JWE envelopes with a single recipient will be shown in both serialization formats: as [JWE Compact](https://tools.ietf.org/html/rfc7516#section-3.1) or [Flattened JWE JSON](https://tools.ietf.org/html/rfc7516#section-7.2.2). +- **General** JWE JSON Serialization format use. the above mentioned AAD value in their envelope. +- JWE **Compact** Serialization format does not support AAD values and therefore were built without it. +- all `apu` recipient header values are set to the raw (no padding) base64URL encoding of the corresponding recipient's ephemeral key's `x` value since Anoncrypt dosen't reveal the sender. +- all `apv` recipient header values are set to the raw (no padding) base64URL encoding of the corresponding recipient's `kid` value. +- The final aad used to encrypt the payload is the concatenation of the raw (no padding) base64URL encoded protected headers and `aad` JWE header joined by a `.`. +- Even though flattened serialization do support `aad`, the field is omitted in the below examples to be consistent with compact JWE serialization format. Implementations should support `aad` for flattened serialization regardless. + +## 1 A256GCM Content Encryption + +The packer generates the following protected headers for A256GCM content encryption in the below examples: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"A256GCM","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9` + +### 1.1 Multi recipients JWEs + +#### 1.1.1 NIST P-256 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "2fpy_fK5FCsap0EbU1Om7QXoVoyvBv8gfdHY3ufIS9w", + "y": "TtVOc9c8ejMeqeaUs1CMS79w0-Al02Fw25WdVEb0DiI", + "d": "kEWLCAyDL8mgDLNnlb1am_B8wcaGAe7ViXx1tqKWTVc" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `s6-ZhI1hpx0kM3pDgOrVQs6mRd_8KfEXUkLg8lK7XNA` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "S9JVfrKenXIMiEUha1k8yt7Zw8d5_bSxEt6RJesPt1g", + "y": "KMWwZzb80uoAjCcuwQ3gSeyjMsbq02AyS7g1D2i7ZwM", + "d": "bHnnqFSAFROp4kLbfBfihHUg6PIviwRCt5foN2Romw4" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `2NfcF400LLr9Wa6QbkUikYUUcdsAUkZBy6ifrrXYI0U` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "tqn3J0p752xWq2T4M11Q8ZcidyEWfaray-2B84hjehg", + "y": "ewcqOkZtlGBfZmP9nr44tq7_vkBJ3fJe9u6TCEyMDh8", + "d": "5XlB_SQXVpA6Id1PNL4SJfrMhCC36xa0hSHB7WpwA9Y" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `xG9z3It37igQIB4Q9jbcKLVjcFvnXIvkuJdLNKFvRB4` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `2NfcF400LLr9Wa6QbkUikYUUcdsAUkZBy6ifrrXYI0U.s6-ZhI1hpx0kM3pDgOrVQs6mRd_8KfEXUkLg8lK7XNA.xG9z3It37igQIB4Q9jbcKLVjcFvnXIvkuJdLNKFvRB4` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `YyqAtGX-dZTiXaZnGazezl-jBXS4uka1sOFv8cV42uM` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "WVU3OHhXeVZLeC1WRVpIV2pWbFN3Z2NndFRtSjBfS09YOE9hTkdnQXNlUQ", + "apv": "czYtWmhJMWhweDBrTTNwRGdPclZRczZtUmRfOEtmRVhVa0xnOGxLN1hOQQ", + "kid": "s6-ZhI1hpx0kM3pDgOrVQs6mRd_8KfEXUkLg8lK7XNA", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "YU78xWyVKx-VEZHWjVlSwgcgtTmJ0_KOX8OaNGgAseQ", + "y": "AiHDxtQBrba6g3_d0tic8LeLZRMz7rqnghQ2DvJh0Xk" + } + }, + "encrypted_key": "fnofbBoie-ywDVjd_Dcdw611KWabq0RptbEybN_AParPMI0qpOwm1Q" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "NkN3ZEt3ZEotczdIZHFpUzExR0x6bS1scVhlUW1TYWJjNXBvRnBaakdZbw", + "apv": "czYtWmhJMWhweDBrTTNwRGdPclZRczZtUmRfOEtmRVhVa0xnOGxLN1hOQQ", + "kid": "2NfcF400LLr9Wa6QbkUikYUUcdsAUkZBy6ifrrXYI0U", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "6CwdKwdJ-s7HdqiS11GLzm-lqXeQmSabc5poFpZjGYo", + "y": "mVsQl_AhZoHpC86UN49k6tAU5B2YLi0HIdWeaIvSQy8" + } + }, + "encrypted_key": "qN1WX7DK0k2GW4qHK0SfQFTRrOM0GFUgzqqy58QTRWi62r9iItmPxA" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "aXZzeDhaVmowbEJ1c2pLNjZSS1dVN0JDRjJzal81QWlQb1VsS21KOHZkSQ", + "apv": "czYtWmhJMWhweDBrTTNwRGdPclZRczZtUmRfOEtmRVhVa0xnOGxLN1hOQQ", + "kid": "xG9z3It37igQIB4Q9jbcKLVjcFvnXIvkuJdLNKFvRB4", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "ivsx8ZVj0lBusjK66RKWU7BCF2sj_5AiPoUlKmJ8vdI", + "y": "Ea6i7ahugWrTZoc9UMq1e3aPmHm0bkGqxTDmoEMyYMU" + } + }, + "encrypted_key": "Yds0G9wYyAaGf2ky9DAT0CITzoD4qHV1fUM-cH-mmGsx8TeFjYBVYw" + } + ], + "aad": "YyqAtGX-dZTiXaZnGazezl-jBXS4uka1sOFv8cV42uM", + "iv": "S9rOxQOd8H-gxZIv", + "ciphertext": "w3kl_QixTanzflQHpuM", + "tag": "4x5wmIBxrCjUpq4wxrWFDQ" +} +``` + +#### 1.1.2 NIST P-384 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "lb17x-OBz2i1kQbkRtSKD3TY1MwIfUMyM8YtqXZXMj884hLJH2QtxmUWKyXIprcn", + "y": "PlT4CInTrA5zAroqwyww0BL6EipnEBTrtbWID8nADz6LFpf_27qlxIARy_iU5OcN", + "d": "JJgpIqGS5JuiKRnsEgGNlYw39pz-XGrsrmniuxlSik0BLwdb8-0K8Xxuqo6yW6NE" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `8wPpWWlLiMBYltw6AoWG3Z_SfgWmXanBHSwZFpQJ0Q0` +- Recipient 2 public key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "ACZDXpzp6cKqsCcWq7sVOcCB_QZLd9ZfhoxhBKCbytrSKVKn7jV3Kv1XlsnH1RH7", + "y": "FQy3qBV-bn4K_5bQXucEPIOupMhEJS7YXCbm-fUb9ZdC59b0-5lbo7l65fkEL3ZO", + "d": "F4BlupNNnLfPOsml1MfBJgw6Oz89L6GnRiJnFi5ay5zVHTIcWzX81D060KsCjK9t" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `8l5z1lSVYFmv8QSboANWcj_UUh4bp3PlwEBNNHd2p3Q` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "msbHjsKVl0paXi-SWZ5_gEMgsMihBW9TEnfScKxfVlFMC6Hi5JIz1wgs58ugqaSX", + "y": "ppzaqlmAjA_iBymA2iBH56mHeTxckL8YNfmcSNa8hJoD4XYZ-4_x9mip-dh8o4gI", + "d": "YT0k8bBmPmecprG6tax6g00wG0JkprPcCqU1jvM86PAGGUU12fY7-Dfmqwhwv5U-" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `t1KsLfBBTG9iXIzyga6xV7RAur2j34dLGB3jqTDuTMo` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `8l5z1lSVYFmv8QSboANWcj_UUh4bp3PlwEBNNHd2p3Q.8wPpWWlLiMBYltw6AoWG3Z_SfgWmXanBHSwZFpQJ0Q0.t1KsLfBBTG9iXIzyga6xV7RAur2j34dLGB3jqTDuTMo` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `jgz9Cgt6lep5QPX0-GCkOMXujjRYgfiTslwut8BdX-0` +- JWE: +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "OVdMemtDbjBlaEFxVTlwZjdvUEFZVUdOcHhkdTR2VWZUZVZxZzlVWEZUNVNPS0dTaDFwZ294aWhOb0tWZlpsNg", + "apv": "OHdQcFdXbExpTUJZbHR3NkFvV0czWl9TZmdXbVhhbkJIU3daRnBRSjBRMA", + "kid": "8wPpWWlLiMBYltw6AoWG3Z_SfgWmXanBHSwZFpQJ0Q0", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "9WLzkCn0ehAqU9pf7oPAYUGNpxdu4vUfTeVqg9UXFT5SOKGSh1pgoxihNoKVfZl6", + "y": "Yuwe4x6Seue5pegwF9px-RQqSxARjf5mHSwVW7ft6dC5TgXdCPzm3bTRW4qxR41X" + } + }, + "encrypted_key": "Dj-4zbK_WbF_5nU1rfvT0dipMtwSUQvmluCrxwu-arKU2w59hN5ecQ" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "Q2hxMTBxU0duM3JQdHVKaFcwcEF1TzIxanh4WkVFb0xVQ1hkajNTbERfelZMamQ4ZHdwSmp5UXhQeEVSQ2ZOTw", + "apv": "OHdQcFdXbExpTUJZbHR3NkFvV0czWl9TZmdXbVhhbkJIU3daRnBRSjBRMA", + "kid": "8l5z1lSVYFmv8QSboANWcj_UUh4bp3PlwEBNNHd2p3Q", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "Chq10qSGn3rPtuJhW0pAuO21jxxZEEoLUCXdj3SlD_zVLjd8dwpJjyQxPxERCfNO", + "y": "9PkX3jqgkslA2Z8rijClt-1yX5uulFcbRl7dCaSgquCfYj0ZmOEVhQqdD9yh955n" + } + }, + "encrypted_key": "LpoFtDL4ac0bx16AkyE4HmpK-F_ibPm1LvyQVo-eFaPEo9HW8FWz_Q" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "T0cyZUptVU05NENDS2w4U2lGVTJNQUhVUnJiRldRSm1xd25ya2VWUFN3NTMzX3lSakFMLVNscnhvZ29uSnBzbA", + "apv": "OHdQcFdXbExpTUJZbHR3NkFvV0czWl9TZmdXbVhhbkJIU3daRnBRSjBRMA", + "kid": "t1KsLfBBTG9iXIzyga6xV7RAur2j34dLGB3jqTDuTMo", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "OG2eJmUM94CCKl8SiFU2MAHURrbFWQJmqwnrkeVPSw533_yRjAL-SlrxogonJpsl", + "y": "suMc0ckI46jPlM0dn7O_4fIpxFAD74LrkOUO_tEKeHD1opEoK7H2iE-1STzjflEm" + } + }, + "encrypted_key": "sAN-AeA0ZtInrhJYtzkNnWooDmXOOYo4mD1hMps8aV2Iw84GheOuMw" + } + ], + "aad": "jgz9Cgt6lep5QPX0-GCkOMXujjRYgfiTslwut8BdX-0", + "iv": "iHzMT8jUCFNsqsZY", + "ciphertext": "IiPn4-09-MFtJggB5yE", + "tag": "Na9kW8Fpw5j4IJ-fdf4jNA" +} +``` + +#### 1.1.3 NIST P-521 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AHrw8TsyZzIkINFPCAS54Y7UoCI1XAlim95ROPykpjo4q2LvW_VWeBtJLU2SuqTFG4WX9VBzMg5Rq4gMj4oCpMFb", + "y": "AUs4vywsYYuRP0LhFvyI_ippvSY6Tv1S8sEzojd41Ubo86bFlCj5c_wHX2N6hplMU01WAcebPWc24plqF39pkNrK", + "d": "AEklgm76AbNl_nydbcINMgytfoZGRMI1mxfGcIiqw-KHENQMtlujImJrKMUd32njHS1M9e-WqAS8AHLoVdBZmkOo" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `9Miv3vUT2vQL0X80PyrLJm3bzGPuc_aKfPr4txRQIpA` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AcJh1U3InkhEW5uvh9x3H_ZkzSRY9aoleTYH0a_ZgVKhGrQrttUgQhzvdj8Oyy389Muu0l5slkKfE_FpNXUoSlq8", + "y": "AB8lDC62GR8b7lz_mboFcrBG4uAWNqQ-E-k4tYqBu8xJOV-v68FeuJKwC9WGFOiIUaCwSGUB4-cYeFPIxq9hxD7Y", + "d": "AXTDpK0Eu6EEZliWHe-zgiY1s23sTepAgmP8KeVTOXeeCnCL12pK4mc-UR9NpEYrxBp_A5srbhzNR5x7mZ1G4kLf" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `l4-wvmALQDp4g-UpilwCHmLZ_zUGfNawYSWQMoLphIk` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "AA63cinH0aZ7e0sLBFx0s3MKQTfvdFjSMVMQHpp5qIF6pWaxV9TrqXkJYkR2fuMqvIRSlH5mMK73kNfEubrvsd7H", + "y": "AY88QmJlRbAbCY9UyeDK0pYFHbSxgdMCauV2GC-W2w5uJekAWoeO9KxSY215W60whRHGRctrTc7LodcV8y7UKOyx", + "d": "AU4kFJPY9rZA89-ZYvoZX_qKPglplaWZdFKU3ZzjZvNt7rBBUuKumsf_khTFF8q-LxJKd11B0rng3PIQRuob4JW-" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `Ev1dKdei9chrjW2-l4bjdXXF5GDZ7CqTcQlGg1W_U24` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `9Miv3vUT2vQL0X80PyrLJm3bzGPuc_aKfPr4txRQIpA.Ev1dKdei9chrjW2-l4bjdXXF5GDZ7CqTcQlGg1W_U24.l4-wvmALQDp4g-UpilwCHmLZ_zUGfNawYSWQMoLphIk` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `uLMTdeuniYvCFTQTamK0pZwFVgkJooGL37HZLm8PVkM` +- JWE: +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "QWNnNWlNaUNjNkozMFg5R3lrTXl4R0dobFFrXzFhRlhJTDQ1cF9DT2l3ODVscFVyR1BOSnNKTVRrdTRHYnlMdndlam9jVHp5ZVZjMUxrX1RWa3o0UmZ4YQ", + "apv": "OU1pdjN2VVQydlFMMFg4MFB5ckxKbTNiekdQdWNfYUtmUHI0dHhSUUlwQQ", + "kid": "9Miv3vUT2vQL0X80PyrLJm3bzGPuc_aKfPr4txRQIpA", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "Acg5iMiCc6J30X9GykMyxGGhlQk_1aFXIL45p_COiw85lpUrGPNJsJMTku4GbyLvwejocTzyeVc1Lk_TVkz4Rfxa", + "y": "AQgFgsVvOfebXZFk8TiBAJef9h6sVpQSJXed0xG3IolDYIllQ_OyQdlFpKHl2xCjgVxRihdf7mS_3SCzEtrcjEzy" + } + }, + "encrypted_key": "juXV2ZGX2MjF1FgjTWke3MTkODrdpqZ_k-5IVqZ568bvN12i8W_KaQ" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "QVJLTGZTNWVoeUlacV9UWmJpbXdESndpYVBsckNMU2RqdG9aVFJSeTl0QVZQelQxbnlub1BYRWZIOHNNNklucDVKdWhvc3BHSVMxQzkzSk01Z1RkNzRtaQ", + "apv": "OU1pdjN2VVQydlFMMFg4MFB5ckxKbTNiekdQdWNfYUtmUHI0dHhSUUlwQQ", + "kid": "l4-wvmALQDp4g-UpilwCHmLZ_zUGfNawYSWQMoLphIk", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "ARKLfS5ehyIZq_TZbimwDJwiaPlrCLSdjtoZTRRy9tAVPzT1nynoPXEfH8sM6Inp5JuhospGIS1C93JM5gTd74mi", + "y": "Ad5hB3rVVxTqvSsiN7NNbClumX-AWTV6r29CHz2Jbcgo5tunFz-5-CwP6EvQNkFrzrOxQ5ViOW5F3pYV-yoksLgO" + } + }, + "encrypted_key": "H-B3FBmwlGFIEtdfWti6tD8LwtuokxxPam5XO3V7wwWNoJ5sEy-LlA" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "QWRTZUxrVWxadHpXRkNDODBvNVYtYTB3Mjl3MjM2OWtLRXlPbUtiQzItVlV4ZEo0OVdBUV9rTVhTempNaE1ON1VMc25mT3pEWFp1QkhwZUVRTU1zbWF5VA", + "apv": "OU1pdjN2VVQydlFMMFg4MFB5ckxKbTNiekdQdWNfYUtmUHI0dHhSUUlwQQ", + "kid": "Ev1dKdei9chrjW2-l4bjdXXF5GDZ7CqTcQlGg1W_U24", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AdSeLkUlZtzWFCC80o5V-a0w29w2369kKEyOmKbC2-VUxdJ49WAQ_kMXSzjMhMN7ULsnfOzDXZuBHpeEQMMsmayT", + "y": "AJKQo494spZjUW85ika3qNyLJJiv_J3FpsYnZt-Ml3q8IqXlHqQV_Nl3s7yn_pq8RWXl_yvo1NPiDWpoDMZ3sUNw" + } + }, + "encrypted_key": "53dtd9R0bbGK96jsPJRu2woQJC7-yBaN-xDw5xSp-pwpCKg1idnZ5w" + } + ], + "aad": "uLMTdeuniYvCFTQTamK0pZwFVgkJooGL37HZLm8PVkM", + "iv": "11_dMZoXv9OaPIR2", + "ciphertext": "ofWv6sUZdYF3rX9A-jQ", + "tag": "TyH-Abl3XTGlkUgjHCE-Vw" +} +``` + +#### 1.1.4 X25519 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "2kvTqkwVF-YSurN533fi-ZDF4PbLbqa7ohC--DJa0nA", + "d": "sPUMndizynb_q6_u9fkbuU8V3I062-RlL114YnJ7KWY" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `eFf9x4K6jhnmAEvveQJo5rIQl32rZooOaNwlJsLf5JQ` +- Recipient 2 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "cb-5cmxUy7xCfQCz0pEjYOGJOp0nf3cH7TU6siQ49wU", + "d": "oCw27m5T-QPr48F_f-CRWWqFgtFxpPISExMhSYQJmF8" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `NaUTcaFDyI3Ss48zMmeg1Dal0vhUpOYpWdwfKd2T2S8` +- Recipient 3 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "pW_fX347OhGgYURSvuM5-NSKw7CgHzCuOZt5ovQCa3E", + "d": "sEZYN-iNbQ22ds1fC_hYgrp7PKbzAtiHqxPhvzon9HE" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `hzSul1PikxGRl7k_QdDfCCRMZP4POmt5eNYN0pbjSzE` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `NaUTcaFDyI3Ss48zMmeg1Dal0vhUpOYpWdwfKd2T2S8.eFf9x4K6jhnmAEvveQJo5rIQl32rZooOaNwlJsLf5JQ.hzSul1PikxGRl7k_QdDfCCRMZP4POmt5eNYN0pbjSzE` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `7iRNh25gyaA9Bpnx7axAbyyvbh-bXaPOz8SgvgGksNc` +- JWE: +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "Q21aM1gzRFBnZFdQWjRKZFF4VVNMSjBKaEtRRXpJZWphV2cxT04tSE13WQ", + "apv": "ZUZmOXg0SzZqaG5tQUV2dmVRSm81cklRbDMyclpvb09hTndsSnNMZjVKUQ", + "kid": "eFf9x4K6jhnmAEvveQJo5rIQl32rZooOaNwlJsLf5JQ", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "CmZ3X3DPgdWPZ4JdQxUSLJ0JhKQEzIejaWg1ON-HMwY" + } + }, + "encrypted_key": "ZFibn07y4G88HTB6haGfKJLQGWi2a25UVlioG93hgjs2BDIRaWRqzw" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "cU9MdWVjZmdaamJkOVRQYV9qbG5CeFAyak9FQjdOVkZKaGZ6UEk1OFNWOA", + "apv": "ZUZmOXg0SzZqaG5tQUV2dmVRSm81cklRbDMyclpvb09hTndsSnNMZjVKUQ", + "kid": "NaUTcaFDyI3Ss48zMmeg1Dal0vhUpOYpWdwfKd2T2S8", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "qOLuecfgZjbd9TPa_jlnBxP2jOEB7NVFJhfzPI58SV8" + } + }, + "encrypted_key": "EKpcwck9zE0WjEq9E60dm_OJY0U2e1UlUAZE8LYfURo_saE2yzxx_A" + }, + { + "header": { + "alg": "ECDH-ES+A256KW", + "apu": "RE1IOGFVVlpUZ2FXaFNaOUFtdFNDQ2M1aUZEbERCeDZnMC1URHpUTFZYUQ", + "apv": "ZUZmOXg0SzZqaG5tQUV2dmVRSm81cklRbDMyclpvb09hTndsSnNMZjVKUQ", + "kid": "hzSul1PikxGRl7k_QdDfCCRMZP4POmt5eNYN0pbjSzE", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "DMH8aUVZTgaWhSZ9AmtSCCc5iFDlDBx6g0-TDzTLVXQ" + } + }, + "encrypted_key": "OeemM4fMI9538IcvG3OwhuVtugrRIoIJEB5iAVZBl7Q59yRr5VZTPQ" + } + ], + "aad": "7iRNh25gyaA9Bpnx7axAbyyvbh-bXaPOz8SgvgGksNc", + "iv": "9deRACZyiau7rIIc", + "ciphertext": "ombMWgwtw2QSfALdiDk", + "tag": "yRwaSiGsQCqYjIdMSwPPNg" +} +``` + +### 1.2 Single Recipient JWEs + +Packing a message with 1 recipient using the **Flattened JWE JSON serialization** and **Compact JWE serialization** formats as mentioned in the [notes](#notes) above. + +#### 1.2.1 NIST P-256 key +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "2fpy_fK5FCsap0EbU1Om7QXoVoyvBv8gfdHY3ufIS9w", + "y": "TtVOc9c8ejMeqeaUs1CMS79w0-Al02Fw25WdVEb0DiI", + "d": "kEWLCAyDL8mgDLNnlb1am_B8wcaGAe7ViXx1tqKWTVc" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `s6-ZhI1hpx0kM3pDgOrVQs6mRd_8KfEXUkLg8lK7XNA` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6IlJuY3lOa2RuVkZJME0ycHhORnB4Wm1GUlJqQkxjMk54U2poNlpFeFliMTlyVm0xZlNtRkJVbHBHVlEiLCJhcHYiOiJjell0V21oSk1XaHdlREJyVFROd1JHZFBjbFpSY3padFVtUmZPRXRtUlZoVmEweG5PR3hMTjFoT1FRIiwiY3R5IjoiYXBwbGljYXRpb24vZGlkY29tbS1wbGFpbitqc29uIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6IkZ3MjZHZ1RSNDNqcTRacWZhUUYwS3NjcUo4emRMWG9fa1ZtX0phQVJaRlUiLCJ5IjoiNENfMk00V2dkcVp5cGdkaVVpMlZCQWsyVXFmYlJvU1AxaUQ3WHIzVGJJZyJ9LCJraWQiOiJzNi1aaEkxaHB4MGtNM3BEZ09yVlFzNm1SZF84S2ZFWFVrTGc4bEs3WE5BIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "l99n6MvHGvUKRrPORElnlerqmmhQc1WMzJ2pxt6H5gaSWPPsj4Gp0A", + "iv": "CKm9svwMrrXarfG2", + "ciphertext": "k_eAXa-uMtMYSVgJO0A", + "tag": "1cYhCprkvxYYfyNp_fJGUQ" +} +``` +- The compact serialization of this envelope is: +`eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6IlJuY3lOa2RuVkZJME0ycHhORnB4Wm1GUlJqQkxjMk54U2poNlpFeFliMTlyVm0xZlNtRkJVbHBHVlEiLCJhcHYiOiJjell0V21oSk1XaHdlREJyVFROd1JHZFBjbFpSY3padFVtUmZPRXRtUlZoVmEweG5PR3hMTjFoT1FRIiwiY3R5IjoiYXBwbGljYXRpb24vZGlkY29tbS1wbGFpbitqc29uIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IkZ3MjZHZ1RSNDNqcTRacWZhUUYwS3NjcUo4emRMWG9fa1ZtX0phQVJaRlUiLCJ5IjoiNENfMk00V2dkcVp5cGdkaVVpMlZCQWsyVXFmYlJvU1AxaUQ3WHIzVGJJZyJ9LCJraWQiOiJzNi1aaEkxaHB4MGtNM3BEZ09yVlFzNm1SZF84S2ZFWFVrTGc4bEs3WE5BIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.l99n6MvHGvUKRrPORElnlerqmmhQc1WMzJ2pxt6H5gaSWPPsj4Gp0A.CKm9svwMrrXarfG2.k_eAXa-uMtMYSVgJO0A.1cYhCprkvxYYfyNp_fJGUQ` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+A256KW", + "apu": "RncyNkdnVFI0M2pxNFpxZmFRRjBLc2NxSjh6ZExYb19rVm1fSmFBUlpGVQ", + "apv": "czYtWmhJMWhweDBrTTNwRGdPclZRczZtUmRfOEtmRVhVa0xnOGxLN1hOQQ", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "Fw26GgTR43jq4ZqfaQF0KscqJ8zdLXo_kVm_JaARZFU", + "y": "4C_2M4WgdqZypgdiUi2VBAk2UqfbRoSP1iD7Xr3TbIg" + }, + "kid": "s6-ZhI1hpx0kM3pDgOrVQs6mRd_8KfEXUkLg8lK7XNA", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 1.2.2 NIST P-384 key +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "lb17x-OBz2i1kQbkRtSKD3TY1MwIfUMyM8YtqXZXMj884hLJH2QtxmUWKyXIprcn", + "y": "PlT4CInTrA5zAroqwyww0BL6EipnEBTrtbWID8nADz6LFpf_27qlxIARy_iU5OcN", + "d": "JJgpIqGS5JuiKRnsEgGNlYw39pz-XGrsrmniuxlSik0BLwdb8-0K8Xxuqo6yW6NE" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `8wPpWWlLiMBYltw6AoWG3Z_SfgWmXanBHSwZFpQJ0Q0` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6ImNWSkZUMncwWTI5bmJUUkZhWGd3TURGd04zSXpaREl5U0VaQ2FXcHZOV2hmT1RGRE9HOTNjVU5yU2pSdlZWZzFRemh6ZUdOd00zTlhTMXBEZEZaWU13IiwiYXB2IjoiT0hkUWNGZFhiRXhwVFVKWmJIUjNOa0Z2VjBjeldsOVRabWRYYlZoaGJrSklVM2RhUm5CUlNqQlJNQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsiY3J2IjoiUC0zODQiLCJrdHkiOiJFQyIsIngiOiJxUkVPbDRjb2dtNEVpeDAwMXA3cjNkMjJIRkJpam81aF85MUM4b3dxQ2tKNG9VWDVDOHN4Y3Azc1dLWkN0VlgzIiwieSI6Im5FbmRyZXVPNVFEWFp5eGVmWkJWRDhJeU53WkJER1AwZlJHdXN1LWZXV0NmWlJBdUVsNkZIaXMtSFRNS1puY0UifSwia2lkIjoiOHdQcFdXbExpTUJZbHR3NkFvV0czWl9TZmdXbVhhbkJIU3daRnBRSjBRMCIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ", + "encrypted_key": "OyvZQT0HdCIgDTQKgSbnMfX6iQvPVkOlurgNRqyZlyxj6XeZROYCEQ", + "iv": "sGHLr4VNPKylOCn7", + "ciphertext": "mfnbfoMx8LfXaWSY5po", + "tag": "_FxUsJeY06_bzGJ9vaAtMA" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6ImNWSkZUMncwWTI5bmJUUkZhWGd3TURGd04zSXpaREl5U0VaQ2FXcHZOV2hmT1RGRE9HOTNjVU5yU2pSdlZWZzFRemh6ZUdOd00zTlhTMXBEZEZaWU13IiwiYXB2IjoiT0hkUWNGZFhiRXhwVFVKWmJIUjNOa0Z2VjBjeldsOVRabWRYYlZoaGJrSklVM2RhUm5CUlNqQlJNQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTM4NCIsIngiOiJxUkVPbDRjb2dtNEVpeDAwMXA3cjNkMjJIRkJpam81aF85MUM4b3dxQ2tKNG9VWDVDOHN4Y3Azc1dLWkN0VlgzIiwieSI6Im5FbmRyZXVPNVFEWFp5eGVmWkJWRDhJeU53WkJER1AwZlJHdXN1LWZXV0NmWlJBdUVsNkZIaXMtSFRNS1puY0UifSwia2lkIjoiOHdQcFdXbExpTUJZbHR3NkFvV0czWl9TZmdXbVhhbkJIU3daRnBRSjBRMCIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ.OyvZQT0HdCIgDTQKgSbnMfX6iQvPVkOlurgNRqyZlyxj6XeZROYCEQ.sGHLr4VNPKylOCn7.mfnbfoMx8LfXaWSY5po._FxUsJeY06_bzGJ9vaAtMA` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+A256KW", + "apu": "cVJFT2w0Y29nbTRFaXgwMDFwN3IzZDIySEZCaWpvNWhfOTFDOG93cUNrSjRvVVg1QzhzeGNwM3NXS1pDdFZYMw", + "apv": "OHdQcFdXbExpTUJZbHR3NkFvV0czWl9TZmdXbVhhbkJIU3daRnBRSjBRMA", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "qREOl4cogm4Eix001p7r3d22HFBijo5h_91C8owqCkJ4oUX5C8sxcp3sWKZCtVX3", + "y": "nEndreuO5QDXZyxefZBVD8IyNwZBDGP0fRGusu-fWWCfZRAuEl6FHis-HTMKZncE" + }, + "kid": "8wPpWWlLiMBYltw6AoWG3Z_SfgWmXanBHSwZFpQJ0Q0", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 1.2.3 NIST P-521 key +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AHrw8TsyZzIkINFPCAS54Y7UoCI1XAlim95ROPykpjo4q2LvW_VWeBtJLU2SuqTFG4WX9VBzMg5Rq4gMj4oCpMFb", + "y": "AUs4vywsYYuRP0LhFvyI_ippvSY6Tv1S8sEzojd41Ubo86bFlCj5c_wHX2N6hplMU01WAcebPWc24plqF39pkNrK", + "d": "AEklgm76AbNl_nydbcINMgytfoZGRMI1mxfGcIiqw-KHENQMtlujImJrKMUd32njHS1M9e-WqAS8AHLoVdBZmkOo" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `9Miv3vUT2vQL0X80PyrLJm3bzGPuc_aKfPr4txRQIpAs` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6ImRsRjZWRnBMWTFSS2JqUlROM0Z6Y0dGMFRGVldaR3hSVTB4clQyaDJUV2RuU0ZsaFRUaEZNRzFwZWpFemJtUXphRlEwUVVoR01XUm9WRWRPYTI5M09HUnlTVFZEU200dGRsbHdlbUZYWnkxcVoxSXRhWFEwIiwiYXB2IjoiT1UxcGRqTjJWVlF5ZGxGTU1GZzRNRkI1Y2t4S2JUTmlla2RRZFdOZllVdG1VSEkwZEhoU1VVbHdRUSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsiY3J2IjoiUC01MjEiLCJrdHkiOiJFQyIsIngiOiJBTDBNMDJTbkV5Wi1FdTZyS1dyUzFGWFpVRWk1RG9ieklJQjJHalBCTkpvczlkNTNkNFUtQUJ4ZFhZVXhqWktNUEhheU9RaVpfcjJLYzJsb1BvNEVmb3JlIiwieSI6IkFXSkxvVnNTS0l6SVF2VWtKVzIxakVmV2ZHTjhWck1tN2owSmtJb2JUVXlCSEJMa0o3SzFUU19zZ1FpOUkxb0tzRTJ5Mjh2WC1DREFKZGp3Z1FWNl9mLTIifSwia2lkIjoiOU1pdjN2VVQydlFMMFg4MFB5ckxKbTNiekdQdWNfYUtmUHI0dHhSUUlwQSIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ", + "encrypted_key": "rK_MtxEobFF8pyYU8T26U7LRlEdjm1ndq8sZoZ2h9BaAyuhE7bcuAA", + "iv": "X1V-4vkZ1qE3_Yhn", + "ciphertext": "XDf5mmhlDaJfTOp1z_4", + "tag": "se7e3wH5grcMEuJIAJbN9A" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6ImRsRjZWRnBMWTFSS2JqUlROM0Z6Y0dGMFRGVldaR3hSVTB4clQyaDJUV2RuU0ZsaFRUaEZNRzFwZWpFemJtUXphRlEwUVVoR01XUm9WRWRPYTI5M09HUnlTVFZEU200dGRsbHdlbUZYWnkxcVoxSXRhWFEwIiwiYXB2IjoiT1UxcGRqTjJWVlF5ZGxGTU1GZzRNRkI1Y2t4S2JUTmlla2RRZFdOZllVdG1VSEkwZEhoU1VVbHdRUSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTUyMSIsIngiOiJBTDBNMDJTbkV5Wi1FdTZyS1dyUzFGWFpVRWk1RG9ieklJQjJHalBCTkpvczlkNTNkNFUtQUJ4ZFhZVXhqWktNUEhheU9RaVpfcjJLYzJsb1BvNEVmb3JlIiwieSI6IkFXSkxvVnNTS0l6SVF2VWtKVzIxakVmV2ZHTjhWck1tN2owSmtJb2JUVXlCSEJMa0o3SzFUU19zZ1FpOUkxb0tzRTJ5Mjh2WC1DREFKZGp3Z1FWNl9mLTIifSwia2lkIjoiOU1pdjN2VVQydlFMMFg4MFB5ckxKbTNiekdQdWNfYUtmUHI0dHhSUUlwQSIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ.rK_MtxEobFF8pyYU8T26U7LRlEdjm1ndq8sZoZ2h9BaAyuhE7bcuAA.X1V-4vkZ1qE3_Yhn.XDf5mmhlDaJfTOp1z_4.se7e3wH5grcMEuJIAJbN9A` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+A256KW", + "apu": "dlF6VFpLY1RKbjRTN3FzcGF0TFVWZGxRU0xrT2h2TWdnSFlhTThFMG1pejEzbmQzaFQ0QUhGMWRoVEdOa293OGRySTVDSm4tdllwemFXZy1qZ1ItaXQ0", + "apv": "OU1pdjN2VVQydlFMMFg4MFB5ckxKbTNiekdQdWNfYUtmUHI0dHhSUUlwQQ", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AL0M02SnEyZ-Eu6rKWrS1FXZUEi5DobzIIB2GjPBNJos9d53d4U-ABxdXYUxjZKMPHayOQiZ_r2Kc2loPo4Efore", + "y": "AWJLoVsSKIzIQvUkJW21jEfWfGN8VrMm7j0JkIobTUyBHBLkJ7K1TS_sgQi9I1oKsE2y28vX-CDAJdjwgQV6_f-2" + }, + "kid": "9Miv3vUT2vQL0X80PyrLJm3bzGPuc_aKfPr4txRQIpA", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 1.2.4 X25519 key +- Single Recipient key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "2kvTqkwVF-YSurN533fi-ZDF4PbLbqa7ohC--DJa0nA", + "d": "sPUMndizynb_q6_u9fkbuU8V3I062-RlL114YnJ7KWY" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `eFf9x4K6jhnmAEvveQJo5rIQl32rZooOaNwlJsLf5JQ` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6IlluQldTM1IyVDJoWGJXOVRRMUJTV21oUk1HdFVaVzlYVDNFMWVrMXZTWGxhY0RCMVlrOU9XVTVXZHciLCJhcHYiOiJaVVptT1hnMFN6WnFhRzV0UVVWMmRtVlJTbTgxY2tsUmJETXljbHB2YjA5aFRuZHNTbk5NWmpWS1VRIiwiY3R5IjoiYXBwbGljYXRpb24vZGlkY29tbS1wbGFpbitqc29uIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJjcnYiOiJYMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiYnBWS3R2T2hXbW9TQ1BSWmhRMGtUZW9XT3E1ek1vSXlacDB1Yk9OWU5WdyJ9LCJraWQiOiJlRmY5eDRLNmpobm1BRXZ2ZVFKbzVySVFsMzJyWm9vT2FOd2xKc0xmNUpRIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "Pe7sGWcXxY9V7xdKWdpa5GvVinr_YWITRIVY8ic7WmKwY-Lh-3OJdA", + "iv": "Rx__OGcTo72Lv6jG", + "ciphertext": "UEFI2_OqNMki1cXraJA", + "tag": "Hc6WxwF2YGvewcWFmhzkrw" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImFwdSI6IlluQldTM1IyVDJoWGJXOVRRMUJTV21oUk1HdFVaVzlYVDNFMWVrMXZTWGxhY0RCMVlrOU9XVTVXZHciLCJhcHYiOiJaVVptT1hnMFN6WnFhRzV0UVVWMmRtVlJTbTgxY2tsUmJETXljbHB2YjA5aFRuZHNTbk5NWmpWS1VRIiwiY3R5IjoiYXBwbGljYXRpb24vZGlkY29tbS1wbGFpbitqc29uIiwiZW5jIjoiQTI1NkdDTSIsImVwayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ4IjoiYnBWS3R2T2hXbW9TQ1BSWmhRMGtUZW9XT3E1ek1vSXlacDB1Yk9OWU5WdyJ9LCJraWQiOiJlRmY5eDRLNmpobm1BRXZ2ZVFKbzVySVFsMzJyWm9vT2FOd2xKc0xmNUpRIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.Pe7sGWcXxY9V7xdKWdpa5GvVinr_YWITRIVY8ic7WmKwY-Lh-3OJdA.Rx__OGcTo72Lv6jG.UEFI2_OqNMki1cXraJA.Hc6WxwF2YGvewcWFmhzkrw` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+A256KW", + "apu": "YnBWS3R2T2hXbW9TQ1BSWmhRMGtUZW9XT3E1ek1vSXlacDB1Yk9OWU5Wdw", + "apv": "ZUZmOXg0SzZqaG5tQUV2dmVRSm81cklRbDMyclpvb09hTndsSnNMZjVKUQ", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "bpVKtvOhWmoSCPRZhQ0kTeoWOq5zMoIyZp0ubONYNVw" + }, + "kid": "eFf9x4K6jhnmAEvveQJo5rIQl32rZooOaNwlJsLf5JQ", + "typ": "application/didcomm-encrypted+json" +} +``` + +## 2 XC20P content encryption + +### 2.1 Multi recipients JWEs + +The packer generates the following protected headers for XC20P content encryption in the below examples with XC20P enc: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"XC20P","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ` + +The same [notes](#notes) above apply here. + +#### 2.1.1 NIST P-256 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "kdAHozUe6HOhNC9_jsOI60FuHa64zHSwcZa0l22rXX4", + "y": "Sj3iIz_HimnXgLRWU-x_gXjVyF2R0rh6OhuD3gzhUMw", + "d": "NTV27xYkYkwDNYePKHlh6CIYHunx-6rn80cSATOI7rI" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `Ivxk0K5tz7csR7MDXllXWd7YJTQF4pS8IHHkIdepgpk` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "sx1ZNsP2rUKuoN0Xe6m2_Zly8wM_-CpuCkDNaOjFYtA", + "y": "lTti40XRekPxw4IfpheZDCxilwEoEWWxyO8d77W_sOo", + "d": "WsHT1GiMy4mxsxQ7mPYtg5Mn18I8PU2wHPttVGEOnXk" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `tkAt85t250uQ3Q3d8W731YJfqF0t1cCwGwWqRxqyQhM` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "AQoZIqg1y0fZ1qvYM5YuinxRtOXa6dMSXfgdYBgsEks", + "y": "JRxsX-U6go0VqWtMFCPFbUNSsLJYiQH7ij2i4-FVQh0", + "d": "Joal2Lk5w6-_C_HpRr__ZtxtJccwjwHZ7RxZe1-CTjY" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `SoySkmiLdE4c7Dp5URlH-DMVNq6-fGrkSpIgzLTYez0` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `Ivxk0K5tz7csR7MDXllXWd7YJTQF4pS8IHHkIdepgpk.SoySkmiLdE4c7Dp5URlH-DMVNq6-fGrkSpIgzLTYez0.tkAt85t250uQ3Q3d8W731YJfqF0t1cCwGwWqRxqyQhM` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `uPokzMsXWxloZTnb2sXzz05KBc_SI1giMmHAenTyMjQ` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "R1NNbnFqcGFQMlltUlRNRTVrNVhYT3E2M3FzZjd2emVtbnY5NENVTm9faw", + "apv": "SXZ4azBLNXR6N2NzUjdNRFhsbFhXZDdZSlRRRjRwUzhJSEhrSWRlcGdwaw", + "kid": "Ivxk0K5tz7csR7MDXllXWd7YJTQF4pS8IHHkIdepgpk", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "GSMnqjpaP2YmRTME5k5XXOq63qsf7vzemnv94CUNo_k", + "y": "tDCIMv5gZqyjZmHYvbHxUQO1zN7fH0n9athoWGlO8nI" + } + }, + "encrypted_key": "n63_NKMEy_KOb_34nrTX_Yvbx3Sliee9yh3ZSqs6nm5vhAuCoBMoU40fSpZMB07QLdXKfrRjB4A-WoL_MjTpcpOZnxc1v2s-" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "N1ZNVG00NEFqc0J3amt6WU1STDk5SURRZUh6aWZaa0Q5Q0hSajJJdGtkOA", + "apv": "SXZ4azBLNXR6N2NzUjdNRFhsbFhXZDdZSlRRRjRwUzhJSEhrSWRlcGdwaw", + "kid": "tkAt85t250uQ3Q3d8W731YJfqF0t1cCwGwWqRxqyQhM", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "7VMTm44AjsBwjkzYMRL99IDQeHzifZkD9CHRj2Itkd8", + "y": "NnVWH1gP7qdqzv4Go-1lT_U02i6fJHhmZO33jt4R0Ys" + } + }, + "encrypted_key": "V3Y_kLiogDKAa4p3MNyfh1IOfexv8rLJsZf5idwI2wJDngYzhNyzaV4kqJMMW6qyMaE4bX5LY-qRP4sPcYPwntMj70LUaC6I" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "NzJQTnJ4a1A2V3JCcV9wUkU4VU42T0I3WHFKUXJuZEZHZ3dERVloR21kdw", + "apv": "SXZ4azBLNXR6N2NzUjdNRFhsbFhXZDdZSlRRRjRwUzhJSEhrSWRlcGdwaw", + "kid": "SoySkmiLdE4c7Dp5URlH-DMVNq6-fGrkSpIgzLTYez0", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "72PNrxkP6WrBq_pRE8UN6OB7XqJQrndFGgwDEYhGmdw", + "y": "gDy2dRBTwt1tQBBSnztN0AqvzCu07yFN9FgG109ytsc" + } + }, + "encrypted_key": "2b4op-H7wPoyzno3Krv65rOal2HNmaiDHnjGTywcHAppz-EgHS7hiqANeRCipCNhPj7VvZqe1PWf2m0qLIdBuUv7ryo_nw9E" + } + ], + "aad": "uPokzMsXWxloZTnb2sXzz05KBc_SI1giMmHAenTyMjQ", + "iv": "KShKEagQokU3UTGeYXw7LwWFankH-zK7", + "ciphertext": "6Z5YKgYQSmxSCtns064", + "tag": "hhW1Y5WgRM2t8-NiUMmKJw" +} +``` + +#### 2.1.2 NIST P-384 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "5aCpGZXwubdOSedZl1wc5PHB175a990-bRo2QKzju6uyeXD6hBKcB6vUijQRILMr", + "y": "TeUA_qsYU8YmbHPA58QJuAJiUe0BEbi8Vuq88ZEWLudhJa4Dp5mBKuFEeJQcOQCa", + "d": "wTv7Yh4bZAfCfmz0qL_lKJNlMRYuXjWzE63p7y3mZW8DRtN5LgOE25QKO9v0xgKN" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `35E0yg0TinUSym5bQ5FnUgWirIrfK81p-QCxW7VzCrE` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "xYFotAHw0kaqsgkW-3ZirL2p3HC0tJCrrNsK-1MfgoUahWpoDiUpEapuLZrO_hz3", + "y": "LLUQ5gRSwn5x0sQJrByWSdWdqojAhizpsx9GPjvPP9uM4gv7jKUEoi0A-2doNSQR", + "d": "OLPQ8giwvg-pKMMaYTGB3O4RGNPtlX-tRZi3ltUb305nPMsuxplI71OQfTH3-Leq" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `wnJRuK09BydTKCPX9DEsf2hxSB1uzHdHrjLTtsiPUZw` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "DWdQi5HdkPpUEqHtQrLU8xR6hW3_IO-8RPcOY4_aI0VACCO9e8WNCFAcjAja5Q8Y", + "y": "jTan4mkzX1uRU9FRIvZgE1NKS-fUe86cl_xmLJ2jPl-A-EXmTHExVT8q63iVnvSC", + "d": "WnCGfWiiOCglkYWQh1t-KM_A8Pb_HXgUXEJFjg7iWT3SYUL2tgMQQ5w9IUNE-D0r" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `j9ZMlUQX9m9t8_6RmshAfMwHTIOE9_0Mv5bd5bQ4nKw` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `35E0yg0TinUSym5bQ5FnUgWirIrfK81p-QCxW7VzCrE.j9ZMlUQX9m9t8_6RmshAfMwHTIOE9_0Mv5bd5bQ4nKw.wnJRuK09BydTKCPX9DEsf2hxSB1uzHdHrjLTtsiPUZw` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `kOd8LfamiqCqZa4kZJPR0M3k11OjHo1dQgdgaI2HreU` +- JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "Zmw3NTdwRFlKVE16YlcwVmdfUWgzTDlrZlRoQ25Dd25uaU81YlBmVkwwUFgxV19LbWpfRzVIT2VDV2NyMEdacQ", + "apv": "MzVFMHlnMFRpblVTeW01YlE1Rm5VZ1dpcklyZks4MXAtUUN4VzdWekNyRQ", + "kid": "35E0yg0TinUSym5bQ5FnUgWirIrfK81p-QCxW7VzCrE", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "fl757pDYJTMzbW0Vg_Qh3L9kfThCnCwnniO5bPfVL0PX1W_Kmj_G5HOeCWcr0GZq", + "y": "moRQSUo5C95n_W5H79i_HWYAIcpmX9Iq2OcuBRe4R9pXmW_p1_dbz7YKSXbJLpEo" + } + }, + "encrypted_key": "fb6sCiAeFzPcfvHdIMKm051fkVioxgBKA6w3sIkw9t_mleCHe_bjFzK9_CfMA6E0aO8Y40WonGWYZ8oKIgRvItNWJsph6zr9" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "ZlcyRHFxR25SaFZHOXlKckN2TWZVRmJlR1RZRl9JWjJYQ1pPcGNvei1vSDJ2aVlERU54Wi1leGJ6c0l1bkoyNQ", + "apv": "MzVFMHlnMFRpblVTeW01YlE1Rm5VZ1dpcklyZks4MXAtUUN4VzdWekNyRQ", + "kid": "wnJRuK09BydTKCPX9DEsf2hxSB1uzHdHrjLTtsiPUZw", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "fW2DqqGnRhVG9yJrCvMfUFbeGTYF_IZ2XCZOpcoz-oH2viYDENxZ-exbzsIunJ25", + "y": "Pz-1Smflo-dAFZ0awotLqF0Qh5iurbbgcCJpN5ZnrrvBlnxiKuAD6o4ytxMS17f1" + } + }, + "encrypted_key": "gGqdDnlCuymQYRwIIHU0Cv4BxUYpby8cjohgbfNc-3kilzLIXN0x53amLz6sxuFvvGjPMv7BykQfoQPZgXj5B5rN--3StojC" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "MTY0dUFMYXVkNmFLR29EMjF0NHd2dGN3QjRxUGNNRFlid3JWemVvY055Q05RelV1NlRTSVFEcExiT3pmMjJIeQ", + "apv": "MzVFMHlnMFRpblVTeW01YlE1Rm5VZ1dpcklyZks4MXAtUUN4VzdWekNyRQ", + "kid": "j9ZMlUQX9m9t8_6RmshAfMwHTIOE9_0Mv5bd5bQ4nKw", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "164uALaud6aKGoD21t4wvtcwB4qPcMDYbwrVzeocNyCNQzUu6TSIQDpLbOzf22Hy", + "y": "SmS8y6E1V87EkDIQfZVJGdyWPRR5gSQXIhNKUF4vDB1OYcMtG4AGFhHlMVNjCipa" + } + }, + "encrypted_key": "ADkTont7J6MvkqtejyCZroaLhzBq6ehDlNJyiIsoV2L-vKOYWPfW2eyhk9_Q_Kc2mdfhsJeZ6S4YN2O1OVSvnGqho3zwKE_z" + } + ], + "aad": "kOd8LfamiqCqZa4kZJPR0M3k11OjHo1dQgdgaI2HreU", + "iv": "lhR0KWdWpo2TeiHgABGNLMYwGXmykQQX", + "ciphertext": "LMVb7K1-YqLUS9JtE0s", + "tag": "7UkWuQPffiWZIwS4sUc1Hg" +} +``` + +#### 2.1.3 NIST P-521 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AIlOiZCrQMU83IOpoiMva75L_OqljXVakEJSjwAl5RaLmaNBZg-TXa0VKlAKTijGZAu_5gS_ZF82LRWDiltUHmX8", + "y": "AFXxgSPOlCNnHtRQE7JmngrT5jgc5kHhMJE82wvMYlyrUdB1kgjN8zJDKkMDJ_dw1U2bEKXmcoCepN654HqmCeNJ", + "d": "ASUBEC_crwIW50ke7p7EBjM0jnA3X7ziwT92TIVgHqTyFkEHKwuP_xbUSePfkhAgcEF2KHz48EgZJuDM6v4L2NXT" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `fr_FYdKBgF_lo1UzC133Tw382LhNDRk6TqwWUwYiytQ` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AT71NCmSChOaf38XudcZFpb7eS6GS3rRgjIeXC5AWm9uqjgk3XloPINvlOkATR9syfonjONi4dvgu6ED0gDKyni2", + "y": "AB6EuKG0Z5mnkw_Kk08EW1igFDoZ8tUzs67AoRrLM_CqufmehumGUBAAgPPyQ43HdZQRKn6UYaRn77JZ0kcUE8ZD", + "d": "AMYS0X7aTtbFL8gcSH8h0AkH1kfgJxqe-vyahUoijuM3WtKp0z7C0j-kT717p8xV4NEnIrP7IP9ewCdh21TwCfdJ" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `z70hxN-69UU6IBsqxWMsKa5LqSnCGhd0BKMihYIeHYM` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AcRZHKNmVZlxrKIcBsX-Z8KaGCJfPirBqOBWDylsVJCwvjEEMfJFS2GZtPwfQI5P561XAxjtb0ARPtucoyh5n4_Q", + "y": "AaU8wdiQUItNWJnDrgMK84HhyloKQyXWEYZoDEjppL4kXvIV4CUhfYkTXnTWACUgnVG1uXdycmJ-XhgqPGfezQVb", + "d": "AKfdXHWLY7WqaVVVLFBRyU7fd3EpfiQJW83IkuCk4tJ51PIO6Jzq17H0RI9XjK1YThz-cV1ZBXw9Q7ezDFusgL3k" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `bU2CyYAuV1kJtU8vTE27PaOh20yTgKBSThtjrYHedf8` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `bU2CyYAuV1kJtU8vTE27PaOh20yTgKBSThtjrYHedf8.fr_FYdKBgF_lo1UzC133Tw382LhNDRk6TqwWUwYiytQ.z70hxN-69UU6IBsqxWMsKa5LqSnCGhd0BKMihYIeHYM` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `gyaNc9X50RymOfupxfij36JjhkUG4SEiI4P8LQ0JCvI` +- JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "QVdYTV9BOVF2WUZnUFYwMTRmUzk5LUNvX2dyS3BTZi1xbTJmeDdYRFpzekJrT2V3ZHlOSUp5S1gteFdQUUM1RWcwc0gtR0VnTGNWNXNRZThrNktuQWZYeA", + "apv": "ZnJfRllkS0JnRl9sbzFVekMxMzNUdzM4MkxoTkRSazZUcXdXVXdZaXl0UQ", + "kid": "fr_FYdKBgF_lo1UzC133Tw382LhNDRk6TqwWUwYiytQ", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AWXM_A9QvYFgPV014fS99-Co_grKpSf-qm2fx7XDZszBkOewdyNIJyKX-xWPQC5Eg0sH-GEgLcV5sQe8k6KnAfXx", + "y": "ANlcV5mvTqpzGF8loKsBjC_UFkfg260SFwrabuTBn_4oi1l5wKx7yootfvqrgGG1ivbuMIZ4NndJsbreyUywddQS" + } + }, + "encrypted_key": "SkZaMkjfoo-0PPQvWXottqV3dwOhcY7rCDckVkPRlxbj8jb_m4veIu-nx8jnkJMLUVqguKD_JhZ78MRAEikPg-gARUKyVRKV" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "SElkUWNuaGluTUhhaEw1eDNsUGYxZWlrbW13NUFxNE9SSUpwTFhiQVV4NVJZbjF2dFVSeld4UHc0aU9nY1FOWjJCbEZVU21Md0FaUmhvdlFfb2J1MmZr", + "apv": "ZnJfRllkS0JnRl9sbzFVekMxMzNUdzM4MkxoTkRSazZUcXdXVXdZaXl0UQ", + "kid": "z70hxN-69UU6IBsqxWMsKa5LqSnCGhd0BKMihYIeHYM", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AByHUHJ4YpzB2oS-cd5T39XopJpsOQKuDkSCaS12wFMeUWJ9b7VEc1sT8OIjoHEDWdgZRVEpi8AGUYaL0P6G7tn5", + "y": "AFbfZdEiMwMy4rN0hzMl3XQgBpE98gE8A37bLLLZi-wAbyuNBhhGCWjxc2XSCRTn9IxBSV72Q8lttaIPWTRGsJPZ" + } + }, + "encrypted_key": "qgNULlqzY68vVzd07nuuuCSqDewr1mu45xhzCFriEdYNvoFmGl_elZua6r0gyknDsskbLOM_zAhg86Ieafn87YT-jOKZWXvB" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "QWNJU1U1bVJwemJrYUs5TUs0ZVNHWXFBNFo5TFVwOF8yNHkwUnhmazExby1GazNvazZCUzk2X3REeWlfM0Y0bDhDU3VyanA3bUxhMGp4YVJ6M1NZbDRRMw", + "apv": "ZnJfRllkS0JnRl9sbzFVekMxMzNUdzM4MkxoTkRSazZUcXdXVXdZaXl0UQ", + "kid": "bU2CyYAuV1kJtU8vTE27PaOh20yTgKBSThtjrYHedf8", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AcISU5mRpzbkaK9MK4eSGYqA4Z9LUp8_24y0Rxfk11o-Fk3ok6BS96_tDyi_3F4l8CSurjp7mLa0jxaRz3SYl4Q3", + "y": "AYfx95SYdTrF5-FFJ6DX8YIQ3-kI3zA2huvwAoE5on4tczuZtRDxAnXocVXwydU_hYFICv4F1_U2wf2MZxu5EjgO" + } + }, + "encrypted_key": "N38f1rvfk00bHCRbAkMajaCmwIM6C96QNs5ck5i6EhoyONADKitu1E7FpMtwA7IBkLZXSPAz_2RRQg_yp494uh5unNgeIAsm" + } + ], + "aad": "gyaNc9X50RymOfupxfij36JjhkUG4SEiI4P8LQ0JCvI", + "iv": "y3t1nlPy-e5KlPZmhH6yvXweEnB50cW9", + "ciphertext": "twYiHmEUk1QZw-XbLbY", + "tag": "WsYbX9YDCcIAorqBbS2X_w" +} +``` + +#### 2.1.4 X25519 keys +- Recipient 1 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "h5iIEBNlEHEhCgYLXAOXOofqYEA9Jo0Q1NUggjdwrVw", + "d": "oEGk3DVSpzrZR6mcUF0EXmijrATej7xnPdlcPJDz53M" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `S-qQ_rRIsrscxdmzuplVLW5bqoxj08KO6BBkLZAxh-E` +- Recipient 2 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "xawtbSFE5QYe7KDcYRBlnyozY9uPTzlRQ3gClzHzt2Q", + "d": "yC7gzjKFdFwsCA4x7QL0S-eRhI2H966MjTdNA8IrMFw" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `m8EQ2XejsBRZ8sieSLapsS4-tO9ZQNjjxtjL6DOhP64` +- Recipient 3 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "cvxZ6JaCIfmrTXiyHYNyqmxRSsUF8TEabuWOcZdgLT0", + "d": "IM-XG4jc_Zyd5yWdv1i7vruFK4X2LzNTRicHvPZNznU" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `oz3AtqUGnNpsT6OugQksyvY52HI36kCBtXqLE4joP3M` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `S-qQ_rRIsrscxdmzuplVLW5bqoxj08KO6BBkLZAxh-E.m8EQ2XejsBRZ8sieSLapsS4-tO9ZQNjjxtjL6DOhP64.oz3AtqUGnNpsT6OugQksyvY52HI36kCBtXqLE4joP3M` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `Iri2F6uTNldPiiJNYNrlVb_Nt_c2XlPVdDKfmlnkBn4` +- JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInR5cCI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tZW5jcnlwdGVkK2pzb24ifQ", + "recipients": [ + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "eE9ZYmZrX0VLbmJaQmRoU1lPclI3NFVWWmlqZFU3LWg3ZF9aTkJ4VW1rMA", + "apv": "Uy1xUV9yUklzcnNjeGRtenVwbFZMVzVicW94ajA4S082QkJrTFpBeGgtRQ", + "kid": "S-qQ_rRIsrscxdmzuplVLW5bqoxj08KO6BBkLZAxh-E", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "xOYbfk_EKnbZBdhSYOrR74UVZijdU7-h7d_ZNBxUmk0" + } + }, + "encrypted_key": "gPbf9-YZLPoEoKmaU70H8O9fsKiPy8rNiNuAvKog4AhGfy1axF4LuMdAZgO4EixyS4WC9V6JnfaYxmt3tFiCx80YXZrVlTBO" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "eU9MMUM0blZzTzRTa1ROWDVRTlVCVl9iVmhJeVd1ZGdKOTlkRWdURDl5cw", + "apv": "Uy1xUV9yUklzcnNjeGRtenVwbFZMVzVicW94ajA4S082QkJrTFpBeGgtRQ", + "kid": "m8EQ2XejsBRZ8sieSLapsS4-tO9ZQNjjxtjL6DOhP64", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "yOL1C4nVsO4SkTNX5QNUBV_bVhIyWudgJ99dEgTD9ys" + } + }, + "encrypted_key": "dsWHHkRbT9BWdgBl5MAUgNTenqiEjR4Z2cgaOLaraCDezRb051Z_muMo70-yJx1O9YDwLHq2V87dKQJX-byYtBeIR-5BubLm" + }, + { + "header": { + "alg": "ECDH-ES+XC20PKW", + "apu": "RkdtN2t4aGJFNGVBLWJpM1l2WTZPNVBCd2YtTlhEZ29YaWwzS19zLW5tSQ", + "apv": "Uy1xUV9yUklzcnNjeGRtenVwbFZMVzVicW94ajA4S082QkJrTFpBeGgtRQ", + "kid": "oz3AtqUGnNpsT6OugQksyvY52HI36kCBtXqLE4joP3M", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "FGm7kxhbE4eA-bi3YvY6O5PBwf-NXDgoXil3K_s-nmI" + } + }, + "encrypted_key": "sEygr10dbgwHRy8-ktu8jLcACTKD1g7LfEkUSV_mAZNr1P06RhijZTRq47xesJuPWF8lfkAsK-UETLJ92KGRmbgCdSHQQwaG" + } + ], + "aad": "Iri2F6uTNldPiiJNYNrlVb_Nt_c2XlPVdDKfmlnkBn4", + "iv": "MWxpdCQBhVoiskZF7QD3bLzgI-iBEE3O", + "ciphertext": "FtAX4yKH2a2dZqM6Zdk", + "tag": "lR8OsOJieRydzSvI-qpy5w" +} +``` + +### 2.2 Single Recipient JWEs + +Packing a message with 1 recipient using the **Flattened JWE JSON serialization** and the **Compact JWE serialization** formats as mentioned in the [notes](#notes) above. + +#### 2.2.1 NIST P-256 key +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "kdAHozUe6HOhNC9_jsOI60FuHa64zHSwcZa0l22rXX4", + "y": "Sj3iIz_HimnXgLRWU-x_gXjVyF2R0rh6OhuD3gzhUMw", + "d": "NTV27xYkYkwDNYePKHlh6CIYHunx-6rn80cSATOI7rI" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `Ivxk0K5tz7csR7MDXllXWd7YJTQF4pS8IHHkIdepgpk` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJUWEl4TnpCM2JqSTJXa00wY0Y5SFVDMTBNazlyVFd0ZmExOVJVRkYxY1hObk5IUlFNV0pMU0hCdk1BIiwiYXB2IjoiU1haNGF6QkxOWFI2TjJOelVqZE5SRmhzYkZoWFpEZFpTbFJSUmpSd1V6aEpTRWhyU1dSbGNHZHdhdyIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IlhDMjBQIiwiZXBrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiTXIxNzB3bjI2WkM0cF9HUC10Mk9rTWtfa19RUFF1cXNnNHRQMWJLSHBvMCIsInkiOiJ1MUMydEJuYlFwUS1YTWx0SHRFdWNJaFVod1FCeDBCbklLZFlkN3FLRVFFIn0sImtpZCI6Ikl2eGswSzV0ejdjc1I3TURYbGxYV2Q3WUpUUUY0cFM4SUhIa0lkZXBncGsiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "encrypted_key": "1k4IQgN6LIiV8mnNWUI2OyNXLRHvg75qZIyHf6_wtrBIYZlic1coUL3lekvesQpmLb1A9vip-pKi0yDKZOQIMtQS3TJ81EJJ", + "iv": "6Qky6FL-Uzpi5nvaZHobo3_8xqv-LF4h", + "ciphertext": "mqQ6nsR76RMLvNLkJgU", + "tag": "5S99fa_S2c4XsVrzM2rPDw" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJUWEl4TnpCM2JqSTJXa00wY0Y5SFVDMTBNazlyVFd0ZmExOVJVRkYxY1hObk5IUlFNV0pMU0hCdk1BIiwiYXB2IjoiU1haNGF6QkxOWFI2TjJOelVqZE5SRmhzYkZoWFpEZFpTbFJSUmpSd1V6aEpTRWhyU1dSbGNHZHdhdyIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IlhDMjBQIiwiZXBrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiTXIxNzB3bjI2WkM0cF9HUC10Mk9rTWtfa19RUFF1cXNnNHRQMWJLSHBvMCIsInkiOiJ1MUMydEJuYlFwUS1YTWx0SHRFdWNJaFVod1FCeDBCbklLZFlkN3FLRVFFIn0sImtpZCI6Ikl2eGswSzV0ejdjc1I3TURYbGxYV2Q3WUpUUUY0cFM4SUhIa0lkZXBncGsiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0.1k4IQgN6LIiV8mnNWUI2OyNXLRHvg75qZIyHf6_wtrBIYZlic1coUL3lekvesQpmLb1A9vip-pKi0yDKZOQIMtQS3TJ81EJJ.6Qky6FL-Uzpi5nvaZHobo3_8xqv-LF4h.mqQ6nsR76RMLvNLkJgU.5S99fa_S2c4XsVrzM2rPDw` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+XC20PKW", + "apu": "TXIxNzB3bjI2WkM0cF9HUC10Mk9rTWtfa19RUFF1cXNnNHRQMWJLSHBvMA", + "apv": "SXZ4azBLNXR6N2NzUjdNRFhsbFhXZDdZSlRRRjRwUzhJSEhrSWRlcGdwaw", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "Mr170wn26ZC4p_GP-t2OkMk_k_QPQuqsg4tP1bKHpo0", + "y": "u1C2tBnbQpQ-XMltHtEucIhUhwQBx0BnIKdYd7qKEQE" + }, + "kid": "Ivxk0K5tz7csR7MDXllXWd7YJTQF4pS8IHHkIdepgpk", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 2.2.2 NIST P-384 key +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "5aCpGZXwubdOSedZl1wc5PHB175a990-bRo2QKzju6uyeXD6hBKcB6vUijQRILMr", + "y": "TeUA_qsYU8YmbHPA58QJuAJiUe0BEbi8Vuq88ZEWLudhJa4Dp5mBKuFEeJQcOQCa", + "d": "wTv7Yh4bZAfCfmz0qL_lKJNlMRYuXjWzE63p7y3mZW8DRtN5LgOE25QKO9v0xgKN" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `35E0yg0TinUSym5bQ5FnUgWirIrfK81p-QCxW7VzCrE` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJkbkJCYkVKc1pXUXlWM0YzTUY5VVNYTk1iM1JLVmpBek4ydzNOMmxDYzA5Mk0xRnhiSEZSVWxaSGNHeGZkRWR2UVc5VFNXRnpVR0kwY0RjeGFIVTBiUSIsImFwdiI6Ik16VkZNSGxuTUZScGJsVlRlVzAxWWxFMVJtNVZaMWRwY2tseVprczRNWEF0VVVONFZ6ZFdla055UlEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJjcnYiOiJQLTM4NCIsImt0eSI6IkVDIiwieCI6InZwQWxCbGVkMldxdzBfVElzTG90SlYwMzdsNzdpQnNPdjNRcWxxUVJWR3BsX3RHb0FvU0lhc1BiNHA3MWh1NG0iLCJ5IjoiU0Y3VEJDVnB5dTUwQ21vMzY0TWsyS2VyWGVwYnlYSklXZF8yTHNYMnNDMENWTkV1aFVJUHhFMmQtVjFVS1hwciJ9LCJraWQiOiIzNUUweWcwVGluVVN5bTViUTVGblVnV2lySXJmSzgxcC1RQ3hXN1Z6Q3JFIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "y7jUbtMzOyerWyPhTgTutFH0r18Ug6uF3FYdTCyp2V-PacHeR8OTsNEh7dEOQk9o5P9mXvcGvfGr2xFNtoBw561TPv_Iw2ZK", + "iv": "DOEADxox8cUL0jQ_H4hP67ymgscn8nQc", + "ciphertext": "hSjiRkcMflJJK18cuXU", + "tag": "SHN2rmcofMmnSqQ8htiCcQ" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJkbkJCYkVKc1pXUXlWM0YzTUY5VVNYTk1iM1JLVmpBek4ydzNOMmxDYzA5Mk0xRnhiSEZSVWxaSGNHeGZkRWR2UVc5VFNXRnpVR0kwY0RjeGFIVTBiUSIsImFwdiI6Ik16VkZNSGxuTUZScGJsVlRlVzAxWWxFMVJtNVZaMWRwY2tseVprczRNWEF0VVVONFZ6ZFdla055UlEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6InZwQWxCbGVkMldxdzBfVElzTG90SlYwMzdsNzdpQnNPdjNRcWxxUVJWR3BsX3RHb0FvU0lhc1BiNHA3MWh1NG0iLCJ5IjoiU0Y3VEJDVnB5dTUwQ21vMzY0TWsyS2VyWGVwYnlYSklXZF8yTHNYMnNDMENWTkV1aFVJUHhFMmQtVjFVS1hwciJ9LCJraWQiOiIzNUUweWcwVGluVVN5bTViUTVGblVnV2lySXJmSzgxcC1RQ3hXN1Z6Q3JFIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.y7jUbtMzOyerWyPhTgTutFH0r18Ug6uF3FYdTCyp2V-PacHeR8OTsNEh7dEOQk9o5P9mXvcGvfGr2xFNtoBw561TPv_Iw2ZK.DOEADxox8cUL0jQ_H4hP67ymgscn8nQc.hSjiRkcMflJJK18cuXU.SHN2rmcofMmnSqQ8htiCcQ` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+XC20PKW", + "apu": "dnBBbEJsZWQyV3F3MF9USXNMb3RKVjAzN2w3N2lCc092M1FxbHFRUlZHcGxfdEdvQW9TSWFzUGI0cDcxaHU0bQ", + "apv": "MzVFMHlnMFRpblVTeW01YlE1Rm5VZ1dpcklyZks4MXAtUUN4VzdWekNyRQ", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "vpAlBled2Wqw0_TIsLotJV037l77iBsOv3QqlqQRVGpl_tGoAoSIasPb4p71hu4m", + "y": "SF7TBCVpyu50Cmo364Mk2KerXepbyXJIWd_2LsX2sC0CVNEuhUIPxE2d-V1UKXpr" + }, + "kid": "35E0yg0TinUSym5bQ5FnUgWirIrfK81p-QCxW7VzCrE", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 2.2.3 NIST P-521 key +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AIlOiZCrQMU83IOpoiMva75L_OqljXVakEJSjwAl5RaLmaNBZg-TXa0VKlAKTijGZAu_5gS_ZF82LRWDiltUHmX8", + "y": "AFXxgSPOlCNnHtRQE7JmngrT5jgc5kHhMJE82wvMYlyrUdB1kgjN8zJDKkMDJ_dw1U2bEKXmcoCepN654HqmCeNJ", + "d": "ASUBEC_crwIW50ke7p7EBjM0jnA3X7ziwT92TIVgHqTyFkEHKwuP_xbUSePfkhAgcEF2KHz48EgZJuDM6v4L2NXT" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `fr_FYdKBgF_lo1UzC133Tw382LhNDRk6TqwWUwYiytQ` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJOa3hhTFd0bGNtczNTWEYzV1hCeE5FOUpYemt0U2tGSGEyMVZUVEl0ZDB0a1VtUlhUV1JxY2sxNlV6ZDVRelpuVTFnMFdHOVJWM0ZRZEdWRE1UTjVTWGxXY2tKVGNuWlJOWGhSZGtVNFVEQllOVTA1UW1GQiIsImFwdiI6IlpuSmZSbGxrUzBKblJsOXNiekZWZWtNeE16TlVkek00TWt4b1RrUlNhelpVY1hkWFZYZFphWGwwVVEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJjcnYiOiJQLTUyMSIsImt0eSI6IkVDIiwieCI6IkFPaTJmcEhxNU95S3NHS2F1RGlQX2ZpUUJwSmxETnZzQ25VWFZqSFk2ek0wdThndW9FbC1GNkVGcWo3WGd0ZDhpTWxhd1VxNzBPY1VMeFBEOUYtVFBRV2ciLCJ5IjoiQUVDX1VwU2poQzZlYnplSlBUc0JSb1YwNG9GdzZleDFRRzVpQW1OMm9hWVA3RVAtbU1YcEJRc2R3SEsyVFhpb1d5Q3ozZEU4d0JLUmZkcHFEaHdrRzFSaiJ9LCJraWQiOiJmcl9GWWRLQmdGX2xvMVV6QzEzM1R3MzgyTGhORFJrNlRxd1dVd1lpeXRRIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "bsghnB_jpcD8E7k1Q2lEizymrCDatLiMH5w9MmWtP6PkpQuonoXXoLk0T-qmC3hK7pEBHdji9YKxPT2NQ-2x7F1Tzf-juieh", + "iv": "SFKS4kMCTfU0tjUfn0YGh79rSWX9RGkP", + "ciphertext": "Fg9hiOjUvP3WU5c0tco", + "tag": "QJ2jlC_o-UiUvpFo7OF0Ew" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJOa3hhTFd0bGNtczNTWEYzV1hCeE5FOUpYemt0U2tGSGEyMVZUVEl0ZDB0a1VtUlhUV1JxY2sxNlV6ZDVRelpuVTFnMFdHOVJWM0ZRZEdWRE1UTjVTWGxXY2tKVGNuWlJOWGhSZGtVNFVEQllOVTA1UW1GQiIsImFwdiI6IlpuSmZSbGxrUzBKblJsOXNiekZWZWtNeE16TlVkek00TWt4b1RrUlNhelpVY1hkWFZYZFphWGwwVVEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtNTIxIiwieCI6IkFPaTJmcEhxNU95S3NHS2F1RGlQX2ZpUUJwSmxETnZzQ25VWFZqSFk2ek0wdThndW9FbC1GNkVGcWo3WGd0ZDhpTWxhd1VxNzBPY1VMeFBEOUYtVFBRV2ciLCJ5IjoiQUVDX1VwU2poQzZlYnplSlBUc0JSb1YwNG9GdzZleDFRRzVpQW1OMm9hWVA3RVAtbU1YcEJRc2R3SEsyVFhpb1d5Q3ozZEU4d0JLUmZkcHFEaHdrRzFSaiJ9LCJraWQiOiJmcl9GWWRLQmdGX2xvMVV6QzEzM1R3MzgyTGhORFJrNlRxd1dVd1lpeXRRIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.bsghnB_jpcD8E7k1Q2lEizymrCDatLiMH5w9MmWtP6PkpQuonoXXoLk0T-qmC3hK7pEBHdji9YKxPT2NQ-2x7F1Tzf-juieh.SFKS4kMCTfU0tjUfn0YGh79rSWX9RGkP.Fg9hiOjUvP3WU5c0tco.QJ2jlC_o-UiUvpFo7OF0Ew` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+XC20PKW", + "apu": "NkxaLWtlcms3SXF3WXBxNE9JXzktSkFHa21VTTItd0tkUmRXTWRqck16Uzd5QzZnU1g0WG9RV3FQdGVDMTN5SXlWckJTcnZRNXhRdkU4UDBYNU05QmFB", + "apv": "ZnJfRllkS0JnRl9sbzFVekMxMzNUdzM4MkxoTkRSazZUcXdXVXdZaXl0UQ", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AOi2fpHq5OyKsGKauDiP_fiQBpJlDNvsCnUXVjHY6zM0u8guoEl-F6EFqj7Xgtd8iMlawUq70OcULxPD9F-TPQWg", + "y": "AEC_UpSjhC6ebzeJPTsBRoV04oFw6ex1QG5iAmN2oaYP7EP-mMXpBQsdwHK2TXioWyCz3dE8wBKRfdpqDhwkG1Rj" + }, + "kid": "fr_FYdKBgF_lo1UzC133Tw382LhNDRk6TqwWUwYiytQ", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 2.2.4 X25519 key +- Single Recipient key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "h5iIEBNlEHEhCgYLXAOXOofqYEA9Jo0Q1NUggjdwrVw", + "d": "oEGk3DVSpzrZR6mcUF0EXmijrATej7xnPdlcPJDz53M" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `S-qQ_rRIsrscxdmzuplVLW5bqoxj08KO6BBkLZAxh-E` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJjR1JKV1dNMlNVRm9SMnN3Unpsd1VHOUxPR1ZpYWtzM1QzbEpWMDlTV25oSVdsQm9hRmhWTWxoR1RRIiwiYXB2IjoiVXkxeFVWOXlVa2x6Y25OamVHUnRlblZ3YkZaTVZ6VmljVzk0YWpBNFMwODJRa0pyVEZwQmVHZ3RSUSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IlhDMjBQIiwiZXBrIjp7ImNydiI6IlgyNTUxOSIsImt0eSI6Ik9LUCIsIngiOiJwZElZYzZJQWhHazBHOXBQb0s4ZWJqSzdPeUlXT1JaeEhaUGhoWFUyWEZNIn0sImtpZCI6IlMtcVFfclJJc3JzY3hkbXp1cGxWTFc1YnFveGowOEtPNkJCa0xaQXhoLUUiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "encrypted_key": "VmgHr9mZuwN1dxRqd0B9n2yE4ErM14Mhri5XpYL93UVT5ZLGkUPKMG1-hdvLDhCUUdfJg5ronQke1HnOKcLgEgEO2Uh-jNHY", + "iv": "M7A2POrqH_lcXV_fwYgYGp3any_9sKFt", + "ciphertext": "gPNQD52uPxlA2881Ct4", + "tag": "JHq2fnYwqUYc3hUgUWaMsw" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILUVTK1hDMjBQS1ciLCJhcHUiOiJjR1JKV1dNMlNVRm9SMnN3Unpsd1VHOUxPR1ZpYWtzM1QzbEpWMDlTV25oSVdsQm9hRmhWTWxoR1RRIiwiYXB2IjoiVXkxeFVWOXlVa2x6Y25OamVHUnRlblZ3YkZaTVZ6VmljVzk0YWpBNFMwODJRa0pyVEZwQmVHZ3RSUSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IlhDMjBQIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6IlgyNTUxOSIsIngiOiJwZElZYzZJQWhHazBHOXBQb0s4ZWJqSzdPeUlXT1JaeEhaUGhoWFUyWEZNIn0sImtpZCI6IlMtcVFfclJJc3JzY3hkbXp1cGxWTFc1YnFveGowOEtPNkJCa0xaQXhoLUUiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0.VmgHr9mZuwN1dxRqd0B9n2yE4ErM14Mhri5XpYL93UVT5ZLGkUPKMG1-hdvLDhCUUdfJg5ronQke1HnOKcLgEgEO2Uh-jNHY.M7A2POrqH_lcXV_fwYgYGp3any_9sKFt.gPNQD52uPxlA2881Ct4.JHq2fnYwqUYc3hUgUWaMsw` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-ES+XC20PKW", + "apu": "cGRJWWM2SUFoR2swRzlwUG9LOGViaks3T3lJV09SWnhIWlBoaFhVMlhGTQ", + "apv": "Uy1xUV9yUklzcnNjeGRtenVwbFZMVzVicW94ajA4S082QkJrTFpBeGgtRQ", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "pdIYc6IAhGk0G9pPoK8ebjK7OyIWORZxHZPhhXU2XFM" + }, + "kid": "S-qQ_rRIsrscxdmzuplVLW5bqoxj08KO6BBkLZAxh-E", + "typ": "application/didcomm-encrypted+json" +} +``` diff --git a/features/0334-jwe-envelope/authcrypt-examples.md b/features/0334-jwe-envelope/authcrypt-examples.md new file mode 100644 index 000000000..c908ff2aa --- /dev/null +++ b/features/0334-jwe-envelope/authcrypt-examples.md @@ -0,0 +1,1347 @@ +Table of Contents +================= + +* [Authcrypt JWE Concrete examples](#authcrypt-jwe-concrete-examples) + * [Notes](#notes) + * [1 A256GCM Content Encryption](#1-a256gcm-content-encryption) + * [1.1 Multi recipients JWEs](#11-multi-recipients-jwes) + * [1.1.1 NIST P-256 keys](#111-nist-p-256-keys) + * [1.1.2 NIST P-384 keys](#112-nist-p-384-keys) + * [1.1.3 NIST P-521 keys](#113-nist-p-521-keys) + * [1.1.4 X25519 keys](#114-x25519-keys) + * [1.2 Single Recipient JWEs](#12-single-recipient-jwes) + * [1.2.1 NIST P-256 key](#121-nist-p-256-key) + * [1.2.2 NIST P-384 key](#122-nist-p-384-key) + * [1.2.3 NIST P-521 key](#123-nist-p-521-key) + * [1.2.4 X25519 key](#124-x25519-key) + * [2 XC20P content encryption](#2-xc20p-content-encryption) + * [2.1 Multi recipients JWEs](#21-multi-recipients-jwes) + * [2.1.1 NIST P-256 keys](#211-nist-p-256-keys) + * [2.1.2 NIST P-384 keys](#212-nist-p-384-keys) + * [2.1.3 NIST P-521 keys](#213-nist-p-521-keys) + * [2.1.4 X25519 keys](#214-x25519-keys) + * [2.2 Single Recipient JWEs](#22-single-recipient-jwes) + * [2.2.1 NIST P-256 key](#221-nist-p-256-key) + * [2.2.2 NIST P-384 key](#222-nist-p-384-key) + * [2.2.3 NIST P-521 key](#223-nist-p-521-key) + * [2.2.4 X25519 key](#224-x25519-key) + +Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc) + +# Authcrypt JWE Concrete examples + +The following examples are for JWE **authcrypt** packer for encrypting the payload `secret message` and aad value set as the concatenation of recipients' KIDs (ASCII sorted) joined by `.` for non-compact serializations (JWE Compact serializations [don't have AAD](https://tools.ietf.org/html/rfc7516#section-7.1)). + +#### Notes +- Since **autchrypt** requires the sender public key, it must be previously sent, out of band, to the recipient(s). For security reasons, the JWE envelope only includes the sender kid as `skid` in the protected headers. The recipient must be able to resolve the corresponding sender public key during unpack(JWE). +- all `x` and `y` key coordinates values below are raw (no padding) base64URL encoded. +- JWE envelopes with multi recipients use the [General JWE JSON Serialization](https://tools.ietf.org/html/rfc7516#section-7.2.1) format. +- JWE envelopes with a single recipient will be shown either as [JWE Compact](https://tools.ietf.org/html/rfc7516#section-3.1) or [Flattened JWE JSON](https://tools.ietf.org/html/rfc7516#section-7.2.2) serialization format. +- **General** JWE JSON Serialization format uses the above mentioned AAD value in their envelope. +- JWE **Compact** Serialization format does not support AAD values and therefore were built without it. +- all `apu` recipient header values are set with the raw (no padding) base64URL encoding of the corresponding sender's `kid` (`skid`) value since authcrypt reveals the sender. +- all `apv` recipient header values are set with the raw (no padding) base64URL encoding of the corresponding recipient's `kid` value. +- The final aad used to encrypt the payload is the concatenation of the raw (no padding) base64URL encoded protected headers and `aad` JWE header joined by a `.`. +- Even though flattened serialization do support `aad`, the field is omitted in the below examples to be consistent with compact JWE serialization format. Implementations should support `aad` for flattened serialization regardless. + +## 1 A256GCM Content Encryption + +### 1.1 Multi recipients JWEs + +#### 1.1.1 NIST P-256 keys + +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"A256GCM","skid":"6PBTUbcLB7-Z4fuAFn42oC1PaMsNmjheq1FeZEUgV_8","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6IjZQQlRVYmNMQjctWjRmdUFGbjQyb0MxUGFNc05tamhlcTFGZVpFVWdWXzgiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0` + +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "eFRTD4VaryfwIqLOpq7iuXmBbLjKPq5sVNzxwL7H1CI", + "y": "cIeogn-pLJXlCepb9BqwNKKW4tmNea3Is8G47aPob6M", + "d": "11NyNGrw4JoU7-_bwoZlVDTJi5vkMrSs4Nme_OHnx6Q" +} +``` +- Sender kid (aka `skid`, jwk thumbprint raw base64 URL encoded): `6PBTUbcLB7-Z4fuAFn42oC1PaMsNmjheq1FeZEUgV_8` +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "UP08dxIWu14HWRCI48Tnohm7jhaJ87fFdvYyf0w4lkg", + "y": "ohZVfvhQViMGb_n-Y66TewBO2gtE_udG_DsNe8c-T8w", + "d": "O0ikvlb4fh7daJpqd9JIgYk5e-twB0IYyKpoqmb7ZCc" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `D_kHovGtLUZ_ssw_vhZcqsx3LvQ6qC5JK74iPf9vqwk` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "XgkWXrogHmvx-wee7KAhi-eP6dpoyUcDKn224vpOshw", + "y": "MAfbXLDMUOg6749jT0nDPZZIxfeozhdaKW6s3hutGHE", + "d": "WIKKCdNWrddYbOtkOxHLfETps1cEBHsPhqGtQPxaLho" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `pXCqiUJ-A6Zlp6LAvkBWLOXPMuww5Hy_PljoODMsGTw` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "xdS1ON9UCKA3s7yOv55fvlegYR5GsLPbOZWi_zsFyEM", + "y": "yeE__UlC9wEIbnCPjoOZa-nD2CN0uHtau7edhcmJiOg", + "d": "Dry6DWrItSzhXS_ep5bvoWHkJEhKKJU-VTkFmNxZ7PI" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `4CB-2PhtYR9WfjsFNb4rmvSmJozJAL4gRCg_am3oDhw` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `4CB-2PhtYR9WfjsFNb4rmvSmJozJAL4gRCg_am3oDhw.D_kHovGtLUZ_ssw_vhZcqsx3LvQ6qC5JK74iPf9vqwk.pXCqiUJ-A6Zlp6LAvkBWLOXPMuww5Hy_PljoODMsGTw` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `vo7O9me-lVJv6Y_vjz-rL8eWaa0Xy1WHm2IOsR_UEpk` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6IjZQQlRVYmNMQjctWjRmdUFGbjQyb0MxUGFNc05tamhlcTFGZVpFVWdWXzgiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "NlBCVFViY0xCNy1aNGZ1QUZuNDJvQzFQYU1zTm1qaGVxMUZlWkVVZ1ZfOA", + "apv": "RF9rSG92R3RMVVpfc3N3X3ZoWmNxc3gzTHZRNnFDNUpLNzRpUGY5dnF3aw", + "kid": "D_kHovGtLUZ_ssw_vhZcqsx3LvQ6qC5JK74iPf9vqwk", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "Vpj5VtHxMt5Xz3vnKA727nTMmJd4zbVcPmKjSyHvLvc", + "y": "C7ZLlNCTduhf2qMXjrY907-OdMw_6ixC3UttKCVqgjk" + } + }, + "encrypted_key": "lIm78Z0OmYR5Jc5D416xjb9K3rkmcOgaEFVut4WyNDueoTnM9B86Ug" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "NlBCVFViY0xCNy1aNGZ1QUZuNDJvQzFQYU1zTm1qaGVxMUZlWkVVZ1ZfOA", + "apv": "RF9rSG92R3RMVVpfc3N3X3ZoWmNxc3gzTHZRNnFDNUpLNzRpUGY5dnF3aw", + "kid": "pXCqiUJ-A6Zlp6LAvkBWLOXPMuww5Hy_PljoODMsGTw", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "wDD9G8UK-I246qp6-A1qBPr6N2yX6nTfYb9Zotf898o", + "y": "KIW0m4mOlWzwnW9y1R9314keHj5W8b7eqUs_dT3LBEw" + } + }, + "encrypted_key": "BjZsq3DwuggMu1YhSZIX7NydPNSIBOfHWVBEZ9t5yDzlt1am_LI8cg" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "NlBCVFViY0xCNy1aNGZ1QUZuNDJvQzFQYU1zTm1qaGVxMUZlWkVVZ1ZfOA", + "apv": "RF9rSG92R3RMVVpfc3N3X3ZoWmNxc3gzTHZRNnFDNUpLNzRpUGY5dnF3aw", + "kid": "4CB-2PhtYR9WfjsFNb4rmvSmJozJAL4gRCg_am3oDhw", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "CHaH39lqKhUQLcrmbL_sVBmVZQaLlDxNGI1WkcCB7ss", + "y": "R36X6eJ2dwPz8T7eto0Uije3KLOGAwzLUVUKWj0SxHk" + } + }, + "encrypted_key": "YnLT86bjwgz4SsKUUiG6bf0AybQywN8k2wHa_E3hGLP3Nwo23CyekQ" + } + ], + "aad": "vo7O9me-lVJv6Y_vjz-rL8eWaa0Xy1WHm2IOsR_UEpk", + "iv": "mwMiQc4m9LaoqnIC", + "ciphertext": "wQGUFlLz9fHpDoACWEQ", + "tag": "Ma9X6kppUNUp5SYH74zXDw" +} +``` + +#### 1.1.2 NIST P-384 keys +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"A256GCM","skid":"0Bz8yRwu9eC8Gi7cYOwAKMJ8jysInhAtwH8k8m9MX04","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6IjBCejh5Und1OWVDOEdpN2NZT3dBS01KOGp5c0luaEF0d0g4azhtOU1YMDQiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0` +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "UW1LtMXuZdFS0gyp0_F19uxHqECvCcJA7SmeeuRSSc_PQfsbZWXt5L0KyLYpNIQb", + "y": "FBdPcUvanB7igwkX0NN5rOvH3OKZ1gQHhcad7cCy6QNYKKz7lBWUUOmzypee31pS", + "d": "wrXW0wsFKjvpTWqOAd1mohRublQs4P014-U4_K-eTRFmzhkyLJqNn91dH_AHUc4-" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `0Bz8yRwu9eC8Gi7cYOwAKMJ8jysInhAtwH8k8m9MX04` +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "k3W_RR59uUG3HFlhhqNNmBDyFdMtWHxKAsJaxLBqQgQer3d3aAN-lfdxzGnHtwj1", + "y": "VMSy5zxFEGaGRINailLTUH6NlP0JO2qu0j0_UbS7Ng1b8JkzHDnDbjGgsLqVJaMM", + "d": "iM5K8uqNvFYJnuToMDBguGwUIlu1erT-K0g7NYtJrQnHZOumS8yIC4MCNC60Ch91" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `obCHRLVDx634Cax_Kr3B8fd_-xj5kAj0r0Kvvvmq1z8` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "W3iUHCzh_PWzUKONKeHwIKcjWNN--c7OlL2H23lV13C9tlkqOleFUmioW-AeitEk", + "y": "CIzVD6KsuDLyKQPm0r62LPZikkT2kiXJpLjcVO3op2kgePQkZ31xniKE0VbUBnTH", + "d": "V_vQwOqHVCGxSjX_dN8H5VXvOGYDRTGI00mNXwB0I0mKDd8kqCJmNtGlf-eUrbub" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `PfuTIXG60dvOwnFOfMxJ0i59_L7vqNytROX_bLRR-3M` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "bsX8qtEtj5IDLp9iDUKlgdu_3nluupFtFBrfIK1nza1bGZQRlZ3JG3PdBzVAoePz", + "y": "QX_2v0BHloNS7iWoB4CcO9UWHdtirMVmbNcB8ZGczCJOfUyjYcQxGr0RU_tGkFC4", + "d": "rQ-4ZmWn09CsCqRQJhpQhDeUZXeZ3cy_Pei-fchVPFTa2FnAzvjwEF2Nsm2f3MmR" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `VTVlkyBsoW4ey0sh7TMJBErLGeBeKQsOttFRrXD6eqI` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `PfuTIXG60dvOwnFOfMxJ0i59_L7vqNytROX_bLRR-3M.VTVlkyBsoW4ey0sh7TMJBErLGeBeKQsOttFRrXD6eqI.obCHRLVDx634Cax_Kr3B8fd_-xj5kAj0r0Kvvvmq1z8` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `m72Q9j28hFk0imbFVzqY4KfTE77L8itJoX75N3hwiwA` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6IjBCejh5Und1OWVDOEdpN2NZT3dBS01KOGp5c0luaEF0d0g4azhtOU1YMDQiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "MEJ6OHlSd3U5ZUM4R2k3Y1lPd0FLTUo4anlzSW5oQXR3SDhrOG05TVgwNA", + "apv": "b2JDSFJMVkR4NjM0Q2F4X0tyM0I4ZmRfLXhqNWtBajByMEt2dnZtcTF6OA", + "kid": "obCHRLVDx634Cax_Kr3B8fd_-xj5kAj0r0Kvvvmq1z8", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "cjJHtV4VkMCww9ig94-_4e4yMfo2WI4Rh4dZh6NkYFvz-EGylA7RLSO5TRC-JJ_G", + "y": "RJe2QisAYpfuTWTV6KVeoLGshsJqYokbcSUqdMxrFGXSp4ZMNrW4yj410Xsn6hy6" + } + }, + "encrypted_key": "o0ZZ_xNtmUPcpQAK3kzjOLp8xWBJ31tr-ORQjXtwpqgTuvM_nvhk_w" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "MEJ6OHlSd3U5ZUM4R2k3Y1lPd0FLTUo4anlzSW5oQXR3SDhrOG05TVgwNA", + "apv": "b2JDSFJMVkR4NjM0Q2F4X0tyM0I4ZmRfLXhqNWtBajByMEt2dnZtcTF6OA", + "kid": "PfuTIXG60dvOwnFOfMxJ0i59_L7vqNytROX_bLRR-3M", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "u1HYhdUJGx49J6wSLYM_JLHTkJrkR7wMSm5uYZMH7ZpcC3qF8MUyKTuKN0FGCBcN", + "y": "K-XI-KAGd2jHebNq44yQrDA6Ubs5M99mIlre0chzI13bSLDOuUG4RJ8yjYjXysWF" + } + }, + "encrypted_key": "iCV1_peiRwnsrrBQWmp7GOd-taee-Yk8t6XqJCZPGziglDpGBu_ZhA" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "MEJ6OHlSd3U5ZUM4R2k3Y1lPd0FLTUo4anlzSW5oQXR3SDhrOG05TVgwNA", + "apv": "b2JDSFJMVkR4NjM0Q2F4X0tyM0I4ZmRfLXhqNWtBajByMEt2dnZtcTF6OA", + "kid": "VTVlkyBsoW4ey0sh7TMJBErLGeBeKQsOttFRrXD6eqI", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "Twps_QU6ShP18uQFNCcdOx9sU9YrHBznNnSbhQD474tLUcnslq5Trubq3ogp-LTX", + "y": "oSES1a5xve9e-lKQ3NMN5_CW9Sii9rTorqUMggDzodLsRGm0Jud3HAy2-uE956Xq" + } + }, + "encrypted_key": "dLDKyXeZJDcB_i1Tnn_EUxqCc2ukneaummXF_FwcbpnMH8B0eVizvA" + } + ], + "aad": "m72Q9j28hFk0imbFVzqY4KfTE77L8itJoX75N3hwiwA", + "iv": "nuuuri2fyNl3jBo6", + "ciphertext": "DCWevJuEo5dx-MmqPvw", + "tag": "Pyt1S_Smg9Pnd1u_5Z7nbA" +} +``` + +#### 1.1.3 NIST P-521 keys +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"A256GCM","skid":"oq-WBIGQm-iHiNRj6nId4-E1QtY8exzp8C56SziUfeU","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6Im9xLVdCSUdRbS1pSGlOUmo2bklkNC1FMVF0WThleHpwOEM1NlN6aVVmZVUiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0` +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AXKDGPnD6hlQIre8aEeu33bQffkfl-eQfQXgzNXQX7XFYt5GKA1N6w4-f0_Ci7fQNKGkQuCoAu5-6CNk9M_cHiDi", + "y": "Ae4-APhoZAmM99MdY9io9IZA43dN7dA006wlFb6LJ9bcusJOi5R-o3o3FhCjt5KTv_JxYbo6KU4PsBwQ1eeKyJ0U", + "d": "AP9l2wmQ85P5XD84CkEQVWHaX_46EDvHxLWHEKsHFSQYjEh6BDSuyy1TUNv68v8kpbLCDjvsBc3cIBqC4_T1r4pU" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `oq-WBIGQm-iHiNRj6nId4-E1QtY8exzp8C56SziUfeU` +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "ALmUHkd9Gi2NApJojNzzA34Qdd1-KLnq6jd2UJ9wl-xJzTQ2leg8qi3-hrFs7NqNfxqO6vE5bBoWYFeAcf3LqJOU", + "y": "AN-MutmkAXGzlgzSQJRnctHDcjQQNpRek-8BeqyUDXdZKNGKSMEAzw6Hnl3VdvsvihQfrxcajpx5PSnwxbbdakHq", + "d": "AKv-YbKdI6y8NRMP-e17-RjZyRTfGf0Xh9Og5g7q7aq0xS2mO59ttIJ67XHW5SPTBQDbltdUcydKroWNUIGvhKNv" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `wax1T_hGUvM0NmlbFJi2RizQ_gWajumI5j0Hx7CbgAw` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "ALmUHkd9Gi2NApJojNzzA34Qdd1-KLnq6jd2UJ9wl-xJzTQ2leg8qi3-hrFs7NqNfxqO6vE5bBoWYFeAcf3LqJOU", + "y": "AN-MutmkAXGzlgzSQJRnctHDcjQQNpRek-8BeqyUDXdZKNGKSMEAzw6Hnl3VdvsvihQfrxcajpx5PSnwxbbdakHq", + "d": "AKv-YbKdI6y8NRMP-e17-RjZyRTfGf0Xh9Og5g7q7aq0xS2mO59ttIJ67XHW5SPTBQDbltdUcydKroWNUIGvhKNv" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `XmLVV-CqMkTGQIe6-KecWZWtZVwORTMP2y5aqMPV7P4` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AHCbpo-299Q0Fk71CtBoPu-40-Z0UOu4cGZfgtHHwcu3ciMWVR8IWF4bgvFpAPfKG8Dqx7JJWO8uEgLE67A7aQOL", + "y": "AQ_JBjS3lt8zz3njFhUoJwEdSJMyrSfGPCLpaWkKuRo25k3im-7IjY8T43gvzZXYwV3PKKR3iJ1jnQCrYmfRrmva", + "d": "ACgCw3U3eWTYD5vcygoOpoGPost9TojYJH9FllyRuqwlS3L8dkZu7vKhFyoEg6Bo8AqcOUj5Mtgxhd6Wu02YvqK3" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `pRJtTY7V1pClPu8WEgEZonzaHq3K0El9Vcb8qmjucSg` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `S8s7FFL7f0fUMXt93WOWC-3PJrV1iuAmB_ZlCDyjXqs.XmLVV-CqMkTGQIe6-KecWZWtZVwORTMP2y5aqMPV7P4.pRJtTY7V1pClPu8WEgEZonzaHq3K0El9Vcb8qmjucSg` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `tOS8nLSCERw2V9WOZVo6cenGuM4DJvHse1dsvTk8_As` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6Im9xLVdCSUdRbS1pSGlOUmo2bklkNC1FMVF0WThleHpwOEM1NlN6aVVmZVUiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "b3EtV0JJR1FtLWlIaU5SajZuSWQ0LUUxUXRZOGV4enA4QzU2U3ppVWZlVQ", + "apv": "WG1MVlYtQ3FNa1RHUUllNi1LZWNXWld0WlZ3T1JUTVAyeTVhcU1QVjdQNA", + "kid": "XmLVV-CqMkTGQIe6-KecWZWtZVwORTMP2y5aqMPV7P4", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AP630J9yi2UFBfRWKucXB8eu9-SSKbbbD1fzFhLgbI3xTRTRNMGm-U5EGHbplMLsOfP2pNxtAgo2-d6abiZiD6gg", + "y": "AE1Grtp1iFvySLN4yHVvE0kYWChqVfkO_kHEMujjL6vVu_AAOvl3aogquLv1zgduitCPbKRTno89r3rv0L0Kuj0M" + } + }, + "encrypted_key": "FSYpXFfgPlSfj91VFQ4zAs0Wb3CEpWcBcGeW4nld9szVfb_WRbqTtA" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "b3EtV0JJR1FtLWlIaU5SajZuSWQ0LUUxUXRZOGV4enA4QzU2U3ppVWZlVQ", + "apv": "WG1MVlYtQ3FNa1RHUUllNi1LZWNXWld0WlZ3T1JUTVAyeTVhcU1QVjdQNA", + "kid": "S8s7FFL7f0fUMXt93WOWC-3PJrV1iuAmB_ZlCDyjXqs", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "Acw0XM1IZl63ltysb-ivw8zBhZ-Wz54SaXM_vGGea8Sa5w6VWdZflp1tibzHkfu4novFFpNbKtnCKi-28AqQnOYZ", + "y": "AajoBj0KMrlaIA17RKnShFNzIb1S81oLYZu5MXzAg-XvT8_q83dXajOCiYJLo3taUvHTlcPjkHMG3_8442DgWpU_" + } + }, + "encrypted_key": "3ct4awH6xyp9BjA74Q_j6ot6F32okEYXbS2e6NIkiAgs-JGyEPWoxw" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "b3EtV0JJR1FtLWlIaU5SajZuSWQ0LUUxUXRZOGV4enA4QzU2U3ppVWZlVQ", + "apv": "WG1MVlYtQ3FNa1RHUUllNi1LZWNXWld0WlZ3T1JUTVAyeTVhcU1QVjdQNA", + "kid": "pRJtTY7V1pClPu8WEgEZonzaHq3K0El9Vcb8qmjucSg", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "APu-ArpY-GUntHG7BzTvUauKVP_YpCcVnZFX6r_VvYY2iPbFSZYxvUdUbX3TGK-Q92rTHNaNnutjbPcrCaBpJecM", + "y": "AONhGq1vGU20Wdrx1FT5SBdLOIvqOK_pxhTJZhS0Vwi_JYQdKN6PHrX9GyJ23ZhaY3bBKX6V2uzRJzV8Qam1FUbz" + } + }, + "encrypted_key": "U51txv9yfZASl8tlT7GbNtLjeAqTHUVT4O9MEqBKaYIdAcA7Qd7dnw" + } + ], + "aad": "tOS8nLSCERw2V9WOZVo6cenGuM4DJvHse1dsvTk8_As", + "iv": "LJl-9ygxPGMAmVHP", + "ciphertext": "HOfi-W7mcQv93scr1z8", + "tag": "zaM6OfzhVhYCsqD2VW5ztw" +} +``` + +#### 1.1.4 X25519 keys +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"A256GCM","skid":"X5INSMIv_w4Q7pljH7xjeUrRAKiBGHavSmOYyyiRugc","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6Ilg1SU5TTUl2X3c0UTdwbGpIN3hqZVVyUkFLaUJHSGF2U21PWXl5aVJ1Z2MiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0` +- Sender key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "WKkktGWkUB9hDITcqa1Z6MC8rcWy8fWtxuT7xwQF1lw", + "d": "-LEcVt6bW_ah9gY7H_WknTsg1MXq8yc42SrSJhqP0Vo" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `X5INSMIv_w4Q7pljH7xjeUrRAKiBGHavSmOYyyiRugc` +- Recipient 1 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "NJzDtIa7vjz-isjaI-6GKGDe2EUx26-D44d6jLILeBI", + "d": "MEBNdr6Tpb0XfD60NeHby-Tkmlpgr7pvVe7Q__sBbGw" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `2UR-nzYjVhsq0cZakWjE38-wUdG0S2EIrLZ8Eh0KVO0` +- Recipient 2 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "_aiA8rwrayc2k9EL-mkqtSh8onyl_-EzVif3L-q-R20", + "d": "ALBfdypF_lAbBtWXhwvq9Rs7TGjcLd-iuDh0s3yWr2Y" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `dvDd4h1rHj-onj-Xz9O1KRIgkMhh3u23d-94brHbBKo` +- Recipient 3 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "zuHJfrIarLGFga0OwZqDlvlI5P1bb9DFhAtdnI54pwQ", + "d": "8BVFAqxPHXB5W-EBxr-EjdUmA4HqY1gwDjiYvt0UxUk" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `hj57wbrmOygTc_ktMPqKMHdiL85FdiGJa5DKzoLIzeU` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `2UR-nzYjVhsq0cZakWjE38-wUdG0S2EIrLZ8Eh0KVO0.dvDd4h1rHj-onj-Xz9O1KRIgkMhh3u23d-94brHbBKo.hj57wbrmOygTc_ktMPqKMHdiL85FdiGJa5DKzoLIzeU` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `L-QV1cHI5u8U9BQa8_S4CFW-LhKNXHCjmqydtQYuSLw` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJBMjU2R0NNIiwic2tpZCI6Ilg1SU5TTUl2X3c0UTdwbGpIN3hqZVVyUkFLaUJHSGF2U21PWXl5aVJ1Z2MiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "WDVJTlNNSXZfdzRRN3Bsakg3eGplVXJSQUtpQkdIYXZTbU9ZeXlpUnVnYw", + "apv": "MlVSLW56WWpWaHNxMGNaYWtXakUzOC13VWRHMFMyRUlyTFo4RWgwS1ZPMA", + "kid": "2UR-nzYjVhsq0cZakWjE38-wUdG0S2EIrLZ8Eh0KVO0", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "IcuAA7zPN0mLt4GSZLQJ6f8p3yPALQaSyupbSRpDnwA" + } + }, + "encrypted_key": "_GoKcbrlbPR8hdgpDdpotO4WvAKOzyOEXo5A2RlxVaEb0enFej2DFQ" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "WDVJTlNNSXZfdzRRN3Bsakg3eGplVXJSQUtpQkdIYXZTbU9ZeXlpUnVnYw", + "apv": "MlVSLW56WWpWaHNxMGNaYWtXakUzOC13VWRHMFMyRUlyTFo4RWgwS1ZPMA", + "kid": "dvDd4h1rHj-onj-Xz9O1KRIgkMhh3u23d-94brHbBKo", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "_BVh0oInkDiqnTkHKLvNMa8cldr79TZS00MJCYwZo3Y" + } + }, + "encrypted_key": "gacTLNP-U5mYAHJLG9F97R52aG244NfLeWg_Dj4Fy0C96oIIN-3psw" + }, + { + "header": { + "alg": "ECDH-1PU+A256KW", + "apu": "WDVJTlNNSXZfdzRRN3Bsakg3eGplVXJSQUtpQkdIYXZTbU9ZeXlpUnVnYw", + "apv": "MlVSLW56WWpWaHNxMGNaYWtXakUzOC13VWRHMFMyRUlyTFo4RWgwS1ZPMA", + "kid": "hj57wbrmOygTc_ktMPqKMHdiL85FdiGJa5DKzoLIzeU", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "alPo4cjEjondCmz8mw8tntYxlpGPSLaqe3SSI_wu11s" + } + }, + "encrypted_key": "q2RpqrdZA9mvVBGTvMNHg3P6SysnuCpfraLWhRseiQ1ImJWdLq53TA" + } + ], + "aad": "L-QV1cHI5u8U9BQa8_S4CFW-LhKNXHCjmqydtQYuSLw", + "iv": "J-OEJGFWvJ6rw9dX", + "ciphertext": "BvFi1vAzq0Uostj0_ms", + "tag": "C6itmqZ7ehMx9FF70fdGGQ" +} +``` + +### 1.2 Single Recipient JWEs + +Packing a message with 1 recipient using the **Flattened JWE JSON serialization** and **Compact JWE serialization** formats as mentioned in the [notes](#notes) above. + +#### 1.2.1 NIST P-256 key +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "eFRTD4VaryfwIqLOpq7iuXmBbLjKPq5sVNzxwL7H1CI", + "y": "cIeogn-pLJXlCepb9BqwNKKW4tmNea3Is8G47aPob6M", + "d": "11NyNGrw4JoU7-_bwoZlVDTJi5vkMrSs4Nme_OHnx6Q" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `6PBTUbcLB7-Z4fuAFn42oC1PaMsNmjheq1FeZEUgV_8` +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "UP08dxIWu14HWRCI48Tnohm7jhaJ87fFdvYyf0w4lkg", + "y": "ohZVfvhQViMGb_n-Y66TewBO2gtE_udG_DsNe8c-T8w", + "d": "O0ikvlb4fh7daJpqd9JIgYk5e-twB0IYyKpoqmb7ZCc" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `D_kHovGtLUZ_ssw_vhZcqsx3LvQ6qC5JK74iPf9vqwk` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJObEJDVkZWaVkweENOeTFhTkdaMVFVWnVOREp2UXpGUVlVMXpUbTFxYUdWeE1VWmxXa1ZWWjFaZk9BIiwiYXB2IjoiUkY5clNHOTJSM1JNVlZwZmMzTjNYM1pvV21OeGMzZ3pUSFpSTm5GRE5VcExOelJwVUdZNWRuRjNhdyIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsiY3J2IjoiUC0yNTYiLCJrdHkiOiJFQyIsIngiOiJzODRGczRGeWRfSEVFQUN2R3dHak0wWDdGYUNwTlZ5cS1tM19MYXVwT2gwIiwieSI6IndsZzZoQnVnZElWMFlaekh1NHNQRnM0OXRtMGtXQlZjenQ0N25IenZ5UU0ifSwia2lkIjoiRF9rSG92R3RMVVpfc3N3X3ZoWmNxc3gzTHZRNnFDNUpLNzRpUGY5dnF3ayIsInNraWQiOiI2UEJUVWJjTEI3LVo0ZnVBRm40Mm9DMVBhTXNObWpoZXExRmVaRVVnVl84IiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "0L4GrPjXIy31JcEjV3sQj1Fbtb-dAtFPLng6mB0jyEyzDxzWcZZWag", + "iv": "V26sXdaKTIo6SDMn", + "ciphertext": "TJcEzgDbw5xDOMOwuuE", + "tag": "vgtkaTIM407IG8ZqLLRk6Q" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJObEJDVkZWaVkweENOeTFhTkdaMVFVWnVOREp2UXpGUVlVMXpUbTFxYUdWeE1VWmxXa1ZWWjFaZk9BIiwiYXB2IjoiUkY5clNHOTJSM1JNVlZwZmMzTjNYM1pvV21OeGMzZ3pUSFpSTm5GRE5VcExOelJwVUdZNWRuRjNhdyIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJzODRGczRGeWRfSEVFQUN2R3dHak0wWDdGYUNwTlZ5cS1tM19MYXVwT2gwIiwieSI6IndsZzZoQnVnZElWMFlaekh1NHNQRnM0OXRtMGtXQlZjenQ0N25IenZ5UU0ifSwia2lkIjoiRF9rSG92R3RMVVpfc3N3X3ZoWmNxc3gzTHZRNnFDNUpLNzRpUGY5dnF3ayIsInNraWQiOiI2UEJUVWJjTEI3LVo0ZnVBRm40Mm9DMVBhTXNObWpoZXExRmVaRVVnVl84IiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.0L4GrPjXIy31JcEjV3sQj1Fbtb-dAtFPLng6mB0jyEyzDxzWcZZWag.V26sXdaKTIo6SDMn.TJcEzgDbw5xDOMOwuuE.vgtkaTIM407IG8ZqLLRk6Q` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-1PU+A256KW", + "apu": "NlBCVFViY0xCNy1aNGZ1QUZuNDJvQzFQYU1zTm1qaGVxMUZlWkVVZ1ZfOA", + "apv": "RF9rSG92R3RMVVpfc3N3X3ZoWmNxc3gzTHZRNnFDNUpLNzRpUGY5dnF3aw", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "s84Fs4Fyd_HEEACvGwGjM0X7FaCpNVyq-m3_LaupOh0", + "y": "wlg6hBugdIV0YZzHu4sPFs49tm0kWBVczt47nHzvyQM" + }, + "kid": "D_kHovGtLUZ_ssw_vhZcqsx3LvQ6qC5JK74iPf9vqwk", + "skid": "6PBTUbcLB7-Z4fuAFn42oC1PaMsNmjheq1FeZEUgV_8", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 1.2.2 NIST P-384 key +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "UW1LtMXuZdFS0gyp0_F19uxHqECvCcJA7SmeeuRSSc_PQfsbZWXt5L0KyLYpNIQb", + "y": "FBdPcUvanB7igwkX0NN5rOvH3OKZ1gQHhcad7cCy6QNYKKz7lBWUUOmzypee31pS", + "d": "wrXW0wsFKjvpTWqOAd1mohRublQs4P014-U4_K-eTRFmzhkyLJqNn91dH_AHUc4-" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `0Bz8yRwu9eC8Gi7cYOwAKMJ8jysInhAtwH8k8m9MX04` +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "k3W_RR59uUG3HFlhhqNNmBDyFdMtWHxKAsJaxLBqQgQer3d3aAN-lfdxzGnHtwj1", + "y": "VMSy5zxFEGaGRINailLTUH6NlP0JO2qu0j0_UbS7Ng1b8JkzHDnDbjGgsLqVJaMM", + "d": "iM5K8uqNvFYJnuToMDBguGwUIlu1erT-K0g7NYtJrQnHZOumS8yIC4MCNC60Ch91" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `obCHRLVDx634Cax_Kr3B8fd_-xj5kAj0r0Kvvvmq1z8` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJNRUo2T0hsU2QzVTVaVU00UjJrM1kxbFBkMEZMVFVvNGFubHpTVzVvUVhSM1NEaHJPRzA1VFZnd05BIiwiYXB2IjoiYjJKRFNGSk1Wa1I0TmpNMFEyRjRYMHR5TTBJNFptUmZMWGhxTld0QmFqQnlNRXQyZG5adGNURjZPQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsiY3J2IjoiUC0zODQiLCJrdHkiOiJFQyIsIngiOiJvZ1dJTHo4aXpDODNWNnFPNFVidHlSMTFadGdtRUMxQV9VM1JtVVV4dk9INE9lVW9xbUxXX295YjJXek5NTTZtIiwieSI6ImNobkphdHpRREJodzhqem5McUFmYWx3eFB3RmFKZjhVY2FzbjlmUWZyeUVWQ2FnRnRBYTNIb1FaSUxoeGxYSWUifSwia2lkIjoib2JDSFJMVkR4NjM0Q2F4X0tyM0I4ZmRfLXhqNWtBajByMEt2dnZtcTF6OCIsInNraWQiOiIwQno4eVJ3dTllQzhHaTdjWU93QUtNSjhqeXNJbmhBdHdIOGs4bTlNWDA0IiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "ojdzwycN1XFKuiwOmlgS4MHApmDAVKVZt1Zl7sgtJkafQRz81FUnZQ", + "iv": "VqEJ6p5J0ZTIw2ts", + "ciphertext": "jGznTL6ruVMXzV8xCA8", + "tag": "YA_A4pjqqaAeUNvEFnCx8Q" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJNRUo2T0hsU2QzVTVaVU00UjJrM1kxbFBkMEZMVFVvNGFubHpTVzVvUVhSM1NEaHJPRzA1VFZnd05BIiwiYXB2IjoiYjJKRFNGSk1Wa1I0TmpNMFEyRjRYMHR5TTBJNFptUmZMWGhxTld0QmFqQnlNRXQyZG5adGNURjZPQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTM4NCIsIngiOiJvZ1dJTHo4aXpDODNWNnFPNFVidHlSMTFadGdtRUMxQV9VM1JtVVV4dk9INE9lVW9xbUxXX295YjJXek5NTTZtIiwieSI6ImNobkphdHpRREJodzhqem5McUFmYWx3eFB3RmFKZjhVY2FzbjlmUWZyeUVWQ2FnRnRBYTNIb1FaSUxoeGxYSWUifSwia2lkIjoib2JDSFJMVkR4NjM0Q2F4X0tyM0I4ZmRfLXhqNWtBajByMEt2dnZtcTF6OCIsInNraWQiOiIwQno4eVJ3dTllQzhHaTdjWU93QUtNSjhqeXNJbmhBdHdIOGs4bTlNWDA0IiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.ojdzwycN1XFKuiwOmlgS4MHApmDAVKVZt1Zl7sgtJkafQRz81FUnZQ.VqEJ6p5J0ZTIw2ts.jGznTL6ruVMXzV8xCA8.YA_A4pjqqaAeUNvEFnCx8Q` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-1PU+A256KW", + "apu": "MEJ6OHlSd3U5ZUM4R2k3Y1lPd0FLTUo4anlzSW5oQXR3SDhrOG05TVgwNA", + "apv": "b2JDSFJMVkR4NjM0Q2F4X0tyM0I4ZmRfLXhqNWtBajByMEt2dnZtcTF6OA", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "ogWILz8izC83V6qO4UbtyR11ZtgmEC1A_U3RmUUxvOH4OeUoqmLW_oyb2WzNMM6m", + "y": "chnJatzQDBhw8jznLqAfalwxPwFaJf8Ucasn9fQfryEVCagFtAa3HoQZILhxlXIe" + }, + "kid": "obCHRLVDx634Cax_Kr3B8fd_-xj5kAj0r0Kvvvmq1z8", + "skid": "0Bz8yRwu9eC8Gi7cYOwAKMJ8jysInhAtwH8k8m9MX04", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 1.2.3 NIST P-521 key +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AXKDGPnD6hlQIre8aEeu33bQffkfl-eQfQXgzNXQX7XFYt5GKA1N6w4-f0_Ci7fQNKGkQuCoAu5-6CNk9M_cHiDi", + "y": "Ae4-APhoZAmM99MdY9io9IZA43dN7dA006wlFb6LJ9bcusJOi5R-o3o3FhCjt5KTv_JxYbo6KU4PsBwQ1eeKyJ0U", + "d": "AP9l2wmQ85P5XD84CkEQVWHaX_46EDvHxLWHEKsHFSQYjEh6BDSuyy1TUNv68v8kpbLCDjvsBc3cIBqC4_T1r4pU" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `oq-WBIGQm-iHiNRj6nId4-E1QtY8exzp8C56SziUfeU` +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "ALmUHkd9Gi2NApJojNzzA34Qdd1-KLnq6jd2UJ9wl-xJzTQ2leg8qi3-hrFs7NqNfxqO6vE5bBoWYFeAcf3LqJOU", + "y": "AN-MutmkAXGzlgzSQJRnctHDcjQQNpRek-8BeqyUDXdZKNGKSMEAzw6Hnl3VdvsvihQfrxcajpx5PSnwxbbdakHq", + "d": "AKv-YbKdI6y8NRMP-e17-RjZyRTfGf0Xh9Og5g7q7aq0xS2mO59ttIJ67XHW5SPTBQDbltdUcydKroWNUIGvhKNv" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `XmLVV-CqMkTGQIe6-KecWZWtZVwORTMP2y5aqMPV7P4` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJiM0V0VjBKSlIxRnRMV2xJYVU1U2FqWnVTV1EwTFVVeFVYUlpPR1Y0ZW5BNFF6VTJVM3BwVldabFZRIiwiYXB2IjoiV0cxTVZsWXRRM0ZOYTFSSFVVbGxOaTFMWldOWFdsZDBXbFozVDFKVVRWQXllVFZoY1UxUVZqZFFOQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsiY3J2IjoiUC01MjEiLCJrdHkiOiJFQyIsIngiOiJBRHdFcDBlZWJseGZhZHdkVFBlTV81b29MZGdHaWhLM3Bqd3AxakxXWmdxLUJrRV9IZDhnZFQ4RThOSFVvWjRFeWVvbWVKX3J0WGFlVnlHdjdoVzBPb1MtIiwieSI6IkFaY0Zzemg3RUstZ2lGQXRIZ2hPQ21uR3NNN1QzSzFjeUhBV0NwYXBqd2ZEclJjYnE5THdhQjFyRVVOdDMyYndLdWNNNG9idldkSndxVGE3SGVZYlNVOHUifSwia2lkIjoiWG1MVlYtQ3FNa1RHUUllNi1LZWNXWld0WlZ3T1JUTVAyeTVhcU1QVjdQNCIsInNraWQiOiJvcS1XQklHUW0taUhpTlJqNm5JZDQtRTFRdFk4ZXh6cDhDNTZTemlVZmVVIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "9OyKH83g7RoS-ykrAoQpqn6FUUuYxeKukJbk6y2x9wfoe__rM8sP4w", + "iv": "JO2ENu2k2O1OFgjl", + "ciphertext": "wpomqxgGqQIWQ_lWCm4", + "tag": "XgUX1EOGAePvjlcO7Dzb3A" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJiM0V0VjBKSlIxRnRMV2xJYVU1U2FqWnVTV1EwTFVVeFVYUlpPR1Y0ZW5BNFF6VTJVM3BwVldabFZRIiwiYXB2IjoiV0cxTVZsWXRRM0ZOYTFSSFVVbGxOaTFMWldOWFdsZDBXbFozVDFKVVRWQXllVFZoY1UxUVZqZFFOQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTUyMSIsIngiOiJBRHdFcDBlZWJseGZhZHdkVFBlTV81b29MZGdHaWhLM3Bqd3AxakxXWmdxLUJrRV9IZDhnZFQ4RThOSFVvWjRFeWVvbWVKX3J0WGFlVnlHdjdoVzBPb1MtIiwieSI6IkFaY0Zzemg3RUstZ2lGQXRIZ2hPQ21uR3NNN1QzSzFjeUhBV0NwYXBqd2ZEclJjYnE5THdhQjFyRVVOdDMyYndLdWNNNG9idldkSndxVGE3SGVZYlNVOHUifSwia2lkIjoiWG1MVlYtQ3FNa1RHUUllNi1LZWNXWld0WlZ3T1JUTVAyeTVhcU1QVjdQNCIsInNraWQiOiJvcS1XQklHUW0taUhpTlJqNm5JZDQtRTFRdFk4ZXh6cDhDNTZTemlVZmVVIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.9OyKH83g7RoS-ykrAoQpqn6FUUuYxeKukJbk6y2x9wfoe__rM8sP4w.JO2ENu2k2O1OFgjl.wpomqxgGqQIWQ_lWCm4.XgUX1EOGAePvjlcO7Dzb3A` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-1PU+A256KW", + "apu": "b3EtV0JJR1FtLWlIaU5SajZuSWQ0LUUxUXRZOGV4enA4QzU2U3ppVWZlVQ", + "apv": "WG1MVlYtQ3FNa1RHUUllNi1LZWNXWld0WlZ3T1JUTVAyeTVhcU1QVjdQNA", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "ADwEp0eeblxfadwdTPeM_5ooLdgGihK3pjwp1jLWZgq-BkE_Hd8gdT8E8NHUoZ4EyeomeJ_rtXaeVyGv7hW0OoS-", + "y": "AZcFszh7EK-giFAtHghOCmnGsM7T3K1cyHAWCpapjwfDrRcbq9LwaB1rEUNt32bwKucM4obvWdJwqTa7HeYbSU8u" + }, + "kid": "XmLVV-CqMkTGQIe6-KecWZWtZVwORTMP2y5aqMPV7P4", + "skid": "oq-WBIGQm-iHiNRj6nId4-E1QtY8exzp8C56SziUfeU", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 1.2.4 X25519 key +- Sender key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "WKkktGWkUB9hDITcqa1Z6MC8rcWy8fWtxuT7xwQF1lw", + "d": "-LEcVt6bW_ah9gY7H_WknTsg1MXq8yc42SrSJhqP0Vo" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `X5INSMIv_w4Q7pljH7xjeUrRAKiBGHavSmOYyyiRugc` +- Single Recipient key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "NJzDtIa7vjz-isjaI-6GKGDe2EUx26-D44d6jLILeBI", + "d": "MEBNdr6Tpb0XfD60NeHby-Tkmlpgr7pvVe7Q__sBbGw" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `2UR-nzYjVhsq0cZakWjE38-wUdG0S2EIrLZ8Eh0KVO0` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJXRFZKVGxOTlNYWmZkelJSTjNCc2FrZzNlR3BsVlhKU1FVdHBRa2RJWVhaVGJVOVplWGxwVW5Wbll3IiwiYXB2IjoiTWxWU0xXNTZXV3BXYUhOeE1HTmFZV3RYYWtVek9DMTNWV1JITUZNeVJVbHlURm80Uldnd1MxWlBNQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsiY3J2IjoiWDI1NTE5Iiwia3R5IjoiT0tQIiwieCI6InpxUDB0WHdqVVFxdnBvSVdqNS16U2Q0WVVZZjdmU2hta2dhR0dXRFFrbGsifSwia2lkIjoiMlVSLW56WWpWaHNxMGNaYWtXakUzOC13VWRHMFMyRUlyTFo4RWgwS1ZPMCIsInNraWQiOiJYNUlOU01Jdl93NFE3cGxqSDd4amVVclJBS2lCR0hhdlNtT1l5eWlSdWdjIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "encrypted_key": "o_tprm3F-VJE2kHFrCBtgbCVDag0Y6AwLm1jD6S3MUS_rHphYy033w", + "iv": "6GKRpv-Bs_2v_7a3", + "ciphertext": "qlfWYkCE7zu-aRVP3R8", + "tag": "oBDt6-tRYcLTMA7QhX0O2Q" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStBMjU2S1ciLCJhcHUiOiJXRFZKVGxOTlNYWmZkelJSTjNCc2FrZzNlR3BsVlhKU1FVdHBRa2RJWVhaVGJVOVplWGxwVW5Wbll3IiwiYXB2IjoiTWxWU0xXNTZXV3BXYUhOeE1HTmFZV3RYYWtVek9DMTNWV1JITUZNeVJVbHlURm80Uldnd1MxWlBNQSIsImN0eSI6ImFwcGxpY2F0aW9uL2RpZGNvbW0tcGxhaW4ranNvbiIsImVuYyI6IkEyNTZHQ00iLCJlcGsiOnsia3R5IjoiT0tQIiwiY3J2IjoiWDI1NTE5IiwieCI6InpxUDB0WHdqVVFxdnBvSVdqNS16U2Q0WVVZZjdmU2hta2dhR0dXRFFrbGsifSwia2lkIjoiMlVSLW56WWpWaHNxMGNaYWtXakUzOC13VWRHMFMyRUlyTFo4RWgwS1ZPMCIsInNraWQiOiJYNUlOU01Jdl93NFE3cGxqSDd4amVVclJBS2lCR0hhdlNtT1l5eWlSdWdjIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9.o_tprm3F-VJE2kHFrCBtgbCVDag0Y6AwLm1jD6S3MUS_rHphYy033w.6GKRpv-Bs_2v_7a3.qlfWYkCE7zu-aRVP3R8.oBDt6-tRYcLTMA7QhX0O2Q` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to: +```json +{ + "alg": "ECDH-1PU+A256KW", + "apu": "WDVJTlNNSXZfdzRRN3Bsakg3eGplVXJSQUtpQkdIYXZTbU9ZeXlpUnVnYw", + "apv": "MlVSLW56WWpWaHNxMGNaYWtXakUzOC13VWRHMFMyRUlyTFo4RWgwS1ZPMA", + "cty": "application/didcomm-plain+json", + "enc": "A256GCM", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "zqP0tXwjUQqvpoIWj5-zSd4YUYf7fShmkgaGGWDQklk" + }, + "kid": "2UR-nzYjVhsq0cZakWjE38-wUdG0S2EIrLZ8Eh0KVO0", + "skid": "X5INSMIv_w4Q7pljH7xjeUrRAKiBGHavSmOYyyiRugc", + "typ": "application/didcomm-encrypted+json" +} +``` + +## 2 XC20P content encryption + +### 2.1 Multi recipients JWEs + +#### 2.1.1 NIST P-256 keys +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"XC20P","skid":"T1jGtZoU-Xa_5a1QKexUU0Jq9WKDtS7TCowVvjoFH04","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJUMWpHdFpvVS1YYV81YTFRS2V4VVUwSnE5V0tEdFM3VENvd1Z2am9GSDA0IiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9` +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "46OXm1dUTO3MB-8zoxbn-9dk0khgeIqsKFO-nTJ9keM", + "y": "8IlrwB-dl5bFd5RT4YAbgAdj5Y-a9zhc9wCMnXDZDvA", + "d": "58GZDz9_opy-nEeaJ_cyEL63TO-l063aV5nLADCgsGY" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `T1jGtZoU-Xa_5a1QKexUU0Jq9WKDtS7TCowVvjoFH04` +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "r9MRjEQ7CBxAgMyEG3ZjIlkGCuRX0rTaBdbkAcY17hA", + "y": "MRSgHQycDFPdSABGv5V0Qd-2q7ebs_x0_fNFyabGgXU", + "d": "LK9yfSxuET5n5uZDNO-64sJKWxJs7LTkqhA4mAuKQnE" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `dmfXisqWjRT-tFpODOD-G0CBF6zjHywNUjrrD3IFmcs` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "PMhlaU_KNEWou004AEyAFoJi8vNOnY75ROiRzzjhDR0", + "y": "tEcJNRv2rqYlYWeRloRabcp2lRorRaZTLM0ZNBoEyN0", + "d": "t1-QysBdkbkpqEBDo_JPsi-6YqD24UoAGBrruI2XNhA" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `2_Sf_YshIFhQ11NH9muAxLWwyFUvJnfXbYFOAC-8HTw` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "V9dWH69KZ_bvrxdWgt5-o-KnZLcGuWjAKVWMueiQioM", + "y": "lvsUBieuXV6qL4R3L94fCJGu8SDifqh3fAtN2plPWX4", + "d": "llg97kts4YxIF-r3jn7wcZ-zV0hLcn_AydIKHDF-HJc" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `mKtrI7SV3z2U9XyhaaTYlQFX1ANi6Wkli8b3NWVq4C4` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `2_Sf_YshIFhQ11NH9muAxLWwyFUvJnfXbYFOAC-8HTw.dmfXisqWjRT-tFpODOD-G0CBF6zjHywNUjrrD3IFmcs.mKtrI7SV3z2U9XyhaaTYlQFX1ANi6Wkli8b3NWVq4C4` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `PNKzNc6e0MtDtIGamjsx2fytSu6t8GygofQbzTrtMNA` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJUMWpHdFpvVS1YYV81YTFRS2V4VVUwSnE5V0tEdFM3VENvd1Z2am9GSDA0IiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "VDFqR3Rab1UtWGFfNWExUUtleFVVMEpxOVdLRHRTN1RDb3dWdmpvRkgwNA", + "apv": "ZG1mWGlzcVdqUlQtdEZwT0RPRC1HMENCRjZ6akh5d05VanJyRDNJRm1jcw", + "kid": "dmfXisqWjRT-tFpODOD-G0CBF6zjHywNUjrrD3IFmcs", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "80NGcUh0mIy_XrcaAqD7GCHF0FU2W5j4Jt-wfwxvJVs", + "y": "KpsNL9A-FGgL7S97ce8wcWYc9J1Q6_luxKAFIu7BNIw" + } + }, + "encrypted_key": "wGQO8LX7o9JmYI0PIGUruU7i6ybZYefsTanZuo7hIDyn21ix6fSFPOmvgjPxZ8q_-hZF2yGYtudfLiuPzXlybWJkmTlP9PcY" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "VDFqR3Rab1UtWGFfNWExUUtleFVVMEpxOVdLRHRTN1RDb3dWdmpvRkgwNA", + "apv": "ZG1mWGlzcVdqUlQtdEZwT0RPRC1HMENCRjZ6akh5d05VanJyRDNJRm1jcw", + "kid": "2_Sf_YshIFhQ11NH9muAxLWwyFUvJnfXbYFOAC-8HTw", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "4YrbAQCLLya1XqRvjfcYdonllWQulrLP7zE0ooclKXA", + "y": "B3tI8lsWHRwBQ19pAFzXiBkLgpE6leTeQT6b709gllE" + } + }, + "encrypted_key": "5tY3t1JI8L6s974kmXbzKMaePHygNan2Qqpd1B0BiqBsjaHNUH2Unv1IMGiT3oQD0xXeVPAxQq7vNZgANitxBbgG_uxGiRld" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "VDFqR3Rab1UtWGFfNWExUUtleFVVMEpxOVdLRHRTN1RDb3dWdmpvRkgwNA", + "apv": "ZG1mWGlzcVdqUlQtdEZwT0RPRC1HMENCRjZ6akh5d05VanJyRDNJRm1jcw", + "kid": "mKtrI7SV3z2U9XyhaaTYlQFX1ANi6Wkli8b3NWVq4C4", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "-e9kPGp2rmtpFs2zzTaY6xfeXjr1Xua1vHCQZRKJ54s", + "y": "Mc7b8U06KHV__1-XMaReilLxa63LcICqsPtkZGXEkEs" + } + }, + "encrypted_key": "zVQUQytYv4EmQS0zye3IsXiN_2ol-Qn2nvyaJgEPvNdwFuzTFPOupTl-PeOhkRvxPfuLlw5TKnSRyPUejP8zyHbBgUZ6gDmz" + } + ], + "aad": "PNKzNc6e0MtDtIGamjsx2fytSu6t8GygofQbzTrtMNA", + "iv": "UKgm1XTPf1QFDXoRWlf-KrsBRQKSwpBA", + "ciphertext": "pbwy8HEnr1hPA0Jt5ho", + "tag": "nUazXvxpMXGoL1__92CAyA" +} +``` + +#### 2.1.2 NIST P-384 keys +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"XC20P","skid":"xXdnS3M4Bb497A0ko9c6H0D4NNbj1XpwGr4Tk9Fcw7k","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJ4WGRuUzNNNEJiNDk3QTBrbzljNkgwRDROTmJqMVhwd0dyNFRrOUZjdzdrIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9` +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "bfuATmVQ_jxLIgfuhKNYrNRNu-VnK4FzTCCVRvycgekS8fIuC4rZS9uQi6Q2Ujwd", + "y": "XkVJ93cLKpeZeCMEOsHRKk4rse1zXpzY6yUibEtwZG9nFWF05Ro8OQs5fZVK2TWC", + "d": "OVzGxGyyaHGJpx1MoSwPjmWPas28sfq1tj7UkYFoK3ENsujmzUduAW6HwyaBlXRW" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `xXdnS3M4Bb497A0ko9c6H0D4NNbj1XpwGr4Tk9Fcw7k` +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "xhk5K7x4xw9OJpkFhmsY39jceQqx57psvcZstiNZmKbXD7kT9ajfGKFA6YA-ali5", + "y": "7Hj32-JDMNDYWRGy3f-0E9lbUGp6yURMaZ9M36Q_FPgljKgHa9i0Fn1ogr_zEmO3", + "d": "Pc3r6eg15XZeKgTDMPcGjf_SvImZxG4bDzgCh3QShClAwMdmoNbzPZGhBByNrlvO" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `aIlhDTWJmT-_Atad5EBbvbZPkPnz2IYT85I6T44kcE4` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "wqW3DUkUAT0Cyk3hq0KVJbqtPSJOoqulp_Tqa29jBEPliIJ9rnq7cRkJyxArCYAj", + "y": "ZfBtdTTVRh9SeQDCwsgAo15cCX2I-7J6xdyxDPyH8LBhbUA_8npHvNquKGta9p8x", + "d": "krddjYsOD4YIIkNjWXTrYV9rOVlmLNaeoLHChJ5oUr4c21LHxGL4xTI1bEoXKgJ2" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `02WdA5ip_Amam611KA6fdoTs533yZH-ovfpt8t9zVjg` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "If6iEafrkcL53mVYCbm5rmnwAw3kjb13gUjBoDePggO7xMiSFyej4wbTabdCyfbg", + "y": "nLX6lEce-9r19NA_nI5mGK3YFLiX9IYRgXZZCUd_Br91PaE8Mr1JR01utAPoGx36", + "d": "jriJKFpQfzJtOrp7PhGvH0osHJQJbZrAKjD95itivioVawzMz9wcI_h9VsFV3ff0" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `zeqnfYLFWtnJ_e5npBs7CtM5KkToyyM9kCKIFlcyId0` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `02WdA5ip_Amam611KA6fdoTs533yZH-ovfpt8t9zVjg.aIlhDTWJmT-_Atad5EBbvbZPkPnz2IYT85I6T44kcE4.zeqnfYLFWtnJ_e5npBs7CtM5KkToyyM9kCKIFlcyId0` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `CftHmHttuxR6mRrHe-zBXV2UEvL2wvZEt5yeFDhYSF8` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJ4WGRuUzNNNEJiNDk3QTBrbzljNkgwRDROTmJqMVhwd0dyNFRrOUZjdzdrIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "eFhkblMzTTRCYjQ5N0Ewa285YzZIMEQ0Tk5iajFYcHdHcjRUazlGY3c3aw", + "apv": "YUlsaERUV0ptVC1fQXRhZDVFQmJ2YlpQa1BuejJJWVQ4NUk2VDQ0a2NFNA", + "kid": "aIlhDTWJmT-_Atad5EBbvbZPkPnz2IYT85I6T44kcE4", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "k7SRlQ7EwCR8VZ-LF92zOgvpFDAed0mN3mmZeCHHDznZp5TLQShFT9TdnwgsvJFP", + "y": "ZHzkS9BD-I2DtNPhbXuTzf6vUnykdZPus9xZnRu1rWgxVtLQ8j-Jp4YoJgdQmcOu" + } + }, + "encrypted_key": "BO597Rs1RU3ZU-WdzWPgRnPmRULcFBihZxE7Jvl3qw3VUmR5RUXY0Xy9k_dWRnuRCh9Yzxef7tXlqVMaL4KBCfaAbAEOReQw" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "eFhkblMzTTRCYjQ5N0Ewa285YzZIMEQ0Tk5iajFYcHdHcjRUazlGY3c3aw", + "apv": "YUlsaERUV0ptVC1fQXRhZDVFQmJ2YlpQa1BuejJJWVQ4NUk2VDQ0a2NFNA", + "kid": "02WdA5ip_Amam611KA6fdoTs533yZH-ovfpt8t9zVjg", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "QT9Q_zU9VE3K9r_50mKh7iG8SxYeXVvwnhykphMAk8akfnTeB7FIRC2MzFat9JMT", + "y": "3HeQPqQ_BS5vy2e2L7kgMhHNwNQ2K1pmL9LImrBg8XROuc9EaAGnFSQ439bZXg9y" + } + }, + "encrypted_key": "oKVlxrYhp8Bvr6s6CW7DxTSCMIFMkqLjDP9sCIkLoetHlXM5Mngq46CUqHusKTceHdSOL8sGUbeSBo6lXRKArywtjiVVyStW" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "eFhkblMzTTRCYjQ5N0Ewa285YzZIMEQ0Tk5iajFYcHdHcjRUazlGY3c3aw", + "apv": "YUlsaERUV0ptVC1fQXRhZDVFQmJ2YlpQa1BuejJJWVQ4NUk2VDQ0a2NFNA", + "kid": "zeqnfYLFWtnJ_e5npBs7CtM5KkToyyM9kCKIFlcyId0", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "GGFw14WnABx5S__MLwjy7WPgmPzCNbygbJikSqwx1nQ7APAiIyLeiAeZnAFQSr8C", + "y": "Bjev4lkaRbd4Ery0vnO8Ox4QgIDGbuflmFq0HhL-QHIe3KhqxrqZqbQYGlDNudEv" + } + }, + "encrypted_key": "S8vnyPjW_19Hws3-igk-cVTSqVTY0_D9SWahnYnWBFBqTdx0b0e8hf06Oiou31Ww-Y3p8Z3O_okqQGzZMWUMLSxUPeCR2ZWx" + } + ], + "aad": "CftHmHttuxR6mRrHe-zBXV2UEvL2wvZEt5yeFDhYSF8", + "iv": "jTaCuNXs4QdX6HuWvl5AsqIEv4nh2JMP", + "ciphertext": "7y463zoRKgVfpKh3EBw", + "tag": "8YKdJpF2DnQQwEkBcbuEnw" +} +``` + +#### 2.1.3 NIST P-521 keys +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"XC20P","skid":"bq3OI5517dSIMeD9K3lTqvkvvkmsRtifD6tvjlrKYsU","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJicTNPSTU1MTdkU0lNZUQ5SzNsVHF2a3Z2a21zUnRpZkQ2dHZqbHJLWXNVIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9` +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "ACN9T83BbPNn1eRyo-TrL0GyC7kBNQvgUxk55fCeQKDSTVhbzCKia7WecCUshyEF-BOQbfEsOIUCq3g7xY3VEeth", + "y": "APDIfDv6abLQ-Zb_p8PxwJe1x3U0-PdgXLNbtS7evGuUROHt79SVkpfXcZ3UaEc6cMoFfd2oMvbmUjCMM4-Sgipn", + "d": "AXCGyR9uXY8vDr7D4HvMxep-d5biQzgHR6WsdOF4R5M9qYb8FhRIQCMbmDSZzCuqgGgXrPRMPm5-omvWVeYqwwa3" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `bq3OI5517dSIMeD9K3lTqvkvvkmsRtifD6tvjlrKYsU` +- Recipient 1 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AZi-AxJkB09qw8dBnNrz53xM-wER0Y5IYXSEWSTtzI5Sdv_5XijQn9z-vGz1pMdww-C75GdpAzp2ghejZJSxbAd6", + "y": "AZzRvW8NBytGNbF3dyNOMHB0DHCOzGp8oYBv_ZCyJbQUUnq-TYX7j8-PlKe9Ce5acxZzrcUKVtJ4I8JgI5x9oXIW", + "d": "AHGOZNkAcQCdDZOpQRdbH-f89mpjY_kGmtEpTExd51CcRlHhXuuAr6jcgb8YStwy9FN7vCU1y5LnJfKhGUGrP2a4" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `7icoqReWFlpF16dzZD3rBgK1cJ265WzfF9sJJXqOe0M` +- Recipient 2 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "ASRvWU-d_XI2S1UQb7PoXIXTLXd8vgLmFb-9mmmIrzTMmIXFXpsDN9_1-Xg_r3qkEg-zBjTi327GIseWFGMa0Mrp", + "y": "AJ0VyjDn4Rn6SKamFms4593mW5K936d4Jr7-J5OjJqTZtS6APgNkrwFjhKPHQfg7o8T4pmX7vlfFY5Flx7IOYJuw", + "d": "ALzWMohuwSqkiqqEhijiBoH6kJ580Dtxe7CfgqEboc5DG0pMtAUf-a91VbmR1U8bQox-B4_YRXoFLRns2tI_wPYz" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `BUEVQ3FlDsml4JYrLCwwsL5BUZt-hYwb2B0SoJ6dzHc` +- Recipient 3 key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AB2ke_2nVg95OP3Xb4Fg0Gg4KgfZZf3wBEYoOlGhXmHNCj56G10vnOe1hGRKIoD-JkPWuulcUtsIUO7r3Rz2mLP0", + "y": "AJTaqfF8d4cFv_fP4Uoqq-uCCObmyPsD1CphbCuCZumarfzjA5SpAQCdfz3No4Nhn53OqdcTkm654Yvfj1vOp5t6", + "d": "Af6Ba1x6i6glhRcR2RmZMZJ5BJXibpMB0TqjY_2Fe2LekS9QQK21JtrF20dj_gahxcrnfcn8oJ2xCrEMKaexgcsb" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `C9iN-jkTFBbTz3Yv3FquR3dAsHYnAIg1_hT0jsefLDE` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `7icoqReWFlpF16dzZD3rBgK1cJ265WzfF9sJJXqOe0M.BUEVQ3FlDsml4JYrLCwwsL5BUZt-hYwb2B0SoJ6dzHc.C9iN-jkTFBbTz3Yv3FquR3dAsHYnAIg1_hT0jsefLDE` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `VBNrffp39h1F6sg0dzkArcd2WjpKeqEvqt6HNXaVfKU` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJicTNPSTU1MTdkU0lNZUQ5SzNsVHF2a3Z2a21zUnRpZkQ2dHZqbHJLWXNVIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "YnEzT0k1NTE3ZFNJTWVEOUszbFRxdmt2dmttc1J0aWZENnR2amxyS1lzVQ", + "apv": "N2ljb3FSZVdGbHBGMTZkelpEM3JCZ0sxY0oyNjVXemZGOXNKSlhxT2UwTQ", + "kid": "7icoqReWFlpF16dzZD3rBgK1cJ265WzfF9sJJXqOe0M", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "ABd71Xomy3mv-mkAipKb18UQ-1xXt7tGDDwf0k5fpLADg1qK--Jhn8TdzyjTuve7rJQrlCJH4GjuQjCWVs4T7J_T", + "y": "ANrWrk69QRi4cr8ZbU2vF_0jSjTIUn-fQCHJtxLg3uuvLtzGW7oIEkUFJq_sTZXL_gaPdFIWlI4aIjKRgzOUP_ze" + } + }, + "encrypted_key": "lZa-4LTyaDP01wmN8bvoD69MLl3VY2H_wNaNJ7kYzTFExlgYTPNrFJ5XL6T_h1DUULX0TYJVxbIWQeJ_x_7i-xSv7-BHbFcm" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "YnEzT0k1NTE3ZFNJTWVEOUszbFRxdmt2dmttc1J0aWZENnR2amxyS1lzVQ", + "apv": "N2ljb3FSZVdGbHBGMTZkelpEM3JCZ0sxY0oyNjVXemZGOXNKSlhxT2UwTQ", + "kid": "BUEVQ3FlDsml4JYrLCwwsL5BUZt-hYwb2B0SoJ6dzHc", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "ALGN2OH1_DKtEZ-990uL1kzHYhYmZD-stOdL6_NMReCKEPZil7Z1tsq0g9l0HNi6DWuMjNyiJCfDd1erWpByFAOX", + "y": "AQgB2aE_3GltqbWzKbWbLa6Fdq6jO4A3LrYUnNDNIuHY6eRH9sRU0yWjmcmWCoukT98wksXJ3isHr9-NqFuZLehi" + } + }, + "encrypted_key": "bybMPkSjuSz8lLAPFJHrxjl1buE8cfONEzvQ2U64h8L0QEZPLK_VewbXVflEPNrOo3oTWlI_878GIKvkxJ8cJOD6a0kZmr87" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "YnEzT0k1NTE3ZFNJTWVEOUszbFRxdmt2dmttc1J0aWZENnR2amxyS1lzVQ", + "apv": "N2ljb3FSZVdGbHBGMTZkelpEM3JCZ0sxY0oyNjVXemZGOXNKSlhxT2UwTQ", + "kid": "C9iN-jkTFBbTz3Yv3FquR3dAsHYnAIg1_hT0jsefLDE", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AZKyI6Mg8OdKUYqo3xuKjHiVrlV56_qGBzdwr86QSnebq3Y69Z0qETiTumQv5J3ECmZzs4DiETryRuzdHc2RkKBZ", + "y": "ARJJT7MWjTWWB7leblQgg7PYn_0deScO7AATlcnukFsLbzly0LHs1msVXaerQUCHPg2t-sYGxDP7w0iaDHB8k3Tj" + } + }, + "encrypted_key": "nMGoNk1brn9uO9hlSa7NwVgFUMXnxpKKPkuFHSE2aM_N8q8wJbVBLC9rJ9sPIiSU20tq2sJXaAcoMteajOX6wj_Hzl1uRT1e" + } + ], + "aad": "VBNrffp39h1F6sg0dzkArcd2WjpKeqEvqt6HNXaVfKU", + "iv": "h0bbZygiAx9MMO2Huxym_QnwrXZHhdyQ", + "ciphertext": "LABYmf_sfPNGgls0wvk", + "tag": "z1rZOEgyryiW_3d5gxnMUQ" +} +``` + +#### 2.1.4 X25519 keys +The packer generates the following protected headers that includes the skid: +- Generated protected headers: `{"cty":"application/didcomm-plain+json","enc":"XC20P","skid":"j8E-tcw1Z_eOCoKEH-7a9T532r8zXfcavbPZlofN0Ek","typ":"application/didcomm-encrypted+json"}` + - raw (no padding) base64URL encoded: `eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJqOEUtdGN3MVpfZU9Db0tFSC03YTlUNTMycjh6WGZjYXZiUFpsb2ZOMEVrIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9` +- Sender key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "g3Lpdd_DRgjK28qi0sR0-hI-zv7a1X52vpzKc6ZM1Qs", + "d": "cPU_Io7RRHNb_xkQ_D6u3ER4vSjvsILDCKwOj8kVHXQ" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `j8E-tcw1Z_eOCoKEH-7a9T532r8zXfcavbPZlofN0Ek` +- Recipient 1 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "VlhpUXj-oGs9ge-VLrmYF7Xuzy73YchIfckaYcQefBw", + "d": "QFHCCy0wzgJ_AlGMnjetTd0tnDaZ_7yqJODSV0d-kkg" +} +``` +- Recipient 1 kid (jwk thumbprint raw base64 URL encoded): `_DHSbVaMeZxriDJn5VoHXYXo6BJacwZx_fGIBfCiJ5c` +- Recipient 2 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "y52sexwATOR5J5znNp94MFx19J0rkgzNyLESMVhkE2M", + "d": "6NwEk3_8lKOwLaZM2YkLdW9MF2zDqMjAx_G-uDoAAkw" +} +``` +- Recipient 2 kid (jwk thumbprint raw base64 URL encoded): `n2MxD23PaCkz7vptma_1j9X2JdUoCFLzrtYuDvOA0Kc` +- Recipient 3 key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "BYL51mNvx1LKD2wDfga_7GZc0YYI82HhRmHtXfiz_ko", + "d": "MLd_nsRRb_CSzc6Ou8TZFm-A17ZpT1Aen6fIvC6ZuV8" +} +``` +- Recipient 3 kid (jwk thumbprint raw, no padding, base64 URL encoded): `HHN2ZcES5ps7gCjK-06bCE4EjX_hh7nq2cWd-GfnI5s` +- List of kids used for AAD for the above recipients (sorted `kid` values joined with `.`): `HHN2ZcES5ps7gCjK-06bCE4EjX_hh7nq2cWd-GfnI5s._DHSbVaMeZxriDJn5VoHXYXo6BJacwZx_fGIBfCiJ5c.n2MxD23PaCkz7vptma_1j9X2JdUoCFLzrtYuDvOA0Kc` +- Resulting AAD value (sha256 of above list raw, no padding, base64 URL encoded): `K1oFStibrX4x6LplTB0-tO3cwGiZzMvG_6w0LfguVuI` +- Finally, packing the payload outputs the following JWE (pretty printed for readability): +```json +{ + "protected": "eyJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsInNraWQiOiJqOEUtdGN3MVpfZU9Db0tFSC03YTlUNTMycjh6WGZjYXZiUFpsb2ZOMEVrIiwidHlwIjoiYXBwbGljYXRpb24vZGlkY29tbS1lbmNyeXB0ZWQranNvbiJ9", + "recipients": [ + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "ajhFLXRjdzFaX2VPQ29LRUgtN2E5VDUzMnI4elhmY2F2YlBabG9mTjBFaw", + "apv": "X0RIU2JWYU1lWnhyaURKbjVWb0hYWVhvNkJKYWN3WnhfZkdJQmZDaUo1Yw", + "kid": "_DHSbVaMeZxriDJn5VoHXYXo6BJacwZx_fGIBfCiJ5c", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "77VAbpx5xn2iavmhzZATXwGnxjRyxjBbtNzojdWP7wo" + } + }, + "encrypted_key": "dvBscDJj2H6kZJgfdqazZ9pXZxUzai-mcExsdr11-RNvxxPd4_Cy6rolLSsY6ugm1sCo9BgRhAW1e6vxgTnY3Ctv0_xZIhvr" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "ajhFLXRjdzFaX2VPQ29LRUgtN2E5VDUzMnI4elhmY2F2YlBabG9mTjBFaw", + "apv": "X0RIU2JWYU1lWnhyaURKbjVWb0hYWVhvNkJKYWN3WnhfZkdJQmZDaUo1Yw", + "kid": "n2MxD23PaCkz7vptma_1j9X2JdUoCFLzrtYuDvOA0Kc", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "sZtHwxjaS51BR2SBGC32jFvUgVlABZ7rkBFqJk8ktXM" + } + }, + "encrypted_key": "2gIQKw_QpnfGbIOso_XesSGWC9ZKu4-ox1eqRu71aS-nBWAbFrdJPqSY7gzAOGUNqg_o6mC1q7coG69G9yen37DIjcoR6mD1" + }, + { + "header": { + "alg": "ECDH-1PU+XC20PKW", + "apu": "ajhFLXRjdzFaX2VPQ29LRUgtN2E5VDUzMnI4elhmY2F2YlBabG9mTjBFaw", + "apv": "X0RIU2JWYU1lWnhyaURKbjVWb0hYWVhvNkJKYWN3WnhfZkdJQmZDaUo1Yw", + "kid": "HHN2ZcES5ps7gCjK-06bCE4EjX_hh7nq2cWd-GfnI5s", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "48AJF8kNoxfHXpUtBApRMUcTf8B0Ho4i_6CvGT4arGY" + } + }, + "encrypted_key": "o_toInYq_NP45UqqFg461O6ruUNSQNKrBXRDA06JQ-faMUUfMGRtzNHK-FzrhtodZLW5bRFFFry9aFjwg5aYloe2JG9-fEcw" + } + ], + "aad": "K1oFStibrX4x6LplTB0-tO3cwGiZzMvG_6w0LfguVuI", + "iv": "tcThx2bVV8jhteYknijC-vxSED_BKPF8", + "ciphertext": "DUZLQAnWzApBFdwlZDg", + "tag": "YLuHzCD4xSTDxe_0AWukyw" +} +``` + +### 2.2 Single Recipient JWEs + +Packing a message with 1 recipient using the **Flattened JWE JSON serialization** and the **Compact JWE serialization** formats as mentioned in the [notes](#notes) above. + +#### 2.2.1 NIST P-256 key +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "46OXm1dUTO3MB-8zoxbn-9dk0khgeIqsKFO-nTJ9keM", + "y": "8IlrwB-dl5bFd5RT4YAbgAdj5Y-a9zhc9wCMnXDZDvA", + "d": "58GZDz9_opy-nEeaJ_cyEL63TO-l063aV5nLADCgsGY" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `T1jGtZoU-Xa_5a1QKexUU0Jq9WKDtS7TCowVvjoFH04` +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-256", + "x": "r9MRjEQ7CBxAgMyEG3ZjIlkGCuRX0rTaBdbkAcY17hA", + "y": "MRSgHQycDFPdSABGv5V0Qd-2q7ebs_x0_fNFyabGgXU", + "d": "LK9yfSxuET5n5uZDNO-64sJKWxJs7LTkqhA4mAuKQnE" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `dmfXisqWjRT-tFpODOD-G0CBF6zjHywNUjrrD3IFmcs` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiVkRGcVIzUmFiMVV0V0dGZk5XRXhVVXRsZUZWVk1FcHhPVmRMUkhSVE4xUkRiM2RXZG1wdlJrZ3dOQSIsImFwdiI6IlpHMW1XR2x6Y1ZkcVVsUXRkRVp3VDBSUFJDMUhNRU5DUmpaNmFraDVkMDVWYW5KeVJETkpSbTFqY3ciLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJjcnYiOiJQLTI1NiIsImt0eSI6IkVDIiwieCI6Ik5ZM3Zra04wYTFPRTBuZk1UaDR4U25IU1A2c0VianYycWp5T3J6Rm9TNnMiLCJ5IjoibUhOdnZYUmVmV0lHcU4zTC1ZWnctdElMTXZlUURWcEEzSk55V20tR21HUSJ9LCJraWQiOiJkbWZYaXNxV2pSVC10RnBPRE9ELUcwQ0JGNnpqSHl3TlVqcnJEM0lGbWNzIiwic2tpZCI6IlQxakd0Wm9VLVhhXzVhMVFLZXhVVTBKcTlXS0R0UzdUQ293VnZqb0ZIMDQiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "encrypted_key": "dXV4byLXvAHCGKSNqOT87cOwTmdlhn9665LvwXre0BJqSectrLZVQZ4udqKCccgdZAGwmIct5T-uwGYz_tLkOUQBbTXBxHDt", + "iv": "ULEzDlTLgPXfS3a-SfspZmD02o53DfTB", + "ciphertext": "8Z4TLHADLiuHmQEFMrU", + "tag": "oJgQoovq__wSPgzco1udpA" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiVkRGcVIzUmFiMVV0V0dGZk5XRXhVVXRsZUZWVk1FcHhPVmRMUkhSVE4xUkRiM2RXZG1wdlJrZ3dOQSIsImFwdiI6IlpHMW1XR2x6Y1ZkcVVsUXRkRVp3VDBSUFJDMUhNRU5DUmpaNmFraDVkMDVWYW5KeVJETkpSbTFqY3ciLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6Ik5ZM3Zra04wYTFPRTBuZk1UaDR4U25IU1A2c0VianYycWp5T3J6Rm9TNnMiLCJ5IjoibUhOdnZYUmVmV0lHcU4zTC1ZWnctdElMTXZlUURWcEEzSk55V20tR21HUSJ9LCJraWQiOiJkbWZYaXNxV2pSVC10RnBPRE9ELUcwQ0JGNnpqSHl3TlVqcnJEM0lGbWNzIiwic2tpZCI6IlQxakd0Wm9VLVhhXzVhMVFLZXhVVTBKcTlXS0R0UzdUQ293VnZqb0ZIMDQiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0.dXV4byLXvAHCGKSNqOT87cOwTmdlhn9665LvwXre0BJqSectrLZVQZ4udqKCccgdZAGwmIct5T-uwGYz_tLkOUQBbTXBxHDt.ULEzDlTLgPXfS3a-SfspZmD02o53DfTB.8Z4TLHADLiuHmQEFMrU.oJgQoovq__wSPgzco1udpA` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-1PU+XC20PKW", + "apu": "VDFqR3Rab1UtWGFfNWExUUtleFVVMEpxOVdLRHRTN1RDb3dWdmpvRkgwNA", + "apv": "ZG1mWGlzcVdqUlQtdEZwT0RPRC1HMENCRjZ6akh5d05VanJyRDNJRm1jcw", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "EC", + "crv": "P-256", + "x": "NY3vkkN0a1OE0nfMTh4xSnHSP6sEbjv2qjyOrzFoS6s", + "y": "mHNvvXRefWIGqN3L-YZw-tILMveQDVpA3JNyWm-GmGQ" + }, + "kid": "dmfXisqWjRT-tFpODOD-G0CBF6zjHywNUjrrD3IFmcs", + "skid": "T1jGtZoU-Xa_5a1QKexUU0Jq9WKDtS7TCowVvjoFH04", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 2.2.2 NIST P-384 key +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "bfuATmVQ_jxLIgfuhKNYrNRNu-VnK4FzTCCVRvycgekS8fIuC4rZS9uQi6Q2Ujwd", + "y": "XkVJ93cLKpeZeCMEOsHRKk4rse1zXpzY6yUibEtwZG9nFWF05Ro8OQs5fZVK2TWC", + "d": "OVzGxGyyaHGJpx1MoSwPjmWPas28sfq1tj7UkYFoK3ENsujmzUduAW6HwyaBlXRW" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `xXdnS3M4Bb497A0ko9c6H0D4NNbj1XpwGr4Tk9Fcw7k` +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-384", + "x": "xhk5K7x4xw9OJpkFhmsY39jceQqx57psvcZstiNZmKbXD7kT9ajfGKFA6YA-ali5", + "y": "7Hj32-JDMNDYWRGy3f-0E9lbUGp6yURMaZ9M36Q_FPgljKgHa9i0Fn1ogr_zEmO3", + "d": "Pc3r6eg15XZeKgTDMPcGjf_SvImZxG4bDzgCh3QShClAwMdmoNbzPZGhBByNrlvO" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `aIlhDTWJmT-_Atad5EBbvbZPkPnz2IYT85I6T44kcE4` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiZUZoa2JsTXpUVFJDWWpRNU4wRXdhMjg1WXpaSU1FUTBUazVpYWpGWWNIZEhjalJVYXpsR1kzYzNhdyIsImFwdiI6IllVbHNhRVJVVjBwdFZDMWZRWFJoWkRWRlFtSjJZbHBRYTFCdWVqSkpXVlE0TlVrMlZEUTBhMk5GTkEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJjcnYiOiJQLTM4NCIsImt0eSI6IkVDIiwieCI6Inp1TjJhYTZBdmRHVVdjaHNyMTdBMENvOWFmcnlnRll6TjRxZlM0dnlNS05BTF83dVVhR1d2ZVBMNkpoc25MMnYiLCJ5IjoiZTJva1U5VWUzbE9CUWxEZnFVczE5NjFQU2tMTkg1d3U1V2NRd2ZuYzdEdmhsU2tXSU9iQWpoekhoVUVZUjRBZSJ9LCJraWQiOiJhSWxoRFRXSm1ULV9BdGFkNUVCYnZiWlBrUG56MklZVDg1STZUNDRrY0U0Iiwic2tpZCI6InhYZG5TM000QmI0OTdBMGtvOWM2SDBENE5OYmoxWHB3R3I0VGs5RmN3N2siLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "encrypted_key": "9bCR6CdqKSRLCFf_vShRhub1pNwoPRypHEqEMfamxy4ZcSp7y8SULzTs2rMmnBt8iJn1PiaBEYbsjsOgzgYamXQ-3OQeIg5z", + "iv": "ryiQAsZiEVcDqJb1jQpG9nQ0p50cXJSM", + "ciphertext": "xQiyTPTrLUFvTeVn9CI", + "tag": "b65D-L5AybH327bWsEIRUg" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiZUZoa2JsTXpUVFJDWWpRNU4wRXdhMjg1WXpaSU1FUTBUazVpYWpGWWNIZEhjalJVYXpsR1kzYzNhdyIsImFwdiI6IllVbHNhRVJVVjBwdFZDMWZRWFJoWkRWRlFtSjJZbHBRYTFCdWVqSkpXVlE0TlVrMlZEUTBhMk5GTkEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMzg0IiwieCI6Inp1TjJhYTZBdmRHVVdjaHNyMTdBMENvOWFmcnlnRll6TjRxZlM0dnlNS05BTF83dVVhR1d2ZVBMNkpoc25MMnYiLCJ5IjoiZTJva1U5VWUzbE9CUWxEZnFVczE5NjFQU2tMTkg1d3U1V2NRd2ZuYzdEdmhsU2tXSU9iQWpoekhoVUVZUjRBZSJ9LCJraWQiOiJhSWxoRFRXSm1ULV9BdGFkNUVCYnZiWlBrUG56MklZVDg1STZUNDRrY0U0Iiwic2tpZCI6InhYZG5TM000QmI0OTdBMGtvOWM2SDBENE5OYmoxWHB3R3I0VGs5RmN3N2siLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0.9bCR6CdqKSRLCFf_vShRhub1pNwoPRypHEqEMfamxy4ZcSp7y8SULzTs2rMmnBt8iJn1PiaBEYbsjsOgzgYamXQ-3OQeIg5z.ryiQAsZiEVcDqJb1jQpG9nQ0p50cXJSM.xQiyTPTrLUFvTeVn9CI.b65D-L5AybH327bWsEIRUg` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-1PU+XC20PKW", + "apu": "eFhkblMzTTRCYjQ5N0Ewa285YzZIMEQ0Tk5iajFYcHdHcjRUazlGY3c3aw", + "apv": "YUlsaERUV0ptVC1fQXRhZDVFQmJ2YlpQa1BuejJJWVQ4NUk2VDQ0a2NFNA", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "EC", + "crv": "P-384", + "x": "zuN2aa6AvdGUWchsr17A0Co9afrygFYzN4qfS4vyMKNAL_7uUaGWvePL6JhsnL2v", + "y": "e2okU9Ue3lOBQlDfqUs1961PSkLNH5wu5WcQwfnc7DvhlSkWIObAjhzHhUEYR4Ae" + }, + "kid": "aIlhDTWJmT-_Atad5EBbvbZPkPnz2IYT85I6T44kcE4", + "skid": "xXdnS3M4Bb497A0ko9c6H0D4NNbj1XpwGr4Tk9Fcw7k", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 2.2.3 NIST P-521 key +- Sender key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "ACN9T83BbPNn1eRyo-TrL0GyC7kBNQvgUxk55fCeQKDSTVhbzCKia7WecCUshyEF-BOQbfEsOIUCq3g7xY3VEeth", + "y": "APDIfDv6abLQ-Zb_p8PxwJe1x3U0-PdgXLNbtS7evGuUROHt79SVkpfXcZ3UaEc6cMoFfd2oMvbmUjCMM4-Sgipn", + "d": "AXCGyR9uXY8vDr7D4HvMxep-d5biQzgHR6WsdOF4R5M9qYb8FhRIQCMbmDSZzCuqgGgXrPRMPm5-omvWVeYqwwa3" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `bq3OI5517dSIMeD9K3lTqvkvvkmsRtifD6tvjlrKYsU` +- Single Recipient key JWK format: +```json +{ + "kty": "EC", + "crv": "P-521", + "x": "AZi-AxJkB09qw8dBnNrz53xM-wER0Y5IYXSEWSTtzI5Sdv_5XijQn9z-vGz1pMdww-C75GdpAzp2ghejZJSxbAd6", + "y": "AZzRvW8NBytGNbF3dyNOMHB0DHCOzGp8oYBv_ZCyJbQUUnq-TYX7j8-PlKe9Ce5acxZzrcUKVtJ4I8JgI5x9oXIW", + "d": "AHGOZNkAcQCdDZOpQRdbH-f89mpjY_kGmtEpTExd51CcRlHhXuuAr6jcgb8YStwy9FN7vCU1y5LnJfKhGUGrP2a4" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `7icoqReWFlpF16dzZD3rBgK1cJ265WzfF9sJJXqOe0M` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiWW5FelQwazFOVEUzWkZOSlRXVkVPVXN6YkZSeGRtdDJkbXR0YzFKMGFXWkVOblIyYW14eVMxbHpWUSIsImFwdiI6Ik4ybGpiM0ZTWlZkR2JIQkdNVFprZWxwRU0zSkNaMHN4WTBveU5qVlhlbVpHT1hOS1NsaHhUMlV3VFEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJjcnYiOiJQLTUyMSIsImt0eSI6IkVDIiwieCI6IkFJemJtMzBZRGVIV21sXy1zeHE2c2NHbEdDS3ZuRmttR2pkc1hKOXN6bm5JQzFMSndvc1hqYmRRd29EX2NjbmtkcUtpaU4tNVVFZGtPTEZldDdXbG83bC0iLCJ5IjoiQVdDendGVjJtUFdYMnpaZzN0SHRpVE11SlhGaEtucWhUT0hPWXBzRF9uRlhGRFhrTlRyd0QyblpVNi1hU2g5Q0NLajF2N0x5VlJ0UE0ybzM5bkt3WEhXWiJ9LCJraWQiOiI3aWNvcVJlV0ZscEYxNmR6WkQzckJnSzFjSjI2NVd6ZkY5c0pKWHFPZTBNIiwic2tpZCI6ImJxM09JNTUxN2RTSU1lRDlLM2xUcXZrdnZrbXNSdGlmRDZ0dmpscktZc1UiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "encrypted_key": "-cL11h9eF6CRycMYxvJ6Ksmlf-97Vg2s_ziVnFF5RueiGrvKFmgQp09GIyxrMdTG2so6IRmifOlpwF0YPuzyThhmxToTyfpr", + "iv": "Q0sk9bMraCAJhZyFi3sOAYMoTac4ZuGj", + "ciphertext": "O6OlFqFMz587083_OMU", + "tag": "TyXZ30wpVZ6nmj16evdBnA" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiWW5FelQwazFOVEUzWkZOSlRXVkVPVXN6YkZSeGRtdDJkbXR0YzFKMGFXWkVOblIyYW14eVMxbHpWUSIsImFwdiI6Ik4ybGpiM0ZTWlZkR2JIQkdNVFprZWxwRU0zSkNaMHN4WTBveU5qVlhlbVpHT1hOS1NsaHhUMlV3VFEiLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJrdHkiOiJFQyIsImNydiI6IlAtNTIxIiwieCI6IkFJemJtMzBZRGVIV21sXy1zeHE2c2NHbEdDS3ZuRmttR2pkc1hKOXN6bm5JQzFMSndvc1hqYmRRd29EX2NjbmtkcUtpaU4tNVVFZGtPTEZldDdXbG83bC0iLCJ5IjoiQVdDendGVjJtUFdYMnpaZzN0SHRpVE11SlhGaEtucWhUT0hPWXBzRF9uRlhGRFhrTlRyd0QyblpVNi1hU2g5Q0NLajF2N0x5VlJ0UE0ybzM5bkt3WEhXWiJ9LCJraWQiOiI3aWNvcVJlV0ZscEYxNmR6WkQzckJnSzFjSjI2NVd6ZkY5c0pKWHFPZTBNIiwic2tpZCI6ImJxM09JNTUxN2RTSU1lRDlLM2xUcXZrdnZrbXNSdGlmRDZ0dmpscktZc1UiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0.-cL11h9eF6CRycMYxvJ6Ksmlf-97Vg2s_ziVnFF5RueiGrvKFmgQp09GIyxrMdTG2so6IRmifOlpwF0YPuzyThhmxToTyfpr.Q0sk9bMraCAJhZyFi3sOAYMoTac4ZuGj.O6OlFqFMz587083_OMU.TyXZ30wpVZ6nmj16evdBnA` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-1PU+XC20PKW", + "apu": "YnEzT0k1NTE3ZFNJTWVEOUszbFRxdmt2dmttc1J0aWZENnR2amxyS1lzVQ", + "apv": "N2ljb3FSZVdGbHBGMTZkelpEM3JCZ0sxY0oyNjVXemZGOXNKSlhxT2UwTQ", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "EC", + "crv": "P-521", + "x": "AIzbm30YDeHWml_-sxq6scGlGCKvnFkmGjdsXJ9sznnIC1LJwosXjbdQwoD_ccnkdqKiiN-5UEdkOLFet7Wlo7l-", + "y": "AWCzwFV2mPWX2zZg3tHtiTMuJXFhKnqhTOHOYpsD_nFXFDXkNTrwD2nZU6-aSh9CCKj1v7LyVRtPM2o39nKwXHWZ" + }, + "kid": "7icoqReWFlpF16dzZD3rBgK1cJ265WzfF9sJJXqOe0M", + "skid": "bq3OI5517dSIMeD9K3lTqvkvvkmsRtifD6tvjlrKYsU", + "typ": "application/didcomm-encrypted+json" +} +``` + +#### 2.2.4 X25519 key +- Sender key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "g3Lpdd_DRgjK28qi0sR0-hI-zv7a1X52vpzKc6ZM1Qs", + "d": "cPU_Io7RRHNb_xkQ_D6u3ER4vSjvsILDCKwOj8kVHXQ" +} +``` +- Sender kid (jwk thumbprint raw base64 URL encoded): `j8E-tcw1Z_eOCoKEH-7a9T532r8zXfcavbPZlofN0Ek` +- Single Recipient key JWK format: +```json +{ + "kty": "OKP", + "crv": "X25519", + "x": "VlhpUXj-oGs9ge-VLrmYF7Xuzy73YchIfckaYcQefBw", + "d": "QFHCCy0wzgJ_AlGMnjetTd0tnDaZ_7yqJODSV0d-kkg" +} +``` +- Single Recipient kid (jwk thumbprint raw base64 URL encoded): `_DHSbVaMeZxriDJn5VoHXYXo6BJacwZx_fGIBfCiJ5c` +- Finally, packing the payload outputs the following flattened serialized JWE JSON: +```json +{ + "protected": "eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiYWpoRkxYUmpkekZhWDJWUFEyOUxSVWd0TjJFNVZEVXpNbkk0ZWxobVkyRjJZbEJhYkc5bVRqQkZhdyIsImFwdiI6IlgwUklVMkpXWVUxbFduaHlhVVJLYmpWV2IwaFlXVmh2TmtKS1lXTjNXbmhmWmtkSlFtWkRhVW8xWXciLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJjcnYiOiJYMjU1MTkiLCJrdHkiOiJPS1AiLCJ4IjoiWmdZTkJwcDlRZkZMZFpBT05LaUYxWGdRTkZCdW4tdkx4V25TeTF3ZDRRdyJ9LCJraWQiOiJfREhTYlZhTWVaeHJpREpuNVZvSFhZWG82QkphY3daeF9mR0lCZkNpSjVjIiwic2tpZCI6Imo4RS10Y3cxWl9lT0NvS0VILTdhOVQ1MzJyOHpYZmNhdmJQWmxvZk4wRWsiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0", + "encrypted_key": "6AxohV0ygxzRGGxqKIMovkJf7rCyE1ymbVzxqVEVpioySTzd4Ociy8yTa4uo-wlVCFaKVxitFgD3bgtuidOw5J8r-CXjR42D", + "iv": "AEv2DrMR4rMV8preS0zndED_u11QNnQx", + "ciphertext": "c_RTSoNM5hFpOr3lEFU", + "tag": "m9GKNsP05SKYS9qdTvnsfA" +} +``` +- The compact serialization of this envelope is: + `eyJhbGciOiJFQ0RILTFQVStYQzIwUEtXIiwiYXB1IjoiYWpoRkxYUmpkekZhWDJWUFEyOUxSVWd0TjJFNVZEVXpNbkk0ZWxobVkyRjJZbEJhYkc5bVRqQkZhdyIsImFwdiI6IlgwUklVMkpXWVUxbFduaHlhVVJLYmpWV2IwaFlXVmh2TmtKS1lXTjNXbmhmWmtkSlFtWkRhVW8xWXciLCJjdHkiOiJhcHBsaWNhdGlvbi9kaWRjb21tLXBsYWluK2pzb24iLCJlbmMiOiJYQzIwUCIsImVwayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJYMjU1MTkiLCJ4IjoiWmdZTkJwcDlRZkZMZFpBT05LaUYxWGdRTkZCdW4tdkx4V25TeTF3ZDRRdyJ9LCJraWQiOiJfREhTYlZhTWVaeHJpREpuNVZvSFhZWG82QkphY3daeF9mR0lCZkNpSjVjIiwic2tpZCI6Imo4RS10Y3cxWl9lT0NvS0VILTdhOVQ1MzJyOHpYZmNhdmJQWmxvZk4wRWsiLCJ0eXAiOiJhcHBsaWNhdGlvbi9kaWRjb21tLWVuY3J5cHRlZCtqc29uIn0.6AxohV0ygxzRGGxqKIMovkJf7rCyE1ymbVzxqVEVpioySTzd4Ociy8yTa4uo-wlVCFaKVxitFgD3bgtuidOw5J8r-CXjR42D.AEv2DrMR4rMV8preS0zndED_u11QNnQx.c_RTSoNM5hFpOr3lEFU.m9GKNsP05SKYS9qdTvnsfA` +- The single recipient's headers are merged into the `protected` header, which base64 URL decoded equals to (pretty printed for readability): +```json +{ + "alg": "ECDH-1PU+XC20PKW", + "apu": "ajhFLXRjdzFaX2VPQ29LRUgtN2E5VDUzMnI4elhmY2F2YlBabG9mTjBFaw", + "apv": "X0RIU2JWYU1lWnhyaURKbjVWb0hYWVhvNkJKYWN3WnhfZkdJQmZDaUo1Yw", + "cty": "application/didcomm-plain+json", + "enc": "XC20P", + "epk": { + "kty": "OKP", + "crv": "X25519", + "x": "ZgYNBpp9QfFLdZAONKiF1XgQNFBun-vLxWnSy1wd4Qw" + }, + "kid": "_DHSbVaMeZxriDJn5VoHXYXo6BJacwZx_fGIBfCiJ5c", + "skid": "j8E-tcw1Z_eOCoKEH-7a9T532r8zXfcavbPZlofN0Ek", + "typ": "application/didcomm-encrypted+json" +} +``` diff --git a/features/0335-http-over-didcomm/README.md b/features/0335-http-over-didcomm/README.md index 18f3654e2..61928ddac 100644 --- a/features/0335-http-over-didcomm/README.md +++ b/features/0335-http-over-didcomm/README.md @@ -1,11 +1,11 @@ # 0335: HTTP Over DIDComm -- Authors: [Filip Burlacu](filip.burlacu@securekey.com) (SecureKey) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-12-03 -- Status Note: implementation is being explored by SecureKey +- Authors: [Filip Burlacu](mailto:filip.burlacu@securekey.com) (SecureKey) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-11-26 -- Tags: feature, protocol +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) ## Summary diff --git a/features/0347-proof-negotiation/README.md b/features/0347-proof-negotiation/README.md index 8f0bd99ef..575e9ce3d 100644 --- a/features/0347-proof-negotiation/README.md +++ b/features/0347-proof-negotiation/README.md @@ -1,16 +1,16 @@ # Aries RFC 0347: Proof Negotiation -- Authors: [Philipp Rieblinger](p.rieblinger@esatus.com), [Sebastian Weidenbach](s.weidenbach@esatus.com) +- Authors: [Philipp Rieblinger](mailto:p.rieblinger@esatus.com), [Sebastian Weidenbach](mailto:s.weidenbach@esatus.com) - Status: [PROPOSED](/README.md#proposed) - Since: 2019-12-13 - Status Note: Initial proposal after discussion on rocketchat - Supersedes: - Start Date: 2019-09-09 -- Tags: feature, protocol +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) ## Summary -This RFC proposes an extension to [Aries RFC 0037: Present Proof Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/master/features/0037-present-proof#aries-rfc-0037-present-proof-protocol-10) by taking the concept of groups out of the [DID credential manifest](https://github.com/decentralized-identity/credential-manifest/blob/master/explainer.md) and including them in the present proof protocol. Additionally to the rules described in the credential manifest, an option to provide alternative attributes with a weight is being introduced here. Also, the possibility to include not only attributes, but also credentials and openids in a proof by using a "type" was taken from the DID credential manifest. +This RFC proposes an extension to [Aries RFC 0037: Present Proof Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/main/features/0037-present-proof#aries-rfc-0037-present-proof-protocol-10) by taking the concept of groups out of the [DID credential manifest](https://github.com/decentralized-identity/credential-manifest/blob/master/explainer.md) and including them in the present proof protocol. Additionally to the rules described in the credential manifest, an option to provide alternative attributes with a weight is being introduced here. Also, the possibility to include not only attributes, but also credentials and openids in a proof by using a "type" was taken from the DID credential manifest. The goal of this is an approach to make proof presentation more flexible, allowing attributes to be required or optional as well as allowing a choose-from-a-list scenario. So far, proof requests were to be replied to with a proof response that contained all attributes listed in the proof request. To this, this RFC adds a way to mark attributes as optional, so that they are communicated as nice-to-have to the user of a wallet. @@ -35,7 +35,7 @@ Example of a proof presentation request (from verifier): ``` { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", + "@type": "https://didcomm.org/present-proof/1.0/request-presentation", "@id": "98fd8d82-81a6-4409-acc2-c35ea39d0f28", "comment": "some comment", "request_presentations~attach": [ @@ -43,16 +43,16 @@ Example of a proof presentation request (from verifier): "@id": "libindy-request-presentation-0", "mime-type": "application/json", "data": { - "base64": "" + "base64": "" } } ] } ``` -The base64-encoded content above decodes to the following data structure, a presentation preview: +The base64url-encoded content above decodes to the following data structure, a presentation preview: ``` { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/presentation-preview", + "@type": "https://didcomm.org/present-proof/1.0/presentation-preview", "@context": "https://path.to/schemas/credentials", "comment":"some comment", "~thread": { @@ -88,7 +88,7 @@ The base64-encoded content above decodes to the following data structure, a pres "name": "routing_number", "group": ["A"], "cred_def_id": "", - // "mime-type": "" is missing, so this defaults to a json-formatted string; if it was non-null, 'value' would be interpreted as a base64-encoded string representing a binary BLOB with mime-type telling how to interpret it after base64-decoding + // "mime-type": "" is missing, so this defaults to a json-formatted string; if it was non-null, 'value' would be interpreted as a base64url-encoded string representing a binary BLOB with mime-type telling how to interpret it after base64url-decoding "value": { "type": "string", "maxLength": 9 @@ -193,7 +193,7 @@ The following data structure is an example for a valid answer to the above crede Valid proof presentation: ``` { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/proof-presentation", + "@type": "https://didcomm.org/present-proof/1.0/proof-presentation", "@id": "98fd8d82-81a6-4409-acc2-c35ea39d0f28", "comment": "some comment", "presentations~attach": [ @@ -201,16 +201,16 @@ Valid proof presentation: "@id": "libindy-presentation-0", "mime-type": "application/json", "data": { - "base64": "" + "base64": "" } } ] } ``` -The base64-encoded content above would decode to this data: +The base64url-encoded content above would decode to this data: ``` { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/presentation-preview", + "@type": "https://didcomm.org/present-proof/1.0/presentation-preview", "@context": "https://path.to/schemas/credentials" "comment":"some comment", "~thread": { @@ -269,7 +269,7 @@ The base64-encoded content above would decode to this data: ``` ## Reference -The "@id"-Tag and thread decorator in the above JSON-messages is taken from [RFC 0008](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0008-message-id-and-threading). +The "@id"-Tag and thread decorator in the above JSON-messages is taken from [RFC 0008](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0008-message-id-and-threading). ## Drawbacks @@ -282,7 +282,7 @@ An alternative way of implementing the proof negotiation is performing it ahead The problem with not implementing this feature would be that a proof request may need to be repeated over and over again with a different list of requested attributes each time, until a list is transferred which the specific user can reply to. This process would be unnecessarily complicated and can be facilitated by implementing this here concept. ## Prior art -[RFC0037-present-proof](https://github.com/hyperledger/aries-rfcs/tree/master/features/0037-present-proof) is the foundation which this RFC builds on using groups from the [credential manifest](https://github.com/decentralized-identity/credential-manifest) by +[RFC0037-present-proof](https://github.com/hyperledger/aries-rfcs/tree/main/features/0037-present-proof) is the foundation which this RFC builds on using groups from the [credential manifest](https://github.com/decentralized-identity/credential-manifest) by the decentralized identity foundation, a "format that normalizes the definition of requirements for the issuance of a credential". ## Unresolved questions diff --git a/features/0348-transition-msg-type-to-https/README.md b/features/0348-transition-msg-type-to-https/README.md index 147a97bd8..2efec08de 100644 --- a/features/0348-transition-msg-type-to-https/README.md +++ b/features/0348-transition-msg-type-to-https/README.md @@ -1,17 +1,17 @@ # Aries RFC 0348: Transition Message Type to HTTPs - Authors: [Stephen Curran](mailto:swcurran@cloudcompass.ca) -- Status: [ACCEPTED](/README.md#accepted) -- Since: 2020-01-30 -- Status Note: In step 1 - community is updating implementations to accept old and new formats. **Target Completion Date: 2020.02.29** +- Status: [RETIRED](/README.md#retired) +- Since: 2020-08-26 +- Status Note: In step 2 - community is updating implementations to send new formats. **Target Completion Date: 2020.10.15** - Supersedes: - Start Date: 2019-12-13 -- Tags: feature, community-update +- Tags: [feature](/tags.md#feature), [community-update](/tags.md#community-update) ## Summary Per issue [#225](https://github.com/hyperledger/aries-rfcs/issues/225), the -Aries community has agreed to change the prefix for protocol message types that currently use the +Aries community has agreed to change the prefix for protocol message types that currently use `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/` to use `https://didcomm.org/`. Examples of the two message types forms are: - Before: `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/notification/1.0/ack` @@ -27,9 +27,9 @@ The transition from the old to new formats will occur in four steps: - **DONE Pre-work**: where we agree on the transition plan outlined in this RFC. - Any RFC updates related to this transition needed before starting the transition are completed. - > To Do: Identify if there any prerequisite RFC changes to be made. -- **IN PROGRESS Step 1: Agent builders MUST update all agent code bases and deployments to accept incoming message types in the old (did) and new (https) formats. During this step, agents MUST default to sending out messages in the old format.** +- **DONE Step 1: Agent builders MUST update all agent code bases and deployments to accept incoming message types in the old (did) and new (https) formats. During this step, agents MUST default to sending out messages in the old format.** - Each agent builder SHOULD notify the community they have completed Step 1 by submitting a PR to update their entry in the [implementations](#implementations) accordingly. -- **Step 2**: Agent builders MUST update all agent code bases and deployments to send out all messages using the new (https) format. The old (did) format is deprecated but will still be accepted. An agent deployment MAY send out an old format message type upon receipt of a message containing an old format message type. +- **IN PROGRESS Step 2**: Agent builders MUST update all agent code bases and deployments to send out all messages using the new (https) format. The old (did) format is deprecated but will still be accepted. An agent deployment MAY send out an old format message type upon receipt of a message containing an old format message type. - Each agent builder SHOULD notify the community they have completed Step 2 by submitting a PR to update their entry in the [implementations](#implementations) accordingly. - **Step 3**: Agent builders SHOULD update their deployments to remove all support for receiving the old format and MUST NOT send out messages using the old message type format. @@ -90,12 +90,14 @@ Name / Link | Implementation Notes [Aries Protocol Test Suite](https://github.com/hyperledger/aries-protocol-test-suite) | No steps completed [Aries Toolbox](https://github.com/hyperledger/aries-toolbox) | Completed Step 1 [code change](https://github.com/hyperledger/aries-toolbox/pull/155). [Aries Framework - .NET](https://github.com/hyperledger/aries-framework-dotnet) | Completed Step 1 [code change](https://github.com/hyperledger/aries-framework-dotnet/pull/116) -[Trinsic](https://trinsic.id/) | No steps completed +[Trinsic.id](https://trinsic.id/) | No steps completed [Aries Cloud Agent - Python](https://github.com/hyperledger/aries-cloudagent-python) | Completed Step 1 [code change](https://github.com/hyperledger/aries-cloudagent-python/pull/379) [Aries Static Agent - Python](https://github.com/hyperledger/aries-staticagent-python) | No steps completed -[Aries Framework - Go](https://github.com/hyperledger/aries-framework-go) | No steps completed +[Aries Framework - Go](https://github.com/hyperledger/aries-framework-go) | Completed Step 2 [Connect.Me](https://www.evernym.com/blog/connect-me-sovrin-digital-wallet/) | No steps completed [Verity](https://www.evernym.com/products/) | No steps completed -[Pico Labs](http://picolabs.io/) | Completed Step 1 [code change](https://github.com/picolab/G2S) and notifying known owner/operators of Pico Agents +[Pico Labs](http://picolabs.io/) | Completed Step 2 even though [deprecated](https://github.com/picolab/G2S) [IBM](https://github.com/IBM-Blockchain-Identity/unknown) | Completed Step 1 [code change](https://github.com/hyperledger/indy-sdk/pull/2136) IBM Agent | Completed Step 1 +[Aries Cloud Agent - Pico](https://github.com/Picolab/aries-cloudagent-pico) | Completed Step 2 [code change](https://github.com/Picolab/aries-cloudagent-pico/commit/2fb4b5f714f32a300ec6ae2655cf9319c0ff3703) +[Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) | Completed Step 2 [code change](https://github.com/hyperledger/aries-framework-javascript/pull/213) diff --git a/features/0351-purpose-decorator/README.md b/features/0351-purpose-decorator/README.md index 0da404844..30e647976 100644 --- a/features/0351-purpose-decorator/README.md +++ b/features/0351-purpose-decorator/README.md @@ -1,11 +1,11 @@ # Aries RFC 0351: Purpose Decorator -- Authors: [Filip Burlacu](filip.burlacu@securekey.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-12-16 -- Status Note: implementation is being explored by SecureKey +- Authors: [Filip Burlacu](mailto:filip.burlacu@securekey.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-12-05 -- Tags: feature, decorator +- Tags: [feature](/tags.md#feature), [decorator](/tags.md#decorator) ## Summary diff --git a/features/0360-use-did-key/README.md b/features/0360-use-did-key/README.md index 90c8c2536..b7fac14ca 100644 --- a/features/0360-use-did-key/README.md +++ b/features/0360-use-did-key/README.md @@ -1,12 +1,11 @@ # Aries RFC 0360: did:key Usage -- Authors: [Tobias Looker](tobias.looker@mattr.global), [Stephen Curran](mailto:swcurran@cloudcompass.ca) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2019-12-17 -- Status Note: Socialized with mixed support; did:key method is a [W3C CCG work item](https://w3c-ccg.github.io/community/work_items.html) -- Supersedes: +- Authors: [Tobias Looker](mailto:tobias.looker@mattr.global), [Stephen Curran](mailto:swcurran@cloudcompass.ca) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 +- Status Note: Referenced in a number of Aries RFCs and formalized as part of [AIP 2.0](../../concepts/0302-aries-interop-profile/README.md) did:key method is a [W3C CCG work item](https://w3c-ccg.github.io/community/work_items.html) - Start Date: 2019-12-17 -- Tags: feature +- Tags: [feature](/tags.md#feature) ## Summary @@ -28,7 +27,7 @@ Note that simply knowing the key type is not necessarily sufficient to be able t ## Tutorial -An example of the use of the replacement of a verkey with `did:key` can be found in the [~service decorator RFC](https://github.com/hyperledger/aries-rfcs/tree/master/features/0056-service-decorator). Notably in the example at the beginning of the [tutorial](https://github.com/hyperledger/aries-rfcs/tree/master/features/0056-service-decorator#tutorial) section, the verkeys in the `recipientKeys` and `routingKeys` items would be changed from native keys to use `did:key` as follows: +An example of the use of the replacement of a verkey with `did:key` can be found in the [~service decorator RFC](https://github.com/hyperledger/aries-rfcs/tree/main/features/0056-service-decorator). Notably in the example at the beginning of the [tutorial](https://github.com/hyperledger/aries-rfcs/tree/main/features/0056-service-decorator#tutorial) section, the verkeys in the `recipientKeys` and `routingKeys` items would be changed from native keys to use `did:key` as follows: ``` jsonc { @@ -46,7 +45,9 @@ Thus, `8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K` becomes `did:key:z6MkmjY8Gn - Start with the original (presumably) base58 ed25519 public key - Since we have only a naked public key, we must assume the format - Base58 decode the public key to get the hex version -- Multicodec: Prefix with the algorithm type. In this case, `ED01` as the key type is ed25519. +- Multicodec: Prefix with the unsigned varint of the algorithm type. In this case, that means prefixing the string with `unsigned_varint(0xed)` (which is `0xed 0x01`) for the key type of ed25519, + - the `0xed` is per the [multicodec table](https://github.com/multiformats/multicodec/blob/master/table.csv) (search for `ed25519`). + - Note that unsigned varint handling varies by key type prefix, so don't just assume the same handling (e.g. `code+0x01`) for other key type prefixes. For a broader discussion of this see this [issue comment](https://github.com/w3c-ccg/did-method-key/issues/29#issuecomment-786039356) in the `did:key` repo. - Multibase: Base58 encode the result and prefix that with "z" to indicate base58 encoding - DID: Prefix that with the DID Method prefix `did:key:` @@ -56,15 +57,17 @@ The `did:key` method uses the strings that are the DID, public key and key type The following currently implemented RFCs would be affected by acceptance of this RFC. In these RFCs, the JSON items that currently contain naked public keys (mostly the items `recipientKeys` and `routingKeys`) would be changed to use `did:key` references where applicable. Note that in these items public DIDs could also be used if applicable for a given use case. -- [0023-did-exchange](https://github.com/hyperledger/aries-rfcs/tree/master/features/0023-did-exchange) - Invitation Message -- [0028-introduce](https://github.com/hyperledger/aries-rfcs/tree/master/features/0028-introduce) -- [0056-service-decorator](https://github.com/hyperledger/aries-rfcs/tree/master/features/0056-service-decorator) -- [0160-connection-protocol](https://github.com/hyperledger/aries-rfcs/tree/master/features/0160-connection-protocol) +- [0023-did-exchange](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange) - Invitation Message +- [0028-introduce](https://github.com/hyperledger/aries-rfcs/tree/main/features/0028-introduce) +- [0056-service-decorator](https://github.com/hyperledger/aries-rfcs/tree/main/features/0056-service-decorator) +- [0160-connection-protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol) +- [0434-out-of-band-protocols](https://github.com/hyperledger/aries-rfcs/blob/main/features/0434-outofband/README.md) +- [0211-mediator-coordination-protocol](https://github.com/hyperledger/aries-rfcs/blob/main/features/0211-route-coordination/README.md) Service entries in `did:peer` DIDDocs (such as in RFCs -[0094-cross-domain-messaging](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0094-cross-domain-messaging) +[0094-cross-domain-messaging](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0094-cross-domain-messaging) and -[0067-didcomm-diddoc-conventions](https://github.com/hyperledger/aries-rfcs/tree/master/features/0067-didcomm-diddoc-conventions)) +[0067-didcomm-diddoc-conventions](https://github.com/hyperledger/aries-rfcs/tree/main/features/0067-didcomm-diddoc-conventions)) should **NOT** use a `did:key` public key representation. Instead, service entries in the DIDDoc should reference keys defined internally in the DIDDoc where appropriate. diff --git a/features/0418-rich-schema-encoding/README.md b/features/0418-rich-schema-encoding/README.md index fc63e82e0..3dcee7ccc 100644 --- a/features/0418-rich-schema-encoding/README.md +++ b/features/0418-rich-schema-encoding/README.md @@ -1,8 +1,8 @@ # Aries RFC 0418: Aries Rich Schema Encoding Objects - Author: [Ken Ebert](mailto:ken@sovrin.org), [Mike Lodder](mailto:mike@sovrin.org), [Brent Zundel](mailto:brent.zundel@evernym.com), [Alexander Shcherbakov](mailto:alexander.shcherbakov@evernym.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-02-10 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-03-19 - Tags: [feature](/tags.md#feature), [rich-schemas](/tags.md#rich-schemas) @@ -25,7 +25,7 @@ and avoid hashed values as much as possible, as they do not support predicate proofs. Encoding objects are processed in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common). ## Motivation @@ -58,7 +58,7 @@ is stored on the ledger. ### Properties Encoding's properties follow the generic template defined in -[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). Encoding's `content` field is a JSON-serialized string with the following fields: @@ -181,12 +181,12 @@ Aries will provide a means for writing contexts to and reading contexts from a verifiable data registry (such as a distributed ledger). An Encoding object will be written to the ledger in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). ### Aries Data Registry Interface Aries Data Registry Interface methods for adding and retrieving an Encoding object from the -ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#aries-data-registry-interface). +ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#aries-data-registry-interface). This means the following methods can be used: - `write_rich_schema_object` @@ -197,13 +197,12 @@ This means the following methods can be used: [reference]: #reference The following is a -[reference implementation of various transformation algorithms](https://github.com/sovrin-foundation/aries-credx-framework-rs/blob/master/src/encoding/mod.rs) -Here is the paper that defines -[Camenisch-Lysyanskaya signatures.][CL-signatures] -[CL-signatures]: (https://groups.csail.mit.edu/cis/pubs/lysyanskaya/cl02b.pdf) +[reference implementation of various transformation algorithms](https://github.com/sovrin-foundation/aries-credx-framework-rs/blob/master/src/encoding/mod.rs). -- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common) +[Here](https://www.researchgate.net/publication/220922101_A_Signature_Scheme_with_Efficient_Protocols) is the paper that defines Camenisch-Lysyanskaya signatures. + +- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common) ## Drawbacks diff --git a/features/0428-prepare-issue-rich-credential/README.md b/features/0428-prepare-issue-rich-credential/README.md index 42cea3b38..472dda37d 100644 --- a/features/0428-prepare-issue-rich-credential/README.md +++ b/features/0428-prepare-issue-rich-credential/README.md @@ -1,8 +1,8 @@ # 0428: Prerequisites to Issue Rich Credential -- Authors: [Brent Zundel](), [Ken Ebert]() -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-02-20 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Authors: [Brent Zundel](mailto:brent.zundel@evernym.com), [Ken Ebert](mailto:ken@sovrin.org) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2020-02-19 - Tags: [feature](/tags.md#feature), [rich-schemas](/tags.md#rich-schemas) @@ -44,7 +44,7 @@ use is already present. definition refers to the issuer DID. 1. Using the credential definition, mapping, and schema(s) issue to the holder a credential based on the credential definition and the supplied claim data. The -[Issue Credential Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/master/features/0036-issue-credential) +[Issue Credential Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential) will be the model for another RFC containing minor modifications to issue a credential using the new rich schema objects. @@ -54,13 +54,13 @@ Subsequent credentials may be issued by repeating only the last step. ## Reference -- [RFC 0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [RFC 0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common) -- [RFC 0249: Aries Rich Schema Contexts](https://github.com/hyperledger/aries-rfcs/tree/master/features/0249-rich-schema-contexts) -- [RFC 0281: Aries Rich Schemas](https://github.com/hyperledger/aries-rfcs/tree/master/features/0281-rich-schemas) -- [RFC XXXX: Aries Rich Schema Mappings](https://github.com/hyperledger/aries-rfcs/tree/master/features/XXXX-rich-schema-mappings) -- [RFC XXXX: Aries Rich Schema Credential Definitions](https://github.com/hyperledger/aries-rfcs/tree/master/features/XXXX-rich-schema-cred-defs) -- [RFC 0036: Issue Credential Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/master/features/0036-issue-credential) +- [RFC 0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [RFC 0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common) +- [RFC 0249: Aries Rich Schema Contexts](https://github.com/hyperledger/aries-rfcs/tree/main/features/0249-rich-schema-contexts) +- [RFC 0281: Aries Rich Schemas](https://github.com/hyperledger/aries-rfcs/tree/main/features/0281-rich-schemas) +- [RFC XXXX: Aries Rich Schema Mappings](https://github.com/hyperledger/aries-rfcs/tree/main/features/XXXX-rich-schema-mappings) +- [RFC XXXX: Aries Rich Schema Credential Definitions](https://github.com/hyperledger/aries-rfcs/tree/main/features/XXXX-rich-schema-cred-defs) +- [RFC 0036: Issue Credential Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential) diff --git a/features/0429-prepare-req-rich-pres/README.md b/features/0429-prepare-req-rich-pres/README.md index e8481fe56..6c22f6b39 100644 --- a/features/0429-prepare-req-rich-pres/README.md +++ b/features/0429-prepare-req-rich-pres/README.md @@ -1,8 +1,8 @@ # 0429: Prerequisites to Request Rich Presentation -- Authors: [Brent Zundel](), [Ken Ebert]() -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-02-21 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Authors: [Brent Zundel](mailto:brent.zundel@evernym.com), [Ken Ebert](mailto:ken@sovrin.org) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2020-02-19 - Tags: [feature](/tags.md#feature), [rich-schemas](/tags.md#rich-schemas) @@ -30,7 +30,7 @@ rules. Presentation definitions specify desired attributes and predicates). the verifiable data registry. (Anchoring the presentation definition to the verifiable data registry allows other verifiers to easily use it. It can be done by writing the full presentation definition's content to the ledger, or just writing a digital fingerprint/hash of the content.) 1. Using the presentation definition, request a presentation from the holder. -The [Present Proof Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/master/features/0037-present-proof) +The [Present Proof Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/main/features/0037-present-proof) will be the model for another RFC containing minor modifications for presenting a proof based on verifiable credentials using the new rich schema objects. @@ -38,10 +38,10 @@ a proof based on verifiable credentials using the new rich schema objects. ## Reference -- [RFC 0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [RFC 0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common) -- [RFC XXXX: Aries Rich Schema Presentation Definitions](https://github.com/hyperledger/aries-rfcs/tree/master/features/XXXX-rich-schema-pres-defs) -- [RFC 0037: Present Proof Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/master/features/0037-present-proof) +- [RFC 0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [RFC 0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common) +- [RFC XXXX: Aries Rich Schema Presentation Definitions](https://github.com/hyperledger/aries-rfcs/tree/main/features/XXXX-rich-schema-pres-defs) +- [RFC 0037: Present Proof Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/main/features/0037-present-proof) diff --git a/features/0434-outofband/ExampleQRCode.png b/features/0434-outofband/ExampleQRCode.png index 7330ccbad..f96415ae7 100644 Binary files a/features/0434-outofband/ExampleQRCode.png and b/features/0434-outofband/ExampleQRCode.png differ diff --git a/features/0434-outofband/README.md b/features/0434-outofband/README.md index 0cabf850a..01f90d316 100644 --- a/features/0434-outofband/README.md +++ b/features/0434-outofband/README.md @@ -1,15 +1,13 @@ -# Aries RFC 0434: Out-of-Band Protocols +# Aries RFC 0434: Out-of-Band Protocol 1.1 -- Authors: [Ryan West](ryan.west@sovrin.org), [Daniel Bluhm](daniel.bluhm@sovrin.org), Matthew Hailstone, [Stephen Curran](swcurran@cloudcompass.ca), [Sam Curren](sam@sovrin.org), [George Aristy](george.aristy@securekey.com) -- Status: [PROPOSED](/README.md#proposed) +- Authors: [Ryan West](mailto:ryan.west@sovrin.org), [Daniel Bluhm](mailto:daniel.bluhm@sovrin.org), Matthew Hailstone, [Stephen Curran](mailto:swcurran@cloudcompass.ca), [Sam Curren](mailto:sam@sovrin.org), [George Aristy](mailto:george.aristy@securekey.com) +- Status: [ADOPTED](/README.md#adopted) - Since: 2020-03-01 - Status Note: This RFC extracts the `invitation` messages from the [DID Exchange](../../features/0023-did-exchange/README.md) protocol (and perhaps [Connection](../../features/0160-connection-protocol/README.md)), and replaces the combined `present_proof/1.0/request` combined with the `~service` decorator to define an ephemeral (connection-less) challenge. - Supersedes: Invitation Message in [0160-Connections](https://github.com/hyperledger/aries-rfcs/blob/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0160-connection-protocol/README.md#0-invitation-to-connect) and Invitation Message in [0023-DID-Exchange](https://github.com/hyperledger/aries-rfcs/blob/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0023-did-exchange/README.md#0-invitation-to-exchange). - Start Date: 2020-03-01 -- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) -- Protocol Name: Out-of-Band Invitation, Out-of-Band Request -- Version: 1.0, 1.0 -- URI: `http://didcomm.org/out-of-band/%VER` +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) +- URI: `https://didcomm.org/out-of-band/%VER` ## Summary @@ -33,7 +31,7 @@ In the existing Connections and DID Exchange `invitation` handling, the _inviter ### Handling of all Out-of-Band Messages -We currently have two sets of out-of-band messages that cannot be delivered via DIDComm because there is no channel. We'd like to align those messages into a single "out of band" protocol so that their handling can be harmonized inside an agent, and a common QR code handling mechanism can be used. +We currently have two sets of out-of-band messages that cannot be delivered via DIDComm because there is no channel. We'd like to align those messages into a single "out-of-band" protocol so that their handling can be harmonized inside an agent, and a common QR code handling mechanism can be used. ### URLs and QR Code Handling @@ -43,7 +41,7 @@ We'd like to have the specification of QR handling harmonized into a single RFC ### Key Concepts -The Out-of-band protocol are used when an agent doesn't know if it has a connection with another agent. This could be because you are trying to establish a new connection with that agent, you have connections but don't know who the other party is, or if you want to have a connection-less interaction. Since there is no DIDComm connection to use for the messages of this protocol, the messages are plaintext and sent out of band, such as via a QR code, in an email message or any other available channel. Since the delivery of out-of-band messages will often be via QR codes, this RFC also covers the use of QR codes. +The Out-of-band protocol is used when an agent doesn't know if it has a connection with another agent. This could be because you are trying to establish a new connection with that agent, you have connections but don't know who the other party is, or if you want to have a connection-less interaction. Since there is no DIDComm connection to use for the messages of this protocol, the messages are plaintext and sent out-of-band, such as via a QR code, in an email message or any other available channel. Since the delivery of out-of-band messages will often be via QR codes, this RFC also covers the use of QR codes. Two well known use cases for using an out-of-band protocol are: @@ -95,20 +93,24 @@ The out-of-band protocol a single message that is sent by the *sender*. "label": "Faber College", "goal_code": "issue-vc", "goal": "To issue a Faber College Graduate credential", + "accept": [ + "didcomm/aip2;env=rfc587", + "didcomm/aip2;env=rfc19" + ], "handshake_protocols": [ - "https://didcomm.org/didexchange/1.0", - "https://didcomm.org/connections/1.0" - ], - "request~attach": [ + "https://didcomm.org/didexchange/1.0", + "https://didcomm.org/connections/1.0" + ], + "requests~attach": [ { - "@id": "request-0", - "mime-type": "application/json", - "data": { - "json": "" - } + "@id": "request-0", + "mime-type": "application/json", + "data": { + "json": "" + } } ], - "service": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] + "services": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] } ``` @@ -119,26 +121,31 @@ The items in the message are: - `label` - [optional] a self-attested string that the receiver may want to display to the user, likely about who sent the out-of-band message. - `goal_code` - [optional] a self-attested code the receiver may want to display to the user or use in automatically deciding what to do with the out-of-band message. - `goal` - [optional] a self-attested string that the receiver may want to display to the user about the context-specific goal of the out-of-band message. -- `handshake_protocols` - [optional] an array of protocols in the order of preference of the sender that the receiver can use in responding to the message in order to create or reuse a connection with the sender. These are not arbitrary protocols but rather protocols that result in the establishment of a connection. One or both of `handshake_protocols` and `request~attach` MUST be included in the message. -- `request~attach` - [optional] an attachment decorator containing an array of request messages in order of preference that the receiver can using in responding to the message. One or both of `handshake_protocols` and `request~attach` MUST be included in the message. +- `accept` - [optional] an array of media (aka mime) types in the order of preference of the sender that the receiver can use in responding to the message. +If `accept` is not specified, the receiver uses its preferred choice to respond to the message. +[RFC 0044](../0044-didcomm-file-and-mime-types/README.md) provides a general discussion of media types. +- `handshake_protocols` - [optional] an array of protocols in the order of preference of the sender that the receiver can use in responding to the message in order to create or reuse a connection with the sender. These are not arbitrary protocols but rather protocols that result in the establishment of a connection. One or both of `handshake_protocols` and `requests~attach` **MUST** be included in the message. +- `requests~attach` - [optional] an attachment decorator containing an array of request messages in order of preference that the receiver can using in responding to the message. One or both of `handshake_protocols` and `requests~attach` **MUST** be included in the message. - While the JSON form of the attachment is used in the example above, the sender could choose to use the base64 form. -- `service` - an item that is the equivalent of the service block of a DIDDoc that the receiver is to use in responding to the message. Additional details below. +- `services` - an array of union types that the receiver uses when responding to the message. Each item is either a DIDComm `service` object (as per [RFC0067](../0067-didcomm-diddoc-conventions/README.md#service-conventions)) or a DID (as per [Decentralized Identifiers v1.0](https://w3c.github.io/did-core/#did-syntax)). Additional details below. If only the `handshake_protocols` item is included, the initial interaction will complete with the establishment (or reuse) of the connection. Either side may then use that connection for any purpose. A common use case (but not required) would be for the sender to initiate another protocol after the connection is established to accomplish some shared goal. -If only the `request~attach` item is included, no new connection is expected to be created, although one could be used if the receiver knows such a connection already exists. The receiver responds to one of the messages in the `request~attach` array. The `request~attach` item might include the first message of a protocol from the sender, or might be a [please-play-the-role](#) message requesting the receiver initiate a protocol. If the protocol requires a further response from the sender to the receiver, the receiver must include a [`~service` decorator](../0056-service-decorator/README.md) for the sender to use in responding. +If only the `requests~attach` item is included, no new connection is expected to be created, although one could be used if the receiver knows such a connection already exists. The receiver responds to one of the messages in the `requests~attach` array. The `requests~attach` item might include the first message of a protocol from the sender, or might be a [please-play-the-role](#) message requesting the receiver initiate a protocol. If the protocol requires a further response from the sender to the receiver, the receiver must include a [`~service` decorator](../0056-service-decorator/README.md) for the sender to use in responding. -If both the `handshake_protocols` and `request~attach` items are included in the message, the receiver should first establish a connection and then respond (using that connection) to one of the messages in the `request~attach` message. If a connection already exists between the parties, the receiver may respond immediately to the `request-attach` message using the established connection. +If both the `handshake_protocols` and `requests~attach` items are included in the message, the receiver should first establish a connection and then respond (using that connection) to one of the messages in the `requests~attach` message. If a connection already exists between the parties, the receiver may respond immediately to the `request-attach` message using the established connection. ### Reuse Messages -While the _receiver_ is expected to respond with an initiating message from a `handshake_protocols` or `request~attach` item using an offered service, the receiver may be able to respond by reusing an existing connection. Specifically, if a connection they have was created from an out-of-band `invitation` from the same public DID of a new `invitation` message, the connection **MAY** be reused. The receiver may choose to not reuse the existing connection for privacy purposes and repeat a handshake protocol to receive a redundant connection. +While the _receiver_ is expected to respond with an initiating message from a `handshake_protocols` or `requests~attach` item using an offered service, the receiver may be able to respond by reusing an existing connection. Specifically, if a connection they have was created from an out-of-band `invitation` from the same `services` DID of a new `invitation` message, the connection **MAY** be reused. The receiver may choose to not reuse the existing connection for privacy purposes and repeat a handshake protocol to receive a redundant connection. -If the receiver desires to reuse the existing connection and a `request~attach` message is present, the receiver should respond to the attached message using the existing connection. +If a message has a service block instead of a DID in the `services` list, you may enable reuse by encoding the key and endpoint of the service block in a [Peer DID numalgo 2](https://identity.foundation/peer-did-method-spec/#generation-method) and using that DID instead of a service block. -If the receiver desires to reuse the existing connection and no request~attach message is present, the receiver **SHOULD** attempt to do so with the `reuse` and `reuse-accepted` messages. This will notify the _inviter_ that the existing connection should be used, along with the context that can be used for follow-on interactions. +If the receiver desires to reuse the existing connection and a `requests~attach` item is included in the message, the receiver **SHOULD** respond to one of the attached messages using the existing connection. -While the `invitation` message is passed unencrypted and out of band, both the `handshake-reuse` and `handshake-reuse-accepted` messages MUST be encrypted and transmitted as normal DIDComm messages. +If the receiver desires to reuse the existing connection and no `requests~attach` item is included in the message, the receiver **SHOULD** attempt to do so with the `reuse` and `reuse-accepted` messages. This will notify the _inviter_ that the existing connection should be used, along with the context that can be used for follow-on interactions. + +While the `invitation` message is passed unencrypted and out-of-band, both the `handshake-reuse` and `handshake-reuse-accepted` messages **MUST** be encrypted and transmitted as normal DIDComm messages. #### Reuse: `https://didcomm.org/out-of-band/%VER/handshake-reuse` @@ -147,8 +154,8 @@ While the `invitation` message is passed unencrypted and out of band, both the ` "@type": "https://didcomm.org/out-of-band/%VER/handshake-reuse", "@id": "", "~thread": { - "thid": "", - "pthid": "" + "thid": "", + "pthid": "" } } ``` @@ -188,28 +195,28 @@ After sending this message, the _inviter_ may continue any desired protocol inte ### Responses -The following table summarizes the different forms of the out-of-band `invitation` message depending on the presence (or not) of the `handshake_protocols` item, the `request~attach` item and whether or not a connection between the agents already exists. +The following table summarizes the different forms of the out-of-band `invitation` message depending on the presence (or not) of the `handshake_protocols` item, the `requests~attach` item and whether or not a connection between the agents already exists. -`handshake_protocols` Present? | `request~attach` Present? | Existing connection? | Receiver action(s) +`handshake_protocols` Present? | `requests~attach` Present? | Existing connection? | Receiver action(s) --- | --- | --- | --- No | No | No | Impossible -Yes | No | No | Uses the first supported protocol from `handshake_protocols` to make a new connection using the first supported `service` entry. -No | Yes | No | Send a response to the first supported request message using the first supported `service` entry. Include a `~service` decorator if the sender is expected to respond. +Yes | No | No | Uses the first supported protocol from `handshake_protocols` to make a new connection using the first supported `services` entry. +No | Yes | No | Send a response to the first supported request message using the first supported `services` entry. Include a `~service` decorator if the sender is expected to respond. No | No | Yes | Impossible -Yes | Yes | No | Use the first supported protocol from `handshake_protocols` to make a new connection using the first supported `service` entry, and then send a response message to the first supported attachment message using the new connection. +Yes | Yes | No | Use the first supported protocol from `handshake_protocols` to make a new connection using the first supported `services` entry, and then send a response message to the first supported attachment message using the new connection. Yes | No | Yes | Send a `handshake-reuse` message. No | Yes | Yes | Send a response message to the first supported request message using the existing connection. Yes | Yes | Yes | Send a response message to the first supported request message using the existing connection. -Both the `goal_code` and `goal` fields should be used with the [localization service decorator](../0043-l10n/README.md). The two fields are to enable both human and machine handling of the out-of-band message. `goal_code` is to specify a generic, protocol level outcome for sending the out-of-band message (e.g. issue verifiable credential, request proof, etc.) that is suitable for machine handling and possibly human display, while `goal` provides context specific guidance, targeting mainly a person controlling the receiver's agent. The list of `goal_code` values is provided in the [Message Catalog](#message-catalog) section of this RFC. +Both the `goal_code` and `goal` fields **SHOULD** be used with the [localization service decorator](../0043-l10n/README.md). The two fields are to enable both human and machine handling of the out-of-band message. `goal_code` is to specify a generic, protocol level outcome for sending the out-of-band message (e.g. issue verifiable credential, request proof, etc.) that is suitable for machine handling and possibly human display, while `goal` provides context specific guidance, targeting mainly a person controlling the receiver's agent. The list of `goal_code` values is provided in the [Message Catalog](#message-catalog) section of this RFC. -#### The `service` Item +#### The `services` Item -As mentioned in the description above, the `service` item array is intended to be analogous to the `service` block of a DIDDoc. When not reusing an existing connection, the receiver scans the array and selects (according to the rules described below) a service entry to use for the response to the out-of-band message. +As mentioned in the description above, the `services` item array is intended to be analogous to the `service` block of a DIDDoc. When not reusing an existing connection, the receiver scans the array and selects (according to the rules described below) a service entry to use for the response to the out-of-band message. -There are two forms of entries in the `service` item array: +There are two forms of entries in the `services` item array: -- a public DID that is resolved to retrieve it's DIDDoc service block, and +- a DID that is resolved to retrieve it's DIDDoc service block, and - an inline service block. The following is an example of a two entry array, one of each form: @@ -218,22 +225,22 @@ The following is an example of a two entry array, one of each form: { "@type": "https://didcomm.org/out-of-band/%VER/invitation", "@id": "", - "label": "Faber College" - "handshake_protocols": ["https://didcomm.org/didexchange/1.0"] - "service": [ - { - "id": "#inline" - "type": "did-communication", - "recipientKeys": ["did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"], - "routingKeys": [], - "serviceEndpoint": "https://example.com:5000" - }, - "did:sov:LjgpST2rjsoxYegQDRm7EL" + "label": "Faber College", + "handshake_protocols": ["https://didcomm.org/didexchange/1.0"], + "services": [ + { + "id": "#inline", + "type": "did-communication", + "recipientKeys": ["did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"], + "routingKeys": [], + "serviceEndpoint": "https://example.com:5000" + }, + "did:sov:LjgpST2rjsoxYegQDRm7EL" ] } ``` -The processing rules for the service block are: +The processing rules for the `services` block are: - Use only entries where the `type` is equal to `did-communication`. - Entries without a `type` are assumed to be `did-communication`. @@ -241,13 +248,13 @@ The processing rules for the service block are: The attributes in the inline form parallel the attributes of a DID Document for increased meaning. The `recipientKeys` and `routingKeys` within the inline block decorator **MUST** be [`did:key` references](https://digitalbazaar.github.io/did-method-key/). -As defined in the [DIDComm Cross Domain Messaging RFC](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0094-cross-domain-messaging), if `routingKeys` is present and non-empty, additional forwarding wrapping are necessary in the response message. +As defined in the [DIDComm Cross Domain Messaging RFC](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0094-cross-domain-messaging), if `routingKeys` is present and non-empty, additional forwarding wrapping are necessary in the response message. When considering routing and options for out-of-band messages, keep in mind that the more detail in the message, the longer the URL will be and (if used) the more dense (and harder to scan) the QR code will be. ##### Service Endpoint -The service endpoint used to transmit the response is either present in the out-of-band message or available in the DID Document of a presented DID. If the endpoint is itself a DID, the `serviceEndpoint` in the DIDDoc of the resolved DID **MUST** be a URI, and the `recipientKeys` must contain a single key. That key is appended to the end of the list of `routingKeys` for processing. For more information about message forwarding and routing, see [RFC 0094 Cross Domain Messaging](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0094-cross-domain-messaging). +The service endpoint used to transmit the response is either present in the out-of-band message or available in the DID Document of a presented DID. If the endpoint is itself a DID, the `serviceEndpoint` in the DIDDoc of the resolved DID **MUST** be a URI, and the `recipientKeys` **MUST** contain a single key. That key is appended to the end of the list of `routingKeys` for processing. For more information about message forwarding and routing, see [RFC 0094 Cross Domain Messaging](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0094-cross-domain-messaging). ### Adoption Messages @@ -255,7 +262,7 @@ The `problem_report` message **MAY** be adopted by the out-of-band protocol if t ### Constraints -An existing connection can only be reused based on a public DID in an out-of-band message. +An existing connection can only be reused based on a DID in the `services` list in an out-of-band message. ## Reference @@ -265,7 +272,7 @@ The full description of the message in this protocol can be found in the [Tutori ### Localization -The `goal_code` and `goal` fields should have localization applied. See the purpose of those fields in the [message type definitions](#messages) section and the [message catalog](#message-catalog) section (immediately below). +The `goal_code` and `goal` fields **SHOULD** have localization applied. See the purpose of those fields in the [message type definitions](#messages) section and the [message catalog](#message-catalog) section (immediately below). ### Message Catalog @@ -273,12 +280,12 @@ The `goal_code` and `goal` fields should have localization applied. See the purp The following values are defined for the `goal_code` field: -Code (cd) | English (en) ---- | --- -issue-vc | To issue a credential -request-proof | To request a proof -create-account | To create an account with a service -p2p-messaging | To establish a peer-to-peer messaging relationship +| Code (cd) | English (en) | +| --------------- | ----------------------------------------------------| +| issue-vc | To issue a credential | +| request-proof | To request a proof | +| create-account | To create an account with a service | +| p2p-messaging | To establish a peer-to-peer messaging relationship | #### `goal` @@ -314,18 +321,18 @@ There is an optional courtesy error message stemming from an out-of-band message ```jsonc { - "@type" : "https://didcomm.org/out-of-band/%VER/problem_report", - "@id" : "5678876542345", - "~thread" : { "pthid": "<@id of the OutofBand message>" }, - "description" : { - "en": "The invitation has expired.", - "code": "expired-invitation" - }, - "impact" : "thread" + "@type": "https://didcomm.org/out-of-band/%VER/problem_report", + "@id": "5678876542345", + "~thread": { "pthid": "<@id of the OutofBand message>" }, + "description": { + "en": "The invitation has expired.", + "code": "expired-invitation" + }, + "impact": "thread" } ``` -See the [problem-report](https://github.com/hyperledger/aries-rfcs/tree/master/features/0035-report-problem) protocol for details on the items in the example. +See the [problem-report](https://github.com/hyperledger/aries-rfcs/tree/main/features/0035-report-problem) protocol for details on the items in the example. ### Flow Overview @@ -335,13 +342,17 @@ The handling of the response is specified by the protocol used. > To Do: Make sure that the following remains in the DID Exchange/Connections RFCs > -> Any Public DID that expresses support for DIDComm by defining a [`service`](https://w3c.github.io/did-core/#service-endpoints) that follows the [DIDComm conventions](../0067-didcomm-diddoc-conventions/README.md#service-conventions) serves as an implicit invitation. If an _invitee_ wishes to connect to any Public DID, they need not wait for an out-of-band invitation message. Rather, they can designate their own label and initiate the appropriate protocol (e.g. [0160-Connections](https://github.com/hyperledger/aries-rfcs/blob/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0160-connection-protocol/README.md#0-invitation-to-connect) or [0023-DID-Exchange](https://github.com/hyperledger/aries-rfcs/blob/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0023-did-exchange/README.md#0-invitation-to-exchange)) for establishing a connection. +> Any Published DID that expresses support for DIDComm by defining a [`service`](https://w3c.github.io/did-core/#service-endpoints) that follows the [DIDComm conventions](../0067-didcomm-diddoc-conventions/README.md#service-conventions) serves as an implicit invitation. If an _invitee_ wishes to connect to any Published DID, they need not wait for an out-of-band invitation message. Rather, they can designate their own label and initiate the appropriate protocol (e.g. [0160-Connections](https://github.com/hyperledger/aries-rfcs/blob/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0160-connection-protocol/README.md#0-invitation-to-connect) or [0023-DID-Exchange](https://github.com/hyperledger/aries-rfcs/blob/9b0aaa39df7e8bd434126c4b33c097aae78d65bf/features/0023-did-exchange/README.md#0-invitation-to-exchange)) for establishing a connection. ### Standard Out-of-Band Message Encoding Using a standard out-of-band message encoding allows for easier interoperability between multiple projects and software platforms. Using a URL for that standard encoding provides a built in fallback flow for users who are unable to automatically process the message. Those new users will load the URL in a browser as a default behavior, and may be presented with instructions on how to install software capable of processing the message. Already onboarded users will be able to process the message without loading in a browser via mobile app URL capture, or via capability detection after being loaded in a browser. -The standard out-of-band message format is a URL with a Base64URLEncoded json object as a query parameter. +The standard out-of-band message format is a URL with a **Base64Url** encoded json object as a query parameter. + +Please note the difference between [Base64Url](https://datatracker.ietf.org/doc/html/rfc4648#section-5) and [Base64](https://datatracker.ietf.org/doc/html/rfc4648#section-4) encoding. + +The Base64URL encoded JSON object **SHOULD NOT** use padding, but the decoding implementation used **MUST** correctly decode padded and unpadded Base64URL encoded data. The URL format is as follows, with some elements described below: @@ -349,17 +360,17 @@ The URL format is as follows, with some elements described below: https:///?oob= ``` -`` and `` should be kept as short as possible, and the full URL should return human readable instructions when loaded in a browser. This is intended to aid new users. The `oob` query parameter is required and is reserved to contain the out-of-band message string. Additional path elements or query parameters are allowed, and can be leveraged to provide coupons or other promise of payment for new users. +`` and `` should be kept as short as possible, and the full URL **SHOULD** return human readable instructions when loaded in a browser. This is intended to aid new users. The `oob` query parameter is required and is reserved to contain the out-of-band message string. Additional path elements or query parameters are allowed, and can be leveraged to provide coupons or other promise of payment for new users. > To do: We need to rationalize this approach `https://` approach with the use of a special protocol (e.g. `didcomm://`) that will enable handling of the URL on mobile devices to automatically invoke an installed app on both Android and iOS. A user must be able to process the out-of-band message on the device of the agent (e.g. when the mobile device can't scan the QR code because it is on a web page on device). -The `` is an agent plaintext message (not a DIDComm message) that has been base64 url encoded. +The `` is an agent plaintext message (not a DIDComm message) that has been Base64Url encoded such that the resulting string can be safely used in a URL. ```javascript -outofband_message = b64urlencode() +outofband_message = base64UrlEncode() ``` -During encoding, whitespace from the json string should be eliminated to keep the resulting out-of-band message string as short as possible. +During Base64Url encoding, whitespace from the JSON string **SHOULD** be eliminated to keep the resulting out-of-band message string as short as possible. #### Example Out-of-Band Message Encoding @@ -371,28 +382,28 @@ Invitation: "@id": "69212a3a-d068-4f9d-a2dd-4741bca89af3", "label": "Faber College", "goal_code": "issue-vc", - "goal": "To issue a Faber College Graduate credential" + "goal": "To issue a Faber College Graduate credential", "handshake_protocols": ["https://didcomm.org/didexchange/1.0", "https://didcomm.org/connections/1.0"], - "service": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] + "services": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] } ``` Whitespace removed: ```jsonc -{"@type":"https://didcomm.org/out-of-band/1.0/invitation","@id":"69212a3a-d068-4f9d-a2dd-4741bca89af3","label":"Faber College", "goal_code":"issue-vc","goal":"To issue a Faber College Graduate credential","handshake_protocols":["https://didcomm.org/didexchange/1.0","https://didcomm.org/connections/1.0"],"service":["did:sov:LjgpST2rjsoxYegQDRm7EL"]} +{"@type":"https://didcomm.org/out-of-band/1.0/invitation","@id":"69212a3a-d068-4f9d-a2dd-4741bca89af3","label":"Faber College","goal_code":"issue-vc","goal":"To issue a Faber College Graduate credential","handshake_protocols":["https://didcomm.org/didexchange/1.0","https://didcomm.org/connections/1.0"],"services":["did:sov:LjgpST2rjsoxYegQDRm7EL"]} ``` -Base 64 URL Encoded: +Base64Url encoded: ```text -eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCAiZ29hbF9jb2RlIjoiaXNzdWUtdmMiLCJnb2FsIjoiVG8gaXNzdWUgYSBGYWJlciBDb2xsZWdlIEdyYWR1YXRlIGNyZWRlbnRpYWwiLCJoYW5kc2hha2VfcHJvdG9jb2xzIjpbImh0dHBzOi8vZGlkY29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIiwiaHR0cHM6Ly9kaWRjb21tLm9yZy9jb25uZWN0aW9ucy8xLjAiXSwic2VydmljZSI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 +eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCJnb2FsX2NvZGUiOiJpc3N1ZS12YyIsImdvYWwiOiJUbyBpc3N1ZSBhIEZhYmVyIENvbGxlZ2UgR3JhZHVhdGUgY3JlZGVudGlhbCIsImhhbmRzaGFrZV9wcm90b2NvbHMiOlsiaHR0cHM6Ly9kaWRjb21tLm9yZy9kaWRleGNoYW5nZS8xLjAiLCJodHRwczovL2RpZGNvbW0ub3JnL2Nvbm5lY3Rpb25zLzEuMCJdLCJzZXJ2aWNlcyI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 ``` -Example URL: +Example URL with Base64Url encoded message: ```text -http://example.com/ssi?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCAiZ29hbF9jb2RlIjoiaXNzdWUtdmMiLCJnb2FsIjoiVG8gaXNzdWUgYSBGYWJlciBDb2xsZWdlIEdyYWR1YXRlIGNyZWRlbnRpYWwiLCJoYW5kc2hha2VfcHJvdG9jb2xzIjpbImh0dHBzOi8vZGlkY29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIiwiaHR0cHM6Ly9kaWRjb21tLm9yZy9jb25uZWN0aW9ucy8xLjAiXSwic2VydmljZSI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 +http://example.com/ssi?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCJnb2FsX2NvZGUiOiJpc3N1ZS12YyIsImdvYWwiOiJUbyBpc3N1ZSBhIEZhYmVyIENvbGxlZ2UgR3JhZHVhdGUgY3JlZGVudGlhbCIsImhhbmRzaGFrZV9wcm90b2NvbHMiOlsiaHR0cHM6Ly9kaWRjb21tLm9yZy9kaWRleGNoYW5nZS8xLjAiLCJodHRwczovL2RpZGNvbW0ub3JnL2Nvbm5lY3Rpb25zLzEuMCJdLCJzZXJ2aWNlcyI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 ``` Out-of-band message URLs can be transferred via any method that can send text, including an email, SMS, posting on a website, or QR Code. @@ -410,9 +421,9 @@ Subject: Your request to connect and receive your graduate verifiable credential Dear Alice, -To receive your Faber College graduation certificate, click here to [connect](http://example.com/ssi?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCAiZ29hbF9jb2RlIjoiaXNzdWUtdmMiLCJnb2FsIjoiVG8gaXNzdWUgYSBGYWJlciBDb2xsZWdlIEdyYWR1YXRlIGNyZWRlbnRpYWwiLCJoYW5kc2hha2VfcHJvdG9jb2xzIjpbImh0dHBzOi8vZGlkY29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIiwiaHR0cHM6Ly9kaWRjb21tLm9yZy9jb25uZWN0aW9ucy8xLjAiXSwic2VydmljZSI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0) with us, or paste the following into your browser: +To receive your Faber College graduation certificate, click here to [connect](http://example.com/ssi?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCJnb2FsX2NvZGUiOiJpc3N1ZS12YyIsImdvYWwiOiJUbyBpc3N1ZSBhIEZhYmVyIENvbGxlZ2UgR3JhZHVhdGUgY3JlZGVudGlhbCIsImhhbmRzaGFrZV9wcm90b2NvbHMiOlsiaHR0cHM6Ly9kaWRjb21tLm9yZy9kaWRleGNoYW5nZS8xLjAiLCJodHRwczovL2RpZGNvbW0ub3JnL2Nvbm5lY3Rpb25zLzEuMCJdLCJzZXJ2aWNlcyI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0) with us, or paste the following into your browser: -http://example.com/ssi?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCAiZ29hbF9jb2RlIjoiaXNzdWUtdmMiLCJnb2FsIjoiVG8gaXNzdWUgYSBGYWJlciBDb2xsZWdlIEdyYWR1YXRlIGNyZWRlbnRpYWwiLCJoYW5kc2hha2VfcHJvdG9jb2xzIjpbImh0dHBzOi8vZGlkY29tbS5vcmcvZGlkZXhjaGFuZ2UvMS4wIiwiaHR0cHM6Ly9kaWRjb21tLm9yZy9jb25uZWN0aW9ucy8xLjAiXSwic2VydmljZSI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 +http://example.com/ssi?oob=eyJAdHlwZSI6Imh0dHBzOi8vZGlkY29tbS5vcmcvb3V0LW9mLWJhbmQvMS4wL2ludml0YXRpb24iLCJAaWQiOiI2OTIxMmEzYS1kMDY4LTRmOWQtYTJkZC00NzQxYmNhODlhZjMiLCJsYWJlbCI6IkZhYmVyIENvbGxlZ2UiLCJnb2FsX2NvZGUiOiJpc3N1ZS12YyIsImdvYWwiOiJUbyBpc3N1ZSBhIEZhYmVyIENvbGxlZ2UgR3JhZHVhdGUgY3JlZGVudGlhbCIsImhhbmRzaGFrZV9wcm90b2NvbHMiOlsiaHR0cHM6Ly9kaWRjb21tLm9yZy9kaWRleGNoYW5nZS8xLjAiLCJodHRwczovL2RpZGNvbW0ub3JnL2Nvbm5lY3Rpb25zLzEuMCJdLCJzZXJ2aWNlcyI6WyJkaWQ6c292OkxqZ3BTVDJyanNveFllZ1FEUm03RUwiXX0 If you don't have an identity agent for holding credentials, you will be given instructions on how you can get one. @@ -424,34 +435,50 @@ Knowledge is Good #### URL Shortening -It seems inevitable that the length of some out-of-band message will be too long to produce a useable QR code. Techniques to avoid unusable QR codes have been presented above, including using attachment links for requests, minimizing the routing of the response and eliminating unnecessary whitespace in the JSON. However, at some point a _sender_ may need generate a very long URL. In that case, a URL shortener redirection should be implemented by the sender as follows: +It seems inevitable that the length of some out-of-band message will be too long to produce a useable QR code. Techniques to avoid unusable QR codes have been presented above, including using attachment links for requests, minimizing the routing of the response and eliminating unnecessary whitespace in the JSON. However, at some point a _sender_ may need generate a very long URL. In that case, a DIDComm specific URL shortener redirection should be implemented by the sender as follows: -- The sender should generate and track a GUID for the out-of-band message URL. -- The shortened version should be: +- The sender generates a unique URL for each shortened out-of-band message. +- The unique URL often includes a unique id component as part of the path or in a query parameter. +- The following URLs are valid examples: - `https://example.com/ssi?id=5f0e3ffb-3f92-4648-9868-0d6f8889e6f3` - - Note the replacement of the query parameter `oob` with `id` when using shortened URL. -- On receipt of this form of message, the agent must do an HTTP GET to retrieve the associated, encoded out-of-band message. - - A sender may want to wait to generate the full invitation until the redirection event of the shortened URL to the full length form dynamic, so a single QR code can be used for distinct out of band messages. + - `https://example.com/8E6nEcJ26TTE` + - `https://example.com/sky/event/8DcnUW2h8m4jcfPdQ2uMN7/work-laptop-bag/s/u` +- On receipt of this form of message, the agent **MUST** perform an HTTP GET to retrieve the associated out-of-band message. The agent **SHOULD** include an `Accept` header requesting the `application/json` MIME type. +- The sender **MAY** include a `Content-Type` header specifying `application/json; charset=utf-8`, and in the case where the agent included an `Accept` header for the `application/json` MIME type, the sender **MUST** include the header. If so, the sender **MUST** return the invitation in JSON format in the response body with a `status_code` of `200`. +- The sender **MAY** respond with a `status_code` of `301` or `302` and include a `Location` header specifying the long out-of-band message URL. + - This redirect option operates like many commercial URL shorteners. +- The sender **MUST** invalidate the URL after message retrieval or after an expiration time to prevent unintended parties from retrieving a copy of the message. + - A sender **MUST NOT** use a commercial URL shortener unless it supports invalidating the URL. A usable QR code will always be able to be generated from the shortened form of the URL. + +#### URL Shortening Caveats + +Some HTTP libraries don't support stopping redirects from occuring on reception of a `301` or `302`, in this instance the redirect is automatically followed and will result in a response that **MAY** have a status of `200` and **MAY** contain a URL that can be processed as a normal `Out-of-Band` message. + +If the agent performs a HTTP GET with the `Accept` header requesting `application/json` MIME type the response can either contain the message in `json` or result in a redirect, processing of the response should attempt to determine which response type is received and process the message accordingly. + #### Out-of-Band Message Publishing The _sender_ will publish or transmit the out-of-band message URL in a manner available to the intended _receiver_. After publishing, the sender is in the _await-response_ state, will the receiver is in the _prepare-response_ state. #### Out-of-Band Message Processing -When they receiver receives the out-of-band message URL, there are two possible user flows, depending on whether the individual has an Aries agent. If the individual is new to Aries, they will likely load the URL in a browser. The resulting page should contain instructions on how to get started by installing an Aries agent. That install flow will transfer the out-of-band message to the newly installed software. +If the receiver receives an `out-of-band` message in the form of a QR code, the receiver should attempt to decode the QR code to an out-of-band message URL for processing. + +When the receiver receives the out-of-band message URL, there are two possible user flows, depending on whether the individual has an Aries agent. If the individual is new to Aries, they will likely load the URL in a browser. The resulting page **SHOULD** contain instructions on how to get started by installing an Aries agent. That install flow will transfer the out-of-band message to the newly installed software. + +A user that already has those steps accomplished will have the URL received by software directly. That software will attempt to base64URL decode the string and can read the out-of-band message directly out of the `oob` query parameter, without loading the URL. If this process fails then the software should attempt the steps to [process a shortened URL](#url-shortening). -A user that already has those steps accomplished will have the URL received by software directly. That software will base64URL decode the string and can read the out-of-band message directly out of the `oob` query parameter, without loading the URL. > **NOTE**: In receiving the out-of-band message, the base64url decode implementation used **MUST** > correctly decode padded and unpadded base64URL encoded data. If the receiver wants to respond to the out-of-band message, they will use the information in the message to prepare the request, including: -- the `handshake_protocols` or `request~attach` to determine the acceptable response messages, and -- the `service` block to determine how to get the response to the sender. +- the `handshake_protocols` or `requests~attach` to determine the acceptable response messages, and +- the `services` block to determine how to get the response to the sender. #### Correlating responses to Out-of-Band messages @@ -467,15 +494,15 @@ Example referencing an explicit invitation: "label": "Bob", "did": "B.did@B:A", "did_doc~attach": { - "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", - "jws": { - "header": { - "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" - }, - "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", - "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" - } - } + "base64": "eyJ0eXAiOiJKV1Qi... (bytes omitted)", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } + } } ``` @@ -485,7 +512,7 @@ The response message from the receiver is encoded according to the standards of ##### Reusing Connections -If an out-of-band invitation has a public DID in the `service` block, and the _receiver_ determines it has previously established a connection with that public DID, the receiver **MAY** send its response on the established connection. See [Reuse Messages](#reuse-messages) for details. +If an out-of-band invitation has a DID in the `services` block, and the _receiver_ determines it has previously established a connection with that DID, the receiver **MAY** send its response on the established connection. See [Reuse Messages](#reuse-messages) for details. ##### Receiver Error Handling @@ -505,17 +532,17 @@ If the receiver included a [`~service` decorator](../0056-service-decorator/READ ## Drawbacks -- Public out-of-band messages (say, a slide at the end of a presentation) all use the same DID. This is not a problem for public institutions, and only provides a minor increase in correlation over sharing an endpoint, key, and routing information in a way that is observable by multiple parties. +- Publicly displayed out-of-band messages (say, a slide at the end of a presentation) all use the same DID. This is not a problem for institutions, and only provides a minor increase in correlation over sharing an endpoint, key, and routing information in a way that is observable by multiple parties. ## Prior art - The out-of-band message/response process is similar to other key exchange protocols. -- The [Connections](https://github.com/hyperledger/aries-rfcs/tree/master/features/0160-connection-protocol) and [DID Exchange](https://github.com/hyperledger/aries-rfcs/tree/master/features/0023-did-exchange) protocols have (or had) their own `invitation` method. +- The [Connections](https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol) and [DID Exchange](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange) protocols have (or had) their own `invitation` method. - The `~service` decorator in combination with a request/response-type protocol message (such as present-proof/request) has previously used in place of the out-of-band `request` message. ## Unresolved questions -- It would be nice if an existing connection could be reused even if it was not started by an agent with a public DID. +- None ## Implementations diff --git a/features/0445-rich-schema-mapping/README.md b/features/0445-rich-schema-mapping/README.md index ffe3b98cc..8abfbbd61 100644 --- a/features/0445-rich-schema-mapping/README.md +++ b/features/0445-rich-schema-mapping/README.md @@ -1,8 +1,8 @@ # Aries RFC 0445: Aries Rich Schema Mapping - Author: [Alexander Shcherbakov](mailto:alexander.shcherbakov@evernym.com), [Ken Ebert](mailto:ken@sovrin.org), [Brent Zundel](mailto:brent.zundel@evernym.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-03-16 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-03-16 - Tags: [feature](/tags.md#feature), [rich-schemas](/tags.md#rich-schemas) @@ -16,12 +16,12 @@ claim in a mapping has a reference to an encoding, and those encodings are defined in encoding objects. Mapping objects are processed in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common). ## Motivation Rich schemas are complex, hierarchical, and possibly nested objects. The -[Camenisch-Lysyanskaya signature][CL-signatures] scheme used by Indy +[Camenisch-Lysyanskaya signature](https://www.researchgate.net/publication/220922101_A_Signature_Scheme_with_Efficient_Protocols) scheme used by Indy requires the attributes to be represented by an array of 256-bit integers. Converting data specified by a rich schema into a flat array of integers requires a mapping object. @@ -70,7 +70,7 @@ with different encodings. Note: The anonymous credential signature scheme currently used by Indy is -[Camenisch-Lysyanskaya signatures][CL-signatures]. It is the use of this +[Camenisch-Lysyanskaya signatures](https://www.researchgate.net/publication/220922101_A_Signature_Scheme_with_Efficient_Protocols). It is the use of this signature scheme in combination with rich schema objects that necessitates a mapping object. If another signature scheme is used which does not have the same requirements, a mapping object may not be necessary or a different @@ -78,13 +78,13 @@ mapping object may need to be defined. ### Properties Mapping's properties follow the generic template defined in -[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). Mapping's `content` field is a JSON-LD-serialized string with the following fields: #### @id A Mapping must have an `@id` property. The value of this property must -be equal to the `id` field which is a DID (see [Identification of Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#identification-of-rich-schema-objects)). +be equal to the `id` field which is a DID (see [Identification of Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#identification-of-rich-schema-objects)). #### @type A Mapping must have a `@type` property. The value of this property must @@ -152,7 +152,7 @@ It is important that no two `rank` values may be identical. '@context': "did:sov:2f9F8ZmxuvDqRiqqY29x6dx9oU4qwFTkPbDpWtwGbdUsrCD", '@type': "rdfs:Class", "schema": "did:sov:4e9F8ZmxuvDqRiqqY29x6dx9oU4qwFTkPbDpWtwGbdUsrCD", - "attribuites" : { + "attributes" : { "issuer": [{ "enc": "did:sov:9x9F8ZmxuvDqRiqqY29x6dx9oU4qwFTkPbDpWtwGbdUsrCD", "rank": 1 @@ -209,12 +209,12 @@ Aries will provide a means for writing contexts to and reading contexts from a verifiable data registry (such as a distributed ledger). A Mapping object will be written to the ledger in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). ### Aries Data Registry Interface Aries Data Registry Interface methods for adding and retrieving a Mapping object from the -ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#aries-data-registry-interface). +ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#aries-data-registry-interface). This means the following methods can be used: - `write_rich_schema_object` @@ -225,13 +225,12 @@ This means the following methods can be used: [reference]: #reference The following is a -[reference implementation of various transformation algorithms](https://github.com/sovrin-foundation/aries-credx-framework-rs/blob/master/src/encoding/mod.rs) -Here is the paper that defines -[Camenisch-Lysyanskaya signatures.][CL-signatures] -[CL-signatures]: (https://groups.csail.mit.edu/cis/pubs/lysyanskaya/cl02b.pdf) +[reference implementation of various transformation algorithms](https://github.com/sovrin-foundation/aries-credx-framework-rs/blob/master/src/encoding/mod.rs). -- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common) +[Here](https://www.researchgate.net/publication/220922101_A_Signature_Scheme_with_Efficient_Protocols) is the paper that defines Camenisch-Lysyanskaya signatures. + +- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common) - [W3C verifiable credential specification](https://www.w3.org/TR/vc-data-model) ## Drawbacks diff --git a/features/0446-rich-schema-cred-def/README.md b/features/0446-rich-schema-cred-def/README.md index 56508d256..81fe80854 100644 --- a/features/0446-rich-schema-cred-def/README.md +++ b/features/0446-rich-schema-cred-def/README.md @@ -1,8 +1,8 @@ # Aries RFC 0446: Aries Rich Schema Credential Definition - Author: [Alexander Shcherbakov](mailto:alexander.shcherbakov@evernym.com), [Ken Ebert](mailto:ken@sovrin.org), [Brent Zundel](mailto:brent.zundel@evernym.com) -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-03-16 -- Status Note: Part of proposed Rich Schema capabilities for credentials +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. - Supersedes: - Start Date: 2019-03-16 - Tags: [feature](/tags.md#feature), [rich-schemas](/tags.md#rich-schemas) @@ -16,7 +16,7 @@ The public keys can be used for signing the credentials by the Issuer according defined by the referenced Mapping. Credential Definition objects are processed in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common). ## Motivation @@ -52,7 +52,7 @@ credentials issued for this key. ### Properties Credential definition's properties follow the generic template defined in -[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). Credential Definition's `content` field is a JSON-serialized string with the following fields: @@ -93,12 +93,12 @@ Aries will provide a means for writing contexts to and reading contexts from a verifiable data registry (such as a distributed ledger). A Credential Definition object will be written to the ledger in a generic way defined in -[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). +[Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#how-rich-schema-objects-are-stored-in-the-data-registry). ### Aries Data Registry Interface Aries Data Registry Interface methods for adding and retrieving a Credential Definition object from the -ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common#aries-data-registry-interface). +ledger comply with the generic approach described in [Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common#aries-data-registry-interface). This means the following methods can be used: - `write_rich_schema_object` @@ -109,13 +109,12 @@ This means the following methods can be used: [reference]: #reference The following is a -[reference implementation of various transformation algorithms](https://github.com/sovrin-foundation/aries-credx-framework-rs/blob/master/src/encoding/mod.rs) -Here is the paper that defines -[Camenisch-Lysyanskaya signatures.][CL-signatures] -[CL-signatures]: (https://groups.csail.mit.edu/cis/pubs/lysyanskaya/cl02b.pdf) +[reference implementation of various transformation algorithms](https://github.com/sovrin-foundation/aries-credx-framework-rs/blob/master/src/encoding/mod.rs). -- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0250-rich-schemas) -- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/master/concepts/0420-rich-schemas-common) +[Here](https://www.researchgate.net/publication/220922101_A_Signature_Scheme_with_Efficient_Protocols) is the paper that defines Camenisch-Lysyanskaya signatures. + +- [0250: Rich Schema Objects](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +- [0420: Rich Schema Objects Common](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0420-rich-schemas-common) ## Drawbacks diff --git a/features/0453-issue-credential-v2/README.md b/features/0453-issue-credential-v2/README.md index c58fc68cc..1a8494a17 100644 --- a/features/0453-issue-credential-v2/README.md +++ b/features/0453-issue-credential-v2/README.md @@ -1,14 +1,35 @@ # Aries RFC 0453: Issue Credential Protocol 2.0 - Authors: Nikita Khateev, Stephen Klump, Stephen Curran -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-03-23 +- Status: [ADOPTED](/README.md#adopted) +- Since: 2021-04-15 - Status Note: See [RFC 0454](../0454-present-proof-v2/README.md) for the presentation part of using credentials. - Supersedes: [RFC 0036 Issue Credential v1.x](../0036-issue-credential/README.md) - Start Date: 2020-03-23 - Tags: [feature](/tags.md#feature), [decorator](/tags.md#decorator), [protocol](/tags.md#protocol), [credentials](/tags.md#credentials), [test-anomaly](/tags.md#test-anomaly) -## Version Change Log +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. +- 20240313: Version 2.0 is the current version +- 20240311: Removed references to payments in the protocol to clarify to those new to the protocol that they have not been implemented by anyone. + +For a period of time, versions 2.1 and 2.2 where defined in this RFC. Those +definitions were added prior to any implementations, and to date, there are no +known implementations available or planned. An attempt at [implementing version 2.1] +was not merged into the main branch of [Aries Cloud Agent Python], deemed +overly complicated and not worth the effort for what amounts to an edge case +(issuing multiple credentials of the same type in a single protocol instance). +Further, there is a [version 3.0] of this protocol that has been specified and implemented that +does not include these capabilities. Thus, a decision was made that versions 2.1 and 2.2 be removed +as being not accepted by the community and overly complicated to both implement +and migrate from. Those interested in seeing how those capabilities were +specified can look at this [protocol before they were removed]. + +[implementing version 2.1]: https://github.com/hyperledger/aries-cloudagent-python/pull/2088 +[protocol before they were removed]: https://github.com/hyperledger/aries-rfcs/tree/00487467f42528a2490bcf9c303b9469ed0da5bb/features/0453-issue-credential-v2 +[Aries Cloud Agent Python]: https://github.com/hyperledger/aries-cloudagent-python +[version 3.0]: https://github.com/decentralized-identity/waci-didcomm/tree/main/issue_credential ### 2.0/propose-credential and identifiers @@ -29,31 +50,39 @@ We need a standard protocol for issuing credentials. This is the basis of intero ## Tutorial +### Name and Version + +`issue-credential`, version 2.0 + ### Roles There are two roles in this protocol: Issuer and Holder. Technically, the latter role is only potential until the protocol completes; that is, the second party becomes a Holder of a credential by completing the protocol. However, we will use the term Holder throughout, to keep things simple. >Note: When a holder of credentials turns around and uses those credentials to prove something, they become a Prover. In the sister RFC to this one, [0454: Present Proof Protocol 2.0](../0454-present-proof-v2/README.md), the Holder is therefore renamed to Prover. Sometimes in casual conversation, the Holder role here might be called "Prover" as well, but more formally, "Holder" is the right term at this phase of the credential lifecycle. +### Goals + +When the goals of each role are not available because of context, goal codes may be specifically included in protocol messages. This is particularly helpful to differentiate between credentials passed between the same parties for several different reasons. A goal code included should be considered to apply to the entire thread and is not necessary to be repeated on each message. Changing the goal code may be done by including the new code in a message. All goal codes are optional, and without default. + ### States The choreography diagram [below](#choreography-diagram) details how state evolves in this protocol, in a "happy path." The states include #### Issuer States -* proposal-received -* offer-sent -* request-received -* credential-issued -* done +- proposal-received +- offer-sent +- request-received +- credential-issued +- done #### Holder States -* proposal-sent -* offer-received -* request-sent -* credential-received -* done +- proposal-sent +- offer-received +- request-sent +- credential-received +- done Errors might occur in various places. For example, an Issuer might offer a credential for a price that the Holder is unwilling to pay. All errors are modeled with a `problem-report` message. Easy-to-anticipate errors reset the flow as shown in the diagrams, and use the code `issuance-abandoned`; more exotic errors (e.g., server crashed at Issuer headquarters in the middle of a workflow) may have different codes but still cause the flow to be abandoned in the same way. That is, in this version of the protocol, all errors cause the state of both parties (the sender and the receiver of the `problem-report`) to revert to `null` (meaning it is no longer engaged in the protocol at all). Future versions of the protocol may allow more granular choices (e.g., requesting and receiving a (re-)send of the `issue-credential` message if the Holder times out while waiting in the `request-sent` state). @@ -63,10 +92,10 @@ The state table outlines the protocol states and transitions. The Issue Credential protocol consists of these messages: -* `propose-credential` - potential Holder to Issuer (optional). Tells what the Holder hopes to receive. -* `offer-credential` - Issuer to potential Holder (optional for some credential implementations; required for Hyperledger Indy). Tells what the Issuer intends to issue, and possibly, the price the Issuer expects to be paid. -* `request-credential` - potential Holder to Issuer. If neither of the previous message types is used, this is the message that begins the protocol. -* `issue-credential` - Issuer to new Holder. Attachment payload contains the actual credential. +- `propose-credential` - potential Holder to Issuer (optional). Tells what the Holder hopes to receive. +- `offer-credential` - Issuer to potential Holder (optional for some credential implementations; required for Hyperledger Indy). Tells what the Issuer intends to issue, and possibly, the price the Issuer expects to be paid. +- `request-credential` - potential Holder to Issuer. If neither of the previous message types is used, this is the message that begins the protocol. +- `issue-credential` - Issuer to new Holder. Attachment payload contains the actual credential. In addition, the [`ack`](../0015-acks/README.md) and [`problem-report`](../0035-report-problem/README.md) messages are adopted into the protocol for confirmation and error handling. @@ -76,20 +105,18 @@ This protocol is about the messages that must be exchanged to issue verifiable c The attachment items in the messages are arrays. The arrays are provided to support the issuing of different credential formats (e.g. ZKP, JSON-LD JWT, or other) containing the same data (claims). The arrays are not to be used for issuing credentials with different claims. The `formats` field of each message associates each attachment with the format (and version) of the attachment. -A registry of attachment formats is provided in this RFC within the message type sections. A sub-section should be added for each attachment format type (and optionally, each version). Updates to the attachment type formats does **NOT** impact the versioning of the Issue Credential protocol. Formats are flexibly defined. For example, the first definitions are for `hlindy-zkp-v1.0`, assuming that all Hyperledger Indy implementations and ledgers will use a common format. However, if a specific instance of Indy uses a different format, another format value can be documented as a new registry entry. +A registry of attachment formats is provided in this RFC within the message type sections. A sub-section should be added for each attachment format type (and optionally, each version). Updates to the attachment type formats does **NOT** impact the versioning of the Issue Credential protocol. Formats are flexibly defined. For example, the first definitions are for `hlindy/cred-abstract@v2.0` et al., assuming that all Hyperledger Indy implementations and ledgers will use a common format. However, if a specific instance of Indy uses a different format, another format value can be documented as a new registry entry. Any of the [0017-attachments RFC](../../concepts/0017-attachments/README.md#json) embedded inline attachments can be used. In the examples below, `base64` is used in most cases, but implementations MUST expect any of the formats. #### Choreography Diagram -
-Note: This diagram was made in draw.io. To make changes: - -- upload the drawing HTML from this folder to the [draw.io](https://draw.io) site (Import From...GitHub), -- make changes, -- export the picture and HTML to your local copy of this repo, and -- submit a pull request. -
+> Note: This diagram was made in draw.io. To make changes: +> +> - upload the drawing HTML from this folder to the [draw.io](https://draw.io) site (Import From...GitHub), +> - make changes, +> - export the picture and HTML to your local copy of this repo, and +> - submit a pull request. The protocol has 3 alternative beginnings: @@ -103,7 +130,7 @@ The offer and proposal messages are part of an optional negotiation phase and ma #### Propose Credential -An optional message sent by the potential Holder to the Issuer to initiate the protocol or in response to a `offer-credential` message when the Holder wants some adjustments made to the credential data offered by Issuer. +An optional message sent by the potential Holder to the Issuer to initiate the protocol or in response to an `offer-credential` message when the Holder wants some adjustments made to the credential data offered by Issuer.
Note: In Hyperledger Indy, where the `request-credential` message can **only** be sent in response to an `offer-credential` message, the `propose-credential` message is the only way for a potential Holder to initiate the workflow. @@ -113,17 +140,18 @@ Message format: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/%VER/propose-credential", + "@type": "https://didcomm.org/issue-credential/%VER/propose-credential", "@id": "", + "goal_code": "", "comment": "", - "credential_proposal": , + "credential_preview": , "formats" : [ { "attach_id" : "", - "format" : "", + "format" : "" } - ] - "filter~attach": [ + ], + "filters~attach": [ { "@id": "", "mime-type": "application/json", @@ -137,17 +165,20 @@ Message format: Description of attributes: -* `comment` -- an optional field that provides human readable information about this Credential Proposal, so the proposal can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). -* `credential_proposal` -- an optional JSON-LD object that represents the credential data that Prover wants to receive. It matches the schema of [Credential Preview](#preview-credential). -* `formats` -- contains an entry for each `filter~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. -* `filter~attach` -- an array of attachments that further define the credential being proposed. This might be used to clarify which formats or format versions are wanted. +- `goal_code` -- optional field that indicates the goal of the message sender. +- `comment` -- an optional field that provides human readable information about this Credential Proposal, so the proposal can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). +- `credential_preview` -- an optional JSON-LD object that represents the credential data that Prover wants to receive. It matches the schema of [Credential Preview](#preview-credential). +- `formats` -- contains an entry for each `filters~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. +- `filters~attach` -- an array of attachments that further define the credential being proposed. This might be used to clarify which formats or format versions are wanted. ##### Propose Attachment Registry Credential Format | Format Value | Link to Attachment Format | Comment | ---- | --- | --- | --- | -DIF Credential Manifest | `dif/credential-manifest@v1.0` | [`propose-credential` attachment format](../0511-dif-cred-manifest-attach/README.md#propose-credential-attachment-format) | -Hyperledger Indy Credential Propose | hlindy-zkp-v1.0 | _To Do_: Add link to point to Indy Docs | +--- | --- | --- | --- | +DIF Credential Manifest | `dif/credential-manifest@v1.0` | [`propose-credential` attachment format](../0511-dif-cred-manifest-attach/README.md#propose-credential-attachment-format) | | +Linked Data Proof VC Detail | `aries/ld-proof-vc-detail@v1.0` | [`ld-proof-vc-detail` attachment format](../0593-json-ld-cred-attach/README.md#ld-proof-vc-detail-attachment-format) | | +Hyperledger Indy Credential Filter | `hlindy/cred-filter@v2.0` | [`cred filter` format](../0592-indy-attachments/README.md#cred-filter-format)| | +Hyperledger AnonCreds Credential Filter | `anoncreds/credential-filter@v1.0` | [`Credential Filter` format](../0771-anoncreds-attachments/README.md#credential-filter-format)| | #### Offer Credential @@ -157,8 +188,9 @@ Message Format: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/%VER/offer-credential", + "@type": "https://didcomm.org/issue-credential/%VER/offer-credential", "@id": "", + "goal_code": "", "replacement_id": "", "comment": "", "credential_preview": , @@ -167,10 +199,10 @@ Message Format: "attach_id" : "", "format" : "", } - ] + ], "offers~attach": [ { - "@id": "", + "@id": "", "mime-type": "application/json", "data": { "base64": "" @@ -182,13 +214,12 @@ Message Format: Description of fields: -* `replacement_id` -- an optional field to help coordinate credential replacement. When this is present and matches the `replacement_id` of a previously issued credential, it may be used to inform the recipient that the offered credential is considered to be a replacement to the previous credential. This value is unique to the issuer. It must not be used in a credential presentation. -* `comment` -- an optional field that provides human readable information about this Credential Offer, so the offer can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). -* `credential_preview` -- a JSON-LD object that represents the credential data that Issuer is willing to issue. It matches the schema of [Credential Preview](#preview-credential); -* `formats` -- contains an entry for each `offers~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. -* `offers~attach` -- an array of attachments that further define the credential being offered. This might be used to clarify which formats or format versions will be issued. - -The Issuer may add a [`~payment-request` decorator](../0075-payment-decorators/README.md#payment_request) to this message to convey the need for payment before issuance. See the [payment section below](#payments-during-credential-exchange) for more details. +- `goal_code` -- optional field that indicates the goal of the message sender. +- `replacement_id` -- an optional field to help coordinate credential replacement. When this is present and matches the `replacement_id` of a previously issued credential, it may be used to inform the recipient that the offered credential is considered to be a replacement to the previous credential. This value is unique to the issuer. It must not be used in a credential presentation. +- `comment` -- an optional field that provides human readable information about this Credential Offer, so the offer can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). +- `credential_preview` -- a JSON-LD object that represents the credential data that Issuer is willing to issue. It matches the schema of [Credential Preview](#preview-credential); +- `formats` -- contains an entry for each `offers~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. +- `offers~attach` -- an array of attachments that further define the credential being offered. This might be used to clarify which formats or format versions will be issued. It is possible for an Issuer to add a [`~timing.expires_time` decorator](../0032-message-timing/README.md#tutorial) to this message to convey the idea that the offer will expire at a particular point in the future. Such behavior is not a special part of this protocol, and support for it is not a requirement of conforming implementations; the `~timing` decorator is simply a general possibility for any DIDComm message. We mention it here just to note that the protocol can be enriched in composable ways. @@ -197,26 +228,29 @@ It is possible for an Issuer to add a [`~timing.expires_time` decorator](../0032 Credential Format | Format Value | Link to Attachment Format | Comment | --- | --- | --- | --- | DIF Credential Manifest | `dif/credential-manifest@v1.0` | [`offer-credential` attachment format](../0511-dif-cred-manifest-attach/README.md#offer-credential-attachment-format) | -Hyperledger Indy Credential Offer | hlindy-zkp-v1.0 | [`indy_issuer_create_credential_offer()`](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L280) | _To Do_: Change link to point to Indy Docs +Hyperledger Indy Credential Abstract | `hlindy/cred-abstract@v2.0` | [`cred abstract` format](../0592-indy-attachments/README.md#cred-abstract-format)| +Linked Data Proof VC Detail | `aries/ld-proof-vc-detail@v1.0` | [`ld-proof-vc-detail` attachment format](../0593-json-ld-cred-attach/README.md#ld-proof-vc-detail-attachment-format) | +Hyperledger AnonCreds Credential Offer | `anoncreds/credential-offer@v1.0` | [`Credential Offer` format](../0771-anoncreds-attachments/README.md#credential-offer-format)| +W3C VC - Data Integrity Proof Credential Offer | `didcomm/w3c-di-vc-offer@v0.1` | [`Credential Offer` format](../0809-w3c-data-integrity-credential-attachment/README.md#credential-offer-attachment-format)| #### Request Credential -This is a message sent by the potential Holder to the Issuer, to request the issuance of a credential. Where circumstances do not require a preceding Offer Credential message (e.g., there is no cost to issuance that the Issuer needs to explain in advance, and there is no need for cryptographic negotiation), this message initiates the protocol. In Hyperledger Indy, this message can only be sent in response to an Offer Credential message. +This is a message sent by the potential Holder to the Issuer, to request the issuance of a credential. Where circumstances do not require a preceding Offer Credential message (e.g., there is no cost to issuance that the Issuer needs to explain in advance, and there is no need for cryptographic negotiation), this message initiates the protocol. When using the Hyperledger Indy AnonCreds verifiable credential format, this message can only be sent in response to an `offer-credential` message. Message Format: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/%VER/request-credential", + "@type": "https://didcomm.org/issue-credential/%VER/request-credential", "@id": "", - "replacement_id": "", + "goal_code": "", "comment": "", "formats" : [ { "attach_id" : "", "format" : "", } - ] + ], "requests~attach": [ { "@id": "", @@ -231,29 +265,32 @@ Message Format: Description of Fields: -* `comment` -- an optional field that provides human readable information about this Credential Request, so it can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). -* `formats` -- contains an entry for each `requests~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. -* `requests~attach` -- an array of [attachments](../../concepts/0017-attachments/README.md) defining the requested formats for the credential. - -This message may have a [`~payment-receipt` decorator](../0075-payment-decorators/README.md#payment_receipt) to prove to the Issuer that the potential Holder has satisfied a payment requirement. See the [payment section below](#payments-during-credential-exchange). +- `goal_code` -- optional field that indicates the goal of the message sender. +- `comment` -- an optional field that provides human readable information about this Credential Request, so it can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). +- `formats` -- contains an entry for each `requests~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. +- `requests~attach` -- an array of [attachments](../../concepts/0017-attachments/README.md) defining the requested formats for the credential. ##### Request Attachment Registry Credential Format | Format Value | Link to Attachment Format | Comment | --- | --- | --- | --- | DIF Credential Manifest | `dif/credential-manifest@v1.0` | [`request-credential` attachment format](../0511-dif-cred-manifest-attach/README.md#request-credential-attachment-format) | -Hyperledger Indy Credential Request | hlindy-zkp-v1.0 | [`indy_prover_create_credential_req()`](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L658) | _To Do_: Change link to point to Indy Docs +Hyperledger Indy Credential Request | `hlindy/cred-req@v2.0` | [`cred request` format](../0592-indy-attachments/README.md#cred-request-format)| +Linked Data Proof VC Detail | `aries/ld-proof-vc-detail@v1.0` | [`ld-proof-vc-detail` attachment format](../0593-json-ld-cred-attach/README.md#ld-proof-vc-detail-attachment-format) | +Hyperledger AnonCreds Credential Request | `anoncreds/credential-request@v1.0` | [`Credential Request` format](../0771-anoncreds-attachments/README.md#credential-request-format)| +W3C VC - Data Integrity Proof Credential Request | `didcomm/w3c-di-vc-request@v0.1` | [`Credential Request` format](../0809-w3c-data-integrity-credential-attachment/README.md#credential-request-attachment-format)| #### Issue Credential -This message contains as an [attached payload](../../concepts/0017-attachments/README.md) the credential being issued. It is sent in response to a valid Request Credential message. +This message contains a verifiable credential being issued as an [attached payload](../../concepts/0017-attachments/README.md). It is sent in response to a valid Request Credential message. Message Format: ```json { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/%VER/issue-credential", + "@type": "https://didcomm.org/issue-credential/%VER/issue-credential", "@id": "", + "goal_code": "", "replacement_id": "", "comment": "", "formats" : [ @@ -261,7 +298,7 @@ Message Format: "attach_id" : "", "format" : "", } - ] + ], "credentials~attach": [ { "@id": "", @@ -276,26 +313,32 @@ Message Format: Description of fields: -* `replacement_id` -- an optional field that provides an identifier used to manage credential replacement. When this value is present and matches the `replacement_id` of a previously issued credential, this credential may be considered as a replacement for that credential. This value is unique to the issuer. It must not be used in a credential presentation. -* `comment` -- an optional field that provides human readable information about the issued credential, so it can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). -* `formats` -- contains an entry for each `credentials~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. -* `credentials~attach` -- an array of attachments containing the issued credentials. +- `replacement_id` -- an optional field that provides an identifier used to manage credential replacement. When this value is present and matches the `replacement_id` of a previously issued credential, this credential may be considered as a replacement for that credential. This value is unique to the issuer. It must not be used in a credential presentation. +- `comment` -- an optional field that provides human readable information about the issued credential, so it can be evaluated by human judgment. Follows [DIDComm conventions for l10n](../0043-l10n/README.md). +- `formats` -- contains an entry for each `credentials~attach` array entry, providing the the value of the attachment `@id` and the verifiable credential format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. +- `credentials~attach` -- an array of attachments containing the issued credentials. -If the issuer wants an acknowledgement that the issued credential was accepted, this message must be decorated with `~please-ack`, and it is then best practice for the new Holder to respond with an explicit `ack` message as described in [0317: Please ACK Decorator](../0317-please-ack/README.md). ##### Credentials Attachment Registry Credential Format | Format Value | Link to Attachment Format | Comment | --- | --- | --- | --- | -Hyperledger Indy Credential | hlindy-zkp-v1.0 | [indy_issuer_create_credential()](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L338) | _To Do_: Change link to point to Indy Docs, including section on Claim Encoding. +Linked Data Proof VC | `aries/ld-proof-vc@v1.0` | [`ld-proof-vc` attachment format](../0593-json-ld-cred-attach/README.md#ld-proof-vc-attachment-format) | +Hyperledger Indy Credential | `hlindy/cred@v2.0` | [credential format](../0592-indy-attachments/README.md#credential-format)| +Hyperledger AnonCreds Credential| `anoncreds/credential@v1.0` | [`Credential` format](../0771-anoncreds-attachments/README.md#credential-format)| +W3C VC - Data Integrity Proof Credential | `didcomm/w3c-di-vc@v0.1` | [`Credential` format](../0809-w3c-data-integrity-credential-attachment/README.md#credential-attachment-format)| + +#### Adopted Problem Report + +The [problem-report message is adopted](../0035-report-problem/README.md) by this protocol. `problem-report` messages can be used by either party to indicate an error in the protocol. #### Preview Credential This is not a message but an inner object for other messages in this protocol. It is used construct a preview of the data for the credential that is to be issued. Its schema follows: -```json +```jsonc { - "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/issue-credential/%VER/credential-preview", + "@type": "https://didcomm.org/issue-credential/%VER/credential-preview", "attributes": [ { "name": "", @@ -319,8 +362,8 @@ The optional `mime-type` advises the issuer how to render a binary attribute, to The mandatory `value` holds the attribute value: -* if `mime-type` is missing (null), then `value` is a string. In other words, implementations interpret it the same as any other key+value pair in JSON -* if `mime-type` is not null, then `value` is always a base64-encoded string that represents a binary BLOB, and `mime-type` tells how to interpret the BLOB after base64-decoding. +- if `mime-type` is missing (null), then `value` is a string. In other words, implementations interpret it the same as any other key+value pair in JSON +- if `mime-type` is not null, then `value` is always a base64url-encoded string that represents a binary BLOB, and `mime-type` tells how to interpret the BLOB after base64url-decoding. ## Threading @@ -328,20 +371,6 @@ Threading can be used to initiate a [sub-protocol](../../concepts/0003-protocols If threading were added to all of the above messages, a `~thread` decorator would be present, and later messages in the flow would reference the `@id` of earlier messages to stitch the flow into a single coherent sequence. Details about threading can be found in the [0008: Message ID and Threading](../../concepts/0008-message-id-and-threading/README.md) RFC. -## Payments during credential exchange - -Credentialing ecosystems may wish to associate credential issuance with payments by fiat currency or tokens. This is common with non-digital credentials today; we pay a fee when we apply for a passport or purchase a plane ticket. Instead or in addition, some circumstances may fit a mode where payment is made each time a credential is *used*, as when a Verifier pays a Prover for verifiable medical data to be used in research, or when a Prover pays a Verifier as part of a workflow that applies for admittance to a university. For maximum flexibility, we mention payment possibilities here as well as in the sister [0037: Present Proof](../0037-present-proof/README.md) RFC. - -### Payment decorators - -Wherever they happen and whoever they involve, payments are accomplished with optional payment decorators. See [0075: Payment Decorators](../0075-payment-decorators/README.md). - -### Payment flow - -A `~payment-request` may decorate a Credential Offer from Issuer to Holder. When they do, a corresponding `~payment-receipt` should be provided on the Credential Request returned to the Issuer. - -During credential presentation, the Verifier may pay the Holder as compensation for Holder for disclosing data. This would require a `~payment-request` in a Presentation Proposal message, and a corresponding `~payment-receipt` in the subsequent Presentation Request. If such a workflow begins with the Presentation Request, the Prover may sending back a Presentation (counter-)Proposal with appropriate decorator inside it. - ### Limitations Smart contracts may be missed in ecosystem, so operation "issue credential after payment received" is not atomic. It’s possible case that malicious issuer will charge first and then will not issue credential in fact. But this situation should be easily detected and appropriate penalty should be applied in such type of networks. @@ -357,7 +386,7 @@ None documented ## Rationale and alternatives - Attention should be paid by the Aries community to other credential issuance protocols being proposed/used in other communities to ensure this RFC could support those protocols. - - Digital Bazaar has proposed the [Credential Handler API (CHAPI)](https://w3c-ccg.github.io/credential-handler-api/) protocol that is being considered by the [W3C Credentials Community Group](https://www.w3.org/community/credentials/). +- Digital Bazaar has proposed the [Credential Handler API (CHAPI)](https://w3c-ccg.github.io/credential-handler-api/) protocol that is being considered by the [W3C Credentials Community Group](https://www.w3.org/community/credentials/). ## Prior art @@ -365,14 +394,12 @@ See [RFC 0036 Issue Credential, v1.x](../0036-issue-credential/README.md). ## Unresolved questions -- References to the expected Ack and Problem Report messages should be added. -- The ['~please-ack` decorator](../0317-please-ack/README.md) needs to move to Accepted so that it is appropriate to be referenced here. - We might need to propose a new MIME type for credential (the same way as .docx is not processed as generic xml). See [this issue](https://github.com/w3c/vc-data-model/issues/421) against the W3C/vc-data-model. ## Implementations The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -Name / Link | Implementation Notes ---- | --- +Name / Link | Implementation Notes | +--- | --- | | | diff --git a/features/0454-present-proof-v2/README.md b/features/0454-present-proof-v2/README.md index ba3c80929..420d9bd4c 100644 --- a/features/0454-present-proof-v2/README.md +++ b/features/0454-present-proof-v2/README.md @@ -1,14 +1,35 @@ # Aries RFC 0454: Present Proof Protocol 2.0 - Authors: Nikita Khateev, Stephen Curran -- Status: [PROPOSED](/README.md#proposed) -- Since: 2020-05-27 +- Status: [ADOPTED](/README.md#adopted) +- Since: 2021-04-15 - Status Note: See [RFC 0453](../0453-issue-credential-v2/README.md) for the corresponding issue credential protocol. - Supersedes: [RFC 0037](../0037-present-proof/README.md) - Start Date: 2020-05-27 - Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [credentials](/tags.md#credentials), [test-anomaly](/tags.md#test-anomaly) -## Version Change Log +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. +- 20240311: Version 2.0 is the current version + +For a period of time, versions 2.1 and 2.2 where defined in this RFC. Those +definitions were added prior to any implementations, and to date, there are no +known implementations available or planned. An attempt at [implementing version 2.1] +of the associated "issue multiple credentials" was not merged into the main branch of +[Aries Cloud Agent Python], deemed overly complicated and not worth the effort +for what amounts to an edge case (presenting multiple presentations of the same type +in a single protocol instance). Further, there is a [version 3.0] of this +protocol that has been specified and implemented that does not include these +capabilities. Thus, a decision was made that versions 2.1 and 2.2 be removed as +being not accepted by the community and overly complicated to both implement and +migrate from. Those interested in seeing how those capabilities were specified +can look at this [protocol before they were removed]. + +[implementing version 2.1]: https://github.com/hyperledger/aries-cloudagent-python/pull/2088 +[protocol before they were removed]: https://github.com/hyperledger/aries-rfcs/tree/00487467f42528a2490bcf9c303b9469ed0da5bb/features/0454-present-proof-v2 +[Aries Cloud Agent Python]: https://github.com/hyperledger/aries-cloudagent-python +[version 3.0]: https://github.com/decentralized-identity/waci-didcomm/blob/main/present_proof/present-proof-v3.md ### 2.0 - Alignment with [RFC 0453 Issue Credential](../0453-issue-credential-v2/README.md) @@ -45,39 +66,43 @@ Diagrams in this protocol were made in draw.io. To make changes: The roles are `verifier` and `prover`. The `verifier` requests the presentation of a proof and verifies the presentation, while the `prover` prepares the proof and presents it to the verifier. Optionally, although unlikely from a business sense, the `prover` may initiate an instance of the protocol using the `propose-presentation` message. +### Goals + +When the goals of each role are not available because of context, goal codes may be specifically included in protocol messages. This is particularly helpful to differentiate between credentials passed between the same parties for several different reasons. A goal code included should be considered to apply to the entire thread and is not necessary to be repeated on each message. Changing the goal code may be done by including the new code in a message. All goal codes are optional, and without default. + ### States The following states are defined and included in the state transition table below. #### States for Verifier -* request-sent -* proposal-received -* presentation-received -* abandoned -* done +- request-sent +- proposal-received +- presentation-received +- abandoned +- done #### States for Prover -* request-received -* proposal-sent -* presentation-sent -* abandoned -* done +- request-received +- proposal-sent +- presentation-sent +- abandoned +- done [![state machine matrix](present-proof-states.png)](https://docs.google.com/spreadsheets/d/1XThILA0_ZiH3voBv5M8-GIt1We9t_Rlg0xaY5jmNVIA/edit) For the most part, these states map onto the transitions shown in both the state transition table above, and in the choreography diagram ([below](#choreography-diagram)) in obvious ways. However, a few subtleties are worth highlighting: -* The final states for both the prover and verifier are `done` or `abandoned`, and once reached, no further updates to the protocol instance are expected. +- The final states for both the prover and verifier are `done` or `abandoned`, and once reached, no further updates to the protocol instance are expected. -* The `ack-presentation` is sent or not based on the value of `will_confirm` in the `request-presentation`. A verifier may send an `ack-presentation` message in response to the prover including the `~please_ack` decorator in the `presentation` message. Whether an `ack-presentation` is expected or not determines whether the states `presentation-sent` and `presentation-received` are used at all in a protocol instance. +- The `ack-presentation` is sent or not based on the value of `will_confirm` in the `request-presentation`. Whether an `ack-presentation` is expected or not determines whether the states `presentation-sent` and `presentation-received` are used at all in a protocol instance. -* The `ack-presentation` message should reflect the business validation of the proof (does the proof satisfy the business need?) not just the cryptographic verification. Ideally, those are as tightly aligned as possible. +- The `ack-presentation` message should reflect the business validation of the proof (does the proof satisfy the business need?) not just the cryptographic verification. Ideally, those are as tightly aligned as possible. -* When a Prover makes a (counter-)proposal, it transitions to the `proposal-sent` state. This state is only present by implication in the choreography diagram; it essentially equates to the null or begin state in that the Prover does nothing until a presentation request arrives, triggering the leftmost transition for the Prover. +- When a Prover makes a (counter-)proposal, it transitions to the `proposal-sent` state. This state is only present by implication in the choreography diagram; it essentially equates to the null or begin state in that the Prover does nothing until a presentation request arrives, triggering the leftmost transition for the Prover. -* Errors might occur in various places. For example, a Prover might decide not to respond to a `presentation-request` or a verifier may time out waiting for the Prover to supply a `presentation`. Errors should trigger a `problem-report`. In this version of the protocol, all errors cause the state of both parties (the sender and the receiver of the `problem-report`) to transition to the terminal `abandoned` state (meaning it is no longer engaged in the protocol at all). +- Errors might occur in various places. For example, a Prover might decide not to respond to a `presentation-request` or a verifier may time out waiting for the Prover to supply a `presentation`. Errors should trigger a `problem-report`. In this version of the protocol, all errors cause the state of both parties (the sender and the receiver of the `problem-report`) to transition to the terminal `abandoned` state (meaning it is no longer engaged in the protocol at all). ### Choreography Diagram @@ -87,9 +112,9 @@ For the most part, these states map onto the transitions shown in both the state The present proof protocol consists of these messages: -* `propose-presentation` - Prover to Verifier (optional) - propose a presentation or send a counter-proposal in response to a `request-presentation` message -* `request-presentation` - Verifier to Prover - request a presentation -* `presentation` - Prover to Verifier - provide a presentation in response to a request +- `propose-presentation` - Prover to Verifier (optional) - propose a presentation or send a counter-proposal in response to a `request-presentation` message +- `request-presentation` - Verifier to Prover - request a presentation +- `presentation` - Prover to Verifier - provide a presentation in response to a request In addition, the [`ack`](../0015-acks/README.md) and [`problem-report`](../0035-report-problem/README.md) messages are adopted into the protocol for confirmation and error handling. @@ -105,6 +130,7 @@ An optional message sent by the prover to the verifier to initiate a proof prese { "@type": "https://didcomm.org/present-proof/%VER/propose-presentation", "@id": "", + "goal_code": "", "comment": "some comment", "formats" : [ { @@ -112,7 +138,7 @@ An optional message sent by the prover to the verifier to initiate a proof prese "format" : "", } ], - "proposal~attach": [ + "proposals~attach": [ { "@id": "", "mime-type": "application/json", @@ -126,11 +152,12 @@ An optional message sent by the prover to the verifier to initiate a proof prese Description of fields: -* `comment` -- a field that provides some human readable information about the proposed presentation. -* `formats` -- contains an entry for each `filter~attach` array entry, including an optional value of the attachment `@id` (if attachments are present) and the verifiable presentation format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. -* `proposal~attach` -- an optional array of attachments that further define the presentation request being proposed. This might be used to clarify which formats or format versions are wanted. +- `goal_code` -- optional field that indicates the goal of the message sender. +- `comment` -- a field that provides some human readable information about the proposed presentation. +- `formats` -- contains an entry for each `filter~attach` array entry, including an optional value of the attachment `@id` (if attachments are present) and the verifiable presentation format and version of the attachment. Accepted values for the `format` items are provided in the per format "Attachment" sections immediately below. +- `proposals~attach` -- an optional array of attachments that further define the presentation request being proposed. This might be used to clarify which formats or format versions are wanted. -If the `proposal~attach` is not provided, the `attach_id` item in the `formats` array should not be provided. That form of the `propose-presentation` message is to indicate the presentation formats supported by the prover, independent of the verifiable presentation request content. +If the `proposals~attach` is not provided, the `attach_id` item in the `formats` array should not be provided. That form of the `propose-presentation` message is to indicate the presentation formats supported by the prover, independent of the verifiable presentation request content. #### Negotiation and Preview @@ -139,9 +166,10 @@ Negotiation prior to the delivery of the presentation can be done using the `pro #### Propose Attachment Registry Presentation Format | Format Value | Link to Attachment Format | Comment | ---- | --- | --- | --- | -Hyperledger Indy | hlindy-zkp-v1.0 | [Libindy Presentation Request API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1214) | _To Do_: Change link to point to Indy Docs -DIF Presentation Exchange | `dif/presentation-exchange/definitions@v1.0` | [`propose-presentation` attachment format](../0510-dif-pres-exch-attach/README.md#propose-presentation-attachment-format) | +--- | --- | --- | --- | +Hyperledger Indy Proof Req | `hlindy/proof-req@v2.0` | [proof request format](../0592-indy-attachments/README.md#proof-request-format) | Used to propose as well as request proofs. | +DIF Presentation Exchange | `dif/presentation-exchange/definitions@v1.0` | [`propose-presentation` attachment format](../0510-dif-pres-exch-attach/README.md#propose-presentation-attachment-format) | | +Hyperledger AnonCreds Proof Request | `anoncreds/proof-request@v1.0` | [`Proof Request` format](../0771-anoncreds-attachments/README.md#proof-request-format) | Used to propose as well as request proofs. | ### Request Presentation @@ -151,8 +179,9 @@ From a verifier to a prover, the `request-presentation` message describes values { "@type": "https://didcomm.org/present-proof/%VER/request-presentation", "@id": "", + "goal_code": "", "comment": "some comment", - "will_confirm": "true", + "will_confirm": true, "formats" : [ { "attach_id" : "", @@ -173,17 +202,19 @@ From a verifier to a prover, the `request-presentation` message describes values Description of fields: -* `comment` -- a field that provides some human readable information about this request for a presentation. -* `will_confirm` -- an optional field that defaults to `"false"` to indicate that the verifier will or will not send a post-presentation confirmation `ack` message -* `formats` -- contains an entry for each `request_presentations~attach` array entry, providing the the value of the attachment `@id` and the verifiable presentation request format and version of the attachment. Accepted values for the `format` items are provided in the per format [Attachment](#presentation-request-attachment-registry) registry immediately below. -* `request_presentations~attach` -- an array of attachments containing the acceptable verifiable presentation requests. +- `goal_code` -- optional field that indicates the goal of the message sender. +- `comment` -- a field that provides some human readable information about this request for a presentation. +- `will_confirm` -- an optional field that defaults to `false` to indicate that the verifier will or will not send a post-presentation confirmation `ack` message +- `formats` -- contains an entry for each `request_presentations~attach` array entry, providing the the value of the attachment `@id` and the verifiable presentation request format and version of the attachment. Accepted values for the `format` items are provided in the per format [Attachment](#presentation-request-attachment-registry) registry immediately below. +- `request_presentations~attach` -- an array of attachments containing the acceptable verifiable presentation requests. #### Presentation Request Attachment Registry Presentation Format | Format Value | Link to Attachment Format | Comment | ---- | --- | --- | --- | -Hyperledger Indy | hlindy-zkp-v1.0 | [Libindy Presentation Request API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1214) | _To Do_: Change link to point to Indy Docs -DIF Presentation Exchange | `dif/presentation-exchange/definitions@v1.0` | [`propose-presentation` attachment format](../0510-dif-pres-exch-attach/README.md#request-presentation-attachment-format) | +--- | --- | --- | --- | +Hyperledger Indy Proof Req| `hlindy/proof-req@v2.0` | [proof request format](../0592-indy-attachments/README.md#proof-request-format) | Used to propose as well as request proofs. | +DIF Presentation Exchange | `dif/presentation-exchange/definitions@v1.0` | [`propose-presentation` attachment format](../0510-dif-pres-exch-attach/README.md#request-presentation-attachment-format) | | +Hyperledger AnonCreds Proof Request | `anoncreds/proof-request@v1.0` | [`Proof Request` format](../0771-anoncreds-attachments/README.md#proof-request-format) | Used to propose as well as request proofs. | ### Presentation @@ -193,6 +224,7 @@ This message is a response to a Presentation Request message and contains signed { "@type": "https://didcomm.org/present-proof/%VER/presentation", "@id": "", + "goal_code": "", "comment": "some comment", "formats" : [ { @@ -215,28 +247,30 @@ This message is a response to a Presentation Request message and contains signed Description of fields: -* `comment` -- a field that provides some human readable information about this presentation. -* `formats` -- contains an entry for each `presentations~attach` array entry, providing the the value of the attachment `@id` and the verifiable presentation format and version of the attachment. Accepted values for the `format` items are provided in the per format [Attachment](#presentation-request-attachment-registry) registry immediately below. -* `presentations~attach` -- an array of attachments containing the presentation in the requested format(s). +- `comment` -- a field that provides some human readable information about this presentation. +- `goal_code` -- optional field that indicates the goal of the message sender. +- `formats` -- contains an entry for each `presentations~attach` array entry, providing the the value of the attachment `@id` and the verifiable presentation format and version of the attachment. Accepted values for the `format` items are provided in the per format [Attachment](#presentation-request-attachment-registry) registry immediately below. +- `presentations~attach` -- an array of attachments containing the presentation in the requested format(s). -A prover may include the [`~please_ack` decorator](../0015-acks/README.md#requesting-acks) to request a `ack-presentation` if the verifier has not indicated they will send a `ack-presentation`. +If the prover wants an acknowledgement that the presentation was accepted, this message may be decorated with the `~please-ack` decorator using the `OUTCOME` acknowledgement request. This is not necessary if the verifier has indicated it will send an `ack-presentation` using the `will_confirm` property. Outcome in the context of this protocol is the definition of "successful" as described in [Ack Presentation](#ack-presentation). Note that this is different from the default behavior as described in [0317: Please ACK Decorator](../0317-please-ack/README.md). It is then best practice for the new Verifier to respond with an explicit `ack` message as described in the please ack decorator RFC. #### Presentations Attachment Registry Presentation Format | Format Value | Link to Attachment Format | Comment | ---- | --- | --- | --- | -Hyperledger Indy | hlindy-zkp-v1.0 | [Libindy Presentation API](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1404) | _To Do_: Change link to point to Indy Docs, including claim encoding -DIF Presentation Exchange | `dif/presentation-exchange/submission@v1.0` | [`propose-presentation` attachment format](../0510-dif-pres-exch-attach/README.md#presentation-attachment-format) | +--- | --- | --- | --- | +Hyperledger Indy Proof | `hlindy/proof@v2.0` | [proof format](../0592-indy-attachments/README.md#proof-format) | | +DIF Presentation Exchange | `dif/presentation-exchange/submission@v1.0` | [`propose-presentation` attachment format](../0510-dif-pres-exch-attach/README.md#presentation-attachment-format) | | +Hyperledger AnonCreds Proof | `anoncreds/proof@v1.0` | [`Proof` format](../0771-anoncreds-attachments/README.md#proof-format) | | ### Ack Presentation -A message from the verifier to the prover that the `Present Proof` protocol was completed successfully and is now in the `done` state. The message is an adopted `ack` from the [RFC 0015 acks protocol](../0015-acks/README.md). The definition of "successful" from a business sense is up to the verifier. +A message from the verifier to the prover that the `Present Proof` protocol was completed successfully and is now in the `done` state. The message is an adopted `ack` from the [RFC 0015 acks protocol](../0015-acks/README.md). The definition of "successful" in this protocol means the acceptance of the presentation in whole, i.e. the proof is verified and the contents of the proof are acknowledged. ### Problem Report A message from the verifier to the prover that follows the `presentation` message to indicate that the `Present Proof` protocol was completed unsuccessfully and is now in the `abandoned` state. The message is an adopted `problem-report` from the [RFC 0015 report-problem protocol](../0035-report-problem/README.md). The definition of "unsuccessful" from a business sense is up to the verifier. The elements of the `problem-report` message can provide information to the prover about why the protocol instance was unsuccessful. -Either party may send a `problem-report` message earlier in the flow to terminate the protocol before it's normal conclusion. +Either party may send a `problem-report` message earlier in the flow to terminate the protocol before its normal conclusion. ## Reference @@ -252,7 +286,7 @@ The verifiable presentation standardization work being conducted in parallel to ## Prior art -The existing [RFC 0036 Present Proof](../0037-present-proof/README.md) protocol and implementations. +The previous major version of this protocol is [RFC 0037 Present Proof](../0037-present-proof/README.md) protocol and implementations. ## Unresolved questions @@ -262,6 +296,6 @@ The existing [RFC 0036 Present Proof](../0037-present-proof/README.md) protocol The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. -Name / Link | Implementation Notes ---- | --- - | +Name / Link | Implementation Notes | +--- | --- | + | | diff --git a/features/0482-coprotocol-protocol/README.md b/features/0482-coprotocol-protocol/README.md new file mode 100644 index 000000000..17810775a --- /dev/null +++ b/features/0482-coprotocol-protocol/README.md @@ -0,0 +1,237 @@ +# Aries RFC 0482: Coprotocol Protocol 0.5 +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [STALLED](/README.md#stalled) +- Since: 2024-04-03 +- Status Note: No implementations have been created. +- Start Date: 2020-02-03 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) + +[![coprotocol icon](../../concepts/0478-coprotocols/icon.png)](https://j.mp/2XgyjH3) + +## Summary + +Allows [coprotocols](../../concepts/0478-coprotocols/README.md) to interact with one another. + +## Motivation + +We need a standard way for one protocol to invoke another, giving it input, getting its output, detaching, and debugging. + +## Tutorial + +### Name and Version + +The name of this protocol is "Coprotocol Protocol 0.5" It is identified by the PIURI "https://didcomm.org/coprotocol/0.5". + +### Key Concepts + +Please make sure you are familiar with the general concept of coprotocols, as set forth in [Aries RFC 0478](../../concepts/0478-coprotocols/README.md). A working knowledge of the terminology and mental model explained there are foundational. + +### Roles + +The `caller` role is played by the entity giving input and getting output. The `called` is the entity getting input and giving output. + +### States + +The caller's normal state progression is `null` -> `detached` -> `attached` -> `done`. It is also possible to return to a `detached` state without ever reaching `done`. + +The coprotocols normal state progression is `null` -> `attached` -> `done`. + +[![state machine](state-machines.png)](https://docs.google.com/spreadsheets/d/1IgvdwMryC5us0Lb5AGzBYl_uGwf6Dt3cWx4jj9MXdTc/edit?usp=sharing) + +### Messages + +>Note: the discussion below is about how to launch and interact with *any* coprotocol. However, for concreteness we frame the walkthru in terms of a co-protocol that makes a payment. You can see an [example definition of such a coprotocol in RFC 0478](../../concepts/0478-coprotocols/README.md#example). + +The protocol consists of 5 messages: `bind`, `attach`, `input`, `output`, `detach` and the adopted `problem-report` (for propagating errors). + +The protocol begins with a `bind` message sent from `caller` to `called`. This message basically says, "I would like to interact with a new coprotocol instance having the following characteristics and the following mapping of identifiers to roles." It might look like this: + +```jsonc +{ + "@id": "4d116a88-1314-4af5-9b3c-848456b8b3dd", + "@type": "https://didcomm.org/coprotocol/1.0/bind", + "goal_code": "aries.buy.make-payment", + "co_binding_id": null, + "cast": [ + // Recipient of the bind message (id = null) should be payee. + {"role": "payee", "id": null}, + // The payer will be did:peer:abc123. + {"role": "payer", "id": "did:peer:abc123" } + ] +} +``` + +When a `called` agent receives this message, it should discover what protocol implementations are available that match the criteria, and sort the candidates by preference. (Note that additional criteria can be added besides those shown here; see the [Reference section](#reference).) This could involve enumerating not-yet-loaded plugins. It could also involve negotiating a protocol with the remote party (e.g., the DID playing the role of `payer` in the example above) by querying its capabilities using the [Discover Features Protocol](../0031-discover-features/README.md). Of course, the capabilities of remote parties could also be cached to avoid this delay, or they could be predicted without confirmation, if circumstances suggest that's the best tradeoff. Once the candidates are sorted by preference, the best match should be selected. The coprotocol is NOT launched, but it is awaiting launch. The `called` agent should now generate an `attach` message that acknowledges the request to bind and tells the `caller` how to interact: + +```jsonc +{ + "@id": "b3dd4d11-6a88-9b3c-4af5-848456b81314", + "@type": "https://didcomm.org/coprotocol/1.0/attach", + "~thread": { "pthid": "4d116a88-1314-4af5-9b3c-848456b8b3dd"}, + // This is the best match. + "piuri": "https://didcomm.org/pay-with-venmo/1.3" +} +``` + +The `@id` of the `bind` message (also the `~thread.pthid` of the `attach` response) becomes a permanent identifier for the __coprotocol binding__. Both the caller and the coprotocol instance code can use it to lookup state as needed. The `caller` can now kick off/invoke the protocol with an `input` message: + +```jsonc +{ + "@id": "56b81314-6a88-9b3c-4af5-b3dd4d118484", + "@type": "https://didcomm.org/coprotocol/1.0/input", + "~thread": { "pthid": "4d116a88-1314-4af5-9b3c-848456b8b3dd"}, + "interaction_point": "invoke", + "data": [ + "amount": 1.23, + "currency": "INR", + "bill_of_sale": { + // describes what's being purchased + } + ] +} +``` + +This allows the `caller` to invoke the bound coprotocol instance, and to pass it any number of named inputs. + +Later, when the coprotocol instance wants to emit an output from `called` to `caller`, it uses an `output` message (in this case, one matching the `preauth` interaction point declared in the [sample coprotocol definition in RFC 0478](../../concepts/0478-coprotocols/README.md#example)): + +```jsonc +{ + "@id": "9b3c56b8-6a88-f513-4a14-4d118484b3dd", + "@type": "https://didcomm.org/coprotocol/1.0/output", + "~thread": { "pthid": "4d116a88-1314-4af5-9b3c-848456b8b3dd"}, + "interaction_point": "preauth", + "data": [ + "code": "6a884d11-13149b3c", + ] +} +``` + +If a `caller` wants to detach, it uses a `detach` message. This leaves the coprotocol running on `called`; all inputs that it emits are sent to the bitbucket, and it advances on its normal state trajectory as if it were a wholly independent protocol: + +```jsonc +{ + "@id": "7a3c56b8-5b88-d413-4a14-ca118484b3ee", + "@type": "https://didcomm.org/coprotocol/1.0/detach", + "~thread": { "pthid": "4d116a88-1314-4af5-9b3c-848456b8b3dd"} +} +``` + +A `caller` can re-attach by sending a new `bind` message; this time, the `co_binding_id` field should have the coprotocol binding id from the original `attach` message. Other fields in the message are optional; if present, they constitute a check that the binding in question has the properties the caller expects. The reattachment is confrimed by a new `attach` message. + +## Reference + +### `bind` +```jsonc +{ + "@id": "4d116a88-1314-4af5-9b3c-848456b8b3dd", + "@type": "https://didcomm.org/coprotocol/1.0/bind", + // I'd like to be bound to a coprotocol that achieves this goal. + "goal_code": "aries.buy.make-payment", + "co_binding_id": + // What is the intent about who plays which roles? + "cast": [ + // Recipient of the bind message (id = null) should be payee. + {"role": "payee", "id": null}, + // The payer will be did:peer:abc123. + {"role": "payer", "id": "did:peer:abc123" } + ], + // Optional and preferably omitted as it creates tight coupling; + // constrains bound coprotocol to just those that have a PIURI + // matching this wildcarded expression. + "piuri_pat": "*/pay*", + // If multiple matches are found, tells how to sort them to pick + // best match. + "prefer": [ + // First prefer to bind a protocol that's often successful. + { "attribute": "success_ratio", "direction": "d" }, + // Tie break by binding a protocol that's been run recently. + { "attribute": "last_run_date", "direction": "d" }, + // Tie break by binding a protocol that's newer. + { "attribute": "release_date", "direction": "d" } + // Tie break by selecting protocols already running (false + // sorts before true). + { "attribute": "running", "direction": "d" } + ] +} +``` + +### `attach` + +```jsonc +{ + "@id": "b3dd4d11-6a88-9b3c-4af5-848456b81314", + "@type": "https://didcomm.org/coprotocol/1.0/attach", + "~thread": { "pthid": "4d116a88-1314-4af5-9b3c-848456b8b3dd"}, + // This is the best match. + "piuri": "https://didcomm.org/pay-with-venmo/1.3", + // Optional. Tells how long the caller has to take the next + // step binding will be held in an + // inactive state before being abandoned. + "~timing.expires_time": "2020-06-23T18:42:07.124" +} +``` + +### Collateral + +This section is optional. It could be used to reference files, code, +relevant standards, oracles, test suites, or other artifacts that would +be useful to an implementer. In general, collateral should be checked in +with the RFC. + +## Drawbacks + +Why should we *not* do this? + +## Rationale and alternatives + +- Why is this design the best in the space of possible designs? +- What other designs have been considered and what is the rationale for not +choosing them? +- What is the impact of not doing this? + +## Prior art + +Discuss prior art, both the good and the bad, in relation to this proposal. +A few examples of what this can include are: + +- Does this feature exist in other SSI ecosystems and what experience have +their community had? +- For other teams: What lessons can we learn from other attempts? +- Papers: Are there any published papers or great posts that discuss this? +If you have some relevant papers to refer to, this can serve as a more detailed +theoretical background. + +This section is intended to encourage you as an author to think about the +lessons from other implementers, provide readers of your proposal with a +fuller picture. If there is no prior art, that is fine - your ideas are +interesting to us whether they are brand new or if they are an adaptation +from other communities. + +Note that while precedent set by other communities is some motivation, it +does not on its own motivate an enhancement proposal here. Please also take +into consideration that Aries sometimes intentionally diverges from common +identity features. + +## Unresolved questions + +- What parts of the design do you expect to resolve through the +enhancement proposal process before this gets merged? +- What parts of the design do you expect to resolve through the +implementation of this feature before stabilization? +- What related issues do you consider out of scope for this +proposal that could be addressed in the future independently of the +solution that comes out of this doc? + +## Implementations + +> NOTE: This section should remain in the RFC as is on first release. Remove this note and leave the rest of the text as is. Template text in all other sections should be replace. + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/features/0482-coprotocol-protocol/state-machines.png b/features/0482-coprotocol-protocol/state-machines.png new file mode 100644 index 000000000..9efe7f7f8 Binary files /dev/null and b/features/0482-coprotocol-protocol/state-machines.png differ diff --git a/features/0496-transition-to-oob-and-did-exchange/README.md b/features/0496-transition-to-oob-and-did-exchange/README.md new file mode 100644 index 000000000..e2544f3e1 --- /dev/null +++ b/features/0496-transition-to-oob-and-did-exchange/README.md @@ -0,0 +1,251 @@ +# Aries RFC 0496: Transition to the Out of Band Protocol + +- Authors: [Stephen Curran](mailto:swcurran@cloudcompass.ca) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2021-11-24 +- Status Note: In step 2 - All systems using OOB. **Target Completion Date: 2024-07-02** +- Supersedes: +- Start Date: 2020-06-07 +- Tags: [feature](/tags.md#feature), [community-update](/tags.md#community-update), [test-anomaly](/tags.md#test-anomaly) + +## Summary + +The Aries community has agreed to transition from using the `invitation` messages in [RFC 0160 Connections](../0160-connection-protocol/README.md) +and [RFC 0023 DID Exchange](../0023-did-exchange/README.md) to using the plaintext `invitation` message in [RFC 0434 Out of Band](../0434-outofband/README.md) and from using RFC 0160 to RFC 0023 for establishing agent-to-agent connections. +As well, the community has agreed to transition from using [RFC 0056 Service Decorator](../0056-service-decorator/README.md) to execute connection-less instances of the [RFC 0037 Present Proof](../0037-present-proof/README.md) protocol to using the out-of-band invitation message. + +This RFC follows the guidance in [RFC 0345](../../concepts/0345-community-coordinated-update/README.md) about +community-coordinated updates to (try to) ensure that independently deployed, interoperable agents remain interoperable throughout this transition. + +The transition from the old to new messages will occur in four steps: + +- **Pre-work**: Agent builders agree on the transition plan outlined in this RFC and the target date for completing Step 1. + - Any RFC updates related to this transition needed before starting the transition are completed. +- **Step 1**: Agent builders update all agent code bases and deployments to accept incoming out-of-band messages requesting equivalent-to-current functionality. + - Equivalent-to-current functionality includes: + - RFC 160 Connections invitations + - Connection-less Present Proof protocol instances using the service decorator + - See the section below on [Step 1 out-of-band messages](#step-1-out-of-band-messages) + - During Step 1, all agents should continue to send the current invitation and connection-less protocol messages. + - Each agent builder SHOULD notify the community they have completed Step 1 by submitting a PR to update their entry in the [implementations](#implementations) section of this RFC. +- **Step 2**: Agent builders update all agent code bases and deployments to send out out-of-band invitations equivalent to the current invitation and connection-less protocol messages, and Agent builders add full out-of-band protocol support to all agent code bases and deployments. + - Messages from existing RFCs being replaced by the out-of-band protocol are marked as `deprecated`. + - Full out-of-band support is **NOT** required—just support for the out-of-band equivalents of the old `invitation` messages. + - When sending or receiving `did:peer` DIDs, the DIDs MUST conform to the [Peer DID Specification](https://identity.foundation/peer-did-method-spec/). + - Each agent builder SHOULD notify the community they have completed Step 2 by submitting a PR to update their entry in the [implementations](#implementations) section. +- **Step 3**: Support for the current invitation and connection-less protocol messages can be removed from all implementations and deployments, and all out-of-band `invitation` capabilities that align with the then current Aries Interop Profile (AIP) may be offered. + +### Step 1 Out-of-Band Messages + +The definition of Step 1 has been deliberately defined to limit the impact of the changes on existing code bases. An implementation may be able to do as little as convert an incoming out-of-band protocol message into its "current format" equivalent and process the message, thus deferring larger changes to the message handling code. The following examples show the equivalence between out-of-band and current messages and the constraints on the out-of-band invitations used in Step 2. + +#### Connection Invitation—Inline DIDDoc Service Entry + +The following is the out-of-band `invitation` message equivalent to an RFC 0160 Connections `invitation` message that may be used in Step 2. + +```jsonc +{ + "@type": "https://didcomm.org/out-of-band/1.0/invitation", + "@id": "1234-1234-1234-1234", + "label": "Faber College", + "goal_code": "establish-connection", + "goal": "To establish a connection", + "handshake_protocols": ["did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation"], + "service": [ + { + "id": "#inline" + "type": "did-communication", + "recipientKeys": ["did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"], + "routingKeys": [], + "serviceEndpoint": "https://example.com:5000" + } + ] +} +``` + +The constraints on this form of the out-of-band `invitation` sent during Step 2 are: + +- `goal_code` and `goal` are ignored. +- `handshake_protocols` MUST have exactly one entry and that entry must be `did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation`. +- `request~attach` MUST NOT be present. +- `service` MUST have exactly one entry and be in the form above or be a single DID (but not both). + +This out-of-band message can be transformed to the following RFC 0160 Connection `invitation` message. + +```jsonc +{ + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", + "@id": "1234-1234-1234-1234", + "label": "Faber College", + "recipientKeys": ["6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"], + "serviceEndpoint": "https://example.com:5000", + "routingKeys": [] +} +``` + +Note the use of `did:key` in the out-of-band message and the "naked" public key in the connection message. Ideally, full support for `did:key` will be added during Step 1. However, if there is not time for an agent builder to add full support, the transformation can be accomplished using simple text transformations between the `did:key` format and the (only) public key format used in current Aries agents. + +#### Connection Invitation—DID Service Entry + +If the out-of-band message `service` item is a single DID, the resulting transformed message is comparably different. For example, this out-of-band `invitation` message: + +```jsonc +{ + "@type": "https://didcomm.org/out-of-band/%VER/invitation", + "@id": "", + "label": "Faber College", + "goal_code": "issue-vc", + "goal": "To issue a Faber College Graduate credential", + "handshake_protocols": ["https://didcomm.org/connections/1.0"], + "service": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] +} +``` + +The `did` form of the connection invitation is implied, as shown here: + +```jsonc +{ + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/connections/1.0/invitation", + "@id": "1234-1234-1234-1234", + "label": "Faber College", + "did": ["did:sov:LjgpST2rjsoxYegQDRm7EL"] +} +``` + +#### Connection-less Present Proof Request + +The most common connection-less form being used in production is the `request-presentation` message from the [RFC 0037 Present Proof](../0037-present-proof/README.md) protocol. The out-of-band invitation for that request looks like this, using the inline form of the service entry. + +```jsonc +{ + "@type": "https://didcomm.org/out-of-band/%VER/invitation", + "@id": "1234-1234-1234-1234", + "label": "Faber College", + "goal_code": "present-proof", + "goal": "Request proof of some claims from verified credentials", + "request~attach": [ + { + "@id": "request-0", + "mime-type": "application/json", + "data": { + "json": { + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", + "@id": "", + "comment": "some comment", + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ] + } + } + } + ], + "service": [ + { + "id": "#inline", + "type": "did-communication", + "recipientKeys": ["did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"], + "routingKeys": [], + "serviceEndpoint": "https://example.com:5000" + } + ] +} +``` + +The constraints on this form of the out-of-band `invitation` sent during Step 2 are: + +- `goal_code` is ignored and `goal` is used as the `comment`. +- `handshake_protocols` MUST NOT be present. +- `request~attach` MUST have exactly one entry and that entry must be a `request-presentation` message. +- `service` MUST have exactly one entry and be in the form above or be a single DID (but not both). + +This out-of-band message can be transformed to the following RFC 0037 Present Proof `request-presentation` message with an [RFC 0056 Service Decorator](../0056-service-decorator/README.md) item. + +```jsonc +{ + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/request-presentation", + "@id": "1234-1234-1234-1234", + "comment": "Request proof of some claims from verified credentials", + "~service": { + "recipientKeys": ["6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH"], + "routingKeys": [], + "serviceEndpoint": "https://example.com:5000" + }, + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ] +} +``` + +If the DID form of the out-of-band `invitation` message `service` entry was used, the `~service` item would be comparably altered. + +#### URL Shortener Handling + +During Step 2 [URL Shortening](../0434-outofband/README.md#url-shortening) as defined in RFC 0434 Out of Band must be supported. + +### Between Step Triggers + +The community coordination triggers between the steps above will be as follows: + +- **Pre-work to Step 1** - a PR to this RFC is merged that sets the RFC status to [ACCEPTED](/README.md#accepted). +- **Step 1 to Step 2** - the community agrees that the majority of the deployed agents have completed Step 1. A PR to this RFC is merged that sets the RFC status to [ADOPTED](/README.md#adopted). + - Agent builders indicate completion of Step 1 by updating the [Implementations](#implementations) section of this RFC. + - A PR to RFC 0160 Connections and RFC 0023 DID Exchange marks the `invitation` messages as deprecated. + - The [ADOPTED](/README.md#adopted) version of this RFC is included in the then-current [Aries Interop Profile](/concepts/0302-aries-interop-profile/README.md) version. +- **Step 2 to Step 3** - the community agrees that the majority of the deployed agents have completed Step 2. A PR to this RFC is merged that sets the RFC status to [RETIRED](/README.md#retired). + - Agent builders indicate completion of Step 2 by updating the [Implementations](#implementations) section of this RFC. + +## Motivation + +To enable agent builders to independently update their code bases and deployed agents to support the out-of-band protocol while maintaining interoperability. + +## Tutorial + +The general mechanism for this type of transition is documented in [RFC 0345](../../concepts/0345-community-coordinated-update/README.md) about +community-coordinated updates. + +The specific sequence of events to make this particular transition is outlined in the [summary](#summary) section of this RFC. + +## Reference + +See the [summary](#summary) section of this RFC for the details of this transition. + +## Drawbacks + +None identified. + +## Rationale and alternatives + +This approach balances the speed of adoption with the need for independent deployment and ongoing interoperability. + +## Prior art + +The approach outlined in [RFC +0345](../../concepts/0345-community-coordinated-update/README.md) about +community-coordinated updates is a well-known pattern for using deprecation to +make breaking changes in an ecosystem. That said, this is the first attempt to +use this approach in Aries. Adjustments to the transition plan will be made as needed, and RFC 0345 will be updated based on lessons learned in executing this plan. + +## Unresolved questions + +- Are the constraints on the proposed "equivalent to existing" messages sufficiently clear? +- Does the community want to support the connection-less `Issue Credential` process to be supported in Step 2? + +## Implementations + +The following table lists the status of various agent code bases and deployments with respect to **Step 1** of this transition. Agent builders MUST update this table as they complete steps of the transition. + +Name / Link | Implementation Notes +--- | --- + | \ No newline at end of file diff --git a/features/0509-action-menu/README.md b/features/0509-action-menu/README.md index f2f5c8bac..2cd2207b8 100644 --- a/features/0509-action-menu/README.md +++ b/features/0509-action-menu/README.md @@ -6,7 +6,7 @@ - Status Note: Implemented and demonstrated in the [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python) code base - Supersedes: - Start Date: 2020-06-24 -- Tags: [feature](/tags.md#feature) +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) - Protocol Name: action-menu - Version: 1.0 - URI: `https://didcomm.org/action-menu/%VER` @@ -197,8 +197,8 @@ N/A There are several existing RFCs that relate to the general problem of "Discovery" -* [Aries RFC 0031 : Discover Features Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/master/features/0031-discover-features) -- This RFC provides _Aries Protocol_ discovery between two Agents but no direction on user interface display or action handling. -* [Aries RFC 0214 : "Help Me Discover" Protocol](https://github.com/hyperledger/aries-rfcs/tree/master/features/0214-help-me-discover) -- This RFC introduces the concept of a query language protocol between agents to obtain "referal" to a third agent. +* [Aries RFC 0031 : Discover Features Protocol 1.0](https://github.com/hyperledger/aries-rfcs/tree/main/features/0031-discover-features) -- This RFC provides _Aries Protocol_ discovery between two Agents but no direction on user interface display or action handling. +* [Aries RFC 0214 : "Help Me Discover" Protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0214-help-me-discover) -- This RFC introduces the concept of a query language protocol between agents to obtain "referal" to a third agent. ## Unresolved questions diff --git a/features/0510-dif-pres-exch-attach/README.md b/features/0510-dif-pres-exch-attach/README.md index eeea3dc6a..14a4598b5 100644 --- a/features/0510-dif-pres-exch-attach/README.md +++ b/features/0510-dif-pres-exch-attach/README.md @@ -1,7 +1,7 @@ # Aries RFC 0510: Presentation-Exchange Attachment format for requesting and presenting proofs - Authors: George Aristy (SecureKey Technologies) -- Status: [PROPOSED](/README.md#proposed) +- Status: [ADOPTED](/README.md#adopted) - Since: 2020-07-21 - Status Note: - Supersedes: @@ -11,16 +11,18 @@ ## Summary -This RFC registers an attachment format for use in the [present-proof V2](../0454-present-proof-v2/README.md) protocol based on -the Decentralized Identity Foundation's (DIF) [Presentation Exchange specification](https://identity.foundation/presentation-exchange/). +This RFC registers three attachment formats for use in the [present-proof V2](../0454-present-proof-v2/README.md) protocol based on +the Decentralized Identity Foundation's (DIF) [Presentation Exchange specification](https://identity.foundation/presentation-exchange/) (P-E). +Two of these formats define containers for a presentation-exchange request object and another _options_ object carrying +additional parameters, while the third format is just a vessel for the final `presentation_submission` verifiable +presentation transferred from the Prover to the Verifier. *Presentation Exchange* defines a data format capable of articulating a rich set of proof requirements from Verifiers, and also provides a means of describing the formats in which Provers must submit those proofs. A Verifier's defines their requirements in a `presentation_definition` containing `input_descriptors` that describe the credential(s) the proof(s) must be derived from as well as a rich set of operators that place `constraints` on those proofs -(eg. "must be issued from issuer X" or "`age` over X", etc.). The Verifier may optionally specify `submission_requirement`s -that layer set-membership requirements on top of `input_descriptors`. +(eg. "must be issued from issuer X" or "`age` over X", etc.). The Verifiable Presentation format of [Presentation Submissions](https://identity.foundation/presentation-exchange/#presentation-submission) is used as opposed to OIDC tokens or CHAPI objects. For an alternative on how to tunnel OIDC messages over DIDComm, see @@ -29,9 +31,9 @@ is used as opposed to OIDC tokens or CHAPI objects. For an alternative on how to ## Motivation -The *Presentation Exchange* specification possesses a rich language for expressing a Verifier's criterion. +The *Presentation Exchange* specification (P-E) possesses a rich language for expressing a Verifier's criterion. -The *Presentation Exchange* specification lends itself well to several transport mediums due to its limited scope as a data format, +P-E lends itself well to several transport mediums due to its limited scope as a data format, and is easily transported over DIDComm. It is furthermore desirable to make use of specifications developed in an open standards body. @@ -47,7 +49,7 @@ The Verifier sends a `request-presentation` to the Prover containing a The Prover can optionally respond to the Verifier's `request-presentation` with a `propose-presentation` message containing "Input Descriptors" that describe the proofs they can provide. The contents of the attachment is just the -`input_descriptors` attribute of the `presentation_definitions` object. +`input_descriptors` attribute of the `presentation_definition` object. The Prover responds with a `presentation` message containing a [`presentation_submission`](https://identity.foundation/presentation-exchange/#presentation-submission). @@ -59,11 +61,13 @@ The Prover responds with a `presentation` message containing a Format identifier: `dif/presentation-exchange/definitions@v1.0` -Complete message example: +#### Examples: propose-presentation + +
Complete message example ```json { - "@type": "http://didcomm.org/present-proof/%VER/propose-presentation", + "@type": "https://didcomm.org/present-proof/%VER/propose-presentation", "@id": "fce30ed1-96f8-44c9-95cf-b274288009dc", "comment": "some comment", "formats" : [{ @@ -77,11 +81,11 @@ Complete message example: "json": { "input_descriptors": [{ "id": "citizenship_input", + "name": "US Passport", "group": ["A"], - "schema": { - "uri": ["hub://did:foo:123/Collections/schema.us.gov/passport.json"], - "name": "US Passport" - }, + "schema": [{ + "uri": "hub://did:foo:123/Collections/schema.us.gov/passport.json" + }], "constraints": { "fields": [{ "path": ["$.credentialSubject.birth_date", "$.vc.credentialSubject.birth_date", "$.birth_date"], @@ -97,25 +101,44 @@ Complete message example: }] } ``` +
### `request-presentation` attachment format Format identifier: `dif/presentation-exchange/definitions@v1.0` -The contents of the attachment is a JSON object containing the Verifier's presentation definitions, a challenge and a domain: +Since the format identifier defined above is the same as the one used in the `propose-presentation` message, it's recommended to consider both the message `@type` and the `format` to accuarately understand the contents of the attachment. + +The contents of the attachment is a JSON object containing the Verifier's presentation definition and an _options_ object +with proof options: ```jsonc { - "challenge": "...", - "domain": "...", - "presentation_definitions": { - // presentation definitions object + "options": { + "challenge": "...", + "domain": "...", + }, + "presentation_definition": { + // presentation definition object } } ``` -Complete message example: +#### The _options_ object + +_options_ is a container of additional parameters required for the Prover to fulfill the Verifier's request. + +Available options are: + +Name|Status|Description +----|------|----------- +`challenge`|RECOMMENDED (for LD proofs)|Random seed provided by the Verifier for [LD Proofs](https://w3c-ccg.github.io/ld-proofs/#dfn-challenge). +`domain`|RECOMMENDED (for LD proofs)|The operational domain of the requested [LD proof](https://w3c-ccg.github.io/ld-proofs/#dfn-domain). + +#### Examples: request-presentation + +
Complete message example requesting a verifiable presentation with proof type Ed25519Signature2018 ```json { @@ -131,19 +154,21 @@ Complete message example: "mime-type": "application/json", "data": { "json": { - "challenge": "23516943-1d79-4ebd-8981-623f036365ef", - "domain": "us.gov/DriversLicense", - "presentation_definitions": { + "options": { + "challenge": "23516943-1d79-4ebd-8981-623f036365ef", + "domain": "us.gov/DriversLicense" + }, + "presentation_definition": { "input_descriptors": [{ "id": "citizenship_input", + "name": "US Passport", "group": ["A"], - "schema": { - "uri": ["hub://did:foo:123/Collections/schema.us.gov/passport.json"], - "name": "US Passport" - }, + "schema": [{ + "uri": "hub://did:foo:123/Collections/schema.us.gov/passport.json" + }], "constraints": { "fields": [{ - "path": ["$.credentialSubject.birth_date", "$.vc.credentialSubject.birth_date", "$.birth_date"], + "path": ["$.credentialSubject.birth_date", "$.birth_date"], "filter": { "type": "date", "minimum": "1999-5-16" @@ -151,23 +176,70 @@ Complete message example: }] } }], - "submission_requirement": { - "name": "Credential issuance requirements", - "purpose": "Verify banking, employment, and citizenship information.", - "rule": "all", - "from": [{ - "name": "Citizenship Information", - "rule": "pick", - "count": 1, - "from": "A" - }] - } + "format": { + "ldp_vp": { + "proof_type": ["Ed25519Signature2018"] + } + } } } } }] } ``` +
+ +
The same example but requesting the verifiable presentation with proof type BbsBlsSignatureProof2020 instead + +```json +{ + "@type": "https://didcomm.org/present-proof/%VER/request-presentation", + "@id": "0ac534c8-98ed-4fe3-8a41-3600775e1e92", + "comment": "some comment", + "formats" : [{ + "attach_id" : "ed7d9b1f-9eed-4bde-b81c-3aa7485cf947", + "format" : "dif/presentation-exchange/definitions@v1.0" + }], + "request_presentations~attach": [{ + "@id": "ed7d9b1f-9eed-4bde-b81c-3aa7485cf947", + "mime-type": "application/json", + "data": { + "json": { + "options": { + "challenge": "23516943-1d79-4ebd-8981-623f036365ef", + "domain": "us.gov/DriversLicense" + }, + "presentation_definition": { + "input_descriptors": [{ + "id": "citizenship_input", + "name": "US Passport", + "group": ["A"], + "schema": [{ + "uri": "hub://did:foo:123/Collections/schema.us.gov/passport.json" + }], + "constraints": { + "fields": [{ + "path": ["$.credentialSubject.birth_date", "$.vc.credentialSubject.birth_date", "$.birth_date"], + "filter": { + "type": "date", + "minimum": "1999-5-16" + } + }], + "limit_disclosure": "required" + } + }], + "format": { + "ldp_vc": { + "proof_type": ["BbsBlsSignatureProof2020"] + } + } + } + } + } + }] +} +``` +
### `presentation` attachment format @@ -176,7 +248,9 @@ Format identifier: `dif/presentation-exchange/submission@v1.0` The contents of the attachment is a Presentation Submission in a standard Verifiable Presentation format containing the proofs requested. -Complete message example: +#### Examples: presentation + +
Complete message example ```json { @@ -241,7 +315,275 @@ Complete message example: }] } ``` +
+ + +### Supported Features of Presentation-Exchange + +Level of support for Presentation-Exchange features: + +Feature|Notes +-------|----- +`presentation_definition.input_descriptors.id`| +`presentation_definition.input_descriptors.name`| +`presentation_definition.input_descriptors.purpose`| +`presentation_definition.input_descriptors.schema.uri`|URI for the credential's schema. +`presentation_definition.input_descriptors.constraints.fields.path`|Array of JSONPath string expressions as defined in [section 8](https://identity.foundation/presentation-exchange/#jsonpath-syntax-definition). REQUIRED as per the spec. +`presentation_definition.input_descriptors.constraints.fields.filter`|JSONSchema descriptor. +`presentation_definition.input_descriptors.constraints.limit_disclosure`|`preferred` or `required` as defined in [the spec](https://identity.foundation/presentation-exchange/#input-descriptor-object) and as supported by the Holder and Verifier proof mechanisms.
Note that the Holder MUST have credentials with cryptographic proof suites that are capable of selective disclosure in order to respond to a request with `limit_disclosure: "required"`.
See [RFC0593](../0593-json-ld-cred-attach/README.md) for appropriate crypto suites. +`presentation_definition.input_descriptors.constraints.is_holder`|`preferred` or `required` as defined in [the spec](https://identity.foundation/presentation-exchange/#input-descriptor-object).
Note that this feature allows the Holder to present credentials with a different subject identifier than the DID used to establish the DIDComm connection with the Verifier. +`presentation_definition.format`|For JSONLD-based credentials: `ldp_vc` and `ldp_vp`. +`presentation_definition.format.proof_type`|For JSONLD-based credentials: `Ed25519Signature2018`, `BbsBlsSignature2020`, and `JsonWebSignature2020`. When specifying `ldp_vc`, `BbsBlsSignatureProof2020` may also be used. + +### Proof Formats + +#### Constraints + +Verifiable Presentations MUST be produced and consumed using the [JSON-LD syntax](https://www.w3.org/TR/vc-data-model/#json-ld). + +The proof types defined below MUST be registered in the [Linked Data Cryptographic Suite Registry](https://w3c-ccg.github.io/ld-cryptosuite-registry/). + +The value of any `credentialSubject.id` in a credential MUST be a [Dentralized Identifier (DID)](https://w3c.github.io/did-core/) +conforming to the [DID Syntax](https://w3c.github.io/did-core/#did-syntax) if present. This allows the Holder to +authenticate as the credential's subject if required by the Verifier (see the `is_holder` property above). The Holder +authenticates as the credential's subject by attaching an LD Proof on the enclosing Verifiable Presentation. + +#### Proof Formats on Credentials + +Aries agents implementing this RFC MUST support the formats outlined in [RFC0593](../0593-json-ld-cred-attach/README.md#supported-proof-types) +for proofs on [Verifiable Credentials](https://www.w3.org/TR/vc-data-model/). + +#### Proof Formats on Presentations + +Aries agents implementing this RFC MUST support the formats outlined below for proofs on [Verifiable Presentations](https://www.w3.org/TR/vc-data-model/). + +##### Ed25519Signature2018 + +[Specification](https://w3c-ccg.github.io/lds-ed25519-2018/). + +**Request Parameters:** + +* `presentation_definition.format`: `ldp_vp` +* `presentation_definition.format.proof_type`: `Ed25519Signature2018` +* `options.challenge`: (Optional) a random string value generated by the Verifier +* `options.domain`: (Optional) a string value specified set by the Verifier + +**Result:** + +A [Verifiable Presentation](https://www.w3.org/TR/vc-data-model/#presentations-0) of type +[Presentation Submission](https://identity.foundation/presentation-exchange/#presentation-submission) containing the +credentials requested under the `verifiableCredential` property and a `proof` property of type `Ed25519Signature2018`. + +
Example + +```json +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://identity.foundation/presentation-exchange/submission/v1" + ], + "type": [ + "VerifiablePresentation", + "PresentationSubmission" + ], + "presentation_submission": { + "descriptor_map": [{ + "id": "citizenship_input", + "path": "$.verifiableCredential.[0]" + }] + }, + "verifiableCredential": [{ + "@context": "https://www.w3.org/2018/credentials/v1", + "id": "https://eu.com/claims/DriversLicense", + "type": [ + "EUDriversLicense" + ], + "issuer": "did:foo:123", + "issuanceDate": "2010-01-01T19:73:24Z", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "license": { + "number": "34DGE352", + "dob": "07/13/80" + } + }, + "proof": { + "type": "RsaSignature2018", + "created": "2017-06-18T21:19:10Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "https://example.edu/issuers/keys/1", + "jws": "..." + } + }], + "proof": { + "type": "Ed25519Signature2018", + "proofPurpose": "authentication", + "created": "2017-09-23T20:21:34Z", + "verificationMethod": "did:example:123456#key1", + "challenge": "2bbgh3dgjg2302d-d2b3gi423d42", + "domain": "example.org", + "jws": "eyJ0eXAiOiJK...gFWFOEjXk" + } +} +``` +
+ +##### BbsBlsSignature2020 + +[Specification](https://w3c-ccg.github.io/ldp-bbs2020/). + +Associated RFC: [RFC0646](../0646-bbs-credentials/README.md). + +**Request Parameters**: +* `presentation_definition.format`: `ldp_vp` +* `presentation_definition.format.proof_type`: `BbsBlsSignature2020` +* `options.challenge`: (Optional) a random string value generated by the Verifier +* `options.domain`: (Optional) a string value specified set by the Verifier + +**Result:** + +A [Verifiable Presentation](https://www.w3.org/TR/vc-data-model/#presentations-0) of type +[Presentation Submission](https://identity.foundation/presentation-exchange/#presentation-submission) containing the +credentials requested under the `verifiableCredential` property and a `proof` property of type `BbsBlsSignature2020`. + +
Example + +```json +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/v2", + "https://w3id.org/security/bbs/v1", + "https://identity.foundation/presentation-exchange/submission/v1" + ], + "type": [ + "VerifiablePresentation", + "PresentationSubmission" + ], + "presentation_submission": { + "descriptor_map": [{ + "id": "citizenship_input", + "path": "$.verifiableCredential.[0]" + }] + }, + "verifiableCredential": [{ + "@context": "https://www.w3.org/2018/credentials/v1", + "id": "https://eu.com/claims/DriversLicense", + "type": ["EUDriversLicense"], + "issuer": "did:foo:123", + "issuanceDate": "2010-01-01T19:73:24Z", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "license": { + "number": "34DGE352", + "dob": "07/13/80" + } + }, + "proof": { + "type": "BbsBlsSignatureProof2020", + "created": "2020-04-25", + "verificationMethod": "did:example:489398593#test", + "proofPurpose": "assertionMethod", + "signature": "F9uMuJzNBqj4j+HPTvWjUN/MNoe6KRH0818WkvDn2Sf7kg1P17YpNyzSB+CH57AWDFunU13tL8oTBDpBhODckelTxHIaEfG0rNmqmjK6DOs0/ObksTZh7W3OTbqfD2h4C/wqqMQHSWdXXnojwyFDEg==" + } + }], + "proof": { + "type": "BbsBlsSignature2020", + "created": "2020-04-25", + "verificationMethod": "did:example:489398593#test", + "proofPurpose": "authentication", + "proofValue": "F9uMuJzNBqj4j+HPTvWjUN/MNoe6KRH0818WkvDn2Sf7kg1P17YpNyzSB+CH57AWDFunU13tL8oTBDpBhODckelTxHIaEfG0rNmqmjK6DOs0/ObksTZh7W3OTbqfD2h4C/wqqMQHSWdXXnojwyFDEg==", + "requiredRevealStatements": [ 4, 5 ] + } +} +``` +
+ +> Note: The above example is for illustrative purposes. In particular, note that whether a Verifier requests a `proof_type` +> of `BbsBlsSignature2020` has no bearing on whether the Holder is required to present credentials with proofs of type +> `BbsBlsSignatureProof2020`. The choice of proof types on the credentials is constrained by a) the available types +> registered in RFC0593 and b) additional constraints placed on them due to other aspects of the proof requested by +> the Verifier, such as requiring limited disclosure with the `limit_disclosure` property. In such a case, a proof +> type of `Ed25519Signature2018` in the credentials is not appropriate whereas `BbsBlsSignatureProof2020` is capable +> of selective disclosure. + +##### JsonWebSignature2020 + +[Specification](https://w3c-ccg.github.io/lds-jws2020/). + +**Request Parameters:** + +* `presentation_definition.format`: `ldp_vp` +* `presentation_definition.format.proof_type`: `JsonWebSignature2020` +* `options.challenge`: (Optional) a random string value generated by the Verifier +* `options.domain`: (Optional) a string value specified set by the Verifier + +**Result:** + +A [Verifiable Presentation](https://www.w3.org/TR/vc-data-model/#presentations-0) of type +[Presentation Submission](https://identity.foundation/presentation-exchange/#presentation-submission) containing the +credentials requested under the `verifiableCredential` property and a `proof` property of type `JsonWebSignature2020`. + +
Example + +```json +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://identity.foundation/presentation-exchange/submission/v1" + ], + "type": [ + "VerifiablePresentation", + "PresentationSubmission" + ], + "presentation_submission": { + "descriptor_map": [{ + "id": "citizenship_input", + "path": "$.verifiableCredential.[0]" + }] + }, + "verifiableCredential": [{ + "@context": "https://www.w3.org/2018/credentials/v1", + "id": "https://eu.com/claims/DriversLicense", + "type": [ + "EUDriversLicense" + ], + "issuer": "did:foo:123", + "issuanceDate": "2010-01-01T19:73:24Z", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "license": { + "number": "34DGE352", + "dob": "07/13/80" + } + }, + "proof": { + "type": "RsaSignature2018", + "created": "2017-06-18T21:19:10Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "https://example.edu/issuers/keys/1", + "jws": "..." + } + }], + "proof": { + "type": "JsonWebSignature2020", + "proofPurpose": "authentication", + "created": "2017-09-23T20:21:34Z", + "verificationMethod": "did:example:123456#key1", + "challenge": "2bbgh3dgjg2302d-d2b3gi423d42", + "domain": "example.org", + "jws": "eyJ0eXAiOiJK...gFWFOEjXk" + } +} +``` +
+ +Available JOSE key types are: +kty|crv |signature +---|------|-------- +EC |P-256 |ES256 +EC |P-384 |ES384 ## Drawbacks @@ -262,7 +604,7 @@ N/A ## Unresolved questions -> TODO it is assumed the Verifier will initiate the protocol if they can transmit their presentation definitions via an out-of-band channel +> TODO it is assumed the Verifier will initiate the protocol if they can transmit their presentation definition via an out-of-band channel > (eg. it is published on their website) with a `request-presentation` message, possibly delivered via an Out-of-Band invitation > (see [RFC0434](../0434-outofband/README.md)). For now, the Prover sends `propose-presentation` as a response to `request-presentation`. diff --git a/features/0511-dif-cred-manifest-attach/README.md b/features/0511-dif-cred-manifest-attach/README.md index c804461ce..978b9474a 100644 --- a/features/0511-dif-cred-manifest-attach/README.md +++ b/features/0511-dif-cred-manifest-attach/README.md @@ -56,7 +56,7 @@ Complete message example: "attach_id": "b45ca1bc-5b3c-4672-a300-84ddf6fbbaea", "format": "dif/credential-manifest@v1.0" }], - "filter~attach": [{ + "filters~attach": [{ "@id": "b45ca1bc-5b3c-4672-a300-84ddf6fbbaea", "mime-type": "application/json", "data": { diff --git a/features/0557-discover-features-v2/README.md b/features/0557-discover-features-v2/README.md new file mode 100644 index 000000000..b6def52c4 --- /dev/null +++ b/features/0557-discover-features-v2/README.md @@ -0,0 +1,150 @@ +# Aries RFC 0557: Discover Features Protocol v2.x + +- Authors: Daniel Hardman +- Status: [ADOPTED](/README.md#adopted) +- Since: 2024-05-01 +- Status Note: Update to version 2.0 proposed in conjunction with DIDComm v2 efforts at DIF, where it became clear that we need to discover more than just protocol support of other agents. Included in [AIP v2.0](../../concepts/0302-aries-interop-profile/README.md). +- Supersedes: [version 1.0 of this protocol in RFC 0031](../0031-discover-features/README.md), which was widely referenced in the Aries eocsystem in 2018 and 2019. +- Start Date: 2018-12-17 +- URI: https://didcomm.org/discover-features/%VER +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [test-anomaly](/tags.md#test-anomaly) + +## Summary + +Describes how one agent can query another to discover which features it supports, and to what extent. + +## Motivation + +Though some agents will support just one feature and will be statically configured to interact with just one other party, many exciting uses of agents are more dynamic and unpredictable. When Alice and Bob meet, they won't know in advance which features are supported by one another's agents. They need a way to find out. + +## Tutorial + +This is version 2.0 of the Discover Features protocol, and its fully qualified [PIURI](../../concepts/0003-protocols/README.md#piuri) for the Discover Features protocol is: + + https://didcomm.org/discover-features/2.0 + +This version is conceptually similar to [version 1.0 of this protocol](../0031-discover-features/README.md). It differs in its ability to ask about multiple feature types, and to ask multiple questions and receive multiple answers in a single round trip. + +### Roles + +There are two roles in the `discover-features` protocol: `requester` and `responder`. Normally, the requester asks the responder about the features it supports, and the responder answers. Each role uses a single message type. + +It is also possible to proactively disclose features; in this case a requester receives a response without asking for it. This may eliminate some chattiness in certain use cases (e.g., where two-way connectivity is limited). + +### States + +The state progression is very simple. In the normal case, it is simple request-response; in a proactive disclosure, it's a simple one-way notification. + +#### Requester +![requester state](requester.png) + +#### Responder +![responder state](responder.png) + +### Messages + +##### `queries` Message Type + +A `discover-features/queries` message looks like this: + +```jsonc +{ + "@type": "https://didcomm.org/discover-features/2.0/queries", + "@id": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU", + "queries": [ + { "feature-type": "protocol", "match": "https://didcomm.org/tictactoe/1.*" }, + { "feature-type": "goal-code", "match": "aries.*" } + ] +} +``` + +Queries messages contain one or more __query objects__ in the `queries` array. Each query essentially says, "Please tell me what features of type X you support, where the feature identifiers match this (potentially wildcarded) string." This particular example asks an agent if it supports any 1.x versions of the [tictactoe protocol]( ../../concepts/0003-protocols/tictactoe/README.md ), and if it supports any [goal codes](../../concepts/0519-goal-codes/README.md) that begin with "aries.". + +Implementations of this protocol must recognize the following values for `feature-type`: `protocol`, `goal-code`, `gov-fw`, `didcomm-version`, and `decorator`/`header`. (The concept known as `decorator` in DIDComm v1 approximately maps to the concept known as `header` in DIDComm v2. The two values should be considered synonyms and must both be recognized.) Additional values of `feature-type` may be standardized by raising a PR against this RFC that defines the new type and increments the minor protocol version number; non-standardized values are also valid, but there is no guarantee that their semantics will be recognized. + +Identifiers for feature types vary. For protocols, identifiers are PIURIs. For goal codes, identifiers are goal code values. For governance frameworks, identifiers are URIs where the framework is published (typically the [`data_uri` field if machine-readable](../../concepts/0430-machine-readable-governance-frameworks/README.md#data_uri). For DIDComm versions, identifiers are the URIs where DIDComm versions are developed (`https://github.com/hyperledger/aries-rfcs` for V1 and `https://github.com/decentralized-identity/didcomm-messaging` for V2; see ["Detecting DIDComm Versions" in RFC 0044](../0044-didcomm-file-and-mime-types/README.md#detecting-didcomm-versions) for more details). + +The `match` field of a query descriptor may use the * wildcard. By itself, a `match` with just the wildcard says, "I'm interested in anything you want to share with me." But usually, this wildcard will be to match a prefix that's a little more specific, as in the example that matches any 1.x version. + +Any agent may send another agent this message type at any time. Implementers of agents that intend to support dynamic relationships and rich features are *strongly* encouraged to implement support for this message, as it is likely to be among the first messages exchanged with a stranger. + +##### `disclosures` Message Type + +A `discover-features/disclosures` message looks like this: + +```jsonc +{ + "@type": "https://didcomm.org/discover-features/2.0/disclosures", + "~thread": { "thid": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU" }, + "disclosures": [ + { + "feature-type": "protocol", + "id": "https://didcomm.org/tictactoe/1.0", + "roles": ["player"] + }, + { + "feature-type": "goal-code", + "id": "aries.sell.goods.consumer" + } + ] +} +``` + +The `disclosures` field is a JSON array of zero or more __disclosure objects__ that describe a feature. Each descriptor has a `feature-type` field that contains data corresponding to `feature-type` in a query object, and an `id` field that unambiguously identifies a single item of that feature type. When the item is a protocol, the disclosure object may also contain a `roles` array that enumerates the roles the responding agent can play in the associated protocol. Future feature types may add additional optional fields, though no other fields are being standardized with this version of the RFC. + +Disclosures messages say, "Here are some features I support (that matched your queries)." + +##### Sparse Disclosures + +Disclosures do not have to contain exhaustive detail. For example, the following response omits the optional `roles` field but may be just as useful as one that includes it: + +```jsonc +{ + "@type": "https://didcomm.org/discover-features/2.0/disclosures", + "~thread": { "thid": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU" }, + "disclosures": [ + {"feature-type": "protocol", "id": "https://didcomm.org/tictactoe/1.0"} + ] +} +``` + +Less detail probably suffices because agents do not need to know everything about one another's implementations in order to start an interaction--usually the flow will organically reveal what's needed. For example, the `outcome` message in the `tictactoe` protocol isn't needed until the end, and is optional anyway. Alice can start a tictactoe game with Bob and will eventually see whether he has the right idea about `outcome` messages. + +The missing `roles` in this disclosure does not say, "I support no roles in this protocol." It says, "I support the protocol but I'm providing no detail about specific roles." Similar logic applies to any other omitted fields. + +An empty `disclosures` array does not say, "I support no features that match your query." It says, "I'm not disclosing to you that I support any features (that match your query)." An agent might not tell another that it supports a feature for various reasons, including: the trust that it imputes to the other party based on cumulative interactions so far, whether it's in the middle of upgrading a plugin, whether it's currently under high load, and so forth. And responses to a `discover-features` query are not guaranteed to be true forever; agents can be upgraded or downgraded, although they probably won't churn in their feature profiles from moment to moment. + +### Privacy Considerations + +Because the wildcards in a `queries` message can be very inclusive, the `discover-features` protocol could be used to mine information suitable for agent fingerprinting, in much the same way that browser fingerprinting works. This is antithetical to the ethos of our ecosystem, and represents bad behavior. Agents should use `discover-features` to answer legitimate questions, and not to build detailed profiles of one another. However, fingerprinting may be attempted anyway. + +For agents that want to maintain privacy, several best practices are recommended: + +##### Follow selective disclosure. + +Only reveal supported features based on trust in the relationship. Even if you support a protocol, you may not wish to use it in every relationship. Don't tell others about features you do not plan to use with them. + +Patterns are easier to see in larger data samples. However, a pattern of ultra-minimal data is also a problem, so use good judgment about how forthcoming to be. + +##### Vary the format of responses. + +Sometimes, you might prettify your agent plaintext message one way, sometimes another. + +##### Vary the order of items in the `disclosures` array. + +If more than one key matches a query, do not always return them in alphabetical order or version order. If you do return them in order, do not always return them in ascending order. + +##### Consider adding some spurious details. + +If a query could match multiple features, then occasionally you might add some made-up features as matches. If a wildcard allows multiple versions of a protocol, then sometimes you might use some made-up *versions*. And sometimes not. (Doing this too aggressively might reveal your agent implementation, so use sparingly.) + +##### Vary how you query, too. + +How you ask questions may also be fingerprintable. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +Name / Link | Implementation Notes +--- | --- diff --git a/features/0557-discover-features-v2/requester.png b/features/0557-discover-features-v2/requester.png new file mode 100644 index 000000000..eb60fd137 Binary files /dev/null and b/features/0557-discover-features-v2/requester.png differ diff --git a/features/0557-discover-features-v2/requester.puml b/features/0557-discover-features-v2/requester.puml new file mode 100644 index 000000000..7f9ab6d9e --- /dev/null +++ b/features/0557-discover-features-v2/requester.puml @@ -0,0 +1,11 @@ +@startuml +scale 350 width +hide empty description +state mode <> +state finish <> +[*] --> mode: normal or short-circuit? +mode --> awaiting_disclosures: normal: send\nqueries +mode --> finish: short-circuit:\nreceive\ndisclosures +awaiting_disclosures --> finish: receive disclosures +finish --> [*]: process\ndisclosures +@enduml \ No newline at end of file diff --git a/features/0557-discover-features-v2/responder.png b/features/0557-discover-features-v2/responder.png new file mode 100644 index 000000000..8fe4ddabb Binary files /dev/null and b/features/0557-discover-features-v2/responder.png differ diff --git a/features/0557-discover-features-v2/responder.puml b/features/0557-discover-features-v2/responder.puml new file mode 100644 index 000000000..e31c810a0 --- /dev/null +++ b/features/0557-discover-features-v2/responder.puml @@ -0,0 +1,6 @@ +@startuml +scale 350 width +hide empty description +[*] --> preparing_disclosures: receive queries\nor\nshort-circuit +preparing_disclosures --> [*]: send\ndisclosures +@enduml \ No newline at end of file diff --git a/features/0587-encryption-envelope-v2/README.md b/features/0587-encryption-envelope-v2/README.md new file mode 100644 index 000000000..9340671a6 --- /dev/null +++ b/features/0587-encryption-envelope-v2/README.md @@ -0,0 +1,196 @@ +# Aries RFC 0587: Encryption Envelope v2 + +- Authors: [Baha A. Shaaban](mailto:baha.shaaban@securekey.com) (SecureKey Technologies Inc.), [Troy Ronda](mailto:troy.ronda@securekey.com) (SecureKey Technologies Inc.) +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2021-04-15 +- Status Note: Included as part of the "prepare for DIDComm v2" subtarget of [AIP 2.0](../../concepts/0302-aries-interop-profile/README.md). +- Supersedes: +- Start Date: 2021-02-10 +- Tags: [feature](/tags.md#feature) + +## Summary + +This RFC proposes that we support the definition of envelopes from [DIDComm Messaging](https://identity.foundation/didcomm-messaging/spec). + +## Motivation + +This RFC defines ciphersuites for envelopes such that we can achieve better compatability with DIDComm Messaging being specified at DIF. +The ciphersuites defined in this RFC are a subset of the definitions in [Aries RFC 0334-jwe-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0334-jwe-envelope). + +## Encryption Algorithms + +DIDComm defines both the concept of authenticated sender encryption (aka `Authcrypt`) and anonymous sender encryption (aka `Anoncrypt`). +In general, Aries RFCs and protocols use `Authcrypt` to exchange messages. +In some limited scenarios (e.g., mediator and relays), an Aries RFC or protocol may define usage of `Anoncrypt`. + +[ECDH-1PU draft 04](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04) defines the JWE structure for `Authcrypt`. +`ECDH-ES` from [RFC 7518](https://tools.ietf.org/html/rfc7518#section-4.6) defines the JWE structure for `Anoncrypt`. +The following sections summarize the supported algorithms. + +### Curves + +DIDComm Messaging (and this RFC) requires support for `X25519`, `P-256`, and `P-384`. + +- P-256 (reference in [RFC4492](https://tools.ietf.org/search/rfc4492#appendix-A)) +- P-384 (reference in [RFC4492](https://tools.ietf.org/search/rfc4492#appendix-A)) +- P-521 (optional, reference in [RFC4492](https://tools.ietf.org/search/rfc4492#appendix-A)) +- X25519 (reference in [RFC7748](https://tools.ietf.org/html/rfc7748#section-5)) + +### Content Encryption Algorithms + +DIDComm Messaging (and this RFC) requires support for both `XC20P` and `A256GCM` for Anoncrypt only and `A256CBC-HS512` for both Authcrypt and Anoncrypt. + +- XC20P (XChaCha20Poly1305 - reference in [xchacha draft 03](https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03)) +- A256GCM (AES-GCM with a 256 bits key - reference in [RFC7518 section 5.1](https://tools.ietf.org/html/rfc7518#section-5.1) and more specifically [RFC7518 section 5.3](https://tools.ietf.org/html/rfc7518#section-5.3)) +- A256CBC-HS512 (AES256-CBC+HMAC-SHA512 with a 512 bits key - reference in [ECDH-1PU section 2.1](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04#section-2.1) and [RFC 7518 section 5.2.5](https://datatracker.ietf.org/doc/html/rfc7518#section-5.2.5)) + +### Key Wrapping Algorithms + +DIDComm Messaging (and this RFC) requires support for `ECDH-1PU+A256KW` and `ECDH-ES+A256KW`. + +- ECDH-1PU+A256KW (defined in [ECDH-1PU draft 04](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-04#section-2)) +- ECDH-ES+A256KW (defined in [RFC 7518](https://tools.ietf.org/html/rfc7518#section-4.6)) + +## Key IDs `kid` and `skid` headers references in the DID document + +Keys used by DIDComm envelopes MUST be sourced from the DIDs exchanged between two agents. Specifically, both sender and recipients keys MUST be retrieved from the DID document's `KeyAgreement` verification section as per the [DID Document Keys](https://identity.foundation/didcomm-messaging/spec/#did-document-keys) definition. + +When Alice is preparing an envelope intended for Bob, the packing process should use a key from both hers and Bob's DID document's `KeyAgreement` section. + +Assuming Alice has a DID Doc with the following `KeyAgreement` definition (source: [DID V1 Example 17](https://www.w3.org/TR/did-core/#example-17-key-agreement-property-containing-two-verification-methods)): +```jsonc +{ + "@context": "https://www.w3.org/ns/did/v1", + "id": "did:example:123456789abcdefghi", + ... + "keyAgreement": [ + // this method can be used to perform key agreement as did:...fghi + "did:example:123456789abcdefghi#keys-1", + // this method is *only* approved for key agreement usage, it will not + // be used for any other verification relationship, so its full description is + // embedded here rather than using only a reference + { + "id": "did:example:123#zC9ByQ8aJs8vrNXyDhPHHNNMSHPcaSgNpjjsBYpMMjsTdS", + "type": "X25519KeyAgreementKey2019", // external (property value) + "controller": "did:example:123", + "publicKeyBase58": "9hFgmPVfmBZwRvFEyniQDBkz9LmV7gDEqytWyGZLmDXE" + } + ], + ... +} +``` + +The envelope packing process should set the `skid` header with value `did:example:123456789abcdefghi#keys-1` in the envelope's protected headers and fetch the underlying key to execute ECDH-1PU key derivation for content key wrapping. + +Assuming she also has Bob's DID document which happens to include the following `KeyAgreement` section: + +```jsonc +{ + "@context": "https://www.w3.org/ns/did/v1", + "id": "did:example:jklmnopqrstuvwxyz1", + ... + "keyAgreement": [ + { + "id": "did:example:jklmnopqrstuvwxyz1#key-1", + "type": "X25519KeyAgreementKey2019", // external (property value) + "controller": "did:example:jklmnopqrstuvwxyz1", + "publicKeyBase58": "9hFgmPVfmBZwRvFEyniQDBkz9LmV7gDEqytWyGZLmDXE" + } + ], + ... +} +``` + +There should be only 1 entry in the recipients of the envelope, representing Bob. The corresponding `kid` header for this recipient MUST have `did:example:jklmnopqrstuvwxyz1#key-1` as value. The packing process MUST extract the public key bytes found in `publicKeyBase58` of Bob's DID Doc `KeyAgreement[0]` to execute the ECDH-1PU key derivation for content key wrapping. + +When Bob receives the envelope, the unpacking process on his end MUST resolve the `skid` protected header value using Alice's DID doc's `KeyAgreement[0]` in order to extract her public key. In Alice's DID Doc example above, `KeyAgreement[0]` is a reference id, it MUST be resolved from the main `VerificationMethod[]` of Alice's DID document (not shown in the example). + +Once resolved, the unpacker will then execute ECDH-1PU key derivation using this key and Bob's own recipient key found in the envelope's `recipients[0]` to unwrap the content encryption key. + +## Protecting the `skid` header +When the `skid` cannot be revealed in a plain-text JWE header (to avoid potentially leaking sender's key id), the `skid` MAY be encrypted for each recipient. In this case, instead of having a `skid` protected header in the envelope, each recipient MAY include an `encrypted_skid` header with a value based on the encryption of `skid` using ECDH-ES `Z` computation of the `epk` and the recipient's key as the encryption key. + +For applications that don't require this protection, they MAY use `skid` protected header directly without any additional recipient headers. + +Applications MUST use either `skid` protected header or `encrypted_skid` recipients header but not both in the same envelope. + +## ECDH-1PU key wrapping and common protected headers +When using authcrypt, the 1PU draft [requires](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04#section-2.1) mandates the use of AES_CBC_HMAC_SHA family of content encryption algorithms. To meet this requirement, JWE messages MUST use common `epk`, `apu`, `apv` and `alg` headers for all recipients. They MUST be set in the `protected` headers JWE section. + +As per this requirement, the JWE building must first encrypt the payload then use the resulting `tag` as part of the key derivation process when wrapping the `cek`. + +To meet this requirement, the above headers must be defined as follows: +* `epk`: generated once for all recipients. It MUST be of the same type and curve as all recipient keys since kdf with the sender key must be on the same curve. + - Example: `"epk": {"kty": "EC","crv": "P-256","x": "BVDo69QfyXAdl6fbK6-QBYIsxv0CsNMtuDDVpMKgDYs","y": "G6bdoO2xblPHrKsAhef1dumrc0sChwyg7yTtTcfygHA"}` +* `apu`: similar to `skid`, this is the producer (sender) identifier, it MUST contain the `skid` value base64 RawURL (no padding) encoded. Note: this is base64URL(`skid` value). + - Example for `skid` mentioned in an earlier [section](#key-ids-kid-and-skid-headers-references-in-the-did-document) above: `ZGlkOmV4YW1wbGU6MTIzNDU2Nzg5YWJjZGVmZ2hpI2tleXMtMQ` +* `apv`: this represents the recipients' `kid` list. The list must be alphanumerically sorted, `kid` values will then be concatenated with a `.` and the final result MUST be base64 URL (no padding) encoding of the SHA256 hash of concatenated list. +* `alg`: this is the key wrapping algorithm, ie: `ECDH-1PU+A256KW`. + +A final note about `skid` header: since the 1PU draft [does not require](https://datatracker.ietf.org/doc/html/draft-madden-jose-ecdh-1pu-04#section-2.2.1) this header, authcrypt implementations MUST be able to resolve the sender kid from the `APU` header if `skid` is not set. + +## Media Type + +The media type associated to this envelope is `application/didcomm-encrypted+json`. +[RFC 0044](../0044-didcomm-file-and-mime-types/README.md) provides a general discussion of media (aka mime) types. + +The media type of the envelope MUST be set in the `typ` [property](https://tools.ietf.org/html/rfc7516#section-4.1.11) of the JWE and the media type of the payload MUST be set in the `cty` [property](https://tools.ietf.org/html/rfc7516#section-4.1.12) of the JWE. + + For example, following the guidelines of [RFC 0044](../0044-didcomm-file-and-mime-types/README.md), an encrypted envelope with a plaintext DIDComm v1 payload contains the `typ` property with the value `application/didcomm-encrypted+json` and `cty` property with the value `application/json;flavor=didcomm-msg`. + + As specified in [IETF RFC 7515](https://tools.ietf.org/html/rfc7515) and referenced in [IETF RFC 7516](https://tools.ietf.org/html/rfc7516), implementations + MUST also support media types that omit `application/`. + For example, `didcomm-encrypted+json` and `application/didcomm-encrypted+json` are treated as equivalent media types. + +As discussed in [RFC 0434](../0434-outofband/README.md) and [RFC 0067](../0067-didcomm-diddoc-conventions/README.md), the `accept` property is used to advertise supported media types. +The `accept` property may contain an envelope media type or a combination of the envelope media type and the content media type. +In cases where the content media type is not present, the expectation is that the appropriate content media type can be inferred. +For example, `application/didcomm-envelope-enc` indicates both Envelope v1 and DIDComm v1 and `application/didcomm-encrypted+json` indicates both Envelope v2 and DIDComm v2. +However, some agents may choose to support Envelope v2 with a DIDComm v1 message payload. + +In case the `accept` property is set in both the DID service block and the out-of-band message, the out-of-band property takes precedence. + +## DIDComm v2 Transition + +As this RFC specifies the same envelope format as will be used in DIDComm v2, an implementor should detect if the payload contains DIDComm v1 content or the JWM from DIDComm v2. +These payloads can be distinguished based on the `cty` [property](https://tools.ietf.org/html/rfc7516#section-4.1.12) of the JWE. + +As discussed in [RFC 0044](../0044-didcomm-file-and-mime-types/README.md), the content type for the plaintext DIDComm v1 message is `application/json;flavor=didcomm-msg`. +When the `cty` property contains `application/json;flavor=didcomm-msg`, the payload is treated as DIDComm v1. +[DIDComm Messaging](https://identity.foundation/didcomm-messaging/spec) will specify appropriate media types for DIDComm v2. +To advertise the combination of Envelope v2 with a DIDComm v1 message, the media type is `application/didcomm-encrypted+json;cty=application/json`. + +## Additional AIP impacts + +Implementors supporting an AIP sub-target that contains this RFC (e.g., `DIDCOMMV2PREP`) MAY choose to only support Envelope v2 without support for the original envelope declared in [RFC 0019](https://github.com/hyperledger/aries-rfcs/tree/main/features/0019-encryption-envelope). In these cases, the `accept` property will not contain `didcomm/aip2;env=rfc19` media type. + +## Drawbacks + +The DIDComm v2 specification is a draft. However, the aries-framework-go project has already implemented the new envelope format. + +## Rationale and alternatives + +Our approach for Authcrypt compliance is to use the NIST approved `One-Pass Unified Model for ECDH` scheme described in [SP 800-56A Rev. 3](https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final). The JOSE version is defined as `ECDH-1PU` in this [IETF draft](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03). + +Aries agents currently use the envelope described in [RFC0019](/features/0019-encryption-envelope/README.md). This envelope uses libsodium (NaCl) encryption/decryption, which is based on Salsa20Poly1305 algorithm. + +## Prior art + +- The [JWE](https://tools.ietf.org/html/rfc7518) family of encryption methods. +- [Aries RFC 0019-encryption-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0019-encryption-envelope) suggested envelope formats will be superseded by this RFC. +- [Aries RFC 0025-didcomm-transports](https://github.com/hyperledger/aries-rfcs/tree/main/features/0025-didcomm-transports#reference) for the content type used in the proposed envelopes. +- [Aries RFC 0334-jwe-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0334-jwe-envelope). +- [DIDComm Messaging](https://identity.foundation/didcomm-messaging/spec). +- [minimal-cipher](https://github.com/digitalbazaar/minimal-cipher) implementation +- [Public Key Authenticated Encryption for JOSE: ECDH-1PU](https://tools.ietf.org/html/draft-madden-jose-ecdh-1pu-03) +- [NIST SP 800-56A Rev. 3 Recommendation for Pair-Wise Key-Establishment schemes Using Discrete Logarithm Cryptography](https://csrc.nist.gov/publications/detail/sp/800-56a/rev-3/final) + +## Unresolved questions + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | | diff --git a/features/0592-indy-attachments/README.md b/features/0592-indy-attachments/README.md new file mode 100644 index 000000000..c8351c483 --- /dev/null +++ b/features/0592-indy-attachments/README.md @@ -0,0 +1,380 @@ +# Aries RFC 0592: Indy Attachment Formats for Requesting and Presenting Credentials + +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2021-04-15 +- Status Note: Formalizes the Indy AnonCreds attachments for issuing credentials and presenting proofs. A part of the Indy AnonCreds subtarget of [AIP v2.0](../../concepts/0302-aries-interop-profile/README.md). +- Supersedes: less formally documented Indy attachment formats documented in [Aries RFC 0036](../0036-issue-credential/README.md), [Aries RFC 0037](../0037-present-proof/README.md), etc. +- Start Date: 2017-01-01 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [credentials](/tags.md#credentials), [test-anomaly](/tags.md#test-anomaly) + + +## Summary + +This RFC registers attachment formats used with Hyperledger Indy-style ZKP-oriented credentials in [Issue Credential Protocol 2.0](../0453-issue-credential-v2/README.md) and [Present Proof Protocol 2.0](../0454-present-proof-v2/README.md). These formats are generally considered v2 formats, as they align with the "anoncreds2" work in Hyperledger Ursa and are a second generation implementation. They began to be used in production in 2018 and are in active deployment in 2021. + + +## Motivation + +Allows Indy-style credentials to be used with credential-related protocols that take pluggable formats as payloads. + + +## Reference + +### cred filter format + +The potential holder uses this format to propose criteria for a potential credential for the issuer to offer. + +The identifier for this format is `hlindy/cred-filter@v2.0`. It is a base64-encoded version of the data structure specifying zero or more criteria from the following (non-base64-encoded) structure: + +```jsonc +{ + "schema_issuer_did": "", + "schema_name": "", + "schema_version": "", + "schema_id": "", + "issuer_did": "", + "cred_def_id": "" +} +``` + +The potential holder may not know, and need not specify, all of these criteria. For example, the holder might only know the schema name and the (credential) issuer DID. Recall that the potential holder may specify target attribute values and MIME types in the [credential preview](../0453-issue-credential-v2/README.md#preview-credential). + +For example, the JSON (non-base64-encoded) structure might look like this: + +```json +{ + "schema_issuer_did": "did:sov:4RW6QK2HZhHxa2tg7t1jqt", + "schema_name": "bcgov-mines-act-permit.bcgov-mines-permitting", + "issuer_did": "did:sov:4RW6QK2HZhHxa2tg7t1jqt" +} +``` + +A complete [`propose-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#propose-credential) embeds this format at `/filters~attach/data/base64`: + +```json +{ + "@id": "", + "@type": "https://didcomm.org/issue-credential/%VER/propose-credential", + "comment": "", + "formats" : [{ + "attach_id": "", + "format": "hlindy/cred-filter@v2.0" + }], + "filters~attach": [{ + "@id": "", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgInNjaGVtYV9pc3N1ZXJfZGlkIjogImRpZDpzb3Y... (clipped)... LMkhaaEh4YTJ0Zzd0MWpxdCIKfQ==" + } + }] +} +``` + +### cred abstract format + +This format is used to clarify the structure and semantics (but not the concrete data values) of a potential credential, in offers sent from issuer to potential holder. + +The identifier for this format is `hlindy/cred-abstract@v2.0`. It is a base64-encoded version of the data returned from [`indy_issuer_create_credential_offer()`](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L280). + +The JSON (non-base64-encoded) structure might look like this: + +```json +{ + "schema_id": "4RW6QK2HZhHxa2tg7t1jqt:2:bcgov-mines-act-permit.bcgov-mines-permitting:0.2.0", + "cred_def_id": "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58160:default", + "nonce": "57a62300-fbe2-4f08-ace0-6c329c5210e1", + "key_correctness_proof" : +} +``` + +A complete [`offer-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#offer-credential) embeds this format at `/offers~attach/data/base64`: + +```json +{ + "@type": "https://didcomm.org/issue-credential/%VER/offer-credential", + "@id": "", + "replacement_id": "", + "comment": "", + "credential_preview": , + "formats" : [ + { + "attach_id" : "", + "format": "hlindy/cred-abstract@v2.0" + } + ], + "offers~attach": [ + { + "@id": "", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgInNjaGVtYV9pZCI6ICI0Ulc2UUsySFpoS... (clipped)... jb3JyZWN0bmVzc19wcm9vZj4KfQ==" + } + } + ] +} +``` + +The same structure can be embedded at `/offers~attach/data/base64` in an [`offer-credential` message](../0453-issue-credential-v2/README.md#offer-credential). + +### cred request format + +This format is used to formally request a credential. It differs from the credential abstract above in that it contains a cryptographic commitment to a link secret; an issuer can therefore use it to bind a concrete instance of an issued credential to the appropriate holder. (In contrast, the credential abstract describes the schema and cred def, but not enough information to actually issue to a specific holder.) + +The identifier for this format is `hlindy/cred-req@v2.0`. It is a base64-encoded version of the data returned from [indy_prover_create_credential_req()](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L658). + +The JSON (non-base64-encoded) structure might look like this: + +```jsonc +{ + "prover_did" : "did:sov:abcxyz123", + "cred_def_id" : "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58160:default", + // Fields below can depend on Cred Def type + "blinded_ms" : , + "blinded_ms_correctness_proof" : , + "nonce": "fbe22300-57a6-4f08-ace0-9c5210e16c32" +} +``` + +A complete [`request-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#request-credential) embeds this format at `/requests~attach/data/base64`: + +```json +{ + "@id": "cf3a9301-6d4a-430f-ae02-b4a79ddc9706", + "@type": "https://didcomm.org/issue-credential/%VER/request-credential", + "comment": "", + "formats": [{ + "attach_id": "7cd11894-838a-45c0-a9ec-13e2d9d125a1", + "format": "hlindy/cred-req@v2.0" + }], + "requests~attach": [{ + "@id": "7cd11894-838a-45c0-a9ec-13e2d9d125a1", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgInByb3Zlcl9kaWQiIDogImRpZDpzb3Y6YWJjeHl.. (clipped)... DAtNTdhNi00ZjA4LWFjZTAtOWM1MjEwZTE2YzMyIgp9" + } + }] +} +``` + +### credential format + +A concrete, issued Indy credential may be transmitted over many protocols, but is specifically expected as the final message in [Issuance Protocol 2.0](../0453-issue-credential-v2/README.md). The identifier for its format is `hlindy/cred@v2.0`. + +This is a credential that's designed to be _held_ but not _shared directly_. It is stored in the holder's wallet and used to [derive a novel ZKP](https://youtu.be/bnbNtjsKb4k?t=1280) or [W3C-compatible verifiable presentation](https://docs.google.com/document/d/1ntLZGMah8iJ_TWQdbrNNW9OVwPbIWkkCMiid7Be1PrA/edit#heading=h.vw0mboesl528) just in time for each sharing of credential material. + +The encoded values of the credential MUST follow the encoding algorithm as described in [Encoding Claims](#encoding-claims). + +This is the format emitted by libindy's [indy_issuer_create_credential()](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L383) function. It is JSON-based and might look like this: + +```jsonc +{ + "schema_id": "4RW6QK2HZhHxa2tg7t1jqt:2:bcgov-mines-act-permit.bcgov-mines-permitting:0.2.0", + "cred_def_id": "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58160:default", + "rev_reg_id", "EyN78DDGHyok8qw6W96UBY:4:EyN78DDGHyok8qw6W96UBY:3:CL:56389:CardossierOrgPerson:CL_ACCUM:1-1000", + "values": { + "attr1" : {"raw": "value1", "encoded": "value1_as_int" }, + "attr2" : {"raw": "value2", "encoded": "value2_as_int" } + }, + // Fields below can depend on Cred Def type + "signature": , + "signature_correctness_proof": + "rev_reg": + "witness": +} +``` + +An exhaustive description of the format is out of scope here; it is more completely documented in white papers, source code, and other Indy materials. + +### proof request format + +This format is used to formally request a verifiable presenation (proof) derived from an Indy-style ZKP-oriented credential. It can also be used by a holder to _propose_ a presentation. + +The identifier for this format is `hlindy/proof-req@v2.0`. It is a base64-encoded version of the data returned from [indy_prover_search_credentials_for_proof_req()](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1214). + +Here is a sample proof request that embodies the following: "Using a government-issued ID, disclose the credential holder’s name and height, hide the credential holder’s sex, get them to self-attest their phone number, and prove that their age is at least 18": + +```jsonc +{ + "nonce": “2934823091873049823740198370q23984710239847”, + "name":"proof_req_1", + "version":"0.1", + "requested_attributes":{ + "attr1_referent": {"name":"sex"}, + "attr2_referent": {"name":"phone"}, + "attr3_referent": {"names": ["name", "height"], "restrictions": } + }, + "requested_predicates":{ + "predicate1_referent":{"name":"age","p_type":">=","p_value":18} + } +} +``` + +### proof format + +This is the format of an Indy-style ZKP. It plays the same role as a W3C-style verifiable presentation (VP) and can be [mapped to one](https://docs.google.com/document/d/1ntLZGMah8iJ_TWQdbrNNW9OVwPbIWkkCMiid7Be1PrA/edit#heading=h.vw0mboesl528). + +The raw values encoded in the presentation SHOULD be verified against the encoded values using the encoding algorithm as described below in [Encoding Claims](#encoding-claims). + +The identifier for this format is `hlindy/proof@v2.0`. It is a version of the (JSON-based) data emitted by libindy's [indy_prover_create_proof()](https://github.com/hyperledger/indy-sdk/blob/57dcdae74164d1c7aa06f2cccecaae121cefac25/libindy/src/api/anoncreds.rs#L1404)) function. A proof that responds to the [previous proof request sample](#proof-request-format) looks like this: + +```jsonc +{ + "proof":{ + "proofs":[ + { + "primary_proof":{ + "eq_proof":{ + "revealed_attrs":{ + "height":"175", + "name":"1139481716457488690172217916278103335" + }, + "a_prime":"5817705...096889", + "e":"1270938...756380", + "v":"1138...39984052", + "m":{ + "master_secret":"375275...0939395", + "sex":"3511483...897083518", + "age":"13430...63372249" + }, + "m2":"1444497...2278453" + }, + "ge_proofs":[ + { + "u":{ + "1":"152500...3999140", + "2":"147748...2005753", + "0":"8806...77968", + "3":"10403...8538260" + }, + "r":{ + "2":"15706...781609", + "3":"343...4378642", + "0":"59003...702140", + "DELTA":"9607...28201020", + "1":"180097...96766" + }, + "mj":"134300...249", + "alpha":"827896...52261", + "t":{ + "2":"7132...47794", + "3":"38051...27372", + "DELTA":"68025...508719", + "1":"32924...41082", + "0":"74906...07857" + }, + "predicate":{ + "attr_name":"age", + "p_type":"GE", + "value":18 + } + } + ] + }, + "non_revoc_proof":null + } + ], + "aggregated_proof":{ + "c_hash":"108743...92564", + "c_list":[ 6 arrays of 257 numbers between 0 and 255] + } + }, + "requested_proof":{ + "revealed_attrs":{ + "attr1_referent":{ + "sub_proof_index":0, + "raw":"Alex", + "encoded":"1139481716457488690172217916278103335" + } + }, + "revealed_attr_groups":{ + "attr4_referent":{ + "sub_proof_index":0, + "values":{ + "name":{ + "raw":"Alex", + "encoded":"1139481716457488690172217916278103335" + }, + "height":{ + "raw":"175", + "encoded":"175" + } + } + } + }, + "self_attested_attrs":{ + "attr3_referent":"8-800-300" + }, + "unrevealed_attrs":{ + "attr2_referent":{ + "sub_proof_index":0 + } + }, + "predicates":{ + "predicate1_referent":{ + "sub_proof_index":0 + } + } + }, + "identifiers":[ + { + "schema_id":"NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0", + "cred_def_id":"NcYxi...cYDi1e:2:gvt:1.0:TAG_1", + "rev_reg_id":null, + "timestamp":null + } + ] +} +``` + +### Unrevealed Attributes + +AnonCreds supports a holder responding to a proof request with some of the +requested claims included in an `unrevealed_attrs` array, as seen in the example +above, with `attr2_referent`. Assuming the rest of the proof is valid, AnonCreds +will indicate that a proof with unrevealed attributes has been successfully +verified. It is the responsibility of the verifier to determine if the purpose +of the verification has been met if some of the attributes are not revealed. + +There are at least a few valid use cases for this approach: + +- A verifier may ask for, but not require, that a prover provide all of the + requested attributes. +- A verifier may ask for claims from several credentials, expecting holders to + only have some of the credentials. The holders respond with claims from the + credentials they have, and leave the other attributes unrevealed. + - For example, a verifier may ask for a national identity card and an resident + card, knowing that most holders will have one or the other. + +### Encoding Claims + +Claims in AnonCreds-based verifiable credentials are put into the credential in two forms, `raw` and `encoded`. `raw` is the actual data value, and `encoded` is the (possibly derived) integer value that is used in presentations. At this time, AnonCreds does not take an opinion on the method used for encoding the raw value. + +AnonCreds issuers and verifiers must agree on the encoding method so that the verifier can check that the `raw` value returned in a presentation corresponds to the proven `encoded` value. The following is the encoding algorithm that MUST be used by Issuers when creating credentials and SHOULD be verified by Verifiers receiving presentations: + +- keep any 32-bit integer as is +- convert any string integer (e.g. `"1234"`) to be a 32-bit integer (e.g. `1234`) +- for data of any other type: + - convert to string (use string "None" for null) + - encode via utf-8 to bytes + - apply SHA-256 to digest the bytes + - convert the resulting digest bytes, big-endian, to integer + - stringify the integer as a decimal. + +An example implementation in Python can be found [here](https://github.com/hyperledger/aries-cloudagent-python/blob/0000f924a50b6ac5e6342bff90e64864672ee935/aries_cloudagent/messaging/util.py#L106). + +A gist of test value pairs can be found [here](https://gist.github.com/swcurran/78e5a9e8d11236f003f6a6263c6619a6). + +#### Notes on Encoding Claims + +- In converting any string integer to an integer, leading 0s in the string are (by definition) not part of the integer. The leading 0's remain in the (untouched) `raw` value. +- The use of AnonCreds predicates, such as proving "older than 21" based on a date of birth claim without sharing the date of birth, is based on an expression involving the `encoded` value. Thus, only `raw` integers or string integers can be used in AnonCreds predicates. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/features/0593-json-ld-cred-attach/README.md b/features/0593-json-ld-cred-attach/README.md new file mode 100644 index 000000000..4f3fda5d1 --- /dev/null +++ b/features/0593-json-ld-cred-attach/README.md @@ -0,0 +1,219 @@ +# Aries RFC 0593: JSON-LD Credential Attachment format for requesting and issuing credentials + +- Authors: Timo Glastra (Animo Solutions), George Aristy (SecureKey Technologies) +- Status: [ADOPTED](/README.md#adopted) +- Since: 2021-04-15 +- Status Note: Included as part of the JSON-LD verifiable credentials subtarget of [AIP v2.0](../../concepts/0302-aries-interop-profile/README.md). +- Supersedes: +- Start Date: 2021-02-17 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [credentials](/tags.md#credentials), [test-anomaly](/tags.md#test-anomaly) + +## Summary + +This RFC registers an attachment format for use in the [issue-credential V2](../0453-issue-credential-v2/README.md) protocol based on JSON-LD credentials with [Linked Data Proofs](https://w3c-ccg.github.io/ld-proofs/) from the [VC Data Model](https://www.w3.org/TR/vc-data-model/#linked-data-proofs). + +It defines a minimal set of parameters needed to create a common understanding of the verifiable credential to issue. It is based on version [1.0 of the Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/) which is a W3C recommendation since 19 November 2019. + +## Motivation + +The Issue Credential protocol needs an attachment format to be able to exchange JSON-LD credentials with Linked Data Proofs. It is desirable to make use of specifications developed in an open standards body, such as the [Credential Manifest](https://identity.foundation/credential-manifest/) for which the attachment format is described in [RFC 0511: Credential-Manifest Attachment format](../0511-dif-cred-manifest-attach/README.md). However, the _Credential Manifest_ is not finished and ready yet, and therefore there is a need to bridge the gap between standards. + +## Tutorial + +Complete examples of messages are provided in the [reference section](#reference). + +## Reference + +### `ld-proof-vc-detail` attachment format + +Format identifier: `aries/ld-proof-vc-detail@v1.0` + +This format is used to formally propose, offer, or request a credential. The `credential` property should contain the credential as it is going to be issued, without the `proof` and `credentialStatus` properties. Options for these properties are specified in the `options` object. + +The JSON structure might look like this: + +```json +{ + "credential": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1" + ], + "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", + "type": ["VerifiableCredential", "UniversityDegreeCredential"], + "issuer": "did:key:z6MkodKV3mnjQQMB9jhMZtKD9Sm75ajiYq51JDLuRSPZTXrr", + "issuanceDate": "2020-01-01T19:23:24Z", + "expirationDate": "2021-01-01T19:23:24Z", + "credentialSubject": { + "id": "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH", + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts" + } + } + }, + "options": { + "proofPurpose": "assertionMethod", + "created": "2020-04-02T18:48:36Z", + "domain": "example.com", + "challenge": "9450a9c1-4db5-4ab9-bc0c-b7a9b2edac38", + "credentialStatus": { + "type": "CredentialStatusList2017" + }, + "proofType": "Ed25519Signature2018" + } +} +``` + +A complete [`request credential` message form the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#request-credential) might look like this: + +```jsonc +{ + "@id": "7293daf0-ed47-4295-8cc4-5beb513e500f", + "@type": "https://didcomm.org/issue-credential/%VER/request-credential", + "comment": "", + "formats": [ + { + "attach_id": "13a3f100-38ce-4e96-96b4-ea8f30250df9", + "format": "aries/ld-proof-vc-detail@v1.0" + } + ], + "requests~attach": [ + { + "@id": "13a3f100-38ce-4e96-96b4-ea8f30250df9", + "mime-type": "application/json", + "data": { + "base64": "ewogICJjcmVkZW50aWFsIjogewogICAgIkBjb250...(clipped)...IkVkMjU1MTlTaWduYXR1cmUyMDE4IgogIH0KfQ==" + } + } + ] +} +``` + +- `credential` - Required. Detail of the JSON-LD Credential that will be issued. Properties MUST align with the [Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model). This also means all properties required by the data model MUST be present. The properties listed below are formally supported, but additional properties MAY be included if it conforms with the data model. + + - `@context` + - `id` + - `type` + - `issuer` + - `issuanceDate` + - `expirationDate` + - `credentialSubject` + +- `options` - Required. Options for specifying how the linked data proof is created. + + - `proofType` - Required string. The proof type used for the proof. Should match suites registered in the [Linked Data Cryptographic Suite Registry](https://w3c-ccg.github.io/ld-cryptosuite-registry/#signature-suites). + - `proofPurpose` - Optional string, default `assertionMethod`. The proof purpose used for the proof. Should match proof purposes registered in the [Linked Data Proofs Specification](https://w3c-ccg.github.io/ld-proofs/#proof-purpose). + - `created` - Optional string, default current system time. The date and time of the proof (with a maximum accuracy in seconds). + - `challenge` - Optional string. A challenge to include in the proof. SHOULD be provided by the requesting party of the credential (=holder). + - `domain` - Optional string. The intended domain of validity for the proof. + - `credentialStatus` - Optional object. The credential status mechanism to use for the credential. Omitting the property indicates the issued credential will not include a credential status. + - `type` - Required string. Credential status method type to use for the credential. Should match status method registered in the [Verifiable Credential Extension Registry](https://w3c-ccg.github.io/vc-extension-registry/#status-methods) + +The format is closely related to the [Verifiable Credentials HTTP API](https://w3c-ccg.github.io/vc-http-api/), but diverts on some places. The main differences are: + +- The types in the VC HTTP API are more restrictive (.e.g. `@context` must be array of strings). This format allows all fields to use the full syntax as described by the verifiable credentials data model. +- Instead of specifying the exact `verificationMethod`, the `proofType` that will be used for the credential can be specified. + +### `ld-proof-vc` attachment format + +Format identifier: `aries/ld-proof-vc@v1.0` + +This format is used to transmit a verifiable credential with linked data proof. The contents of the attachment is a standard JSON-LD Verifiable Credential object with linked data proof as defined by the [Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model) and the [Linked Data Proofs](https://w3c-ccg.github.io/ld-proofs) specification. + +The JSON structure might look like this: + +```json +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1" + ], + "id": "http://example.gov/credentials/3732", + "type": ["VerifiableCredential", "UniversityDegreeCredential"], + "issuer": { + "id": "did:web:vc.transmute.world" + }, + "issuanceDate": "2020-03-10T04:24:12.164Z", + "credentialSubject": { + "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", + "degree": { + "type": "BachelorDegree", + "name": "Bachelor of Science and Arts" + } + }, + "proof": { + "type": "JsonWebSignature2020", + "created": "2020-03-21T17:51:48Z", + "verificationMethod": "did:web:vc.transmute.world#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A", + "proofPurpose": "assertionMethod", + "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..OPxskX37SK0FhmYygDk-S4csY_gNhCUgSOAaXFXDTZx86CmI5nU9xkqtLWg-f4cqkigKDdMVdtIqWAvaYx2JBA" + } +} +``` + +A complete [`issue-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#issue-credential) might look like this: + +```json +{ + "@id": "284d3996-ba85-45d9-964b-9fd5805517b6", + "@type": "https://didcomm.org/issue-credential/%VER/issue-credential", + "comment": "", + "formats": [ + { + "attach_id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8", + "format": "aries/ld-proof-vc@v1.0" + } + ], + "credentials~attach": [ + { + "@id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8", + "mime-type": "application/ld+json", + "data": { + "base64": "ewogICAgICAgICAgIkBjb250ZXogWwogICAgICAg...(clipped)...RNVmR0SXFXZhWXgySkJBIgAgfQogICAgICAgIH0=" + } + } + ] +} +``` + +### Supported Proof Types + +Following are the [Linked Data proof](https://w3c-ccg.github.io/ld-proofs/) types on [Verifiable Credentials](https://www.w3.org/TR/vc-data-model/) +that MUST be supported for compliance with this RFC. All suites listed in the following table MUST be registered in the +[Linked Data Cryptographic Suite Registry](https://w3c-ccg.github.io/ld-cryptosuite-registry/): + +Suite|Spec|Enables Selective disclosure?|Enables Zero-knowledge proofs?|Optional +-----|----|-----------------------------|------------------------------|---------- +Ed25519Signature2018|[Link](https://w3c-ccg.github.io/lds-ed25519-2018/)|No|No|No +BbsBlsSignature2020**|[Link](https://w3c-ccg.github.io/ldp-bbs2020/)|Yes|No|No +JsonWebSignature2020***|[Link](https://w3c-ccg.github.io/lds-jws2020/)|No|No|Yes + +> ** Note: see [RFC0646](../0646-bbs-credentials/README.md) for details on how BBS+ signatures are to be produced and +> consumed by Aries agents. + +> *** Note: P-256 and P-384 curves are supported. + +## Drawbacks + +N/A + +## Rationale and alternatives + +- The `hlindy-zkp-v1.0` format is an alternative restricted to the Hyperledger Indy network. The `dif/credential-manifest@v1.0` allows to issue JSON-LD credentials but is not ready yet for usage. + +## Prior art + +N/A + +## Unresolved questions + +N/A + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0627-static-peer-dids/README.md b/features/0627-static-peer-dids/README.md new file mode 100644 index 000000000..aea840735 --- /dev/null +++ b/features/0627-static-peer-dids/README.md @@ -0,0 +1,52 @@ +# Aries RFC 0627: Static Peer DIDs +- Authors: [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [RETIRED](/README.md#retired) +- Since: 2021-04-07 +- Status Note: formally freezes a set of features that have been relatively stable for about 18 months +- Start Date: 2021-03-24 +- Tags: [feature](/tags.md#feature) + +## Summary + +Formally documents a very crisp profile of peer DID functionality that can be referenced in [Aries Interop Profiles](../../concepts/0302-aries-interop-profile/README.md). + +## Motivation + +The [Peer DID Spec](https://identity.foundation/peer-did-method-spec) includes a number of advanced features that are still evolving. However, a subset of its functionality is easy to implement and would be helpful to freeze for the purpose of Aries interop. + +## Tutorial + +### Spec version + +The Peer DID method spec is still undergoing minor evolution. However, it is relatively stable, particularly in the simpler features. + +This Aries RFC targets the version of the spec that is dated April 2, 2021 in its [rendered form](https://identity.foundation/peer-did-method-spec), or [github commit 202a913](https://github.com/decentralized-identity/peer-did-method-spec/commit/202a91338f18e28612724b60f3843c6f6b123226) in its source form. Note that the rendered form of the spec may update without warning, so the github commit is the better reference. + +### Targeted layers + +Support for peer DIDs is imagined to target configurable "layers" of interoperability: + +![layers](https://identity.foundation/peer-did-method-spec/impl-layers.png) + +For a careful definition of what these layers entail, please see https://identity.foundation/peer-did-method-spec/#layers-of-support. + +This Aries RFC targets Layers 1 and 2. That is, code that complies with this RFC would satisfy the required behaviors for Layer 1 and for Layer 2. Note, however, that Layer 2 is broken into _accepting_ and _giving_ static peer DIDs. An RFC-compliant implementation may choose to implement either side, or both. + +Support for Layer 3 (dynamic peer DIDs that have updatable state and that synchronize that state using [Sync Connection Protocol as documented in Aries RFC 0030](../0030-sync-connection/README.md)) is NOT required by this RFC. However, if there is an intent to support dynamic updates in the future, use of `numalgo` Method 1 is encouraged, as this allows static peer DIDs to acquire new state when dynamic support is added. (See next section.) + +### Targeted Generation Methods (`numalgo`) + +Peer DIDs can use several different algorithms to generate the entropy that constitutes their _numeric basis_. See https://identity.foundation/peer-did-method-spec/#generation-method for details. + +This RFC targets Method 0 (inception key without doc), Method 1 (genesis doc), and Method 2 (multiple inception keys). Code that complies with this RFC, and that intends to accept static DIDs at Layer 2a, MUST accept peer DIDs that use any of these methods. Code that intends to give peer DIDs (Layer 2b) MUST give peer DIDs that use at least one of these three methods. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/features/0641-linking-binary-objects-to-credentials/README.md b/features/0641-linking-binary-objects-to-credentials/README.md new file mode 100644 index 000000000..e1608e507 --- /dev/null +++ b/features/0641-linking-binary-objects-to-credentials/README.md @@ -0,0 +1,217 @@ +# 0641: Linking binary objects to credentials using hash based references + +- Authors: [Berend Sliedrecht](mailto:berend@animo.id) (Animo Solutions) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2021-04-22 +- Status Note: Proposal +- Start Date: 2021-03-17 +- Tags: [feature](/tags.md#feature), [credentials](/tags.md#credentials) + +## Summary + +This RFC provides a solution for issuing and presenting credentials with external binary objects, after referred to as attachments. It is compatible with [0036: Issue Credential Protocol V1](https://github.com/hyperledger/aries-rfcs/tree/main/features/0036-issue-credential), [0453: Issue Credential Protocol V2](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2), [0037: Present Proof V1 protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0037-present-proof) and [0454: Present Proof V2 Protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0454-present-proof-v2). These external attachments could consist of images, PDFs, zip files, movies, etc. Through the use of `DIDComm attachments`, [0017: Attachments](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0017-attachments), the data can be embedded directly into the attachment or externally hosted. In order to maintain integrity over these attachments, hashlinks are used as the checksum. + +## Motivation + +Many use cases, such as a rental agreement or medical data in a verifiable credential, rely on attachments, small or large. At this moment, it is possible to issue credentials with accompanying attachments. When the attachment is rather small, this will work fine. However, larger attachments cause inconsistent timing issues and are resource intensive. + +## Tutorial + +It is already possible to issue and verify base64-encoded attachments in credentials. When a credential is getting larger and larger, it becomes more and more impractical as it has to be signed, which is time consuming and resource intensive. A solution for this is to use the attachments decorator. This decorator creates a way to externalize the attachment from the credential attributes. By allowing this, the signing will be faster and more consistent. However, DIDComm messages SHOULD stay small, like with SMTP or Bluetooth, as specified in [0017: Attachments](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0017-attachments). In the attachments decorator it is also possible to specify a list of URLs where the attachment might be located for download. This list of URLs is accompanied by a `sha256` tag that is a checksum over the file to maintain integrity. This `sha256` tag can only contain a sha256 hash and if another algorithm is preferred then the hashlink MUST be used as the checksum. + +When issuing and verifying a credential, messages have to be sent between the holder, issuer and verifier. In order to circumvent additional complexity, such as looking at previously sent credentials for the attachment, the attachments decorator, when containing an attachment, MUST be sent at all of the following steps: + +**Issue Credential V1 & V2** + +1. Credential Proposal +2. Credential Offer +3. Credential Request +4. Credential + +**Present Proof V1 & V2** + +1. Presentation Proposal +2. Presentation Request +3. Presentation + +### Linking + +When a credential is issued with an attachment in the attachments decorator, be it a base64-encoded file or a hosted file, the link has to be made between the credential and the attachment. The link MUST be made with the `attribute.value` of the credential and the `@id` tag of the attachment in the attachments decorator. + +### Hashlink + +A hashlink, as specified in [IETF: Cryptographic Hyperlinks](https://tools.ietf.org/html/draft-sporny-hashlink-06), is a formatted hash that has a prefix of `hl:` and an optional suffix of metadata. The hash in the hashlink is a [multihash](https://tools.ietf.org/html/draft-multiformats-multihash-02), which means that according to the prefix of the hash it is possible to see which hashing algorithm and encoding algorithm has been chosen. An example of a hashlink would be: + +`hl:zQmcWyBPyedDzHFytTX6CAjjpvqQAyhzURziwiBKDKgqx6R` + +This example shows the prefix of `hl:` indicating that it is a hashlink and the hash after the prefix is a multihash. + +The hashlink also allows for opional metadata, such as; a list of URLs where the attachment is hosted and a MIME-type. These metadata values are encoded in the CBOR data format using the specified algortihm from section 3.1.2 in the [IETF: Cryptographic Hyperlinks](https://tools.ietf.org/html/draft-sporny-hashlink-06). + +When a holder receives a credential with hosted attachments, the holder MAY rehost these attachments. A holder would do this in order to prevent the phone-home problem. If a holder does not care about this issue, this is use case specific, this can be left out but should be considered. + +### Inlined Attachments as a Credential Attribute + +Attachments can be inlined in the credential attribute as a base64-encoded string. With this, there is no need for the attachment decorator. Below is an example of embedding a base64-encoded file as a string in a credential attribute. + +```json +{ + "name": "Picture of a cat", + "mime-type": "image/png", + "value": "VGhpcyBpc ... (many bytes omitted) ... C4gSG93IG5pY2U=" +} +``` + +### Attachments inlined in the Attachment Decorator + +When the attachments decorator is used to issue a credential with a binary object, a link has to be made between the credential value and the corresponding attachment. This link MUST be a hash, specifically a hashlink based on the checksum of the attachment. + +As stated in [0008: message id and threading](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0008-message-id-and-threading/README.md), the `@id` tag of the attachment MUST NOT contain a colon and MUST NOT be longer than 64 characters. because of this, the `@id` can not contain a hashlink and MUST contain the multihash with a maximum length of 64 characters. When a hash is longer than 64 character, use the first 64 characters. + +```json +{ + "@type": "https://didcomm.org/issue-credential/%VER/issue-credential", + "@id": "", + "goal_code": "", + "replacement_id": "", + "comment": "", + "formats": [ + { + "attach_id": "", + "format": "hlindy/cred@v2.0" + } + ], + "credentials~attach": [ + { + "@id": "", + "mime-type": "application/json", + "data": { + "json": { + "schema_id": "4RW6QK2HZhHxa2tg7t1jqt:2:catSchema:0.3.0", + "cred_def_id": "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58161:default", + "values": { + "pictureOfACat": { + "raw": "hl:zQmcWyBPyedDzHFytTX6CAjjpvqQAyhzURziwiBKDKgqx6R", + "encoded": "hl:zQmcWyBPyedDzHFytTX6CAjjpvqQAyhzURziwiBKDKgqx6R" + } + }, + "signature": "", + "signature_correctness_proof": "" + } + } + } + ], + "~attach": [ + { + "@id": "zQmcWyBPyedDzHFytTX6CAjjpvqQAyhzURziwiBKDKgqx6R", + "mime-type": "image/png", + "filename": "cat.png", + "byte_count": 2181, + "lastmod_time": "2021-04-20 19:38:07Z", + "description": "Cute picture of a cat", + "data": { + "base64": "VGhpcyBpcyBhIGNv ... (many bytes omitted) ... R0ZXIgU0hJQkEgSU5VLg==" + } + } + ] +} +``` + +## Hosted attachments + +The last method of adding a binary object in a credential is by using the attachments decorator in combination with external hosting. In the example below the attachment is hosted at two locations. These two URLs MUST point to the same file and match the integrity check with the `sha256` value. It is important to note that when an issuer hosts an attachment, and issues a credential with this attachment, that the holder rehosts this attachment to prevent the phone-home assosiation. + +```json +{ + "@type": "https://didcomm.org/issue-credential/%VER/issue-credential", + "@id": "", + "goal_code": "", + "replacement_id": "", + "comment": "", + "formats": [ + { + "attach_id": "", + "format": "hlindy/cred@v2.0" + } + ], + "credentials~attach": [ + { + "@id": "", + "mime-type": "application/json", + "data": { + "json": { + "schema_id": "4RW6QK2HZhHxa2tg7t1jqt:2:catSchema:0.3.0", + "cred_def_id": "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58161:default", + "values": { + "pictureOfACat": { + "raw": "hl:zQmcWyBPyedDzHFytTX6CAjjpvqQAyhzURziwiBKDKgqx6R", + "encoded": "hl:zQmcWyBPyedDzHFytTX6CAjjpvqQAyhzURziwiBKDKgqx6R" + } + }, + "signature": "", + "signature_correctness_proof": "" + } + } + } + ], + "~attach": [ + { + "@id": "zQmcWyBPyedDzHFytTX6CAjjpvqQAyhzURziwiBKDKgqx6R", + "mime-type": "application/zip", + "filename": "cat.zip", + "byte_count": 218187322, + "lastmod_time": "2021-04-20 19:38:07Z", + "description": "Cute pictures of multiple cats", + "data": { + "links": [ + "https://drive.google.com/kitty/cats.zip", + "s3://bucket/cats.zip" + ] + } + } + ] +} +``` + +### Matching + +Now that a link has been made between the attachment in the attachments decorator, it is possible to match the two together. When a credential is received and a value of an attribute starts with `hl:` it means that there is a linked attachment. To find the linked attachment to the credential attribute to following steps SHOULD be done: + +1. Extract the multihash from the credential attribute value +2. Extract the first 64 characters of this multihash +3. Loop over the `@id` tag of all the attachments in the attachment decorator +4. Compare the value of the `@id` tag with the multihash +5. If the `@id` tag matches with the multihash, then there is a link +6. An integrity check can be done with the original, complete hashlink + +## Reference + +When an issuer creates a value in a credential attribute with a prefix of `hl:`, but there is no attachment, a warning SHOULD be thrown. + +When DIDcomm V2 is implemented the attachment decorator will not contain the `sha256` tag anymore and it will be replaced by `hash` to allow for any algorithm. [DIDcomm messaging Attachments](https://identity.foundation/didcomm-messaging/spec/#reference-2) + +## Drawbacks + +- Hashlinks, multibase and multihash are not confirmed IETF RFCs yet +- Hosting some files at third party locations is not preferred + +## Rationale and alternatives + +The findings that large credentials are inconsistent and resource intensive are derived from issuing and verifying credentials of 100 kilobytes to 50 megabytes in Aries Framework JavaScript and Aries Cloudagent Python. + +The Identity Foundation is currently working on confidential storage, a way to allow access to your files based on DIDs. This storage would be a sleek fix for the last drawback. + +## Prior art + +- [0017: Attachments](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0017-attachments) discusses the attachments in DIDcomm messaging and formulates the attachment decorator. +- [HIPE-0139: Image As Attribute Via Aries-0036 Issue-Credential Protocol](https://github.com/hyperledger/indy-hipe/blob/main/text/0139-image-as-cred-attr/README.md) has been written for the support of images in credentials. It points out that the attachment RFC and the issue credential RFC are separate and could drift apart. +- [Linking and Exchanging Attachments with Verifiable Credentials](https://sovrin.org/interoperability-series-linking-and-exchanging-attachments-with-verifiable-credentials/) describes the linking between the attachment the credential based on the `@id` tag. + +## Unresolved questions + +- N/A + +## Implementations + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | diff --git a/features/0646-bbs-credentials/README.md b/features/0646-bbs-credentials/README.md new file mode 100644 index 000000000..a70089a23 --- /dev/null +++ b/features/0646-bbs-credentials/README.md @@ -0,0 +1,281 @@ +# 0646: W3C Credential Exchange using BBS+ Signatures + +- Authors: [Timo Glastra](mailto:timo@animo.id) (Animo Solutions), [Brent Zundel](mailto:brent.zundel@evernym.com) (Evernym) +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2021-04-28 +- Status Note: +- Supersedes: +- Start Date: 2021-04-15 +- Tags: [feature](/tags.md#feature) + +## Summary + +This RFC describes how the Hyperledger Aries community should use [BBS+ Signatures](https://w3c-ccg.github.io/ldp-bbs2020/) that conform with the [Linked-Data Proofs Specification](https://w3c-ccg.github.io/ld-proofs/) to perform exchange of credentials that comply with the [W3C Verifiable Credential specification](https://www.w3.org/TR/vc-data-model/). + +Key features include: + +- zero-knowledge proofs (ZKPs), +- selective disclosure, +- private holder binding, +- signature blinding, +- compatibility with privacy preserving revocation. + +This RFC sets guidelines for their safe usage and describes privacy-enabling features that should be incorporated. + +The usage of zero-knowledge proofs, selective disclosure and signature blinding are already supported using the specifications as described in this document. Support for private holder binding and privacy preserving revocation will be added in the future. + +## Motivation + +Aries currently supports credential formats used by Indy (Anoncreds based on JSON) and Aries-Framework-Go. BBS+ signatures with JSON-LD Proofs provide a unified credential format that includes strong privacy protecting anti-correlation features and wide interoperability with verifiable credentials outside the Aries ecosystem. + +## Tutorial + +### Issuing Credentials + +This section highlights the process of issuing credentials with BBS+ signatures. The first section ([Creating BBS+ Credentials](#creating-bbs-credentials)) highlights the process of **creating** credentials with BBS+ signatures, while the next section focusses on the the process of **exchanging** credentials with BBS+ signatures ([Exchanging BBS+ Credentials](#exchanging-bbs-credentials)). + +#### Creating BBS+ Credentials + +The process to create verifiable credentials with BBS+ signatures is mostly covered by the [VC Data Model](https://www.w3.org/TR/vc-data-model) and [BBS+ LD-Proofs](https://w3c-ccg.github.io/ldp-bbs2020) specifications. At the date of writing this RFC, the BBS+ LD-Proofs specification still has some unresolved issues. The issues are documented in the [Issues with the BBS+ LD-Proofs specification](#issues-with-the-bbs-ld-proofs-specification) section below. + +Aries implementations MUST use the [BBS+ Signature Suite 2020](https://w3c-ccg.github.io/ldp-bbs2020/#the-bbs-signature-suite-2020) to create verifiable credentials with BBS+ signatures, identified by the `BbsBlsSignature2020` proof type. + +> NOTE: Once the signature suites for bound signatures (private holder binding) are defined in the [BBS+ LD-Proofs](https://w3c-ccg.github.io/ldp-bbs2020) spec, the use of the `BbsBlsSignature2020` suite will be deprecated and superseded by the `BbsBlsBoundSignature2020` signature suite. See [Private Holder Binding](#private-holder-binding) below for more information. + +##### Identifiers in Issued Credentials + +It is important to note that due to limitations of the underlying RDF canonicalization scheme, which is used by [BBS+ LD-Proofs](https://w3c-ccg.github.io/ldp-bbs2020/), issued credentials SHOULD NOT have any `id` properties, as the value of these properties will be revealed during the RDF canonicalization process, regardless of whether or not the holder chooses to disclose them. + +Credentials can make use of other identifier properties to create selectively disclosable identifiers. An example of this is the `identifier` property from the [Citizenship Vocabulary](https://w3c-ccg.github.io/citizenship-vocab/#identifier) + +##### Private Holder Binding + +A private holder binding allows the holder of a credential to authenticate itself without disclosing a correlating identifier (such as a DID) to the verifier. The current [BBS+ LD-Proofs](https://w3c-ccg.github.io/ldp-bbs2020/) specification does not describe a mechanism yet to do private holder binding, but it is expected this will be done using two new signature suites: `BbsBlsBoundSignature2020` and `BbsBlsBoundSignatureProof2020`. Both suites feature a commitment to a private key held by the credential holder, for which they prove knowledge of when deriving proofs without ever directly revealing the private key, nor a unique identifier linked to the private key (e.g its complementary public pair). + +##### Usage of Credential Schema + +The [zero-knowledge proof section](https://www.w3.org/TR/vc-data-model/#zero-knowledge-proofs) of the VC Data Model requires verifiable credentials used in zero-knowledge proof systems to include a credential definition using the `credentialSchema` property. Due to the nature of how BBS+ LD proofs work, it is NOT required to include the `credentialSchema` property. See [Issue 726](https://github.com/w3c/vc-data-model/issues/726) in the VC Data Model. + +##### Example BBS+ Credential + +Below is a complete example of a Verifiable Credential with BBS+ linked data proof. + +```jsonc +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/citizenship/v1", + "https://w3id.org/security/bbs/v1" // <-- BBS+ context + ], + "id": "https://issuer.oidp.uscis.gov/credentials/83627465", + "type": ["VerifiableCredential", "PermanentResidentCard"], + "issuer": "did:example:489398593", + "identifier": "83627465", // <-- `identifier` property allows for seletively disclosable id property + "name": "Permanent Resident Card", + "description": "Government of Example Permanent Resident Card.", + "issuanceDate": "2019-12-03T12:19:52Z", + "expirationDate": "2029-12-03T12:19:52Z", + "credentialSubject": { + "id": "did:example:b34ca6cd37bbf23", + "type": ["PermanentResident", "Person"], + "givenName": "JOHN", + "familyName": "SMITH", + "gender": "Male", + "image": "data:image/png;base64,iVBORw0KGgokJggg==", + "residentSince": "2015-01-01", + "lprCategory": "C09", + "lprNumber": "999-999-999", + "commuterClassification": "C1", + "birthCountry": "Bahamas", + "birthDate": "1958-07-17" + }, + "proof": { + "type": "BbsBlsSignature2020", // <-- type must be `BbsBlsSignature2020` + "created": "2020-10-16T23:59:31Z", + "proofPurpose": "assertionMethod", + "proofValue": "kAkloZSlK79ARnlx54tPqmQyy6G7/36xU/LZgrdVmCqqI9M0muKLxkaHNsgVDBBvYp85VT3uouLFSXPMr7Stjgq62+OCunba7bNdGfhM/FUsx9zpfRtw7jeE182CN1cZakOoSVsQz61c16zQikXM3w==", + "verificationMethod": "did:example:489398593#test" + } +} +``` + +#### Exchanging BBS+ Credentials + +While the process of creating credentials with BBS+ signatures is defined in specifications outside of Aries, the process of exchanging credentials with BBS+ signatures is defined within Aries. + +Credentials with BBS+ signatures can be exchanged by following [RFC 0453: Issue Credential Protocol 2.0](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2). The Issue Credential 2.0 provides a registry of attachment formats that can be used for credential exchange. Currently, agents are expected to use the format as described in RFC 0593 (see below). + +> NOTE: Once [Credential Manifest](https://identity.foundation/credential-manifest/) v1.0 is released, RFC 0593 is expected to be deprecated and replaced by an updated version of [RFC 0511: Credential-Manifest Attachment format](https://github.com/hyperledger/aries-rfcs/blob/main/features/0511-dif-cred-manifest-attach/README.md) + +##### 0593: JSON-LD Credential Attachment format + +[RFC 0593: JSON-LD Credential Attachment format for requesting and issuing credentials](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md) defines a very simple, feature-poor attachment format for issuing JSON-LD credentials. + +The only requirement for exchanging BBS+ credentials, in addition to the requirements as specified in [Creating BBS+ Credentials](#creating-bbs-credentials) and [RFC 0593](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md), is the `options.proofType` in the [`ld-proof-vc-detail`](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md#ld-proof-vc-detail-attachment-format) MUST be `BbsBlsSignature2020`. + +### Presenting Derived Credentials + +This section highlights the process of creating and presenting derived BBS+ credentials containing a BBS+ proof of knowledge. + +#### Deriving Credentials + +Deriving credentials should be done according to the [BBS+ Signature Proof Suite 2020](https://w3c-ccg.github.io/ldp-bbs2020/#the-bbs-signature-proof-suite-2020) + +##### Disclosing Required Properties + +> A verifiable presentation MUST NOT leak information that would enable the verifier to correlate the holder across multiple verifiable presentations. + +The above section from the VC Data Model may give the impression that it is allowed to omit required properties from a derived credential if this prevents correlation. However things the holder chooses to reveal are in a different category than things the holder MUST reveal. Derived credentials MUST disclose required properties, even if it can correlate them. + +E.g. a credential with `issuanceDate` of `2017-12-05T14:27:42Z` could create a correlating factor. However it is against the VC Data Model to not include the property. Take this into account when issuing credentials. + +##### Transforming Blank Node Identifiers + +> This section will be removed once [Issue 10](https://github.com/w3c-ccg/ldp-bbs2020/issues/10) in the LD Proof BBS+ spec is resolved. + +For the verifier to be able to verify the signature of a derived credential it should be able to deterministically normalize the credentials statements for verification. RDF Dataset Canonicalization defines a way in which to allocate identifiers for blank nodes deterministically for normalization. However, the algorithm does not guarantee that the same blank node identifiers will be allocated in the event of modifications to the graph. Because selective disclosure of signed statements modifies the graph as presented to the verifier, the blank node identifiers must be transformed into actual node identifiers when presented to the verifier. + +The [BBS+ LD-Proofs](https://w3c-ccg.github.io/ldp-bbs2020) specification does not define a mechanism to transform blank node identifiers into actual identifiers. Current implementations use the mechanism as described in this [Issue Comment](https://github.com/w3c-ccg/ldp-bbs2020/issues/10#issuecomment-616216278). Some reference implementations: + +- [Aries Framework Go](https://github.com/hyperledger/aries-framework-go/blob/d83e137/pkg/doc/signature/jsonld/processor.go#L451-L452) +- [JSON-LD Signatures BBS](https://github.com/mattrglobal/jsonld-signatures-bbs/blob/01000b4bf48932a47d7c8c889d2201f8e8085d46/src/BbsBlsSignatureProof2020.ts#L116-L132) +- [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python/blob/eb3fd94ffaf623e4207ec1c8cb140345a489599d/aries_cloudagent/vc/ld_proofs/suites/BbsBlsSignatureProof2020.py#L314-L345) + +#### Verifying Presented Derived Credentials + +##### Transforming Back into Blank Node Identifiers + +> This section will be removed once [Issue 10](https://github.com/w3c-ccg/ldp-bbs2020/issues/10) in the LD Proof BBS+ spec is resolved. + +Transforming the blank node identifiers into actual node identifiers in the derived credential means the verification data will be different from the verification data at issuance, invalidating the signature. Therefore the blank node identifier placeholders should be transformed back into blank node identifiers before verification. + +Same as with [Transforming Blank Node Identifiers](#transforming-blank-node-identifiers), current implementations use the mechanism as described in this [Issue Comment](https://github.com/w3c-ccg/ldp-bbs2020/issues/10#issuecomment-616216278). Some reference implementations: + +- [Aries Framework Go](https://github.com/hyperledger/aries-framework-go/blob/b1b076db898fe8c922c6dc093d3fa52d448f0c30/pkg/doc/signature/verifier/public_key_verifier.go#L434) +- [JSON-LD Signatures BBS](https://github.com/mattrglobal/jsonld-signatures-bbs/blob/01000b4bf48932a47d7c8c889d2201f8e8085d46/src/BbsBlsSignatureProof2020.ts#L254-L267) +- [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python/blob/main/aries_cloudagent/vc/ld_proofs/suites/BbsBlsSignatureProof2020.py#L347-L381) + +#### Exchanging Derived Credentials + +The presentation of credentials with BBS+ signatures can be exchanged by following [RFC 0454: Present Proof Protocol 2.0](https://github.com/hyperledger/aries-rfcs/blob/main/features/0454-present-proof-v2). The Present Proof Protocol 2.0 provides a registry of attachment formats that can be used for presentation exchange. Although agents can use any attachment format they want, agents are expected to use the format as described in RFC 0510 (see below). + +##### 0510: Presentation-Exchange Attachment format + +[RFC 0510: Presentation-Exchange Attachment format for requesting and presenting proofs](https://github.com/hyperledger/aries-rfcs/blob/main/features/0510-dif-pres-exch-attach/README.md) defines an attachment format based on the [DIF Presentation Exchange](https://identity.foundation/presentation-exchange/) specification. + +The following part of this section describes the requirements of exchanging derived credentials using the Presentation Exchange Attachment format, in addition to the requirements as specified above and in [RFC 0510](https://github.com/hyperledger/aries-rfcs/blob/main/features/0510-dif-pres-exch-attach/README.md). + +The Presentation Exchange MUST include the `ldp_vp` [Claim Format Designation](https://identity.foundation/presentation-exchange/#claim-format-designations). In turn the `proof_type` property of the `ldp_vp` claim format designation MUST include the `BbsBlsSignatureProof2020` proof type. + +#### Example BBS+ Derived Credential + +```jsonc +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/citizenship/v1", + "https://w3id.org/security/bbs/v1" // BBS + Context + ], + "id": "https://issuer.oidp.uscis.gov/credentials/83627465", + "type": ["PermanentResidentCard", "VerifiableCredential"], + "description": "Government of Example Permanent Resident Card.", + "identifier": "83627465", + "name": "Permanent Resident Card", + "credentialSubject": { + "id": "did:example:b34ca6cd37bbf23", + "type": ["Person", "PermanentResident"], + "familyName": "SMITH", + "gender": "Male", + "givenName": "JOHN" + }, + "expirationDate": "2029-12-03T12:19:52Z", + "issuanceDate": "2019-12-03T12:19:52Z", + "issuer": "did:example:489398593", + "proof": { + "type": "BbsBlsSignatureProof2020", // <-- type must be `BbsBlsSignatureProof2020` + "nonce": "wrmPiSRm+iBqnGBXz+/37LLYRZWirGgIORKHIkrgWVnHtb4fDe/4ZPZaZ+/RwGVJYYY=", + "proofValue": "ABkB/wbvt6213E9eJ+aRGbdG1IIQtx+IdAXALLNg2a5ENSGOIBxRGSoArKXwD/diieDWG6+0q8CWh7CViUqOOdEhYp/DonzmjoWbWECalE6x/qtyBeE7W9TJTXyK/yW6JKSKPz2ht4J0XLV84DZrxMF4HMrY7rFHvdE4xV7ULeC9vNmAmwYAqJfNwY94FG2erg2K2cg0AAAAdLfutjMuBO0JnrlRW6O6TheATv0xZZHP9kf1AYqPaxsYg0bq2XYzkp+tzMBq1rH3tgAAAAIDTzuPazvFHijdzuAgYg+Sg0ziF+Gw5Bz8r2cuvuSg1yKWqW1dM5GhGn6SZUpczTXuZuKGlo4cZrwbIg9wf4lBs3kQwWULRtQUXki9izmznt4Go98X/ElOguLLum4S78Gehe1ql6CXD1zS5PiDXjDzAAAACWz/sbigWpPmUqNA8YUczOuzBUvzmkpjVyL9aqf1e7rSZmN8CNa6dTGOzgKYgDGoIbSQR8EN8Ld7kpTIAdi4YvNZwEYlda/BR6oSrFCquafz7s/jeXyOYMsiVC53Zls9KEg64tG7n90XuZOyMk9RAdcxYRGligbFuG2Ap+rQ+rrELJaW7DWwFEI6cRnitZo6aS0hHmiOKKtJyA7KFbx27nBGd2y3JCvgYO6VUROQ//t3F4aRVI1U53e5N3MU+lt9GmFeL+Kv+2zV1WssScO0ZImDGDOvjDs1shnNSjIJ0RBNAo2YzhFKh3ExWd9WbiZ2/USSyomaSK4EzdTDqi2JCGdqS7IpooKSX/1Dp4K+d8HhPLGNLX4yfMoG9SnRfRQZZQ==", + "verificationMethod": "did:example:489398593#test", + "proofPurpose": "assertionMethod", + "created": "2020-10-16T23:59:31Z" + } +} +``` + +### Privacy Considerations + +Private Holder Binding is an evolution of CL Signatures Linked Secrets. + +- `id` properties are always disclosed in derived credentials due to how JSON-LD works. +- Required properties from the VC Data Model MUST be disclosed in derived credentials. +- BBS+ credentials SHOULD not be used in conjunction with non-ZKP signature as this removes the privacy features of BBS. + +## Reference + +### Interoperability with Existing Credential Formats + +We expect that many issuers will choose to shift exclusively to BBS+ +credentials for the benefits described here. Accessing these benefits will +require reissuing credentials that were previously in a different format. + +An issuer can issue duplicate credentials with both signature formats. + +A holder can hold both types of credentials. The holder wallet could display the two credentials as a single entry in their credential list if the data is the same (it’s “enhanced” with both credential formats). + +A verifier can send a proof request for the formats that they choose to support. + +- The holder wallet can provide the credential that fulfills that proof restriction. This allows old credentials to continue being used without being reissued. +- The verifier may accept credentials of multiple formats. + +### Issues with the BBS+ LD-Proofs specification + +- `requiredRevealStatements` will be removed ([Issue 50](https://github.com/w3c-ccg/ldp-bbs2020/issues/50)) +- `proofValue` and `nonce` must be base64 encoded ([Issue 51](https://github.com/w3c-ccg/ldp-bbs2020/issues/51)) +- `signature` must be updated to `proofValue` for the `BbsBlsSignature2020` suite ([Issue 52](https://github.com/w3c-ccg/ldp-bbs2020/issues/52)) +- The application of blank node identifiers ([Issue 10](https://github.com/w3c-ccg/ldp-bbs2020/issues/10)) +- Private holder binding ([Issue 37](https://github.com/w3c-ccg/ldp-bbs2020/issues/37)) + +## Drawbacks + +Existing implementations of BBS+ Signatures do not support ZKP proof predicates, but it is theoretically possible to support numeric date predicates. ZKP proof predicates are considered a key feature of CL signatures, and a migration to BBS+ LD-Proofs will lose this capability. The Indy maintainers consider this a reasonable trade-off to get the other benefits of BBS+ LD-Proofs. A mechanism to support predicates can hopefully be added in future work. + +As mentioned in the [Private Holder Binding](#private-holder-binding) section, the [BBS+ LD-Proofs](https://w3c-ccg.github.io/ldp-bbs2020/) specification does not define a mechanism for private holder binding yet. This means implementing this RFC does not provide all privacy-enabling features that should be incorporated until the `BbsBlsBoundSignature2020` and `BbsBlsBoundSignatureProof2020` signature suites are formally defined. + +## Rationale and alternatives + +BBS+ LD-Proofs is a reasonable evolution of CL Signatures, as it supports most of the same features (with the exception of ZKP Proof Predicates), while producing smaller credentials that require less computation resources to validate (a key requirement for mobile use cases). + +BBS+ LD-Proofs are receiving broad support across the verifiable credentials implementation community, so supporting this signature format will be strategic for interoperability and allow Aries to promote the privacy preserving capabilities such as zero knowledge proofs and private holder binding. + +## Prior art + +Indy Anoncreds used CL Signatures to meet many of the use cases currently envisioned for BBS+ LD-Proofs. + +BBS+ Signatures were [originally proposed by Boneh, Boyen, and Shacham in 2004](https://crypto.stanford.edu/~xb/crypto04a/groupsigs.pdf). + +The approach was [improved by Au, Susilo, and Mu in 2006](http://web.cs.iastate.edu/~wzhang/teach-552/ReadingList/552-14.pdf). + +It was then further refined by +[Camenisch, Drijvers, and Lehmann in section 4.3 of this paper from 2016](https://eprint.iacr.org/2016/663.pdf). + +In 2019, Evernym and Sovrin proposed [BBS+ Signatures as the foundation for Indy Anoncreds 2.0](https://github.com/hyperledger/ursa-docs/tree/main/specs/anoncreds2), +which in conjunction with [Rich Schemas](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0250-rich-schemas) +addressed a similar set of goals and capabilities as those addressed here, but were ultimately too heavy a solution. + +In 2020, Mattr provided [a draft specification for BBS+ LD-Proofs](https://w3c-ccg.github.io/ldp-bbs2020/) that comply with [the Linked Data proof specification](https://w3c-ccg.github.io/ld-proofs/) in the W3C Credentials Community Group. The authors acknowledged that their approach did not support two key Anoncreds features: proof predicates and link secrets. + +[Aries RFC 593](https://github.com/hyperledger/aries-rfcs/tree/main/features/0593-json-ld-cred-attach) describes the JSON-LD credential format. + +## Unresolved questions + +See the above note in [the Drawbacks Section](#drawbacks) about ZKP predicates. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +_Implementation Notes_ [may need to include a link to test results](/README.md#accepted). + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0685-pickup-v2/README.md b/features/0685-pickup-v2/README.md new file mode 100644 index 000000000..4e7948c83 --- /dev/null +++ b/features/0685-pickup-v2/README.md @@ -0,0 +1,239 @@ +# 0685: Pickup Protocol 2.0 + +- Authors: [Sam Curren](mailto:telegramsam@gmail.com), [James Ebert](mailto:james.ebert@indicio.tech) +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2024-05-01 +- Status Note: Initial version +- Start Date: 2020-12-22 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) + +## Summary + +A protocol to facilitate an agent picking up messages held at a mediator. + +## Motivation + +Messages can be picked up simply by sending a message to the _Mediator_ with a `return_route` decorator specified. This mechanism is implicit, and lacks some desired behavior made possible by more explicit messages. + +This protocol is the explicit companion to the implicit method of picking up messages. + +## Tutorial + +### Roles + +**Mediator** - The agent that has messages waiting for pickup by the _Recipient_. + +**Recipient** - The agent who is picking up messages. + +### Flow + +The `status-request` message is sent by the _Recipient_ to the _Mediator_ to query how many messages are pending. + +The `status` message is the response to `status-request` to communicate the state of the message queue. + +The `delivery-request` message is sent by the _Recipient_ to request delivery of pending messages. + +The `message-received` message is sent by the _Recipient_ to confirm receipt of delivered messages, +prompting the _Mediator_ to clear messages from the queue. + +The `live-delivery-change` message is used to set the state of `live_delivery`. + +- When Live Mode is enabled, messages that arrive when an existing connection exists are delivered over the connection immediately, +rather than being pushed to the queue. See [Live Mode](#live-mode) for more details. + +## Reference + +Each message sent MUST use the `~transport` decorator as follows, which has been adopted from [RFC 0092 transport return route](/features/0092-transport-return-route/README.md) protocol. This has been omitted from the examples for brevity. + +```json +"~transport": { + "return_route": "all" +} +``` + +## Message Types + +### Status Request + +Sent by the _Recipient_ to the _Mediator_ to request a `status` message. +#### Example: + +```json +{ + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/2.0/status-request", + "recipient_key": "" +} +``` + +`recipient_key` is optional. When specified, the _Mediator_ MUST only return status related to that recipient key. This allows the _Recipient_ to discover if any messages are in the queue that were sent to a specific key. You can find more details about `recipient_key` and how it's managed in [0211-route-coordination](https://github.com/hyperledger/aries-rfcs/blob/master/features/0211-route-coordination/README.md). + +### Status + +Status details about waiting messages. + +#### Example: + +```json +{ + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/2.0/status", + "recipient_key": "", + "message_count": 7, + "longest_waited_seconds": 3600, + "newest_received_time": "2019-05-01 12:00:00Z", + "oldest_received_time": "2019-05-01 12:00:01Z", + "total_bytes": 8096, + "live_delivery": false +} +``` + +`message_count` is the only REQUIRED attribute. The others MAY be present if offered by the _Mediator_. + +`longest_waited_seconds` is in seconds, and is the longest delay of any message in the queue. + +`total_bytes` represents the total size of all messages. + +If a `recipient_key` was specified in the `status-request` message, the matching value MUST be specified +in the `recipient_key` attribute of the status message. + +`live_delivery` state is also indicated in the status message. + +> Note: due to the potential for confusing what the actual state of the message queue +> is, a status message MUST NOT be put on the pending message queue and MUST only +> be sent when the _Recipient_ is actively connected (HTTP request awaiting +> response, WebSocket, etc.). + +### Delivery Request + +A request from the _Recipient_ to the _Mediator_ to have pending messages delivered. + +#### Examples: + +```json +{ + "@id": "123456781", + "@type": "https://didcomm.org/messagepickup/2.0/delivery-request", + "limit": 10, + "recipient_key": "" +} +``` + +```json +{ + "@type": "https://didcomm.org/messagepickup/2.0/delivery-request", + "limit": 1 +} +``` + + +`limit` is a REQUIRED attribute, and after receipt of this message, the _Mediator_ SHOULD deliver up to the `limit` indicated. + +`recipient_key` is optional. When [specified](), the _Mediator_ MUST only return messages sent to that recipient key. + +If no messages are available to be sent, a `status` message MUST be sent immediately. + +Delivered messages MUST NOT be deleted until delivery is acknowledged by a `messages-received` message. + +### Message Delivery + +Messages delivered from the queue must be delivered in a batch `delivery` message as attachments. The ID of each attachment is used to confirm receipt. The ID is an opaque value, and the _Recipient_ should not infer anything from the value. + +The ONLY valid type of attachment for this message is a DIDComm Message in encrypted form. + +The `recipient_key` attribute is only included when responding to a `delivery-request` message that indicates a `recipient_key`. + +```json +{ + "@id": "123456781", + "~thread": { + "thid": "" + }, + "@type": "https://didcomm.org/messagepickup/2.0/delivery", + "recipient_key": "", + "~attach": [{ + "@id": "", + "data": { + "base64": "" + } + }] +} +``` + +This method of delivery does incur an encoding cost, but is much simpler to implement and a more robust interaction. + +### Messages Received +After receiving messages, the _Recipient_ sends an ack message indiciating +which messages are safe to clear from the queue. + +#### Example: + +```json +{ + "@type": "https://didcomm.org/messagepickup/2.0/messages-received", + "message_id_list": ["123","456"] +} +``` + +`message_id_list` is a list of ids of each message received. The id of each message is present in the attachment descriptor of each attached message of a `delivery` message. + +Upon receipt of this message, the _Mediator_ knows which messages have been received, and can remove them from the collection of queued messages with confidence. The mediator SHOULD send an updated `status` message reflecting the changes to the queue. + +### Multiple Recipients + +If a message arrives at a _Mediator_ addressed to multiple _Recipients_, the message MUST be queued for each _Recipient_ independently. If one of the addressed _Recipients_ retrieves a message and indicates it has been received, that message MUST still be held and then removed by the other addressed _Recipients_. + +## Live Mode +Live mode is the practice of delivering newly arriving messages directly to a connected _Recipient_. It is disabled by default and only activated by the _Recipient_. Messages that arrive when Live Mode is off MUST be stored in the queue for retrieval as described above. If Live Mode is active, and the connection is broken, a new inbound connection starts with Live Mode disabled. + +Messages already in the queue are not affected by Live Mode - they must still be requested with `delivery-request` messages. + +Live mode MUST only be enabled when a persistent transport is used, such as WebSockets. + +_Recipients_ have three modes of possible operation for message delivery with various abilities and level of development complexity: + +1. Never activate live mode. Poll for new messages with a `status_request` message, and retrieve them when available. +2. Retrieve all messages from queue, and then activate Live Mode. This simplifies message processing logic in the _Recipient_. +3. Activate Live Mode immediately upon connecting to the _Mediator_. Retrieve messages from the queue as possible. When receiving a message delivered live, the queue may be queried for any waiting messages delivered to the same key for processing. + +### Live Mode Change +Live Mode is changed with a `live-delivery-change` message. + +#### Example: + +```json +{ + "@type": "https://didcomm.org/messagepickup/2.0/live-delivery-change", + "live_delivery": true +} +``` + +Upon receiving the `live_delivery_change` message, the _Mediator_ MUST respond with a `status` message. + +If sent with `live_delivery` set to `true` on a connection incapable of live delivery, a `problem_report` SHOULD be sent as follows: + +```json +{ + "@type": "https://didcomm.org/notification/1.0/problem-report", + "~thread": { + "pthid": "" + }, + "description": "Connection does not support Live Delivery" +} +``` + +## Prior art + +Version 1.0 of this protocol served as the main inspiration for this version. Version 1.0 suffered from not being very explicit, and an incomplete model of message delivery signaling. + +## Alternatives + +- An alternative to deriving a message ID is to wrap each message in a delivery wrapper. This would enable the mediator to include a mediator managed id and metadata along with the message itself, but carries the downside of double encrypting messages and extra processing. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +Name / Link | Implementation Notes +--- | --- + | | diff --git a/features/0693-credential-representation/README.md b/features/0693-credential-representation/README.md new file mode 100644 index 000000000..ce0eaf3ff --- /dev/null +++ b/features/0693-credential-representation/README.md @@ -0,0 +1,59 @@ +# 0693: Cross-Platform Credential Representation + +- Authors: [Horacio Nunez](mailto:horacio.nunez@kiva.org) (Kiva Protocol) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2021-07-06 +- Status Note: +- Supersedes: +- Start Date: 2021-02-10 +- Tags: [feature](/tags.md#feature) + +## Summary +Aries Agent developers currently build end user products without a standard method of rendering credentials. +This RFC proposes how the Aries community can reuse available open technologies to build such a rendering method. + +Key results include: +- Feasibility of cross platform rendering. +- Enable branding of credentials. + +This RFC also enumerate the specific challenges that by using this method could be tackled next. + +## Motivation +The human computer interaction between agents and their users will always gravitate around credentials. +This interaction is more useful for users when their representation resembles that of their conventional +(physical) counterparts. + +Achieving effortless semiotic parity with analog credentials doesn't come easy or cheap. +In fact, when reviewing new Aries-base projects, is always the case that the rendering of +credentials with any form of branding is a demanding portion of the roadmap. + +Since the work required here is never declarative the work never stops feeling sysyphean. +Indeed, the cost of writing code of representing a credential remains constant over time, no +matter how many times we do it. + +Imagine if we achieve declarative while empowering branding. + +### Entering SVG + +The solution we propose is to adopt SVG as the default format to describe how to represent SSI credentials, and to +introduce a convention to ensure that credentials values could be embedded in the final user interface. +The following images illustrates how this can work: + +![SVG + Credential Values](https://i.imgur.com/3ssaQUB.png "SVG + Credential Values") + +### SVG + Credential Values + +We propose a notation of the form `{{credential.values.[AttributeName]}}` and `{{credential.names.[AttributeName]}}`. +This way both values and attributes names can be used in branding activities. + +#### Cross Platform + +Since SVG is a web standard based on XML there isn't a shortage of existing tools to power brand and engineering needs +right away. Indeed, any implementation will be powered by native SVG renderer and XML parser. + +## Future work + +* (RFC) A default credential representation to serves as community baseline +* (RFC) How to communicate the designated credential representation among agents. +* (RFC) Expand metadata available to include Revocation status. +* (Dev Tool) Standalone desktop tool to help design/brand a credential stored in an agent. diff --git a/features/0699-push-notifications-apns/README.md b/features/0699-push-notifications-apns/README.md new file mode 100644 index 000000000..ce9172380 --- /dev/null +++ b/features/0699-push-notifications-apns/README.md @@ -0,0 +1,153 @@ +# Aries RFC 0699: Push Notifications apns Protocol 1.0 + +- Authors: [Timo Glastra](mailto:timo@animo.id) (Animo Solutions) & [Berend Sliedrecht](mailto:berend@animo.id) (Animo Solutions) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2021-10-07 +- Status Note: Initial version +- Start Date: 2021-05-05 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) + +> Note: This protocol is currently written to support native push notifications for iOS via [Apple Push Notification Service](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/sending_notification_requests_to_apns/). +> For the implementation for Android (using fcm), please refer to [0734: Push Notifications fcm](../0734-push-notifications-fcm/README.md) + +## Summary + +A protocol to coordinate a push notification configuration between two agents. + +## Motivation + +This protocol would give an agent enough information to send push notifications about specific events to an iOS device. This would be of great benefit for mobile wallets, as a holder can be notified when new messages are pending at the mediator. Mobile applications, such as wallets, are often killed and can not receive messages from the mediator anymore. Push notifications would resolve this problem. + +## Tutorial + +### Name and Version + +URI: `https://didcomm.org/push-notifications-apns/1.0` + +Protocol Identifier: `push-notifications-apns` + +Version: `1.0` + +Since apns only supports iOS, no `-ios` or `-android` is required as it is implicit. + +### Key Concepts + +When an agent would like to receive push notifications at record event changes, e.g. incoming credential offer, incoming connection request, etc., the agent could initiate the protocol by sending a message to the other agent. + +This protocol only defines how an agent would get the token which is necessary for push notifications. + +Each platform is has its own protocol so that we can easily use [0031: Discover Features 1.0](https://github.com/hyperledger/aries-rfcs/blob/main/features/0031-discover-features/README.md) and [0557: Discover Features 2.X](https://github.com/hyperledger/aries-rfcs/blob/main/features/0557-discover-features-v2/README.md) to see which specific services are supported by the other agent. + +### Roles + +**notification-sender** + +**notification-receiver** + +The **notification-sender** is an agent who will send the **notification-receiver** notifications. The **notification-receiver** can get and set their push notification configuration at the **notification-sender**. + +### Services + +This RFC focusses on configuring the data necessary for pushing notifications to iOS, via [apns](https://developer.apple.com/notifications/). + +In order to implement this protocol, the [set-device-info](#set-device-info) and [get-device-info](#get-device-info) messages MUST be implemented by the **notification-sender** and [device-info](#device-info) message MUST be implemented by the **notification-receiver**. + +#### Supported Services + +The protocol currently supports the following push notification services + +- [apns](https://developer.apple.com/notifications/) for iOS devices + +### Messages + +When a notification-receiver wants to receive push notifications from the notification-sender, the notification-receiver has to send the following message: + +#### Set Device Info + +Message to set the device info using the native iOS device token for push notifications. + +```json +{ + "@type": "https://didcomm.org/push-notifications-apns/1.0/set-device-info", + "@id": "", + "device_token": "" +} +``` + +Description of the fields: + +- `device_token` -- The token that is required by the notification provider (string, null) + +It is important to note that the set device info message can be used to set, update and remove the device info. To set, and update, these values the normal messages as stated above can be used. To remove yourself from receiving push notifications, you can send the same message where all values MUST be `null`. If either value is `null` a `problem-report` MAY be sent back with `missing-value`. + +#### Get Device Info + +When a notification-receiver wants to get their push-notification configuration, they can send the following message: + +```json +{ + "@type": "https://didcomm.org/push-notifications-apns/1.0/get-device-info", + "@id": "" +} +``` + +#### Device Info + +Response to the get device info: + +```json +{ + "@type": "https://didcomm.org/push-notifications-apns/1.0/device-info", + "device_token": "", + "~thread": { + "thid": "" + } +} +``` + +This message can be used by the notification-receiver to receive their device info, e.g. `device_token`. If the notification-sender does not have this field for that connection, a `problem-report` MAY be used as a response with `not-registered-for-push-notifications`. + +#### Adopted messages + +In addition, the [`ack`](https://github.com/hyperledger/aries-rfcs/blob/08653f21a489bf4717b54e4d7fd2d0bdfe6b4d1a/features/0015-acks/README.md) message is adopted into the protocol for confirmation by the notification-sender. The ack message SHOULD be sent in response to any of the set-device-info messages. + +### Sending Push Notifications + +When an agent wants to send a push notification to another agent, the payload of the push notifications MUST include the `@type` property, and COULD include the `message_tag` property, to indicate the message is sent by the notification-sender. Guidelines on notification messages are not defined. + +```json +{ + "@type": "https://didcomm.org/push-notifications-apns", + "message_tag": "", + "message_id": "", + ... +} +``` + +Description of the fields: + +- `@type` -- Indicator of what kind of notification it is. (This could help the notification-receiver with parsing if a notification comes from another agent, for example) +- `message_tag` -- Optional field to connect the push notification to a DIDcomm message. As defined in [0334: jwe-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0334-jwe-envelope) or [0019: encryption-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0019-encryption-envelope). +- `message_id` -- Optional field to pickup the message from the mediator that the notification was linked to. As defined in [0685: Pickup Protocol 2.0](https://github.com/hyperledger/aries-rfcs/blob/main/features/0685-pickup-v2/README.md). + +## Drawbacks + +Each service requires a considerable amount of domain knowledge. The RFC can be extended with new services over time. + +The `@type` property in the push notification payload currently doesn't indicate which agent the push notification came from. In e.g. the instance of using multiple mediators, this means the notification-receiver does not know which mediator to retrieve the message from. + +## Prior art + +- This RFC is based on the implementation of the [`AddDeviceInfoMessage`](https://github.com/hyperledger/aries-framework-dotnet/blob/9bc6346a21da263083bbac8dd8227cc941c95ea9/src/Hyperledger.Aries.Routing/AddDeviceInfoMessage.cs) in Aries Framework .NET + +## Unresolved questions + +None + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | | diff --git a/features/0721-revocation-notification-v2/README.md b/features/0721-revocation-notification-v2/README.md new file mode 100644 index 000000000..3b3af4e2d --- /dev/null +++ b/features/0721-revocation-notification-v2/README.md @@ -0,0 +1,128 @@ +# Aries RFC 0721: Revocation Notification 2.0 +- Authors: Keith Smith, Daniel Bluhm, James Ebert +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2024-05-01 +- Status Note: Updates the credential identifiers format after discussions while implementing [RFC 0183 Revocation Notification](../0183-revocation-notification/README.md) +- Supersedes: [RFC 0183 Revocation Notification](../0183-revocation-notification/README.md) +- Start Date: 2021-11-01 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) + +## Summary + +This RFC defines the message format which an issuer uses to notify a holder that a previously issued credential has been revoked. + +## Change Log + +- 20240320: Clarification removing references to retired `~please_ack` decorator and RFC. + +## Motivation + +We need a standard protocol for an issuer to notify a holder that a previously issued credential has been revoked or unrevoked. + +For example, suppose a passport agency revokes Alice's passport. +The passport agency (an issuer) may want to notify Alice (a holder) that her passport has been revoked so that she +knows that she will be unable to use her passport to travel. + +## Tutorial + +The Revocation Notification protocol is a very simple protocol consisting of two messages: + +* Revoke - issuer to holder +* Unrevoke - issuer to holder + +This simple protocol allows an issuer to choose to notify a holder that a previously issued credential has been revoked or unrevoked. + +It is the issuer's prerogative whether or not to notify the holder that a credential has been (un)revoked. It is not a security risk if the issuer does not notify the holder that the credential has been (un)revoked, nor if the message is lost. The holder will still be unable to use a revoked credential without this notification. + +### Roles + +There are two parties involved in a Revocation Notification: `issuer` and `holder`. +The `issuer` sends the `revoke` or `unrevoke` message to the `holder`. + +### Messages + +#### Revoke + +The `revoke` message sent by the `issuer` to the `holder`. The holder should verify that the `revoke` message came from the connection that was originally used to issue the credential. + +Message format: + +```JSON +{ + "@type": "https://didcomm.org/revocation_notification/2.1/revoke", + "@id": "", + "revocation_format": "", + "credential_id": "", + "comment": "Some comment" +} +``` + +Description of fields: + +* `revocation_format` (required) -- the format of the credential revocation. Accepted values for the revocation format are provided in the "Revocation Credential Identification Formats" section immediately below. + +* `credential_id` (required) -- the individual credential identifier of a credential issued using the [issue-credential-v2](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2) protocol that has been revoked by the issuer. Accepted values for the credential id format are provided in the "Revocation Credential Identification Formats" section immediately below. + +* `comment` (optional) -- a field that provides some human readable information about the revocation notification. This is typically the reason for the revocation as deemed appropriate by the issuer. + +#### Unrevoke + +The `unrevoke` message sent by the `issuer` to the `holder`. The holder should verify that the `unrevoke` message came from the connection that was originally used to issue the credential. + +Message format: + +```JSON +{ + "@type": "https://didcomm.org/revocation_notification/2.1/unrevoke", + "@id": "", + "revocation_format": "", + "credential_id": "", + "comment": "Some comment" +} +``` + +Description of fields: + +* `revocation_format` (required) -- the format of the credential revocation. Accepted values for the revocation format are provided in the "Revocation Credential Identification Formats" section immediately below. + +* `credential_id` (required) -- the individual credential identifier of a credential issued using the [issue-credential-v2](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2) protocol that has been revoked by the issuer. Accepted values for the credential id format are provided in the "Revocation Credential Identification Formats" section immediately below. + +* `comment` (optional) -- a field that provides some human readable information about the revocation notification. This is typically the reason for the revocation as deemed appropriate by the issuer. + +#### Revocation Credential Identification Formats + +In order to support multiple credential revocation formats, the following dictates the format of revocation formats and their credential ids. As additional credential revocation formats are determined their credential id formats should be added. + +Revocation Format | Credential Identifier Format | Example | +--- | --- | --- | +`indy-anoncreds` | `::` | `AsB27X6KRrJFsqZ3unNAH6:4:AsB27X6KRrJFsqZ3unNAH6:3:cl:48187:default:CL_ACCUM:3b24a9b0-a979-41e0-9964-2292f2b1b7e9::1` | +`anoncreds` | `::` | `did:indy:sovrin:5nDyJVP1NrcPAttP3xwMB9/anoncreds/v0/REV_REG_DEF/56495/npdb/TAG1::1` | + +## Reference + +* See the [issue-credential-v2](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2) protocol. +* See the [Please ACK Decorator RFC](https://github.com/hyperledger/aries-rfcs/tree/main/features/0317-please-ack). + +## Drawbacks + +If we later added support for more general event subscription and notification message flows, this would be redundant. + +## Rationale and alternatives + +- Why is this design the best in the space of possible designs? It is simple. +- What other designs have been considered and what is the rationale for not +choosing them? A more general event subscription and notification mechanism was considered but chose to keep this simple for the same reasons that the basic message was kept simple. +- What is the impact of not doing this? There is no standard way of sending a revocation notification which is a common scenario. + +## Prior art + +## Unresolved questions + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +Name / Link | Implementation Notes +--- | --- + | | + diff --git a/features/0728-device-binding-attachments/README.md b/features/0728-device-binding-attachments/README.md new file mode 100644 index 000000000..e127cba1e --- /dev/null +++ b/features/0728-device-binding-attachments/README.md @@ -0,0 +1,270 @@ +# Aries RFC 0728 : Device Binding Attachments + +- Authors: [Paul Bastian](mailto:paul.bastian@bdr.de), [Sebastian Bickerle](mailto:sebastian.bickerle@main-incubator.com) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2022-04-07 +- Status Note: This is an initial draft +- Start Date: 2022-01-01 +- Tags: [feature](/tags.md#feature) + +## Summary + +Extends existing present-proof protocols to allow proofing the control of a hardware bound key embedded within a verfiable credential. + +## Motivation + +To enable use-cases which require a high level of assurance a verifier must reach a high degree of confidence that a verifiable credential (VC) can only be used by the person it was issued for. One way to enforce this requirement is that the issuer additionally binds the VC to a hardware bound public key and therefore binding the credential to the device, as discussed in the [DIF Wallet Security WG](https://github.com/decentralized-identity/wallet-security). The issaunce process, including the attestation of the wallet and the hardware bound key is off-scope for this Aries RFC. A valid presentation of the VC then requires an additional challenge which proofs that the presenter is in control of the corresponding private key. Since the proof of control must be part of legitimate presentation it makes sense to extend all current `present-proof` protocols. + +Note: The focus so far has been on AnonCreds, we will also look into device binding of W3C VC, however this is currently lacking in the examples. + +Warning: **This concept is primarily meant for regulated, high-security usecases**. Please review the drawbacks before considering using this. + +## Tutorial + +To proof the control of a hardware bound key the holder must answer a challenge for one or more public keys embedded within verifiable credentials. + +### Challenge + +The following challenge object must be provided by the verifier. + +#### device-binding-challenge + +```json +{ + "@type": "https://didcomm.org/device-binding/%ver/device-binding-challenge", + "@id": "", + "nonce": "", // recommend at least 128-bit unsigned integer + "requests": [ + { + "id": "libindy-request-presentation-0", + "path": "$.requested_attributes.attr2_referent.names.hardwareDid" + } + ] +} +``` + +Description of attributes: + +- `nonce` -- a nonce which has to be signed by the holder to proof control +- `requests` -- an array of referenced presentation requests + - `id` -- reference to an attached presentation request of `request-presentation` message (e.g. libindy request) + - `path` -- JsonPath to a requested attribute which represents a public key of a hardware bound key pair - represented as did:key + +The `device-binding-challenge` must be attached to the `request-presentations~attach` array of the `request-presentation` message defined by [RFC-0037](https://github.com/hyperledger/aries-rfcs/blob/main/features/0037-present-proof/README.md#request-presentation) and [RFC-0454](https://github.com/hyperledger/aries-rfcs/tree/main/features/0454-present-proof-v2#request-presentation). + +#### Example request-presentation messages + +The following represents a request-presentation message with an attached libindy presentation request and a corresponding device-binding-challenge. + +**Present Proof v1** + +```json +{ + "@type": "https://didcomm.org/present-proof/1.0/request-presentation", + "@id": "", + "comment": "some comment", + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ], + "device_binding~attach": [ + { + "@id": "device-binding-challenge-0" + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ] +} +``` + +**Present Proof v2** + +```json +{ + "@type": "https://didcomm.org/present-proof/2.0/request-presentation", + "@id": "", + "goal_code": "", + "comment": "some comment", + "will_confirm": true, + "present_multiple": false, + "formats" : [ + { + "attach_id" : "libindy-request-presentation-0", + "format" : "hlindy/proof-req@v2.0", + } + ], + "request_presentations~attach": [ + { + "@id": "libindy-request-presentation-0", + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ], + "device_binding~attach": [ + { + "@id": "device-binding-challenge-0" + "mime-type": "application/json", + "data": { + "base64": "" // inner object + } + } + ] +} +``` + +### Response + +The following response must be generated by the holder of the VC. + +#### device-binding-reponse + +```json +{ + "@type": "https://didcomm.org/device-binding/%ver/device-binding-response", + "@id": "", + "proofs": [ + { + "id": "libindy-presentation-0", + "path": "$.requested_proof.revealed_attrs.attr1_referent.raw" + } + ] +} +``` + +Description of attributes: + +- `proofs` -- an array of proofs for different hardware keys which must match the `requests` array from the [device-binding-challenge](#device-binding-challenge) + - `id` -- reference to presentation of VC with an embeded hardware bound key + - `path` -- JsonPath to raw value of hardware bound public key within the attached presentation of the VC represented as did:key + +The `device-binding-response` must be attached to the `device_binding~attach` array of a `presentation` message defined by [RFC-0037](https://github.com/hyperledger/aries-rfcs/blob/main/features/0037-present-proof/README.md#presentation) or [RFC-0454](https://github.com/hyperledger/aries-rfcs/tree/main/features/0454-present-proof-v2#presentation). + +- `jws` -- Nonce from [device-binding-challenge](#device-binding-challenge) signed with the corresponding private key as a Json Web Signature object, acording to Aries [RFC-0017](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0017-attachments#signing-attachments). + +### Example presentation messages + +The following represents a presentation message with an attached libindy presentation and a corresponding device-binding-response. + +**Present Proof v1** + +```json +{ + "@type": "https://didcomm.org/present-proof/1.0/presentation", + "@id": "", + "comment": "some comment", + "presentations~attach": [ + { + "@id": "libindy-presentation-0", + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ], + "device_binding~attach": [ + { + "@id": "device-binding-response-0", + "mime-type": "application/json", + "data": { + "base64": "", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } + } + } + ] +} +``` + +**Present Proof v2** + +```json +{ + "@type": "https://didcomm.org/present-proof/%VER/presentation", + "@id": "", + "goal_code": "", + "comment": "some comment", + "last_presentation": true, + "formats" : [ + { + "attach_id" : "libindy-presentation-0", + "format" : "hlindy/proof-req@v2.0", + } + ], + "presentations~attach": [ + { + "@id": "libindy-presentation-0", + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ], + "device_binding~attach": [ + { + "@id": "device-binding-response-0" + "mime-type": "application/json", + "data": { + "base64": "", + "jws": { + "header": { + "kid": "did:key:z6MkmjY8GnV5i9YTDtPETC2uUAW6ejw3nk5mXF5yci5ab7th" + }, + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } + } + } + ] +} +``` + +## Reference + +- [DIF Wallet Security Github Page](https://github.com/decentralized-identity/wallet-security) + +## Drawbacks + +Including a hardware-bound public key (as an attribute) into a Verifiable Credential/AnonCred is necessary for this concept but introduces a globally unique and therefore trackable identifier. As this public key is revealed to the verifier, there is a higher risk of correlation. The Issuer must always use a hardware-bound key for a single credential and the Wallet should enforce to never reuse the key. Additionally, the holder should ideally be informed about the increased correlation risk by the wallet UX. + +## Rationale and alternatives + +The rationale behind this proposal is to formalize the way a holder wallet can proof the control of a (hardware-bound) key. + +This proposal tries to extend existing protocols to reduce the implementation effort for existing solutions. It might be reasonable to include this only in a new version of the present proof protocol (e.g. present-proof v3). + +## Prior art + +None to our knowledge. + +## Unresolved questions + +- What is the best way to reference hardware bound keys within VCs and presentations? + - Do we need a standardised attribute name for the hardware backed public key (e.g. "HardwareDid") + - Can we just reference the hardware key within the request object? + - Is it required to explicitly define the accepted signing algorithm within the `device-binding-challenge` object? +- What kind of key encoding do we choose? + - did:key, base64-encoded JWK and did:jwk in discussion + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +_Implementation Notes_ [may need to include a link to test results](/README.md#accepted). + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0734-push-notifications-fcm/README.md b/features/0734-push-notifications-fcm/README.md new file mode 100644 index 000000000..4d4380e89 --- /dev/null +++ b/features/0734-push-notifications-fcm/README.md @@ -0,0 +1,154 @@ +# Aries RFC 0734: Push Notifications fcm Protocol 1.0 + +- Authors: [Timo Glastra](mailto:timo@animo.id) (Animo Solutions) & [Berend Sliedrecht](mailto:berend@animo.id) (Animo Solutions) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2022-05-12 +- Status Note: Initial version +- Start Date: 2022-05-12 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) + +> Note: This protocol is currently written to support native push notifications using fcm. +> For the implementation for iOS (via apns), please refer to [0699: Push Notifications apns](../0699-push-notifications-apns/README.md) + +## Summary + +A protocol to coordinate a push notification configuration between two agents. + +## Motivation + +This protocol would give an agent enough information to send push notifications about specific events to a device that supports fcm. This would be of great benefit for mobile wallets, as a holder can be notified when new messages are pending at the mediator. Mobile applications, such as wallets, are often killed and can not receive messages from the mediator anymore. Push notifications would resolve this problem. + +## Tutorial + +### Name and Version + +URI: `https://didcomm.org/push-notifications-fcm/1.0` + +Protocol Identifier: `push-notifications-fcm` + +Version: `1.0` + +### Key Concepts + +When an agent would like to receive push notifications at record event changes, e.g. incoming credential offer, incoming connection request, etc., the agent could initiate the protocol by sending a message to the other agent. + +This protocol only defines how an agent would get the token and platform that is necessary for push notifications. + +Each platform has its own protocol so that we can easily use [0031: Discover Features 1.0](https://github.com/hyperledger/aries-rfcs/blob/main/features/0031-discover-features/README.md) and [0557: Discover Features 2.X](https://github.com/hyperledger/aries-rfcs/blob/main/features/0557-discover-features-v2/README.md) to see which specific services are supported by the other agent. + +### Roles + +**notification-sender** + +**notification-receiver** + +The **notification-sender** is an agent who will send the **notification-receiver** notifications. The **notification-receiver** can get and set their push notification configuration at the **notification-sender**. + +### Services + +This RFC focuses on configuring the data necessary for pushing notifications via [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging). + +In order to implement this protocol, the [set-device-info](#set-device-info) and [get-device-info](#get-device-info) messages MUST be implemented by the **notification-sender** and [device-info](#device-info) message MUST be implemented by the **notification-receiver**. + +#### Supported Services + +The protocol currently supports the following push notification services + +- [Firebase Cloud Messaging](https://firebase.google.com/docs/cloud-messaging) + +### Messages + +When a notification-receiver wants to receive push notifications from the notification-sender, the notification-receiver has to send the following message: + +#### Set Device Info + +Message to set the device info using the fcm device token and device platform for push notifications. + +```json +{ + "@type": "https://didcomm.org/push-notifications-fcm/1.0/set-device-info", + "@id": "", + "device_token": "", + "device_platform": "" +} +``` + +Description of the fields: + +- `device_token` -- The token that is required by the notification provider (string, null) +- `device_platform` -- The platform used by the sender, e.g. Android / iOS / Linux / etc. (string, null) + +It is important to note that the set device info message can be used to set, update and remove the device info. To set, and update, these values the normal messages as stated above can be used. To remove yourself from receiving push notifications, you can send the same message where all values MUST be `null`. If either value is `null`, a `problem-report` MAY be sent back with `missing-value`. + +#### Get Device Info + +When a notification-receiver wants to get their push-notification configuration, they can send the following message: + +```json +{ + "@type": "https://didcomm.org/push-notifications-fcm/1.0/get-device-info", + "@id": "" +} +``` + +#### Device Info + +Response to the get device info: + +```json +{ + "@type": "https://didcomm.org/push-notifications-fcm/1.0/device-info", + "device_token": "", + "device_platform": "", + "~thread": { + "thid": "" + } +} +``` + +This message can be used by the notification-receiver to receive their device info, e.g. `device_token` and `device_platform`. If the notification-sender does not have this field for that connection, a `problem-report` MAY be used as a response with `not-registered-for-push-notifications`. + +#### Adopted messages + +In addition, the [`ack`](https://github.com/hyperledger/aries-rfcs/blob/08653f21a489bf4717b54e4d7fd2d0bdfe6b4d1a/features/0015-acks/README.md) message is adopted into the protocol for confirmation by the notification-sender. The ack message SHOULD be sent in response to any of the set-device-info messages. + +### Sending Push Notifications + +When an agent wants to send a push notification to another agent, the payload of the push notifications MUST include the `@type` property, and COULD include the `message_tags` property, to indicate the message is sent by the notification-sender. Guidelines on notification messages are not defined. + +```json +{ + "@type": "https://didcomm.org/push-notifications-fcm", + "message_tags": [""], + "message_ids": [""], + ... +} +``` + +Description of the fields: + +- `@type` -- Indicator of what kind of notification it is. (This could help the notification-receiver with parsing if a notification comes from another agent, for example) +- `message_tag` -- Optional list field to connect the push notification to a DIDcomm message, this can be used for batching multiple messages to a single notification. As defined in [0334: jwe-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0334-jwe-envelope) or [0019: encryption-envelope](https://github.com/hyperledger/aries-rfcs/tree/main/features/0019-encryption-envelope). +- `message_ids` -- Optional list field to pickup the message from the mediator that the notification was linked to, this can be used for batching multiple messages to a single notification. As defined in [0685: Pickup Protocol 2.0](https://github.com/hyperledger/aries-rfcs/blob/main/features/0685-pickup-v2/README.md). + +## Drawbacks + +Each service requires a considerable amount of domain knowledge. The RFC can be extended with new services over time. + +The `@type` property in the push notification payload currently doesn't indicate which agent the push notification came from. In e.g. the instance of using multiple mediators, this means the notification-receiver does not know which mediator to retrieve the message from. + +## Prior art + +- This RFC is based on the implementation of the [`AddDeviceInfoMessage`](https://github.com/hyperledger/aries-framework-dotnet/blob/9bc6346a21da263083bbac8dd8227cc941c95ea9/src/Hyperledger.Aries.Routing/AddDeviceInfoMessage.cs) in Aries Framework .NET + +## Unresolved questions + +None + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | | diff --git a/features/0748-n-wise-did-exchange/README.md b/features/0748-n-wise-did-exchange/README.md new file mode 100644 index 000000000..f5ecafb9f --- /dev/null +++ b/features/0748-n-wise-did-exchange/README.md @@ -0,0 +1,380 @@ +# Aries RFC 0748: N-wise DID Exchange Protocol 1.0 + +- Authors: [Mikhail Lytaev](mailto:mikelytaev@gmail.com), [Pavel Minenkov](mailto:minikspb@gmail.com) +- Status: [DEMONSTRATED](/README.md#demonstrated) +- Since: 2022-08-03 +- Status Note: Under research +- Supersedes: +- Start Date: 2022-06-03 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) +- URI: https://didcomm.org/n-wise/1.0 + +## Summary + +This RFC defines a protocol for creating and managing relationships within a group of SSI subjects. In a certain sense, this RFC is a generalization of the pairwise concept and protocols [0160-connection-protocol](https://github.com/hyperledger/aries-rfcs/tree/main/features/0160-connection-protocol) and [0023-did-exchange](https://github.com/hyperledger/aries-rfcs/tree/main/features/0023-did-exchange) for an arbitrary number of parties (n-wise). + +## Motivation + +SSI subjects and [agents](https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0004-agents) representing them must have a way to establish relationships with each other in a trustful manner. In the simplest case, when only two participants are involved, this goal is achieved using [0023-did-exchange](https://github.com/hyperledger/aries-rfcs/blob/main/features/0023-did-exchange/README.md) protocol by creating and securely sharing their DID Documents directly between agents. However, it is often desirable to organize an interaction involving more than two paries. The number of parties of such an interaction may change over time, and most of the agents may be mobile ones. The simplest and most frequently used example of such interaction is a group chat in instant messenger. The trusted nature of SSI technology makes it possible to use group relationships for holding legally significant unions, such as board of directors, territorial community or dissertation councils. + +## Tutorial + +### Name and Version + +n-wise, version 1.0 + +URI: https://didcomm.org/n-wise/1.0 + +### Registry of n-wise states + +The current state of n-wise is an up-to-date list of the parties' DID Documents. In pairwise relation the state is stored by the participants and updated by a direct notification of the other party. When there are more than two participants, the problem of synchronizing the state of this n-wise (i.e. [consensus](https://en.wikipedia.org/wiki/Consensus_(computer_science))) arising. It should be borne in mind that the state may change occasionally: users may be added or deleted, DID Documents may be modified (when keys are rotated or endpoints are changed). + +In principle, any trusted repository can act as a registry of n-wise states. The following options for storing the n-wise state can be distinguished: + +- #### Directly on the agent's side (Edge chain) + + - This approach is the closest to [0023-did-exchange](https://github.com/hyperledger/aries-rfcs/blob/main/features/0023-did-exchange/README.md) protocol. However since there are more than two participants, an additional consensus procedure is required to correctly account for changes in the n-wise state. This option is suitable if the participants are represented by cloud agents which are (almost) always online. In this case, a consensus can be established between them using the well-known algorithms (RAFT, Paxos, BFT). However, if most of the agents are mobile and are online only occasionally, the mentioned consensus algorithms are not applicable. So it is preferable to use external solutions for storing and updating the n-wise states. + +- #### Public or private distributed ledger + + - In this case, the task of recording and storing the state is taken over by a third-party distributed network. The network can verify incoming transactions by executing a smart contract, or accept all incoming transactions, so transaction validation takes place only on the participating agents. + +- #### Centralized storage + + - This case is applicable when security requirements allow participants to trust a centralized solution. + +The concept of pluggable consensus implies choosing the most appropriate way to maintain a registry of states, depending on the needs. + +N-wise state update is performed by committing the corresponding transaction to the registry of n-wise states. To get the current n-wise state, the agent receives a list of transactions from the registry of states, verifies them and applies sequentially, starting with the `genesisTx`. Incorrect transactions (without a proper signature or missing the required fields) are ignored. Thus, n-wise can be considered as a replicated state machine, which is executed on each participant. + +The specifics of recording and receiving transactions depend on the particular method of maintaining the n-wise registry and on a particular ledger. This RFC DOES NOT DEFINE specific n-wise registry implementations. + +### Roles + +- ##### User + + - The party of n-wise. Has the right to: + + - Modify its DID Document; + - Remove himself from n-wise; + - Invite new parties. + +- ##### Owner + - In addition to user's rights, has the right to: + - Remove other users from n-wise; + - Modify n-wise meta information; + - Transfer its role to another user. + + - There can be only one owner in n-wise at a time. + +- ##### Creator + + - Creator of the n-wise and the author of `genesisTx`. + - The creator automatically becomes the owner of n-wise after creation. + +- ##### Inviter + + - The n-wise participant who initiates the invitation of a new one. + +- ##### Invitee + + - The participant accepting the invitation and connecting to n-wise. If successful, the participant becomes a user of n-wise. + +### Actions + +#### N-wise creation + +The creation begins with the initialization of the n-wise registry. This RFC DOES NOT SPECIFY the procedure for n-wise registry creation. After creating the registry, the creator commits the `genesisTx` transaction. The creator automatically obtains the role of owner. The creator MUST generate a unique DID and DID Document for n-wise. + +#### Invitation of a new party + +Any n-wise party can create an invitation to join n-wise. First, inviter generates a pair of public and private invitation keys according to Ed25519. The public key of the invitation is pushed to the registry using the `invitationTx` transaction. Then the `Invitation` message with the invitation private key is sent out-of-band to the invitee. The invitation key pair is unique for each invitee and can be used only once. + +#### Accepting the invitation + +Once `Invitation` received, the invite generates a unique DID and DID Document for the n-wise and commits `AddParticipantTx` transaction to the registry. +It is NOT ALLOWED to reuse DID from other relationships. + +The process of adding a new participant is shown in the figure below + +![](add_participant.png) + +#### Updating DID Document + +Updating the user's DID Document is required for the key rotation or endpoint updating. To update the associated DID Document, user commits the `updateParticipantTx` transaction to the registry. + +#### Removing a party form n-wise + +Removing is performed using the `removeParticipantTx` transaction. +The user can delete itself (the corresponding transaction is signed by the user's public key). The owner can delete any user (the corresponding transaction is signed by the owner's public key). + +#### Updating n-wise meta information + +Meta information can be updated by the owner using the `updateMetadataTx` transaction. + +#### Transferring the owner role to other user + +The owner can transfer control of the n-wise to other user. The old owner loses the corresponding privileges and becomes a regular user. The operation is performed using the `NewOwnerTx` transaction. + +#### Notification on n-wise state update + +Just after committing the transaction to the n-wise registry, the participant MUST send the `ledger-update-notify` message to all other parties. +The participant who received `ledger-update-notify` SHOULD fetch updates from the n-wise registry. + +### DIDComm messaging within n-wise + +It is allowed to exchange DIDComm messages of any type within n-wise. +The belonging of the sender to a certain n-wise is determined by the sender's verkey. + +This RFC DOES NOT DEFINE a procedure of exchanging messages within n-wise. In the simplest case, this can be implemented as sending a message to each participant in turn. In case of a large number of parties, it is advisable to consider using a centralized coordinator who would be responsible for the ordering and guaranteed sending of messages from the sender to the rest of parties. + +## Reference + +### N-wise registry transactions + +N-wise state is modified using transactions in the following form + +```json +{ + "type": "transaction type", + ... + "proof" { + "type": "JcsEd25519Signature2020", + "verificationMethod": "did:alice#key1", + "signatureValue": "..." + + } +} +``` + +#### Attributes +* `type` - required attribute, type of transaction; +* `proof` - required attribute, transaction signature in [JSON-LD Proof](https://w3c-ccg.github.io/data-integrity-spec/) format; +* `verificationMethod` - required attribute, depends on the specific type of transaction and is defined below. + +### GenesisTx + +'GenesisTx' is a mandatory initial transaction that defines the basic properties of the n-wise. + +```json +{ + "type": "genesisTx", + "label": "Council", + "creatorNickname": "Alice", + "creatorDid": "did:alice", + "creatorDidDoc": { + .. + }, + "ledgerType": "iota@1.0", + "metaInfo" { + ... + } +} +``` + +#### Attributes +* `label` - required attribute, n-wise name; +* `creatorNickname` - required attribute, creator nickname; +* `creatorDid` - required attribute, DID of the creator; +* `creatorDidDoc` - required attribute, DID Document of the creator; +* `ledgerType` - required attribute, n-wise registry type; +* `metaInfo` - optional attribute, additional n-wise meta information; the format is determined by a particular n-wise state implementation; + +The `genesisTx` transaction MUST be signed by the creator's public key defined in his DID Document. + +### InvitationTx + +This transaction adds the invitation public keys to the n-wise registry. + +```json +{ + "type": "invitationTx", + "publicKey": [ + { + "id": "invitationVerkeyForBob", + "type": "Ed25519VerificationKey2018", + "publicKeyBase58": "arekhj893yh3489qh" + } + ] +} + +``` +#### Attributes +* `publicKey` - required attribute, array of invitation public keys; +* `id` - required attribute, invitation public key ID; +* `type` - required attribute, key type; +* `publicKeyBase58` - required attribute, base58 encoded public key. + +invitationTx` MUST be signed by the user's public key defined in it's DID Document. + +### Invitation message + +The message is intended to invite a new participant. It is sent via an arbitrary communication channel (pairwise, QR code, e-mail, etc.). + +```json +{ + "@id": "5678876542345", + "@type": "https://didcomm.org/n-wise/1.0/invitation", + "label": "Invitaion to join n-wise", + "invitationKeyId": "invitationVerkeyForBob", + "invitationPrivateKeyBase58": "qAue25rghuFRhrue....", + "ledgerType": "iota@1.0", + "ledger~attach": [ + { + "@id": "attachment id", + "mime-type": "application/json", + "data": { + "base64": "" + } + } + ] +} + +``` +#### Attributes +* `label` - optional attribute, human readable invitation text; +* `invitationKeyId` - required attribute, invitation key ID; +* `invitationPrivateKeyBase58`- required attribute, base58 encoded invitation private key; +* `ledgerType` - required attribute, n-wise registry type; +* `ledger~attach` - optional attribute, attachment with meta information, required for connection to n-wise registry; defined by a particular registry implementation. + +### AddParticipantTx + +The transaction is designed to add a new user to n-wise. + +```json +{ + "id": "addParticipantTx", + "nickname": "Bob", + "did": "did:bob", + "didDoc": { + ... + } + +} + +``` +#### Attributes +* `nickname` - required attribute, user nickname; +* `did` - required attribute, user's DID; +* `didDoc` - required attribute, user's DID Document. + +`AddParticipantTx` transaction MUST be signed by the invitation private key (`invitationPrivateKeyBase58`), received in `Invitation` message. As committing the `AddParticipantTx` transaction, the corresponding invitation key pair is considered deactivated (other invitations cannot be signed by it). + +The transaction executor MUST verify if the invitation key was indeed previously added. Execution of the transaction entails the addition of a new party to n-wise. + +### UpdateParticipantTx + +The transaction is intended to update information about the participant. + +```json +{ + "type": "updateParticipantTx", + "did": "did:bob", + "nickname": "Updated Bob", + "didDoc" { + ... + } +} + +``` +#### Attributes +* `did` - requred attribute, DID of the updating user; +* `nickname` - optional attribute, new nickname; +* `didDoc` - optional attribute, new DID document. + +Transaction MUST be signed by the public key of the user being updated. The specified public key MUST be defined in the previous version of the DID Document. + +Execution of the transaction entails updating information about the participant. + +### RemoveParticipantTx + +The transaction is designed to remove a party from n-wise. + +```json +{ + "type": "removeParticipantTx", + "did": "did:bob" +} +``` +#### Attributes +* `did` - requred attribute, DID of the removing user; + +The execution of the transaction entails the removal of the user and his DID Document from the list of n-wise parties. + +The transaction MUST be signed by the public key of the user who is going to be removed from n-wise, or with the public key of the owner. + +### UpdateMetadataTx + +The transaction is intended to update the meta-information about n-wise. + +```json +{ + "type": "updateMetadataTx", + "label": "Updated Council" + "metaInfo": { + ... + } +} +``` + +#### Attributes +* `label` - optional attribute, new n-wise name; +* `metaInfo` - optional attribute, new n-wise meta-information. + +The transaction MUST be signed by the owner's public key. + +### NewOwnerTx + +The transaction is intended to transfer the owner role to another user. The old owner simultaneously becomes a regular user. + +```json +{ + "type": "newOwnerTx", + "did": "did:bob" +} +``` + +#### Attributes +* `did` required attribute, new owner's DID. + +The transaction MUST be signed by the owner's public key. + +### ledger-update-notify + +The message is intended to notify participants about the modifications of the n-wise state. + +```json +{ + "@id": "4287428424", + "@type": "https://didcomm.org/n-wise/1.0/ledger-update-notify" +} +``` + +## Drawbacks + +- External DLT is required; +- The user hierarchy is quite primitive. + +## Rationale and alternatives +Public DID methods use blockchain networks or other public storages for its DID Documents. [Peer DID](https://identity.foundation/peer-did-method-spec/) rejects the use of external storage, which is absolutely justified for a pairwise relationship, since a DID Document can be stored by the other participant. If there are more than two participants, consensus on the list of DID Documents is required. N-wise is somewhat of a middle ground between a Peer DID (DID document is stored only by a partner) and a public DID (DID document is available to everyone in the internet). So, the concept of n-wise state registry was introduced in this RFC, and its specific implementations (consensus between participants or a third-party trusted registry) remain at the discretion of the n-wise creator. The concept of [microledger](https://github.com/the-human-colossus-foundation/microledger-spec/blob/main/microledger.md) is also considerable to use for the n-wise state registry. + +One more promising high-level concept for building n-wise protocols is +[Gossyp](https://github.com/dhh1128/didcomm.org/tree/gossyp/gossyp). + +## Prior art + +The term of n-wise was proposed in [Peer DID](https://identity.foundation/peer-did-method-spec/) specification, and previously discussed in [document](https://docs.google.com/document/d/1BjYdivGQ9GxIz9CJ2ymNvMA68uHZm8bFOTyCHDmziOU/edit#). However, no strict formalization of this process was proposed, as well as the need for consensus between the participants was not noted. + +## Unresolved questions + +* Who should be responsible for the order of transactions? +* How to define specific n-wise state registry implementations (separate RFCs?) +* How to make a flexible user hierarchy? + +## Implementations +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +Name / Link | Implementation Notes +--- | --- +[Sirius SDK Java](https://github.com/Sirius-social/sirius-sdk-java/) | [IOTA Ledger](https://www.iota.org/) based implementation ([IOTA n-wise registry spec](https://github.com/Sirius-social/docs/blob/main/specs/iota-n-wise-registry.md)). See a detailed [example](https://github.com/Sirius-social/Notebooks/blob/main/notebooks/NwiseJava.ipynb) in Jupyter notebook. diff --git a/features/0748-n-wise-did-exchange/add_participant.png b/features/0748-n-wise-did-exchange/add_participant.png new file mode 100644 index 000000000..2fca39cff Binary files /dev/null and b/features/0748-n-wise-did-exchange/add_participant.png differ diff --git a/features/0755-oca-for-aries/OCA4Aries.xlsx b/features/0755-oca-for-aries/OCA4Aries.xlsx new file mode 100644 index 000000000..28b6fc184 Binary files /dev/null and b/features/0755-oca-for-aries/OCA4Aries.xlsx differ diff --git a/features/0755-oca-for-aries/OCA4AriesBundle.json b/features/0755-oca-for-aries/OCA4AriesBundle.json new file mode 100644 index 000000000..27d1ac295 --- /dev/null +++ b/features/0755-oca-for-aries/OCA4AriesBundle.json @@ -0,0 +1,231 @@ +[ + { + "capture_base": { + "attributes": { + "birthdate_dateint": "DateTime", + "country": "Text", + "expiry_date_dateint": "DateTime", + "family_name": "Text", + "given_names": "Text", + "issuing_jurisdiction": "Text", + "locality": "Text", + "picture": "Binary", + "postal_code": "Text", + "region": "Text", + "street_address": "Text" + }, + "classification": "", + "digest": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "flagged_attributes": [ + "given_names", + "family_name", + "birthdate_dateint", + "street_address", + "locality", + "region", + "postal_code", + "country", + "picture", + "expiry_date_dateint" + ], + "type": "spec/capture_base/1.0" + }, + "overlays": [ + { + "attribute_character_encoding": { + "birthdate_dateint": "utf-8", + "country": "utf-8", + "expiry_date_dateint": "utf-8", + "family_name": "utf-8", + "given_names": "utf-8", + "issuing_jurisdiction": "utf-8", + "locality": "utf-8", + "picture": "base64", + "postal_code": "utf-8", + "region": "utf-8", + "street_address": "utf-8" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "default_character_encoding": "utf-8", + "digest": "Ek-rB1QH1LWWFp21WtxjO-eaCzIHm1jL3QTXqTc5CYiQ", + "type": "spec/overlays/character_encoding/1.0" + }, + { + "attribute_categories": [], + "attribute_labels": { + "birthdate_dateint": "Date of Birth", + "country": "Country", + "expiry_date_dateint": "Expiry Date", + "family_name": "Family Name", + "given_names": "Given Names", + "issuing_jurisdiction": "Issuing Jurisdiction", + "locality": "Locality", + "picture": "Photo (if issued)", + "postal_code": "Postal Code", + "region": "Region", + "street_address": "Street Address" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "category_labels": {}, + "digest": "EZlM7u7Waz53UZQqWnbK1t11PC_sLBaV03esGRg9EvP8", + "language": "en-CA", + "type": "spec/overlays/label/1.0" + }, + { + "attribute_information": { + "birthdate_dateint": "The date of birth of the person", + "country": "The country code of the person's address", + "expiry_date_dateint": "The expiry date of this [credential / ID]", + "family_name": "The legal family name of the person", + "given_names": "The legal first name(s) of the person", + "issuing_jurisdiction": "The jurisdiction (province, territory, or federal) that issued this [credential / ID]", + "locality": "The city name or locality name of the person's address", + "picture": "A verified photo of the person (if issued)", + "postal_code": "The postal code of the person's address", + "region": "For Canadian addresses, the province or territory of the person's address. For other countries, the regional code of the person's address.", + "street_address": "The full address of the person, excluding locality, region, and postal code" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EgbEwEyKPpfkzJyb4TKHUfRKUpY-EuvJEQxDPSIg-PeU", + "language": "en-CA", + "type": "spec/overlays/information/1.0" + }, + { + "attribute_categories": [], + "attribute_labels": { + "birthdate_dateint": "Date de naissance", + "country": "Pays", + "expiry_date_dateint": "Date d'expiration", + "family_name": "Nom de famille", + "given_names": "Prénoms", + "issuing_jurisdiction": "Autorité de délivrance", + "locality": "Localité", + "picture": "Photo (si délivrée)", + "postal_code": "Code postal", + "region": "Région", + "street_address": "Adresse municipale" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "category_labels": {}, + "digest": "E-8GcJ-wUUkea3cYV-7jzVNYV2Lb9gkAbfmQzmxCPyQU", + "language": "fr-CA", + "type": "spec/overlays/label/1.0" + }, + { + "attribute_information": { + "birthdate_dateint": "La date de naissance de la personne", + "country": "Le code du pays de l'adresse de la personne", + "expiry_date_dateint": "La date d'expiration de ce/cette [justificatif / pièce d'identité].", + "family_name": "Le nom de famille légal de la personne", + "given_names": "Le ou les prénoms légaux de la personne", + "issuing_jurisdiction": "L'autorité (province, territoire ou fédéral) qui a délivré ce/cette [justificatif / pièce d'identité]", + "locality": "Le nom de la ville ou de la localité de l'adresse de la personne", + "picture": "Une photo vérifiée de la personne (si délivrée)", + "postal_code": "Le code postal de l'adresse de la personne", + "region": "Pour les adresses canadiennes, la province ou le territoire de l'adresse de la personne. Pour les autres pays, l’indicatif régional de l'adresse de la personne", + "street_address": "L'adresse complète de la personne, sans la localité, la région et le code postal" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EPukcZklEiGw87fzn2WD6o7mgDcM-wVvTs327JMLnT_s", + "language": "fr-CA", + "type": "spec/overlays/information/1.0" + }, + { + "attribute_formats": { + "birthdate_dateint": "YYYYMMDD", + "expiry_date_dateint": "YYYYMMDD", + "picture": "image/jpeg" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EbDQxonRzsXsZxMeflemhNSbaV3FZon6C114U4jdPc24", + "type": "spec/overlays/format/1.0" + }, + { + "attribute_standards": { + "birthdate_dateint": "urn:iso:std:iso:1989", + "expiry_date_dateint": "urn:iso:std:iso:1989" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "ExyElGOmvaHOBtZhOTnNlpblsqpDUcb3xE_qxWgO-GCc", + "type": "spec/overlays/standard/1.0" + }, + { + "attribute_entry_codes": { + "issuing_jurisdiction": [ + "BC", + "ON", + "QC" + ] + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "E8C3mJfLUPM0tasawt7FeuhiTvxQ7QDPaGBRCEpKfvJU", + "type": "spec/overlays/entry_code/1.0" + }, + { + "attribute_entries": { + "issuing_jurisdiction": { + "BC": "Colombie-Britannique", + "ON": "Ontario", + "QC": "Québec" + } + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EDeOfI580ee7MDfRriE9FxMoY0VDOOvsRyXEafw_yL0Y", + "language": "fr-CA", + "type": "spec/overlays/entry/1.0" + }, + { + "attribute_entries": { + "issuing_jurisdiction": { + "BC": "British Columbia", + "ON": "Ontario", + "QC": "Québec" + } + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "Ej5eE3PhtzglfUMIO9-cmPWYnZcgk7Q9kQG4RuqPY4I8", + "language": "en-CA", + "type": "spec/overlays/entry/1.0" + }, + { + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "credential_help_text": "Example credential help text.", + "credential_support_url": "https://www.gov.bc.ca/", + "description": "A Canadian schema used for the identity of a person", + "digest": "EhGmnV8_T-Gw646j8r8kI2RHRVv6Znx8XrOPFKoLnRR8", + "issuer": "Government of British Columbia", + "issuer_description": "Government of British Columbia", + "issuer_url": "https://www.gov.bc.ca/", + "language": "en-CA", + "name": "Person Credential", + "type": "spec/overlays/meta/1.0" + }, + { + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "credential_help_text": "Exemple de texte d'aide sur les informations d'identification.", + "credential_support_url": "https://www.gov.bc.ca/", + "description": "Schéma canadien utilisé pour l'identité d'une personne", + "digest": "EboSiMc4qQKjoRKkQuBiBZbDoZxnP4XLn7yaY6NDHOGA", + "issuer": "Gouvernement de la Colombie-Britannique", + "issuer_description": "Gouvernement de la Colombie-Britannique", + "issuer_url": "https://www.gov.bc.ca/", + "language": "fr-CA", + "name": "Informations d'identification de la personne", + "type": "spec/overlays/meta/1.0" + }, + { + "logo": "https://raw.githubusercontent.com/swcurran/aries-rfcs/oca4aries/features/0755-oca-for-aries/best-bc-logo.png", + "background_image_slice": "https://raw.githubusercontent.com/swcurran/aries-rfcs/oca4aries/features/best-bc-background-image-slice.png", + "background_image": "https://raw.githubusercontent.com/swcurran/aries-rfcs/oca4aries/features/best-bc-background-image.png", + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "description": "", + "digest": "EBQbQEV6qSEGDzGLj1CqT4e6yzESjPimF-Swmyltw5jU", + "expiry_date_attribute": "expiry_date_dateint", + "name": "", + "primary_attribute": "family_name", + "secondary_attribute": "given_names", + "type": "aries/overlays/branding/1.0" + } + ] + } +] diff --git a/features/0755-oca-for-aries/OCA4AriesExcel.json b/features/0755-oca-for-aries/OCA4AriesExcel.json new file mode 100644 index 000000000..512b04b57 --- /dev/null +++ b/features/0755-oca-for-aries/OCA4AriesExcel.json @@ -0,0 +1,218 @@ +[ + { + "capture_base": { + "attributes": { + "birthdate_dateint": "DateTime", + "country": "Text", + "expiry_date_dateint": "DateTime", + "family_name": "Text", + "given_names": "Text", + "issuing_jurisdiction": "Text", + "locality": "Text", + "picture": "Binary", + "postal_code": "Text", + "region": "Text", + "street_address": "Text" + }, + "classification": "", + "digest": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "flagged_attributes": [ + "given_names", + "family_name", + "birthdate_dateint", + "street_address", + "locality", + "region", + "postal_code", + "country", + "picture", + "expiry_date_dateint" + ], + "type": "spec/capture_base/1.0" + }, + "overlays": [ + { + "attribute_character_encoding": { + "birthdate_dateint": "utf-8", + "country": "utf-8", + "expiry_date_dateint": "utf-8", + "family_name": "utf-8", + "given_names": "utf-8", + "issuing_jurisdiction": "utf-8", + "locality": "utf-8", + "picture": "base64", + "postal_code": "utf-8", + "region": "utf-8", + "street_address": "utf-8" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "default_character_encoding": "utf-8", + "digest": "Ek-rB1QH1LWWFp21WtxjO-eaCzIHm1jL3QTXqTc5CYiQ", + "type": "spec/overlays/character_encoding/1.0" + }, + { + "attribute_categories": [], + "attribute_labels": { + "birthdate_dateint": "Date of Birth", + "country": "Country", + "expiry_date_dateint": "Expiry Date", + "family_name": "Family Name", + "given_names": "Given Names", + "issuing_jurisdiction": "Issuing Jurisdiction", + "locality": "Locality", + "picture": "Photo (if issued)", + "postal_code": "Postal Code", + "region": "Region", + "street_address": "Street Address" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "category_labels": {}, + "digest": "EZlM7u7Waz53UZQqWnbK1t11PC_sLBaV03esGRg9EvP8", + "language": "en-CA", + "type": "spec/overlays/label/1.0" + }, + { + "attribute_information": { + "birthdate_dateint": "The date of birth of the person", + "country": "The country code of the person's address", + "expiry_date_dateint": "The expiry date of this [credential / ID]", + "family_name": "The legal family name of the person", + "given_names": "The legal first name(s) of the person", + "issuing_jurisdiction": "The jurisdiction (province, territory, or federal) that issued this [credential / ID]", + "locality": "The city name or locality name of the person's address", + "picture": "A verified photo of the person (if issued)", + "postal_code": "The postal code of the person's address", + "region": "For Canadian addresses, the province or territory of the person's address. For other countries, the regional code of the person's address.", + "street_address": "The full address of the person, excluding locality, region, and postal code" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EgbEwEyKPpfkzJyb4TKHUfRKUpY-EuvJEQxDPSIg-PeU", + "language": "en-CA", + "type": "spec/overlays/information/1.0" + }, + { + "attribute_categories": [], + "attribute_labels": { + "birthdate_dateint": "Date de naissance", + "country": "Pays", + "expiry_date_dateint": "Date d'expiration", + "family_name": "Nom de famille", + "given_names": "Prénoms", + "issuing_jurisdiction": "Autorité de délivrance", + "locality": "Localité", + "picture": "Photo (si délivrée)", + "postal_code": "Code postal", + "region": "Région", + "street_address": "Adresse municipale" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "category_labels": {}, + "digest": "E-8GcJ-wUUkea3cYV-7jzVNYV2Lb9gkAbfmQzmxCPyQU", + "language": "fr-CA", + "type": "spec/overlays/label/1.0" + }, + { + "attribute_information": { + "birthdate_dateint": "La date de naissance de la personne", + "country": "Le code du pays de l'adresse de la personne", + "expiry_date_dateint": "La date d'expiration de ce/cette [justificatif / pièce d'identité].", + "family_name": "Le nom de famille légal de la personne", + "given_names": "Le ou les prénoms légaux de la personne", + "issuing_jurisdiction": "L'autorité (province, territoire ou fédéral) qui a délivré ce/cette [justificatif / pièce d'identité]", + "locality": "Le nom de la ville ou de la localité de l'adresse de la personne", + "picture": "Une photo vérifiée de la personne (si délivrée)", + "postal_code": "Le code postal de l'adresse de la personne", + "region": "Pour les adresses canadiennes, la province ou le territoire de l'adresse de la personne. Pour les autres pays, l’indicatif régional de l'adresse de la personne", + "street_address": "L'adresse complète de la personne, sans la localité, la région et le code postal" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EPukcZklEiGw87fzn2WD6o7mgDcM-wVvTs327JMLnT_s", + "language": "fr-CA", + "type": "spec/overlays/information/1.0" + }, + { + "attribute_formats": { + "birthdate_dateint": "YYYYMMDD", + "expiry_date_dateint": "YYYYMMDD", + "picture": "image/jpeg" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EbDQxonRzsXsZxMeflemhNSbaV3FZon6C114U4jdPc24", + "type": "spec/overlays/format/1.0" + }, + { + "attribute_standards": { + "birthdate_dateint": "urn:iso:std:iso:1989", + "expiry_date_dateint": "urn:iso:std:iso:1989" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "ExyElGOmvaHOBtZhOTnNlpblsqpDUcb3xE_qxWgO-GCc", + "type": "spec/overlays/standard/1.0" + }, + { + "attribute_entry_codes": { + "issuing_jurisdiction": [ + "BC", + "ON", + "QC" + ] + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "E8C3mJfLUPM0tasawt7FeuhiTvxQ7QDPaGBRCEpKfvJU", + "type": "spec/overlays/entry_code/1.0" + }, + { + "attribute_entries": { + "issuing_jurisdiction": { + "BC": "Colombie-Britannique", + "ON": "Ontario", + "QC": "Québec" + } + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EDeOfI580ee7MDfRriE9FxMoY0VDOOvsRyXEafw_yL0Y", + "language": "fr-CA", + "type": "spec/overlays/entry/1.0" + }, + { + "attribute_entries": { + "issuing_jurisdiction": { + "BC": "British Columbia", + "ON": "Ontario", + "QC": "Québec" + } + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "Ej5eE3PhtzglfUMIO9-cmPWYnZcgk7Q9kQG4RuqPY4I8", + "language": "en-CA", + "type": "spec/overlays/entry/1.0" + }, + { + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "credential_help_text": "Example credential help text.", + "credential_support_url": "https://www.gov.bc.ca/", + "description": "A Canadian schema used for the identity of a person", + "digest": "EhGmnV8_T-Gw646j8r8kI2RHRVv6Znx8XrOPFKoLnRR8", + "issuer": "Government of British Columbia", + "issuer_description": "Government of British Columbia", + "issuer_url": "https://www.gov.bc.ca/", + "language": "en-CA", + "name": "Person Credential", + "type": "spec/overlays/meta/1.0" + }, + { + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "credential_help_text": "Exemple de texte d'aide sur les informations d'identification.", + "credential_support_url": "https://www.gov.bc.ca/", + "description": "Schéma canadien utilisé pour l'identité d'une personne", + "digest": "EboSiMc4qQKjoRKkQuBiBZbDoZxnP4XLn7yaY6NDHOGA", + "issuer": "Gouvernement de la Colombie-Britannique", + "issuer_description": "Gouvernement de la Colombie-Britannique", + "issuer_url": "https://www.gov.bc.ca/", + "language": "fr-CA", + "name": "Informations d'identification de la personne", + "type": "spec/overlays/meta/1.0" + } + ] + } +] diff --git a/features/0755-oca-for-aries/README.md b/features/0755-oca-for-aries/README.md new file mode 100644 index 000000000..9b2cbc0e6 --- /dev/null +++ b/features/0755-oca-for-aries/README.md @@ -0,0 +1,688 @@ +# 0755: Overlays Capture Architecture (OCA) For Aries + +- Authors: [Stephen Curran](mailto:swcurran@gmail.com) +- Status: [DEMONSTRATED](/README.md#demonstrated) +- Since: 2024-03-02 +- Status Note: Implemented in the [Bifold Wallet](https://github.com/openwallet-foundation/bifold-wallet) +- Start Date: 2022-09-25 +- Version: 1.0 +- Tags: [feature](/tags.md#feature) + +## Summary + +[Overlays Capture Architecture](https://oca.colossi.network/) (OCA) is, per the +[OCA specification], a "standardized global solution for data capture and +exchange." Given a data structure (such as a verifiable credential), OCA allows +for the creation of purpose-specific overlays of information about that data +structure. Each overlay provides some knowledge (human and machine-readable) +about the overall data structure or the individual attributes within it. The +information in the overlays makes it possible to create useful software for +capturing data, displaying it and exchanging it. While the [OCA +website](https://oca.colossi.network/) and [OCA specification] can be reviewed +for a detailed background of OCA and its various purposes, in this RFC we'll +focus on its purpose in Aries, which is quite constrained and pragmatic--a +mechanism for an issuer to provide information about a verifiable credential to +allow holder and verifier software to display the credential in a human-friendly +way, including using the viewers preferred language, and the issuer's preferred +branding. The image below shows an Aries mobile Wallet displaying the same +credential without and with OCA overlays applied in two languages. All of the +differences in the latter two screenshots from the first come from +issuer-supplied OCA data. + +[OCA Specification]: https://oca.colossi.network/specification/ +[RFC0756 OCA for Aries Style Guide]: ../../features/0756-oca-for-aries-style-guide/README.md + +![Example: Using OCA in Aries Bifold](assets/bifold-oca-example.jpg) + +This RFC formalizes how Aries verifiable credential issuers can make a JSON [OCA +Bundle] (a set of related OCA overlays about a base data structure) available to +holders and verifiers that includes the following information for each type of +credential they issue. + +- Metadata about the credential, such as the Classification system upon which + the credential is based. +- Metadata about the credential in multiple languages, such as its name, + description, the name and description of the issuer and so on. +- Type, format, encoding, standard and units information about the credential's raw + attribute data. +- Metadata about the attributes within the credential in multiple languages, + such as a label and help text. +- A set of branding elements (logo, background image, color and so on) that + holder and verifier software are expected to use in displaying the credential. + +The standard flow of data between participants is as follows: + +- An issuer creates an OCA Bundle for each type of verifiable credential it +issues. +- During credential issuance using [RFC 0453 Issue Credential V2 v2.2 (or later) +protocol] the issuer MAY include in the protocol's `credential-offer` or +`credential` messages the OCA Bundle for the credential type as an `oca-bundle` +[issue credential supplement]. +- When provided, the holder software has full access to the OCA information +published by that issuer and can use the OCA data to render the credential for +its user(s) in the language of their choice, with credential branding from +the issuer, based on the [RFC0756 OCA for Aries Style Guide]. +- The holder MAY share the OCA Bundle with a verifier by using [RFC 0453 Issue +Credential V2 v2.2 (or later) protocol] to add the `oca-bundle` credential +supplement received from the issuer. +- On receipt, the verifier software has full access to the OCA information +published by that issuer and can use the OCA data to render the credential for +its user(s) in the language of their choice, with credential branding from +the issuer, based on the [RFC0756 OCA for Aries Style Guide]. + +[RFC 0453 Issue Credential V2 v2.2 (or later) +protocol]: https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2#22---addition-of-supplements +[issue credential supplement]: https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2#supplements +[OCA Bundle]: https://oca.colossi.network/specification/#bundle + +While the issuer providing the OCA Bundle for a credential type using the +credential supplement mechanism is the typical flow (as detailed in this RFC), +other flows, outside of the scope of this RFC are possible. See the [rationale +and alternatives section of this RFC for some +examples](#rationale-and-alternatives). + +## Motivation + +The core data models for verifiable credentials are more concerned about the +correct cryptographic processing of the credentials than about general +processing of the attribute data, and the user experience of those using +credentials. An AnonCreds verifiable credential contains the bare minimum of +metadata about a credential--basically, just the developer-style names for the +type of credential and the attributes within it. JSON-LD-based verifiable +credentials has the capacity to add more information about the attributes in a +credential, but the data is not easily accessed and is provided to enable +machine processing rather than improving user experience. + +OCA allows credential issuers to declare information about the verifiable +credential types it issues to improve the handling of those credentials by +holder and verifier Aries agents, and to improve the on-screen display of the +credentials, through the application of issuer-specified branding elements. + +## Tutorial + +The tutorial section of this RFC defines the coordination necessary for an +the creation, publishing, retrieval and use of an OCA Bundle for a given +type of verifiable credential. + +``` Note + +In this overview, we assume the the use of OCA specifically for verifiable +credentials, and further, specifically for AnonCreds verifiable credentials. OCA +can also be used be applied to any data structure, not just verifiable +credentials, and for other verifiable credential models, such as those based on +the JSON-LD- or JWT-style verifiable credentials. As the Aries +community applies OCA to other styles of verifiable credential, we +will extend this RFC. + +``` + +### Issuer Activities + +The use of OCA as defined in this RFC begins with an issuer preparing an [OCA +Bundle] for each type of credential they issue. An OCA Bundle is a JSON data +structure consisting of the [Capture Base], and some additional overlays of +different types (listed in the [next section](#oca-specification-overlays)). + +While an OCA Bundle can be manually maintained in an OCA Bundle JSON file, a +common method of maintaining OCA source data is to use a spreadsheet, and +generating the OCA Bundle from the Excel source. See the section of this RFC +called [OCA Tooling](#oca-issuer-tools) for a link to an OCA Source spreadsheet, +and information on tools available for managing the OCA Source data and +generating a corresponding OCA Bundle. + +The creation of the OCA Bundle and the configuration of the issuer's Aries +Framework to deliver the OCA Bundle during credential issuance should be all +that a specific issuer needs to do in using OCA for Aries. An Aries Framework +that supports OCA for Aries should handle the rest of the technical +requirements. + +#### OCA Specification Overlays + +All OCA data is based on a [Capture Base], which defines the data structure +described in the overlays. For AnonCreds, the Capture Base attributes MUST be +the list of attributes in the AnonCreds schema for the given credential type. +The Capture Base also MUST contain: + +- the type of each attribute, based on an enumerated list of [types defined in + the OCA + specification](https://oca.colossi.network/v1.1.0-rc.html#attribute-type) +- a list of the base attributes that will hold Personally Identifiable +Information (PII) in an issued credential. An issuer SHOULD use the [Kantara +Initiative's Blinding Identity +Taxonomy](https://docs.kantarainitiative.org/Blinding-Identity-Taxonomy-Report-Version-1.0.html) +to identify the attributes to flag as being PII. + +With the Capture Base defined, the following additional overlay types MAY be +created by the Issuer and SHOULD be expected by holders and verifiers. +Overlay types flagged "multilingual" may have multiple instances of the overlay, +one for each issuer-supported language (e.g en for English, fr French, SP +Spanish, etc.) or country-language (e.g., en-CA for Canadian English, fr-CA for +Canadian French), as defined in the [OCA Specification about +languages](https://oca.colossi.network/specification/#language). + +An OCA Bundle that contains overlay types that a holder or verifier does not +expect MUST be processed, with the unexpected overlays ignored. + +- The **[Character Encoding Overlay]** contains the encoding for each attribute +in the capture base. +- The **[Format Overlay]** provides +the input structure for each data attribute. The format may be useful to the +holder (or verifier) in displaying the data in a style expected by the user, +such as knowing that a given field of `type` binary is an image in `image/jpeg` +format. +- The multilingual **[Label Overlay]** provides a label to be used for each +attribute for a given language. The label overlay also includes labels for +attributes with enumerated values (called categories in the OCA specification). +For example, a data attribute containing the codes "EN", "FR", "SP" could have a +category entries that indicate the codes correspond to "English", "French" and +"Spanish", respectively. +- The multilingual **[Information Overlay]** provides a description or help text +about each attribute for a given language. There will be one overlay per +issuer-supported language. +- The multilingual **[Meta Overlay]** contains information about the credential +itself. For Aries, the meta overlay SHOULD include the following additional +name/value pairs, specific to the OCA for Aries use case: + - `name` - the name of the credential. + - `description` - a description of the credential. + - `issuer` - the name of the issuer of the credential. + - `issuer_description` - a description for the issuer of the credential. + - `issuer_url` - a URL for the issuer of the credential. + - `credential_help_text` - help text about the credential + - `credential_support_url` - a URL for a service providing support in the use of the credential. +- The **[Unit Overlay]** + allows the issuer to declare the units of measurement for the attributes in + the overlay. +- The **[Standard Overlay]** indicates that some or all of the attributes use + specific data standards populating the attribute in a credential. This might + be used, for example, for defining the standard applied in populating a data + attribute with a date or date/time. +- The **[Entry Code Overlay]** contains a list of enumerated values for each + data attribute that uses enumerated values. An example might be a list of + regional jurisdiction (such as provinces or states) short forms that will be + placed in an attribute (e.g., NY, ND, AL, CA, etc.). The attributes in the + credential are expected to be populated with one of the enumerated values. +- The **[Entry Overlay]** contains a language-specific list of the meanings for + each enumerated value for each data attribute that uses enumerated values. For + our example of short forms of jurisdictions, the "meanings" would be the + expanded list per language supported (English, French, Spanish, etc.) of + jurisdictions (e.g., New York, North Dakota, Alabama, California, etc.). + +[Capture Base]: https://oca.colossi.network/v1.1.0-rc.html#capture-base +[Character Encoding Overlay]: https://oca.colossi.network/v1.1.0-rc.html#character-encoding-overlay +[Format Overlay]: https://oca.colossi.network/v1.1.0-rc.html#format-overlay +[Label Overlay]: https://oca.colossi.network/v1.1.0-rc.html#label-overlay +[Information Overlay]: https://oca.colossi.network/v1.1.0-rc.html#information-overlay +[Meta Overlay]: https://oca.colossi.network/v1.1.0-rc.html#meta-overlay +[Unit Overlay]: https://oca.colossi.network/specification/#unit-overlay +[Standard Overlay]: https://oca.colossi.network/specification/#standard-overlay +[Entry Code Overlay]: https://oca.colossi.network/specification/#entry-code-overlay +[Entry Overlay]: https://oca.colossi.network/specification/#entry-overlay + +#### Aries-Specific Dates in the OCA Format Overlay + +In AnonCreds, zero-knowledge proof (ZKP) predicates (used, for example, to prove +older than a given age based on date of birth without sharing the actual date of +birth) must be based on **integers**. In the AnonCreds/Aries community, common +ways for representing dates and date/times as integers so that they can be used +in ZKP predicates are the `dateint` and `Unix Time` formats, respectively. + +- "`dateint`" is a credential attribute that uses the Aries `dateint` +specification as described in [Aries RFC +0592](../0592-indy-attachments/README.md). Briefly, `dateint` is a date +(YYYYMMDD) provided in a credential attribute as an integer (for example +`September 29, 2022` is the integer `20220929` or `20,220,929`). `dateint` is +also part of [ISO standard 1989 for COBOL Programming +Interfaces](https://www.iso.org/standard/74527.html), described [here in an IBM +document](https://www.ibm.com/docs/en/cobol-zos/6.3?topic=sf-format-arguments-return-values-date-time-intrinsic-functions#INFFORM__stand_date). + +- "`Unix Time`" is a credential attribute that is a date/time timestamp +constructed according to the `Unix Time` [Unix/POSIX data +standard](https://en.wikipedia.org/wiki/Unix_time). Briefly, `Unix Time` is a +date/time represented as the number of seconds since January 1, 1970 UTC. + +In an OCA for Aries OCA Bundle, a `dateint` and `Unix Time` attributes MUST +have the following values in the indicated overlays: + +- `dateint` + - datatype `DateTime` in the [Capture Base] + - standard `urn:iso:std:iso:1989` in the [Standard Overlay] + - character encoding `utf-8` in the [Character Encoding Overlay] + - format `YYYYMMDD` in the [Format Overlay] + - Example: `20230114` for "January 14, 2023" +- `Unix Time` + - datatype `DateTime` in the [Capture Base] + - standard `urn:unix:unix-time` in the [Standard Overlay] + - character encoding `utf-8` in the [Character Encoding Overlay] + - format `epoch` in the [Format Overlay] + - Example: `1673715495` for "Sat Jan 14 2023 16:58:15 GMT+0000" + +A recipient of an OCA Bundle with the combination of overlay values referenced +above for `dateint` and `Unix Time` SHOULD convert the integer attribute data +into a date or date/time (respectively) and display the information as +appropriate for the user. For example, a mobile app should display the data as a +date or date/time based on the user's language/country setting and timezone, +possibly combined with an app setting for showing the data in [short, medium, +long or full +form](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat). + +#### Aries Specific "branding" Overlay + +In addition to the core OCA Overlays listed earlier, Aries issuers MAY include +an additional Aries-specific extension overlay, the **"branding" overlay**, that +gives the issuer a way to provide a set of data elements about the branding that +they would like to see applied to a given type of credential. The `branding +overlay` is similar to the multilanguage Meta overlay (e.g. ones for English, +French and Spanish), with a specified set of name/value pairs. Holders (and +verifiers) use the branding values from the issuer when rendering a credential +of that type according the [RFC0756 OCA for Aries Style Guide]. + +An example of the use of the branding overlay is as follows, along with a +definition of the name/value pair elements, and a sample image of how the +elements are to be used. The sample is provide only to convey the concept of the +branding overlay and how it is to be used. Issuers, holders and verifiers should +refer to [RFC0756 OCA for Aries Style Guide] for details on how the elements are to +be provided and used in displaying credentials. + +``` +{ + "type": "aries/overlays/branding/1.0" + "digest": "EBQbQEV6qSEGDzGLj1CqT4e6yzESjPimF-Swmyltw5jU", + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "logo": "https://raw.githubusercontent.com/hyperledger/aries-rfcs/oca4aries/features/0755-oca-for-aries/best-bc-logo.png", + "background_image": "https://raw.githubusercontent.com/hyperledger/aries-rfcs/oca4aries/features/best-bc-background-image.png", + "background_image_slice": "https://raw.githubusercontent.com/hyperledger/aries-rfcs/oca4aries/features/best-bc-background-image-slice.png", + "primary_background_color": "#003366", + "secondary_background_color": "#003366", + "secondary_attribute": "given_names", + "primary_attribute": "family_name", + "secondary_attribute": "given_names", + "issued_date_attribute": "", + "expiry_date_attribute": "expiry_date_dateint", +} +``` + +![Sample: Using the Branding Overlay, from the Aries Credential Branding Style +Guide](assets/Sample-use-of-Branding-Overlay.png) + +[hashlink]: https://datatracker.ietf.org/doc/html/draft-sporny-hashlink +[Data URL Scheme]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs + +- OCA Overlay-related items: + - `type` - a the type of the overlay, using the `aries` namespace. + - `digest` - the self-addressing identifier (SAID) for the overlay. Note that in this example, the SAID is not accurate for the data in the example. + - `capture_base` - the self-addressing identifier (SAID) for the capture base to which this overlay applies. +- `logo` - a URI for a logo to display on the credential in some contexts. +The URI can be an HTTP URL, a [hashlink] or, to support inline images, a data +URL (e.g.: `data:image/png;base64,...`) as defined by the [Data URL Scheme]. The +logo MUST adhere to the logo properties defined in [RFC0756 OCA for Aries Style Guide]. +- `background_image` - a URI for a background image to display with the +credential in some contexts. The URI could be an HTTP URL, a [hashlink] or, to +support inline images, a data URL (e.g.: `data:image/png;base64,...`) as defined +by the [Data URL Scheme]. The image MUST adhere to the background image +properties defined in [RFC0756 OCA for Aries Style Guide]. +- `background_image_slice` - a URI for a background image slice to display +with the credential in some contexts. The URI could be a HTTP URL, a [hashlink] +or, to support inline images, a data URL (e.g.: `data:image/png;base64,...`) as +defined by the [Data URL Scheme]. The image MUST adhere to the background image slice +properties defined in [RFC0756 OCA for Aries Style Guide]. +- `primary_background_color` - hex color code for the primary background color of the + credential to be used in some contexts. +- `secondary_background_color` - hex color code for the secondary background color of the + credential to be used in some contexts. +- `primary_attribute` - the name of a capture base attribute to be displayed on + the credential in some contexts. +- `secondary_attribute` - the name of a capture base attribute to be displayed on + the credential in some contexts. +- `issued_date_attribute` - the name of a capture base attribute that is the date + of issuance of the credential. If there is no such attribute, leave blank. +- `expiry_date_attribute` - the name of a capture base attribute that is the + expiry date of the credential. If there is no such attribute, leave blank. + +It is deliberate that the credential branding defined in this RFC does **not** +attempt to achieve pixel-perfect on screen rendering of the equivalent paper +credential. There are two reasons for this: + +- First, studies have shown that issuers do not want people to think that the +digital credentials they have in their mobile wallet can be used as literal +replacements for paper during person-to-person (non-digital) verifications by +the holder showing their mobile device screen to the verifier. By showing +verifiers their screen, the holder may be oversharing their personal data. As +well, digital credentials are even easier to forge than paper credentials when +they are to be verified by a human, and we want to discourage using digital +credentials in that way. +- Second, having each issuer provide pixel-perfect layout guidance to Aries agents +that supports a responsive user interface on a wide range of devices (laptops, +tablets and thousands of mobile phones) is extraordinarily complex. Further, a +wallet wanting to provide a consistent, helpful user experience will be severely +hampered by displaying credentials with many (perhaps hundreds) of completely +different credential layouts and styles. + +Instead, the guidance in this RFC and the [RFC0756 OCA for Aries Style Guide] +gives the issuer a few ways to brand their credentials, and holder/verifier apps +information on how to use those issuer-provided elements in a manner consistent +for all issuers and all credentials. + +#### OCA Issuer Tools + +An Aries OCA Bundle can be managed as pure JSON as found in this [sample OCA for +Aries OCA Bundle]. However, managing such multilingual content in JSON is not +easy, particularly if the language translations come from team members not +comfortable with working in JSON. An easier way to manage the data is to use an +OCA source spreadsheet for most of the data, some in a source JSON file, and to +use a converter to create the OCA Bundle JSON from the two sources. We recommend +that an issuer maintain the spreadsheet file and source JSON in version control +and use a pipeline action to generate the OCA Bundle when the source files are +updated. + +The OCA Source Spreadsheet, an [example of which is attached to this +RFC](OCA4Aries.xlsx), contains the following: + +- An introductory tab about the OCA content in the spreadsheet. +- A tab with instructions on using the spreadsheet. +- A "Main" tab with the "Capture Base" data, along with data for other, non-multilingual overlays. +- A language or country-language code tab per country-language to be supported by the issuer + containing the source data for all multilingual overlays. + +The JSON Source file contains the [Aries-specific Branding +Overlay](#aries-specific-branding-overlay). Attached to this RFC is an [example +Branding Overlay JSON file](branding.json) that issuers can use to start. + +The following is how to create an OCA Source spreadsheet and from that, generate +an OCA Bundle. Over time, we expect that this part of the RFC will be clarified +as the tooling evolves. + +- Creating/Maintaining the Excel File + - Make a copy of the latest [OCA Template] from the [Human Colossus Foundation]. + - Fill in the "Main" tab with the attributes from the schema, completing the + relevant columns for each attribute. Current columns to complete: + - CB-CL: Classification + - CB-AN: Attribute Name + - CB-AT: Attribute Type + - CB-FA: Flagged Attribute + - OL-CH: Character Encoding + - OL-FT: Format + - OL-ST: Standard + - OL-EC: Entry Codes + - OL-UT: Unit + - As needed, populate the columns for "dateint" and "Unix Time" attributes as indicated in the [Aries Specific Dates in the OCA Formats Overlay](#aries-specific-dates-in-the-oca-format-overlay) section of this document. + - Rename the sample language tab (`en`) to one of the language or language-country that as an issuer, you want to support. + - Fill in the data in columns other than C (which is automatically populated from the `Main` tab) for the first language as appropriate. + - Populate column A and B as follows: + - In column A (`OL-MN: Meta [Attribute Name]`), add the values: + - "name" + - "description" + - "issuer" + - "issuer_description" + - "issuer_url" + - "credential_help_text" + - "credential_support_url" + - "watermark" + - The "watermark" is used to mark non-production credentials, as described in the ["non-production watermark" section of RFC0756 OCA for Aries Style Guide](../../features/0756-oca-for-aries-style-guide/README.md#non-production-watermark) + - Complete column B (`OL-MV: Meta [Attribute Value]`) as appropriate for each column A name (listed above). + - Duplicate and rename the initial language tab for each language or language-country that as an issuer, you want to support. + - Update each additional language tab. +- Creating/Maintaining the Branding JSON file + - Make a copy of the attached example [branding JSON file](branding.json), and update the values for the credential you are issuing. +- Generating the OCA Bundle from the OCA for Aries Source files: + - Use the open source [OCA Parser from the Human Colossus Foundation] to convert the + spreadsheet to JSON. The current command to use is `parser parse oca --path > ` + - Use the open source [jq utility](https://stedolan.github.io/jq/) to add the `branding.json` file to the JSON Excel output to produce the OCA Bundle with the following command, replacing the file names in the command with the ones for your use: + - `jq ".[].overlays += $(cat BRANDING-JSON-FILE)" OCA-EXCEL-FILE > OCA-BUNDLE-JSON-FILE` + - From a command line in this folder, the following command can be run to generate the OCA Bundle JSON to standard output: + - `jq ".[].overlays += $(cat branding.json)" OCA4AriesExcel.json` + +> NOTE: The `capture_base` and `digest` fields in the branding overlay of the resulting OCA Bundle JSON file will **not** be updated to be proper self-addressing identifiers (SAIDs) as required by the [OCA Specification]. We are looking into how to automate the updating of those data elements. + +[OCA Template]: https://github.com/THCLab/oca-ecosystem/raw/main/examples/template.xlsx + +Scripting the generation process should be relatively simple, and our expectation is that +the community will evolve the [Parser from the Human Colossus Foundation] to +simplify the process further. + +[sample OCA for Aries OCA Bundle]: ./sample_oca_for_aries_oca_bundle.json +[OCA Parser from the Human Colossus Foundation]: https://github.com/THCLab/oca-rust + +Over time, we expect to see other tooling become available--notably, a tool for +issuers to see what credentials will look like when their OCA Bundle is applied. + +#### Issuing A Credential + +> This section of the specification remains under consideration. The use of the +> `credential supplement` as currently described here is somewhat problematic +> for a number of reasons. +> +> - The issuer has no way to update the OCA Bundle for a given holder after +> issueance. We see this as a likely use case to enable, for example, an +> issuer supporting additional languages over time. +> - The "External Attachments" risk, as described in [this section of this +> RFC](#warning-external-attachments). +> - The complicated way for a verifier to get an OCA Bundle when needed after a +> presentation. +> +> We are currently investigating if an OCA Bundle can be published to the same +> VDR as holds an AnonCreds Schema or Credential Definition. We think that would +> overcome each of those concerns and make it easier to both publish and +> retrieve OCA Bundles. + +The currently preferred mechanism for an issuer to provide an OCA Bundle to a +holder is when issuing a credential using +[RFC0453 Issue Credential](../0453-issue-credential-v2/README.md), version 2.2 or later, the issuer +provides, in the [credential offer +message](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2/README.md#offer-credential), +an OCA Bundle as a [credential +supplement](https://github.com/hyperledger/aries-rfcs/tree/main/features/0453-issue-credential-v2/README.md#supplements). + +- The supplement type MUST be `oca-bundle`. +- The OCA Bundle MUST be in the JSON form of an OCA Bundle, not the ZIP format. +- The attachment MUST be +[signed](../../concepts/0017-attachments/README.md#signing-attachments) by the +issuer, and may be of [type +`base64url`](../../concepts/0017-attachments/README.md#base64url), meaning the +OCA Bundle is embedded in the message, or of [type +`link`](../../concepts/0017-attachments/README.md#links). + +The reason OCA Bundle attachment must be signed by the issuer so that if the holder +passes the OCA Bundle on to the verifier, the verifier can be certain that the +issuer provided the OCA Bundle, and that it was not created by a malicious holder. + +Issuers should be aware that to ensure that the signature on a linked OCA Bundle +(using the attachment [type `link`](../../concepts/0017-attachments/README.md#links)) +remains verifiable, the content resolved by the link must not change over time. +For example, an Issuer might publish their OCA Bundles in a public GitHub +repository, and send a link to the OCA Bundle during issuance. In that case the +Issuer is advised to send a commit-based GitHub URL, rather than a branch-based +reference. The Issuer may update the OCA Bundle sent to different holders over +time, but once issued, each OCA Bundle MUST remain accessible. + +#### Warning: External Attachments + +The use of an attachment of type `link` for the OCA Bundle itself, or the use of +external references to the images in the +[branding Overlay](#aries-specific-branding-overlay) could provide malicious issuers with +a mechanism for tracking the use of a holder's verifiable credential. +Specifically, the issuer could: + +- Make any or all of the OCA bundle external references a unique identifier for + the holder. +- When the holder retrieves the OCA bundle, the issuer does not learn anything + useful as they already know they have issued a credential to that holder. +- If the holder passes the OCA bundle to verifiers and the verifiers resolve the + external references, the malicious issuer would learn that the holder has used + their verifiable credential in a presentation, and perhaps, with what verifier. + +A holder MAY choose not to attach an OCA Bundle to a verifier if it contains any +external references. Non-malicious issuers are encouraged to **not** use +external references in their OCA Bundles and as such, to minimize the inlined +images in the branding overlay. + +### Holder Activities + +Before processing a credential and an associated OCA Bundle, the holder SHOULD +determine if the issuer is known in an ecosystem and has a sufficiently positive +reputation. For example, the holder might determine if the issuer is in a suitable [Trust Registry] +or request a presentation from the issuer about their identity. + +[Trust Registry]: https://wiki.trustoverip.org/display/HOME/ToIP+Trust+Registry+Protocol+Specification + +On receipt of a credential with an OCA Bundle supplement, the holder SHOULD +retrieve the OCA Bundle attachment, verify the signature is from the issuer's +public DID, verify the signature, and verify that the [OCA Capture Base] is for +the credential being offered or issued to the holder. If verified, the holder +should associate the OCA Bundle with the credential, including the signature. + +The holder SHOULD take appropriate security precautions in handling the +remainder of the OCA data, especially the images as they could contain a +malicious payload. The security risk is comparable to a browser receiving a web +page containing images. + +Holder software should be implemented to use the OCA Bundle when processing +and displaying the credential as noted in the list below. Developers of holder +software should be familiar with the overlays the issuer is likely to provide +(see list [here](#oca-specification-overlays)) and how to use them according to +[RFC0756 OCA for Aries Style Guide]. + +- Check the country and language settings of the current user and use the +appropriate multilingual overlays to respect those settings in displaying +credential metadata and attributes (labels, etc.). +- Consider adding multilingual informational popups in your app using the per + attribute data in the "information" overlay. +- Consider using the PII flag in the Capture Base to provide guidance to the + user about the sharing of PII. +- Use the branding overlay and [RFC0756 OCA for Aries Style Guide] in + displaying the credential in various contexts (e.g., in a credential offer + prompt, in a list, selected from a list, alone on a page, etc.). +- Process the attribute data using the `type`, `character encoding`, `format`, + `unit` and `standard` overlays and display tha attributes appropriately for a + given user. For example, display dates in a form suitable for the language and + country settings of the user. +- Where enumerated names are used for credential attributes, retrieve and use + the name-value pairs in the [Entry Code Overlay] and [Entry Overlay] to display the data. +- Use the OCA-provide metadata about the credential, such as the + name/description of the issuer, name/description of the credential type. + +A recommended tactic when adding OCA support to a holder is when a credential is +issued without an associated OCA Bundle, generate an OCA Bundle for the +credential using the information available about the type of the credential, +default images, and randomly generated colors. That allows for the creation of +screens that assume an OCA Bundle is available. The [RFC0756 OCA for Aries Style +Guide] contains guidelines for doing that. + +#### Adding OCA Bundles to Present Proof Messages + +Once a holder has an OCA Bundle that was issued with the credential, it MAY pass +the OCA Bundle to a verifier when a presenting a proof that includes claims from +that credential. This can be done via the [present proof credential supplements] +approach, similar to what used when the credential was issued to the holder. +When constructing the `present_proof` message to hold a proof, the holder would +iterate through the credentials in the proof, and if there is an issuer-supplied +OCA Bundle for the credentials, add the OCA Bundle as a supplement to the +message. The signature from the Issuer MUST be included with the supplement. + +A holder SHOULD NOT send an OCA Bundle to a verifier if the OCA Bundle is a +link, or if any of the data items in the OCA Bundle are links, as noted in the +in the [warning about external attachments in OCA +Bundles](#warning-external-attachments). + +[present proof credential supplements]: https://github.com/hyperledger/aries-rfcs/tree/main/features/0454-present-proof-v2#22---addition-of-supplements + +### Verifier Activities + +On receipt of a presentation with OCA Bundle supplements, the verifier SHOULD +retrieve the OCA Bundle attachments, verify the signatures are from the +credential issuers' public DIDs, verify the signatures, and verify that the [OCA +Capture Base] is for the credentials being presented to the verifier. If +verified, the verifier should associate the OCA Bundle with the source +credential from the presentation. + +On receipt of a presentation with OCA Bundle supplements, the verifier MAY +process the OCA Bundle attachment and verify the issuer's signature. If it +verifies, the verifier should associate the OCA Bundle with the source +credential from the presentation. The verifier SHOULD take appropriate security +precautions in handling the data, especially the images. The holder software +should be implemented to use the OCA Bundle when processing and displaying the +credential as noted in the list below. + +Developers of verifier software should be familiar with the overlays the issuer +is likely to provide (see list [here](#oca-specification-overlays)) and how to +use them according to [RFC0756 OCA for Aries Style Guide]. The list of [how to +use the OCA Bundle as a holder](#holder-activities) applies equally to +verifiers. + +## Reference + +- The [OCA Specification] +- [RFC0756 OCA for Aries Style Guide] + +## Drawbacks + +- The use of credential supplements might not be the best way to publish OCA + Bundles. The Aries community is currently investigating if OCA Bundles can be + published to the Verifiable Data Registry upon which the schema and credential + definition are published. +- As noted in this [warning](#warning-external-attachments), the use of links + either for OCA Bundles or for the images that are embedded in OCA Bundles are + both extremely useful and problematic. It would be nice to be able to allow + links for/in the OCA Bundles without the potential of being used to track the + holder. +- If the OCA Bundle is passed to the holder as a link, the issuer must continue + to make that content available for as long as the holder might retain the + credential. Putting the OCA Bundle on a verifiable data registry (such as a + ledger/blockchain) might be a good way to publish such data. +- The processing of an OCA Bundle, and particularly the processing of images in + the branding overlay, provide an attack vector for malicious issuers. + Developers of holder software SHOULD take precautions in handling and + displaying the data. + +## Rationale and alternatives + +- The OCA architecture seems well suited to the Aries verifiable credential +use case, supporting the important capabilities of data formats, accessibility +support, multilingual support and the desire for issuers to brand their +credentials. +- The use of JSON-LD could provide some of the required capabilities covered by +OCA (such as multilingual labels), but that solution requires adding +considerable overhead and far more complicated processing to achieve a minimum +of the capabilities available through OCA. +- The current situation of having almost no metadata about credentials is +extremely limiting. + - Extracting best available metadata from the Schema and Credential Definition + objects, converting developer attribute/credential names of human friendly + (e.g. "given_name" to Given Name, or "ssn" to "Ssn") and using that for the + display of a credential. + - The random generation of a background color for a given credential for use + when displaying a credential. +- There are other flows that could be used to get an OCA Bundle to holders and +verifiers. + - A publisher of a schema might also publish an OCA Bundle based on the +schema, for anyone to use. + - An Aries agent vendor (such as the creator of an Aries mobile wallet) might +create a repository of OCA Bundles of common credential types for deployments of +their agent. + - When using such alternatives, agents retrieving an OCA Bundle should have a +way to verify the source of the OCA Bundle, such as having a cryptographic +signature over the OCA Bundle from the designated publisher. + +## Prior art + +None, as far as we are aware. + +## Unresolved questions + +- Are there better ways for issuers to publish OCA Bundles for consumption by + holders/verifiers? +- How do we balance the prevention of possible tracking by issuers, and the use + of links to OCA Bundles or assets within OCA Bundles. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull +request to add your implementation. If the implementation is open source, +include a link to the repo or to the implementation within the repo. Please be +consistent in the "Name" field so that a mechanical processing of the RFCs can +generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | diff --git a/features/0755-oca-for-aries/assets/Sample-use-of-Branding-Overlay.png b/features/0755-oca-for-aries/assets/Sample-use-of-Branding-Overlay.png new file mode 100644 index 000000000..d1242b65b Binary files /dev/null and b/features/0755-oca-for-aries/assets/Sample-use-of-Branding-Overlay.png differ diff --git a/features/0755-oca-for-aries/assets/bifold-oca-example.jpg b/features/0755-oca-for-aries/assets/bifold-oca-example.jpg new file mode 100644 index 000000000..a2020578b Binary files /dev/null and b/features/0755-oca-for-aries/assets/bifold-oca-example.jpg differ diff --git a/features/0755-oca-for-aries/best-bc-background-image-slice.png b/features/0755-oca-for-aries/best-bc-background-image-slice.png new file mode 100644 index 000000000..babf3ec3b Binary files /dev/null and b/features/0755-oca-for-aries/best-bc-background-image-slice.png differ diff --git a/features/0755-oca-for-aries/best-bc-background-image.jpg b/features/0755-oca-for-aries/best-bc-background-image.jpg new file mode 100644 index 000000000..1a7c484fc Binary files /dev/null and b/features/0755-oca-for-aries/best-bc-background-image.jpg differ diff --git a/features/0755-oca-for-aries/best-bc-logo.png b/features/0755-oca-for-aries/best-bc-logo.png new file mode 100644 index 000000000..883a43412 Binary files /dev/null and b/features/0755-oca-for-aries/best-bc-logo.png differ diff --git a/features/0755-oca-for-aries/branding.json b/features/0755-oca-for-aries/branding.json new file mode 100644 index 000000000..c2e06b409 --- /dev/null +++ b/features/0755-oca-for-aries/branding.json @@ -0,0 +1,15 @@ +[ + { + "logo": "https://raw.githubusercontent.com/swcurran/aries-rfcs/oca4aries/features/0755-oca-for-aries/best-bc-logo.png", + "background_image_slice": "https://raw.githubusercontent.com/swcurran/aries-rfcs/oca4aries/features/best-bc-background-image-slice.png", + "background_image": "https://raw.githubusercontent.com/swcurran/aries-rfcs/oca4aries/features/best-bc-background-image.png", + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "description": "", + "digest": "EBQbQEV6qSEGDzGLj1CqT4e6yzESjPimF-Swmyltw5jU", + "expiry_date_attribute": "expiry_date_dateint", + "name": "", + "primary_attribute": "family_name", + "secondary_attribute": "given_names", + "type": "aries/overlays/branding/1.0" + } +] \ No newline at end of file diff --git a/features/0755-oca-for-aries/sample_oca_for_aries_oca_bundle.json b/features/0755-oca-for-aries/sample_oca_for_aries_oca_bundle.json new file mode 100644 index 000000000..940ad9870 --- /dev/null +++ b/features/0755-oca-for-aries/sample_oca_for_aries_oca_bundle.json @@ -0,0 +1,223 @@ +[ + { + "capture_base": { + "attributes": { + "birthdate_dateint": "DateTime", + "country": "Text", + "expiry_date_dateint": "DateTime", + "family_name": "Text", + "given_names": "Text", + "issuing_jurisdiction": "Text", + "locality": "Text", + "picture": "Binary", + "postal_code": "Text", + "region": "Text", + "street_address": "Text" + }, + "classification": "", + "digest": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "flagged_attributes": [ + "given_names", + "family_name", + "birthdate_dateint", + "street_address", + "locality", + "region", + "postal_code", + "country", + "picture", + "expiry_date_dateint" + ], + "type": "spec/capture_base/1.0" + }, + "overlays": [ + { + "attribute_character_encoding": { + "birthdate_dateint": "utf-8", + "country": "utf-8", + "expiry_date_dateint": "utf-8", + "family_name": "utf-8", + "given_names": "utf-8", + "issuing_jurisdiction": "utf-8", + "locality": "utf-8", + "picture": "base64", + "postal_code": "utf-8", + "region": "utf-8", + "street_address": "utf-8" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "default_character_encoding": "utf-8", + "digest": "Ek-rB1QH1LWWFp21WtxjO-eaCzIHm1jL3QTXqTc5CYiQ", + "type": "spec/overlays/character_encoding/1.0" + }, + { + "attribute_categories": [], + "attribute_labels": { + "birthdate_dateint": "Date de naissance", + "country": "Pays", + "expiry_date_dateint": "Date d'expiration", + "family_name": "Nom de famille", + "given_names": "Prénoms", + "issuing_jurisdiction": "Autorité de délivrance", + "locality": "Localité", + "picture": "Photo (si délivrée)", + "postal_code": "Code postal", + "region": "Région", + "street_address": "Adresse municipale" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "category_labels": {}, + "digest": "E-8GcJ-wUUkea3cYV-7jzVNYV2Lb9gkAbfmQzmxCPyQU", + "language": "fr-CA", + "type": "spec/overlays/label/1.0" + }, + { + "attribute_information": { + "birthdate_dateint": "La date de naissance de la personne", + "country": "Le code du pays de l'adresse de la personne", + "expiry_date_dateint": "La date d'expiration de ce/cette [justificatif / pièce d'identité].", + "family_name": "Le nom de famille légal de la personne", + "given_names": "Le ou les prénoms légaux de la personne", + "issuing_jurisdiction": "L'autorité (province, territoire ou fédéral) qui a délivré ce/cette [justificatif / pièce d'identité]", + "locality": "Le nom de la ville ou de la localité de l'adresse de la personne", + "picture": "Une photo vérifiée de la personne (si délivrée)", + "postal_code": "Le code postal de l'adresse de la personne", + "region": "Pour les adresses canadiennes, la province ou le territoire de l'adresse de la personne. Pour les autres pays, l’indicatif régional de l'adresse de la personne", + "street_address": "L'adresse complète de la personne, sans la localité, la région et le code postal" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EPukcZklEiGw87fzn2WD6o7mgDcM-wVvTs327JMLnT_s", + "language": "fr-CA", + "type": "spec/overlays/information/1.0" + }, + { + "attribute_categories": [], + "attribute_labels": { + "birthdate_dateint": "Date of Birth", + "country": "Country", + "expiry_date_dateint": "Expiry Date", + "family_name": "Family Name", + "given_names": "Given Names", + "issuing_jurisdiction": "Issuing Jurisdiction", + "locality": "Locality", + "picture": "Photo (if issued)", + "postal_code": "Postal Code", + "region": "Region", + "street_address": "Street Address" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "category_labels": {}, + "digest": "EZlM7u7Waz53UZQqWnbK1t11PC_sLBaV03esGRg9EvP8", + "language": "en-CA", + "type": "spec/overlays/label/1.0" + }, + { + "attribute_information": { + "birthdate_dateint": "The date of birth of the person", + "country": "The country code of the person's address", + "expiry_date_dateint": "The expiry date of this [credential / ID]", + "family_name": "The legal family name of the person", + "given_names": "The legal first name(s) of the person", + "issuing_jurisdiction": "The jurisdiction (province, territory, or federal) that issued this [credential / ID]", + "locality": "The city name or locality name of the person's address", + "picture": "A verified photo of the person (if issued)", + "postal_code": "The postal code of the person's address", + "region": "For Canadian addresses, the province or territory of the person's address. For other countries, the regional code of the person's address.", + "street_address": "The full address of the person, excluding locality, region, and postal code" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EgbEwEyKPpfkzJyb4TKHUfRKUpY-EuvJEQxDPSIg-PeU", + "language": "en-CA", + "type": "spec/overlays/information/1.0" + }, + { + "attribute_formats": { + "birthdate_dateint": "dateint", + "expiry_date_dateint": "dateint", + "picture": "image/jpeg" + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EpLFl6BPqESrirpFvZD4WmWs12B0nktGH5haGY68lGYY", + "type": "spec/overlays/format/1.0" + }, + { + "attribute_entry_codes": { + "issuing_jurisdiction": [ + "BC", + "ON", + "QC" + ] + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "E8C3mJfLUPM0tasawt7FeuhiTvxQ7QDPaGBRCEpKfvJU", + "type": "spec/overlays/entry_code/1.0" + }, + { + "attribute_entries": { + "issuing_jurisdiction": { + "BC": "Colombie-Britannique", + "ON": "Ontario", + "QC": "Québec" + } + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "EDeOfI580ee7MDfRriE9FxMoY0VDOOvsRyXEafw_yL0Y", + "language": "fr-CA", + "type": "spec/overlays/entry/1.0" + }, + { + "attribute_entries": { + "issuing_jurisdiction": { + "BC": "British Columbia", + "ON": "Ontario", + "QC": "Québec" + } + }, + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "digest": "Ej5eE3PhtzglfUMIO9-cmPWYnZcgk7Q9kQG4RuqPY4I8", + "language": "en-CA", + "type": "spec/overlays/entry/1.0" + }, + { + "background_image": "data:image/png;base64,iVBORw...", + "background_image_slide": "data:image/png;base64,iVBORw...", + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "description": "", + "digest": "E1nQd76Qx7LLbmqG0ZO--0IccL5xozK4_-J5oYLvSpNA", + "logo": "data:image/png;base64,iVBORw...", + "name": "", + "primary_attribute": "family_name", + "primary_background_color": "#2E86C1", + "secondary_attribute": "given_name", + "secondary_background_color": "#2E86C1", + "type": "aries/overlays/branding/1.0" + }, + { + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "credential_help_text": "Exemple de texte d'aide sur les informations d'identification.", + "credential_support_url": "https://www.gov.bc.ca/", + "description": "Schéma canadien utilisé pour l'identité d'une personne", + "digest": "EboSiMc4qQKjoRKkQuBiBZbDoZxnP4XLn7yaY6NDHOGA", + "issuer": "Gouvernement de la Colombie-Britannique", + "issuer_description": "Gouvernement de la Colombie-Britannique", + "issuer_url": "https://www.gov.bc.ca/", + "language": "fr-CA", + "name": "Informations d'identification de la personne", + "type": "spec/overlays/meta/1.0" + }, + { + "capture_base": "EKpcSmz06sJs0b4g24e0Jc7OerbJrGN2iMVEnwLYKBS8", + "credential_help_text": "Example credential help text.", + "credential_support_url": "https://www.gov.bc.ca/", + "description": "A Canadian schema used for the identity of a person", + "digest": "EhGmnV8_T-Gw646j8r8kI2RHRVv6Znx8XrOPFKoLnRR8", + "issuer": "Government of British Columbia", + "issuer_description": "Government of British Columbia", + "issuer_url": "https://www.gov.bc.ca/", + "language": "en-CA", + "name": "Person Credential", + "type": "spec/overlays/meta/1.0" + } + ] + } +] \ No newline at end of file diff --git a/features/0756-oca-for-aries-style-guide/README.md b/features/0756-oca-for-aries-style-guide/README.md new file mode 100644 index 000000000..dc1dc2e07 --- /dev/null +++ b/features/0756-oca-for-aries-style-guide/README.md @@ -0,0 +1,585 @@ +# 0756: OCA for Aries Style Guide + +- Authors: [Stephen Curran](mailto:swcurran@cloudcompass.ca) +- Status: [DEMONSTRATED](/README.md#demonstrated) +- Since: 2023-01-05 +- Status Note: Implemented in the [Bifold Wallet](https://github.com/openwallet-foundation/bifold-wallet) +- Supersedes: N/A +- Start Date: 2022-11-15 +- Version: 1.0 +- Tags: [feature](/tags.md#feature) + +[RFC0755 OCA for Aries]: ../0755-oca-for-aries/README.md + +## Summary + +Support for credential branding in Aries agents is provided by information +provided from the issuer of a given credential type using Overlays Capture +Architecture (OCA) overlays. Aries agents (software) use the issuer-provided OCA +data when displaying (rendering) the issuer’s credential on screens. This style +guide is for issuers to know what information to include in the OCA overlays and +how those elements will be used by holders and verifiers. The style guide is +also for Aries holder and verifier software makers about how to use the OCA data +provided from issuers for a given credential type. It is up to the software +makers to use OCA data provided by the issuers as outlined in this guide. + +For more information about the use of OCA in Aries, please see [RFC0755 OCA for +Aries] + +## Motivation + +OCA Bundles is intended to be used by ALL Aries issuers and ALL Aries Holders. Some +Aries verifiers might also use OCA Bundles. This Style Guide provides guidance for +issuers about what overlays to populate and with what information, and guidance +for holders (and verifiers) about how to use the OCA Bundle data provided by the +issuers when rendering Credentials on screen. + +* Issuers **SHOULD** follow this Style Guide in preparing an OCA Bundle for each + credential type they issue. Holders (and verifiers) **expect** issuers to follow + the guidance provided in this RFC. +* Holder creators (and verifiers) **SHOULD** follow this Style Guide in + rendering credentials for users. Issuers **expect** holders (and verifiers) to + follow the guidance provided in this RFC. + +Issuers, holders and verifiers expect other issuers, holders and verifiers to +follow this Style Guide. Issuers, holders and verifiers not following this Style +Guide will likely cause end users to see unpredictable and potential +"unfriendly" results when credentials are displayed. + +It is in the best interest of the Aries community as a whole for those writing +Aries agent software to use OCA Bundles and to follow this Style Guide in +displaying credentials. + +## Tutorial + +Before reviewing this Style Guide, please review and be familiar with [RFC0755 +OCA for Aries]. It provides the technical details about OCA, the issuer role in +creating an OCA Bundle and delivering to holders (and optionally, from holders +to verifiers) and the holders role in extracting information from the OCA Bundle +about a held credential. This Style Guide provides the details about what each +participant is expected to do in creating OCA Bundles and using the data in OCA +Bundles to render credentials on screen. + + + + + + + + + + +## OCA for Aries Style Guide + +A Credential User Interface (UI) pulls from a issuer-provided OCA Bundle the following elements: + + + +* **Meta Overlays (multilingual):** + * Credential name + * Issuer name + * Issuer description + * Issuer URL + * Credential help text + * Credential support URL + * Non-Production watermark +* **“branding” Overlay:** + * **_logo_** - a URI for an inline or external logo image to display with the credential. See details below about the use and requirements for the image. + * **_background_image_** - a URI for an inline or external background image to display with the credential. See details below about the use and requirements for the image. + * **_background_image_slice_** - a URI for an inline or external background image slice to display with the credential. See details below about the use and requirements for the image. + * **_primary_background_color_** - an RGB color code for the credential background + * **_secondary_background_color_** - an RGB color code for the credential background highlight background color. + * **_primary_attribute_** - the name of the primary capture base attribute to display \ +on the credential. + * **_secondary_attribute_** - the name of the secondary capture base attribute to \ +display on the credential. + * **_issued_date_attribute_** - the name of a capture base attribute that is the date of issuance of the credential. If there is no such attribute, leave it blank. + * **_expiry_date_attribute_** - the name of a capture base attribute that is the expiry date of the credential. If there is no such attribute, leave it blank. + + +### Credential Layouts + +This style guide defines three layouts for credentials, the credential list layout, the stacked list layout, and the single credential layout. Holders and verifiers SHOULD display credentials using only these layouts in the context of a screen containing either a list of credentials or a single credential, respectively. Holders and verifiers MAY display other relevant information on the page along with one of the layouts. + +The stacked list is the same as the credential layout, with the credentials that are stacked cutoff between elements 6 and 7. Examples of the stacked layout can be seen in the [Stacking](#heading=h.27voxgccn7kf) section of this document. In the Stacked layout, one of the credentials in the stack may be displayed using the full credential list layout. + + + + + + + + + + + +
+alt_text + + +alt_text + +
Credential List Layout + Single Credential Layout +
+ + +**_Figure: Credential Layouts_** + +The numbered items in the layouts are as follows. In the list, the OCA data element(s) is provided first, and, where the needed data element(s) is not available through an OCA Bundle, a calculation for a fallback is defined. It is good practice to have code that populates a per credential data structure with data from the credential’s OCA Bundle if available, and if not, populated by the fallbacks. That way, the credentials are displayed in the same way with or without an OCA Bundle per credential. Unless noted, all of the data elements come from the “branding” overlay. Items 10 and 11 are not included in the layouts but are included to document the fallbacks for those values. + + + +1. `logo` + * Fallback: First letter of the alias of the DIDComm connection +2. `background_image_slice` if present, else `secondary_background_color` + * Fallback: Black overlay at 24% opacity +3. `primary_background_color` + * Fallback: Randomly generated color +4. Credential Status derived from revocation status and expiry date (if available) + * Fallback: Empty +5. Meta overlay item `issuer_name` + * Fallback: Alias of the DIDComm connection +6. Meta overlay item `name` + * Fallback: The AnonCreds Credential Definition `tag`, unless the value is either `credential` or `default`, otherwise the AnonCreds `schema_name` attribute from the AnonCreds schema +7. `primary_attribute` + * Fallback: Empty +8. `secondary_attribute` + * Fallback: Empty +9. `background_image` if present, else `secondary_background_color` + * Fallback: Black overlay at 24% opacity (default) +10. `issued_date_attribute` + * Fallback: If tracked, the date the credential was received by the Holder, else empty. +11. `expiry_date_attribute` + * Fallback: Empty + + +![alt_text](images/image3.png "image_tooltip") + + +**_Figure: Template layers_** + +The font color is either black or white, as determined by calculating contrast levels (following [Web Content Accessibility Guidelines](https://www.w3.org/WAI/WCAG2AA-Conformance)) against the background colors from either the OCA Bundle or the generated defaults. + + + + + + + +
+alt_text + + +alt_text + +
+ + +**_Figure: example of a credential with no override specifications_** + + +### Logo Image Specifications + +The image in the top left corner is a space for the issuer logo. This space should not be used for anything other than the issuer logo. The logo image may be masked to fit within a rounded square with varying corner radii. Thus, the logo must be a square image (aspect ratio 1:1), as noted in the table below. The background is default white, therefore logo files with a transparent background will overlay a white background. + +The following are the specifications for the credential logo for issuers. + +Images should be as small as possible to balance quality and download speed. To ensure image quality on all devices, it is recommended to use vector based file types such as SVG. + + + + + + + + + + + + + + + + + + + +
Preferred file type + SVG, JPG, PNG with transparent background, +
Aspect ratio + 1:1 +
Recommended image size + 240x240 px +
Color space + RGB +
+ + + +### Background Image Slice Specifications + +For issuers to better represent their brand, issuers may specify an image slice that will be used as outlined in the samples below. Note the use of the image in a long, narrow space and the dynamic height. The image slice will be top aligned, scaled (preserving aspect ratio) and cropped as needed to fill the space. + +Credential height is dependent on the content and can be unpredictable. Different languages (English, French, etc.) will add more length to names, OS level settings such as font changes or text enlargement will unpredictably change the height of the credential. The recommended image size below is suggested to accommodate for most situations. Note that since the image is top aligned, the top area of the image is certain to be displayed, while the bottom section of the image may not always be visible. + + +![alt_text](images/image6.jpg "image_tooltip") + + +**_Figure: Examples of the image slice behavior_** + +Types of images best used in this area are abstract images or graphical art. Do not use images that are difficult to interpret when cropped. + + + + + + + + + + + +
+alt_text + + +alt_text + +
Do +

+Use an abstract image that can work even when cropped unexpectedly. +

Don’t +

+Use images that are hard to interpret when cropped. Avoid words +

+ + +**_Figure: Background image slice Do’s and Don’ts_** + + + + + + + + + + + + + + + + + + + +
Preferred file type + SVG, PNG, JPG +
Aspect ratio + 1:10 +
Recommended image size + 120x1200 px +
Color space + RGB +
+ + + +### Background Image Specifications + +The background image is to give issuers more opportunities to represent their brand and is used in some credential display screens. Avoid text in the background image. + + + + + + + + + + + +
+alt_text + + +alt_text + +
Do +

+Use an image that represents your brand. +

Don’t +

+Use this image as a marketing platform. Avoid the use of text. +

+ + +**_Figure: Background image Do’s and Don’ts_** + + + + + + + + + + + + + + + + + + + +
Preferred file type + SVG, PNG, JPG +
Aspect ratio + 3:1 +
Recommended image size + 1080x360 px +
Color space + RGB +
+ + + +### Credential Status + +To reduce visual clutter, the issued date (if present), expiry date (if present), and revocation status (if applicable) may be interpreted by an icon at the top right corner when: + + + +* A new credential has been added, based on _issued_date_attribute_, if set, or for a holder agent/wallet, the date the credential was received. +* A credential is revoked, if the credential is revocable and is known to have been revoked. +* A credential is expiring soon or expired, based on _expiry_date_attribute_, if set. + + +![alt_text](images/image11.png "image_tooltip") + + +**_Figure: An example demonstrating how the revocation date, expiry date or issued date may be represented._** + +The interpretation of the issued date, expiry date and revocation status may be dependent on the holder software, such as a wallet. For example, the specific icons used may vary by wallet, or the full status data may be printed over the credential. + + +### Credential name and Issuer name guidelines + +Issuers should be mindful of the length of text on the credential as lengthy text will dynamically change the height of the credential. Expansive credentials risk reducing the number of fully visible credentials in a list. + + + +![alt_text](images/image12.png "image_tooltip") + + +**_Figure: An example demonstrating how lengthy credentials can limit the number of visible credentials._** + +Be mindful of other factors that may increase the length of text and hence, the height of the credential such as translated languages or the font size configured at the OS level. + + +![alt_text](images/image13.png "image_tooltip") + + +**_Figure: Examples showing the treatment of lengthy names_** + + +### Primary and Secondary Attribute Guidelines + +If issuers expect people to hold multiples of their credentials of the same type, they may want to specify a primary and secondary attribute to display on the card face. + +Note that wallet builders or holders may limit the visibility of the primary and secondary attributes on the card face to mitigate privacy concerns. Issuers can expect that these attributes may be fully visible, redacted, or hidden. + +To limit personal information from being displayed on a card face, only specify what is absolutely necessary for wallet holders to differentiate between credentials of the same type. Do not display private information such as medical related attributes. + + + + + + + + + + + +
+alt_text + + +alt_text + +
Do +

+Use attributes that help users identify their credentials. Always consider if a primary and secondary attribute is absolutely necessary. +

Don’t +

+Display attributes that contain private information. +

+ + +**_Figure: Primary/secondary attribute Do’s and Don’ts_** + + +### Non-production watermark + +To identify non-production credentials, issuers can add a watermark to their credentials. The watermark is a simple line of text that can be customized depending on the issuer needs. The line of text will also appear as a prefix to the credential name. The line of text should be succinct to ensure legibility. This watermark is not intended to be used for any other purpose than to mark non-production credentials. Ensure proper localization to the watermark is present in all languages. + +Example text include: + + + +* DEMO +* SAMPLE +* NON-PRODUCTION +* TEST +* DEVELOPMENT +* DO NOT USE + + + + + + + + + + +
+ +alt_text + + +alt_text + +
Do +

+Use succinct words to describe the type of issued credential. This ensures legibility and does not increase the size of the credential unnecessarily. +

Don’t +

+Use long works or words that do not describe non-production credentials. +

+ + + +### Credential resizing + +Credential size depends on the content of the credential and the size of the device. Text areas are resized according to the width. + + +![alt_text](images/image18.png "image_tooltip") + + +**_Figure: Treatment of the credential template on different devices_** + + +![alt_text](images/image19.png "image_tooltip") + + +**_Figure: An example of credential on different devices_** + + +### Stacking + +Credentials may be stacked to overlap each other to increase the number of visible credentials in the viewport. The header remains unchanged. The issuer name, logo and credential name will always be visible but the primary and secondary attributes and the image slice will be obscured. + + +![alt_text](images/image20.png "image_tooltip") + + +**_Figure: An example of stacked credentials with default and enlarged text._** + + +### Accessibility + +The alt-tags for the logo and background images come from the multilingual OCA Meta Overlay for the issuer name and credential type name. + + +### More Variations + +To view more credential variations using this template, [view the Adobe XD file](https://xd.adobe.com/view/045a1969-719a-4aa5-848f-637ef1b7051a-5109/). + + + +## Drawbacks + +Defining and requesting adherence to a style guide is a lofty goal. With so many +independent issuers, holders and verifiers using Aries, it is a challenge +to get everyone to agree on a single way to display credentials for users. However, +the alternative of everyone "doing their own thing", perhaps in small groups, will +result in a poor experience for users, and be frustrating to both issuers trying +to convey their brand, and holders (and verifiers) trying to create a beautiful +experience for their users. + +## Rationale and alternatives + +In coming up with this Style Guide, we consider how much control to give +issuers, ultimately deciding that given them too much control (e.g., pixel +precise layout of their credential) creates a usage/privacy risk (people using +their credentials by showing them on screen, with all private data showing), is +technical extremely difficult given the variations of holder devices, and likely +to result in a very poor user experience. + +A user experience group in Canada came up with the core design, and the Aries +Working Group reviewed and approved of the Style Guide. + +## Prior art + +The basic concept of giving issuers a small set of parameters that they could +control in branding of their data is used in many applications and communities. +Relevant to the credential use case is the application of this concept in the +Apple Wallet and Google Wallet. Core to this is the setting of expectations of +all of the participants of how their data will be used, and how to use the data +provided. In the Aries holder (and verifier) case, unlike that of the Apple +Wallet and Google Wallet, is that there is not just one holder that is using the +data from many issuers to render the data on screen, but many holders that are +expected to adhere to this Style Guide. + +## Unresolved questions + +- A challenge will be in evolving this Style Guide based on new input from those +that use it over time. We expect the Aries RFC version process to be sufficient. +However, this is the first time that this process has been applied to a user +experience "protocol", as opposed to a technical, messaging protocol. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | diff --git a/features/0756-oca-for-aries-style-guide/images/image1.png b/features/0756-oca-for-aries-style-guide/images/image1.png new file mode 100644 index 000000000..073dfea64 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image1.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image10.png b/features/0756-oca-for-aries-style-guide/images/image10.png new file mode 100644 index 000000000..da6c3f5f8 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image10.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image11.png b/features/0756-oca-for-aries-style-guide/images/image11.png new file mode 100644 index 000000000..ddcbbae39 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image11.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image12.png b/features/0756-oca-for-aries-style-guide/images/image12.png new file mode 100644 index 000000000..eff7f3e98 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image12.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image13.png b/features/0756-oca-for-aries-style-guide/images/image13.png new file mode 100644 index 000000000..ddbedd9e9 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image13.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image14.png b/features/0756-oca-for-aries-style-guide/images/image14.png new file mode 100644 index 000000000..26169aeb7 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image14.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image15.png b/features/0756-oca-for-aries-style-guide/images/image15.png new file mode 100644 index 000000000..5376619d4 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image15.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image16.png b/features/0756-oca-for-aries-style-guide/images/image16.png new file mode 100644 index 000000000..b6f6e9319 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image16.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image17.png b/features/0756-oca-for-aries-style-guide/images/image17.png new file mode 100644 index 000000000..f28f00725 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image17.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image18.png b/features/0756-oca-for-aries-style-guide/images/image18.png new file mode 100644 index 000000000..72cd9dc4c Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image18.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image19.png b/features/0756-oca-for-aries-style-guide/images/image19.png new file mode 100644 index 000000000..945c8b919 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image19.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image2.png b/features/0756-oca-for-aries-style-guide/images/image2.png new file mode 100644 index 000000000..6e8d5c746 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image2.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image20.png b/features/0756-oca-for-aries-style-guide/images/image20.png new file mode 100644 index 000000000..ab86d9219 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image20.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image3.png b/features/0756-oca-for-aries-style-guide/images/image3.png new file mode 100644 index 000000000..d1242b65b Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image3.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image4.png b/features/0756-oca-for-aries-style-guide/images/image4.png new file mode 100644 index 000000000..38b7378a9 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image4.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image5.png b/features/0756-oca-for-aries-style-guide/images/image5.png new file mode 100644 index 000000000..bc440e866 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image5.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image6.jpg b/features/0756-oca-for-aries-style-guide/images/image6.jpg new file mode 100644 index 000000000..6d215de9d Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image6.jpg differ diff --git a/features/0756-oca-for-aries-style-guide/images/image7.png b/features/0756-oca-for-aries-style-guide/images/image7.png new file mode 100644 index 000000000..aa863ba6e Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image7.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image8.png b/features/0756-oca-for-aries-style-guide/images/image8.png new file mode 100644 index 000000000..f7270510b Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image8.png differ diff --git a/features/0756-oca-for-aries-style-guide/images/image9.png b/features/0756-oca-for-aries-style-guide/images/image9.png new file mode 100644 index 000000000..10dff8021 Binary files /dev/null and b/features/0756-oca-for-aries-style-guide/images/image9.png differ diff --git a/features/0771-anoncreds-attachments/README.md b/features/0771-anoncreds-attachments/README.md new file mode 100644 index 000000000..ea3318964 --- /dev/null +++ b/features/0771-anoncreds-attachments/README.md @@ -0,0 +1,341 @@ +# Aries RFC 0771: AnonCreds Attachment Formats for Requesting and Presenting Credentials + +- Authors: [Timo Glastra](mailto:timo@animo.id), [Daniel Hardman](mailto:daniel.hardman@gmail.com) +- Status: [PROPOSED](/README.md#proposed) +- Since: 2023-02-24 +- Status Note: Formalizes the AnonCreds attachments for issuing credentials and presenting proofs over DIDComm. +- Supersedes: Hyperledger Indy specific AnonCreds attachment formats documented in [Aries RFC 0592](../0592-indy-attachments/README.md). +- Start Date: 2023-02-24 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [credentials](/tags.md#credentials), [test-anomaly](/tags.md#test-anomaly) + +## Summary + +This RFC registers attachment formats used with [Hyperledger AnonCreds](https://hyperledger.github.io/anoncreds-spec/) ZKP-oriented credentials in the [Issue Credential Protocol 2.0](../0453-issue-credential-v2/README.md) and [Present Proof Protocol 2.0](../0454-present-proof-v2/README.md). If not specified otherwise, this follows the rules as defined in the [AnonCreds Specification](https://hyperledger.github.io/anoncreds-spec/). + +## Motivation + +Allows AnonCreds credentials to be used with credential-related protocols that take pluggable formats as payloads. + +## Reference + +### Credential Filter format + +The potential holder uses this format to propose criteria for a potential credential for the issuer to offer. The format defined here is not part of the AnonCreds spec, but is a Hyperledger Aries-specific message. + +The identifier for this format is `anoncreds/credential-filter@v1.0`. The data structure allows specifying zero or more criteria from the following structure: + +```jsonc +{ + "schema_issuer_id": "", + "schema_name": "", + "schema_version": "", + "schema_id": "", + "issuer_id": "", + "cred_def_id": "" +} +``` + +The potential holder may not know, and need not specify, all of these criteria. For example, the holder might only know the schema name and the (credential) issuer id. Recall that the potential holder may specify target attribute values and MIME types in the [credential preview](../0453-issue-credential-v2/README.md#preview-credential). + +For example, the JSON structure might look like this: + +```json +{ + "schema_issuer_id": "did:sov:4RW6QK2HZhHxa2tg7t1jqt", + "schema_name": "bcgov-mines-act-permit.bcgov-mines-permitting", + "issuer_id": "did:sov:4RW6QK2HZhHxa2tg7t1jqt" +} +``` + +A complete [`propose-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#propose-credential) embeds this format as an attachment in the `filters~attach` array: + +```json +{ + "@id": "", + "@type": "https://didcomm.org/issue-credential/%VER/propose-credential", + "comment": "", + "formats": [ + { + "attach_id": "", + "format": "anoncreds/credential-filter@v1.0" + } + ], + "filters~attach": [ + { + "@id": "", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgInNjaGVtYV9pc3N1ZXJfZGlkIjogImRpZDpzb3Y... (clipped)... LMkhaaEh4YTJ0Zzd0MWpxdCIKfQ==" + } + } + ] +} +``` + +### Credential Offer format + +This format is used to clarify the structure and semantics (but not the concrete data values) of a potential credential, in offers sent from issuer to potential holder. + +The identifier for this format is `anoncreds/credential-offer@v1.0`. It must follow the [structure of a Credential Offer](https://hyperledger.github.io/anoncreds-spec/#credential-offer) as defined in the AnonCreds specification. + +The JSON structure might look like this: + +```json +{ + "schema_id": "4RW6QK2HZhHxa2tg7t1jqt:2:bcgov-mines-act-permit.bcgov-mines-permitting:0.2.0", + "cred_def_id": "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58160:default", + "nonce": "57a62300-fbe2-4f08-ace0-6c329c5210e1", + "key_correctness_proof" : +} +``` + +A complete [`offer-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#offer-credential) embeds this format as an attachment in the `offers~attach` array: + +```json +{ + "@type": "https://didcomm.org/issue-credential/%VER/offer-credential", + "@id": "", + "replacement_id": "", + "comment": "", + "credential_preview": , + "formats" : [ + { + "attach_id" : "", + "format": "anoncreds/credential-offer@v1.0" + } + ], + "offers~attach": [ + { + "@id": "", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgInNjaGVtYV9pZCI6ICI0Ulc2UUsySFpoS... (clipped)... jb3JyZWN0bmVzc19wcm9vZj4KfQ==" + } + } + ] +} +``` + +### Credential Request format + +This format is used to formally request a credential. It differs from the Credential Offer above in that it contains a cryptographic commitment to a link secret; an issuer can therefore use it to bind a concrete instance of an issued credential to the appropriate holder. (In contrast, the credential offer describes the schema and cred definition, but not enough information to actually issue to a specific holder.) + +The identifier for this format is `anoncreds/credential-request@v1.0`. It must follow the [structure of a Credential Request](https://hyperledger.github.io/anoncreds-spec/#credential-request) as defined in the AnonCreds specification. + +The JSON structure might look like this: + +```jsonc +{ + "entropy" : "e7bc23ad-1ac8-4dbc-92dd-292ec80c7b77", + "cred_def_id" : "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58160:default", + // Fields below can depend on Cred Def type + "blinded_ms" : , + "blinded_ms_correctness_proof" : , + "nonce": "fbe22300-57a6-4f08-ace0-9c5210e16c32" +} +``` + +A complete [`request-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#request-credential) embeds this format as an attachment in the `requests~attach` array: + +```json +{ + "@id": "cf3a9301-6d4a-430f-ae02-b4a79ddc9706", + "@type": "https://didcomm.org/issue-credential/%VER/request-credential", + "comment": "", + "formats": [ + { + "attach_id": "7cd11894-838a-45c0-a9ec-13e2d9d125a1", + "format": "anoncreds/credential-request@v1.0" + } + ], + "requests~attach": [ + { + "@id": "7cd11894-838a-45c0-a9ec-13e2d9d125a1", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgInByb3Zlcl9kaWQiIDogImRpZDpzb3Y6YWJjeHl.. (clipped)... DAtNTdhNi00ZjA4LWFjZTAtOWM1MjEwZTE2YzMyIgp9" + } + } + ] +} +``` + +### Credential format + +A concrete, issued AnonCreds credential may be transmitted over many protocols, but is specifically expected as the final message in [Issuance Protocol 2.0](../0453-issue-credential-v2/README.md). The identifier for this format is `anoncreds/credential@v1.0`. + +This is a credential that's designed to be _held_ but not _shared directly_. It is stored in the holder's wallet and used to [derive a novel ZKP](https://youtu.be/bnbNtjsKb4k?t=1280) or [W3C-compatible verifiable presentation](https://docs.google.com/document/d/1ntLZGMah8iJ_TWQdbrNNW9OVwPbIWkkCMiid7Be1PrA/edit#heading=h.vw0mboesl528) just in time for each sharing of credential material. + +The encoded values of the credential MUST follow the encoding algorithm as described in [Encoding Attribute Data](https://hyperledger.github.io/anoncreds-spec/#encoding-attribute-data). It must follow the [structure of a Credential](https://hyperledger.github.io/anoncreds-spec/#constructing-a-credential) as defined in the AnonCreds specification. + +The JSON structure might look like this: + +```jsonc +{ + "schema_id": "4RW6QK2HZhHxa2tg7t1jqt:2:bcgov-mines-act-permit.bcgov-mines-permitting:0.2.0", + "cred_def_id": "4RW6QK2HZhHxa2tg7t1jqt:3:CL:58160:default", + "rev_reg_id", "EyN78DDGHyok8qw6W96UBY:4:EyN78DDGHyok8qw6W96UBY:3:CL:56389:CardossierOrgPerson:CL_ACCUM:1-1000", + "values": { + "attr1" : {"raw": "value1", "encoded": "value1_as_int" }, + "attr2" : {"raw": "value2", "encoded": "value2_as_int" } + }, + // Fields below can depend on Cred Def type + "signature": , + "signature_correctness_proof": + "rev_reg": + "witness": +} +``` + +An exhaustive description of the format is out of scope here; it is more completely documented in the [AnonCreds Specification](https://hyperledger.github.io/anoncreds-spec). + +### Proof Request format + +This format is used to formally request a verifiable presenation (proof) derived from an AnonCreds-style ZKP-oriented credential. + +The format can also be used to _propose_ a presentation, in this case the `nonce` field MUST NOT be provided. The `nonce` field is required when the proof request is used to request a proof. + +The identifier for this format is `anoncreds/proof-request@v1.0`. It must follow the [structure of a Proof](https://hyperledger.github.io/anoncreds-spec/#create-presentation-request) as defined in the AnonCreds specification. + +Here is a sample proof request that embodies the following: "Using a government-issued ID, disclose the credential holder’s name and height, hide the credential holder’s sex, get them to self-attest their phone number, and prove that their age is at least 18": + +```jsonc +{ + "nonce": "2934823091873049823740198370q23984710239847", + "name":"proof_req_1", + "version":"0.1", + "requested_attributes":{ + "attr1_referent": {"name":"sex"}, + "attr2_referent": {"name":"phone"}, + "attr3_referent": {"names": ["name", "height"], "restrictions": } + }, + "requested_predicates":{ + "predicate1_referent":{"name":"age","p_type":">=","p_value":18} + } +} +``` + +### Proof format + +This is the format of an AnonCreds-style ZKP. The raw values encoded in the presentation MUST be verified against the encoded values using the encoding algorithm as described in [Encoding Attribute Data](https://hyperledger.github.io/anoncreds-spec/#encoding-attribute-data) + +The identifier for this format is `anoncreds/proof@v1.0`. It must follow the [structure of a Presentation](https://hyperledger.github.io/anoncreds-spec/#generate-presentation) as defined in the AnonCreds specification. + +A proof that responds to the [previous proof request sample](#proof-request-format) looks like this: + +```jsonc +{ + "proof":{ + "proofs":[ + { + "primary_proof":{ + "eq_proof":{ + "revealed_attrs":{ + "height":"175", + "name":"1139481716457488690172217916278103335" + }, + "a_prime":"5817705...096889", + "e":"1270938...756380", + "v":"1138...39984052", + "m":{ + "master_secret":"375275...0939395", + "sex":"3511483...897083518", + "age":"13430...63372249" + }, + "m2":"1444497...2278453" + }, + "ge_proofs":[ + { + "u":{ + "1":"152500...3999140", + "2":"147748...2005753", + "0":"8806...77968", + "3":"10403...8538260" + }, + "r":{ + "2":"15706...781609", + "3":"343...4378642", + "0":"59003...702140", + "DELTA":"9607...28201020", + "1":"180097...96766" + }, + "mj":"134300...249", + "alpha":"827896...52261", + "t":{ + "2":"7132...47794", + "3":"38051...27372", + "DELTA":"68025...508719", + "1":"32924...41082", + "0":"74906...07857" + }, + "predicate":{ + "attr_name":"age", + "p_type":"GE", + "value":18 + } + } + ] + }, + "non_revoc_proof":null + } + ], + "aggregated_proof":{ + "c_hash":"108743...92564", + "c_list":[ 6 arrays of 257 numbers between 0 and 255] + } + }, + "requested_proof":{ + "revealed_attrs":{ + "attr1_referent":{ + "sub_proof_index":0, + "raw":"Alex", + "encoded":"1139481716457488690172217916278103335" + } + }, + "revealed_attr_groups":{ + "attr4_referent":{ + "sub_proof_index":0, + "values":{ + "name":{ + "raw":"Alex", + "encoded":"1139481716457488690172217916278103335" + }, + "height":{ + "raw":"175", + "encoded":"175" + } + } + } + }, + "self_attested_attrs":{ + "attr3_referent":"8-800-300" + }, + "unrevealed_attrs":{ + "attr2_referent":{ + "sub_proof_index":0 + } + }, + "predicates":{ + "predicate1_referent":{ + "sub_proof_index":0 + } + } + }, + "identifiers":[ + { + "schema_id":"NcYxiDXkpYi6ov5FcYDi1e:2:gvt:1.0", + "cred_def_id":"NcYxi...cYDi1e:2:gvt:1.0:TAG_1", + "rev_reg_id":null, + "timestamp":null + } + ] +} +``` + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +| Name / Link | Implementation Notes | +| ----------- | -------------------- | +| | diff --git a/features/0780-data-urls-images/README.md b/features/0780-data-urls-images/README.md new file mode 100644 index 000000000..b0d307528 --- /dev/null +++ b/features/0780-data-urls-images/README.md @@ -0,0 +1,185 @@ +# RFC 0780: Use Data URLs for Images and More in Credential Attributes + +- Authors: [Stephen Curran](mailto:swcurran@cloudcompass.ca), [Clecio Varjao](mailto:clecio.varjao@gov.bc.ca) +- Status: [DEMONSTRATED](/README.md#demonstrated) +- Since: 2024-03-02 +- Status Note: Implemented in the [Bifold Wallet](https://github.com/openwallet-foundation/bifold-wallet) +- Supersedes: None +- Start Date: 2023-03-31 +- Tags: [feature](/tags.md#feature) + +## Summary + +Some credentials include attributes that are not simple strings or numbers, such +as images or JSON data structures. When complex data is put in an attribute +the issuer **SHOULD** issue the attribute as a Data URL, as defined in [IETF RFC 2397], and whose use +is described in this [Mozilla Developer Documentation] article. + +[IETF RFC 2397]: https://datatracker.ietf.org/doc/rfc2397/ +[Mozilla Developer Documentation]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs + +On receipt of all credentials and presentations, holders and verifiers +**SHOULD** check all string attributes to determine if they are Data URLs. If +so, they **SHOULD** securely process the data according to the metadata +information in the Data URL, including: + +- the [MIME type] of the data (such as `image/png` or `application/json`) +- whether the data is [base64 encoded]. + +[base64 encoded]: https://datatracker.ietf.org/doc/rfc4648/ +[MIME type]: https://www.ucolick.org/~sla/fits/mime/inetstds.html + +This allows, for example, an Aries Mobile Wallet to detect that a data element +is an image and how it is encoded, and display it for the user as an image, +not as a long (long) string of gibberish. + +## Motivation + +Holders and verifiers want to enable a delightful user experience when an issuer +issues attributes that contain other than strings or numbers, such as an +image or a JSON data structure. In such cases, the holder and +verifiers need a way to know the format of the data so it can be processed +appropriately and displayed usefully. While the Aries community encourages the +use of the [Overlays Capture Architecture specification] as outlined +in [RFC 0755 OCA for Aries] for such information, there will be times where an +OCA Bundle is not available for a given credential. In the absence of an OCA Bundle, the holders and verifiers of +such attributes need data type information for processing and displaying the attributes. + +[Overlays Capture Architecture specification]: https://oca.colossi.network/specification/ +[RFC 0755 OCA for Aries]: https://github.com/swcurran/aries-rfcs/blob/oca4aries/features/0755-oca-for-aries/README.md + +## Tutorial + +An issuer wants to issue a verifiable credential that contains an image, such as +a photo of the holder to which the credential is issued. Issuing such an +attribute is typically done by converting the image to a base64 string. This is +handled by the various verifiable credential formats supported by Aries issuers. +The challenge is to convey to the holder and verifiers that the attribute is not +"just another string" that can be displayed on screen to the user. By making the +attribute a Data URL, the holder and verifiers can detect the type and encoding +of the attribute, process it, and display it correctly. + +For example, this image (from the IETF 2793 specification): + +![](photo.png) + +can be issued as the attribute `photo` in a verifiable credential with its value a Data URL as follows: + +```json +{ +"photo": "data:image/png;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7" +} +``` + +The syntax of a Data URL is described in [IETF RFC 2397]. The \ version is: + +- `data:` -- hardcoded. +- `` -- optional, the [MIME type] of the data. +- `;base64` -- optional, if present, the data is [base64 encoded]. +- `,` -- hardcoded separator. +- `` -- the attribute data in the specified encoding. + +A holder or verifier receiving a credential or presentation **MUST** check +each attribute is a string, and if so, if it is a Data URL (likely by using a +regular expression). If it is a Data URL it should be securely processed +accordingly. + +Aries Data URL verifiable credential attributes **MUST** include the ``. + +### Image Size + +A separate issue from the use of Data URLs is how large an image (or other data +type) can be put into an attribute and issued as a verifiable credential. That +is an issue that is dependent on the verifiable credential implementation and +other factors. For AnonCreds credentials, the attribute will be treated as a +string, a hash will be calculated over the string, and the resulting number will +be signed--just as for any string. The size of the image does not matter. +However, there may be other components in your deployment that might impact how +big an attribute in a credential can be. Many in the community have successfully +experimented with the use of images in credentials, so consulting others on the +question might be helpful. + +For the purpose of this RFC, the amount of data in the attribute is not +relevant. + +### Security + +As noted in this [Mozilla Developer Documentation] and this [Mozilla Security +Blog Post about Data URLs], Data URLs are blocked from being used in the Address +Bar of all major browsers. That is because Data URLs may contain HTML that can +contain anything, including HTML forms that collect data from users. Since Aries +holder and verifier agents are not general purpose content presentation engines +(as are browsers) the use of Data URLs are less of a security risk. Regardless, +holders and verifiers **MUST** limit their processing of attributes containing +Data URLs to displaying the data, and not executing the data. Further, Aries +holders and verifiers **MUST** stay up on dependency vulnerabilities, such as +images constructed to exploit vulnerabilities in libraries that display images. + +[Mozilla Security Blog Post about Data URLs]: https://blog.mozilla.org/security/2017/11/27/blocking-top-level-navigations-data-urls-firefox-59/ + +## Reference + +References for implementing this RFC are: + +- [IETF RFC 2397] +- [Mozilla Developer Documentation] +- [Stack Overflow Article on a Data URL Regex](https://stackoverflow.com/questions/5714281/regex-to-parse-image-data-uri) +- [A GitHub Gist of JavaScript to detect a data URL](https://gist.github.com/bgrins/6194623) + +## Drawbacks + +The Aries community is moving to the use of the [Overlay Capture Architecture +Specification] to provide a more generalized way to accomplish the same thing +(understanding the meaning, format and encoding of attributes), so this RFC is +duplicating a part of that capability. That said, it is easier and faster for +issuers to start using, and for holders and verifiers to detect and use. + +Issuers may choose to issue Data URLs with MIME types not commonly known to +Aries holder and verifier components. In such cases, the holder or verifier +**MUST NOT** display the data. + +Even if the MIME type of the data is known to the holders and verifiers, it may +not be obvious how to present the data on screen in a useful way. For example, +an attribute holding a JSON data structure with an array of values may not +easily be displayed. + +## Rationale and alternatives + +We considered using the same approach as is used in [RFC 0441 Present Proof Best +Practices](../../concepts/0441-present-proof-best-practices/README.md#dates-and-predicates) +of a special suffix (`_img`) for the attribute name in a credential to indicate that +the attribute held an image. However, that provides far less information than this +approach (e.g., what type of image?), and its use is limited to images. This RFC +defines a far more complete, standard, and useful approach. + +As noted in the drawbacks section, this same functionality can (and should) be +achieved with the broad deployment of [Overlay Capture Architecture +Specification] and [RFC 0755 OCA for Aries]. However, the full deployment of +[RFC 0755 OCA for Aries] will take some time, and in the meantime, this is a +"quick and easy" alternate solution that is useful alongside OCA for Aries. + +## Prior art + +In the use cases of which we are aware of issuers putting images and JSON +structures into attributes, there was no indicator of the attribute content, and +the holders and verifiers were assumed to either "know" about the data content +based on the type of credential, or they just displayed the data as a string. + +## Unresolved questions + +Should this RFC define a list (or the location of a list) of MIME types that +Aries issuers can use in credential attributes? + +For supported MIME types that do not have obvious display methods (such as +JSON), should there be a convention for how to display the data? + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | + diff --git a/features/0780-data-urls-images/photo.png b/features/0780-data-urls-images/photo.png new file mode 100644 index 000000000..3dc4fc65f Binary files /dev/null and b/features/0780-data-urls-images/photo.png differ diff --git a/features/0793-unqualfied-dids-transition/README.md b/features/0793-unqualfied-dids-transition/README.md new file mode 100644 index 000000000..c5a772413 --- /dev/null +++ b/features/0793-unqualfied-dids-transition/README.md @@ -0,0 +1,105 @@ +# Aries RFC 0793: Unqualified DID Transition + +- Authors: [Sam Curren](mailto:swcurran@cloudcompass.ca) +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2023-07-11 +- Status Note: In Step 1 - **Target Deployment Date: 2024-07-02** +- Supersedes: +- Start Date: 2023-07-11 +- Tags: [feature](/tags.md#feature), [community-update](/tags.md#community-update) + +## Summary + +Historically, Aries use of the Indy SDK's wallet included the use of 'unqualified DIDs' or DIDs without a did: prefix and method. +This transition documents the process of migrating any such DIDs still in use to fully qualified DIDs. + +This process involves the adoption of the Rotate DID protocol and algorithm 4 of the Peer DID Method, then the rotation from the unqualified DIDs to any fully qualified DID, with preference for did:peer:4. + +The adoption of these specs will further prepare the Aries community for adoption of DIDComm v2 by providing an avenue for adding DIDComm v2 compatible endpoints. + +Codebases that do not use unqualified DIDs MUST still adopt DID Rotation and did:peer:4 as part of this process, even if no unqualified DIDs must be rotated. + +This RFC follows the guidance in [RFC +0345](../../concepts/0345-community-coordinated-update/README.md) about +community-coordinated updates to (try to) ensure that independently deployed, +interoperable agents remain interoperable throughout this transition. + +The transition from the unqualified to qualified DIDs will occur in four steps: + +- **Pre-work**: where we agree on the transition plan outlined in this RFC. + - Finalize did:peer:4 details, including feature discovery support of did:peer:4. + - Verify transisiton plan and code. +- **Step 1**: Agent builders MUST update all agent code bases and deployments to support DID Rotation and did:peer:4. + - Each agent builder SHOULD notify the community they have completed Step 1 by submitting a PR to update their entry in the [implementations](#implementations) accordingly. + - Target Date for code update: 2024-05-01 + - Target Date for deployment update: 2024-07-02 +- **Step 2**: Agent builders using unqualified DIDs MUST no longer use new unqualified DIDs, and MUST use DID Rotation to rotate to a fully qualified DID. + - Each agent builder SHOULD notify the community they have completed Step 2 by submitting a PR to update their entry in the [implementations](#implementations) accordingly. + - Target Date for finishing step 2: 2024-11-01 +- **Step 3**: Agent builders SHOULD update their deployments to remove all support for receiving unqualified DIDs from other agents. + +The community coordination triggers between the steps above will be as follows: + +- **Pre-work to Step 1** - a PR to this RFC is merged that sets the RFC status to [ACCEPTED](/README.md#accepted). + - The [ACCEPTED](/README.md#accepted) version of this RFC is included in the current [Aries Interop Profile](/concepts/0302-aries-interop-profile/README.md) version. +- **Step 1 to Step 2** - the community agrees that the majority of the deployed agents have completed Step 1. A PR to this RFC is merged that sets the RFC status to [ADOPTED](/README.md#adopted). + - Agent builders indicate completion of Step 1 by updating the [Implementations](#implementations) section of this RFC. + - All other RFCs in this repo are updated to use the new message type format. + - The [ADOPTED](/README.md#adopted) version of this RFC is included in the current [Aries Interop Profile](/concepts/0302-aries-interop-profile/README.md) version. +- **Step 2 to Step 3** - the community agrees that the majority of the deployed agents have completed Step 2. A PR to this RFC is merged that sets the RFC status to [RETIRED](/README.md#retired). + - Agent builders indicate completion of Step 2 by updating the [Implementations](#implementations) section of this RFC. + +## Motivation + +To enable agent builders to independently update their code bases and deployed agents while maintaining interoperability. + +## Tutorial + +The general mechanism for this type of transition is documented in [RFC 0345](../../concepts/0345-community-coordinated-update/README.md) about +community-coordinated updates. + +The specific sequence of events to make this particular transition is outlined in the [summary](#summary) section of this RFC. + +## Reference + +See the [summary](#summary) section of this RFC for the details of this transition. + +## Drawbacks + +None identified. + +## Rationale and alternatives + +This approach balances the speed of adoption with the need for independent deployment and interoperability. + +## Prior art + +The approach outlined in [RFC +0345](../../concepts/0345-community-coordinated-update/README.md) about +community-coordinated updates is a well-known pattern for using deprecation to +make breaking changes in an ecosystem. That said, this is the first attempt to +use this approach in Aries. Adjustments to the transition plan will be made as needed, and RFC 0345 will be updated based on lessons learned in executing this plan. + +## Unresolved questions + +- Are any changes to existing RFCs needed before starting Step 1? + +## Implementations + +The following table lists the status of various agent code bases and deployments with respect to the steps of this transition. Agent builders MUST update this table as they complete steps of the transition. + +Name / Link | Implementation Notes +--- | --- +[Aries Protocol Test Suite](https://github.com/hyperledger/aries-protocol-test-suite) | No steps completed +[Aries Framework - .NET](https://github.com/hyperledger/aries-framework-dotnet) | No steps completed +[Trinsic.id](https://trinsic.id/) | No steps completed +[Aries Cloud Agent - Python](https://github.com/hyperledger/aries-cloudagent-python) | No steps completed +[Aries Static Agent - Python](https://github.com/hyperledger/aries-staticagent-python) | No steps completed +[Aries Framework - Go](https://github.com/hyperledger/aries-framework-go) | No steps completed +[Connect.Me](https://www.evernym.com/blog/connect-me-sovrin-digital-wallet/) | No steps completed +[Verity](https://www.evernym.com/products/) | No steps completed +[Pico Labs](http://picolabs.io/) | No steps completed +[IBM](https://github.com/IBM-Blockchain-Identity/unknown) | No steps completed +IBM Agent | No steps completed +[Aries Cloud Agent - Pico](https://github.com/Picolab/aries-cloudagent-pico) | No steps completed +[Aries Framework JavaScript](https://github.com/hyperledger/aries-framework-javascript) | No steps completed \ No newline at end of file diff --git a/features/0794-did-rotate/README.md b/features/0794-did-rotate/README.md new file mode 100644 index 000000000..0218fdae2 --- /dev/null +++ b/features/0794-did-rotate/README.md @@ -0,0 +1,147 @@ +# Aries RFC 0794: DID Rotate 1.0 + +- Authors: [Sam Curren](mailto:telegramsam@gmail.com) +- Status: [ACCEPTED](/README.md#accepted) +- Since: 2024-03-02 +- Status Note: Implemented in the [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python) +- Start Date: 2023-08-18 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) +- URI: https://didcomm.org/did-rotate/1.0 + +## Summary + +This protocol signals the change of DID in use between parties. + +This protocol is only applicable to DIDComm v1 - in DIDComm v2 use the more efficient DID Rotation header. + +## Motivation + +This mechanism allows a party in a relationship to change the DID they use to identify themselves in that relationship. This may be used to switch DID methods, +but also to switch to a new DID within the same DID method. For non-updatable DID methods, this allows updating DID Doc attributes such as service endpoints. Inspired by (but different from) the DID rotation feature of the DIDComm Messaging (DIDComm v2) spec. + +## Implications for Software Implementations + +Implementations will need to consider how data (public keys, DIDs and the ID for the relationship) related to the relationship is managed. If the relationship DIDs are used as identifiers, those identifiers may need to be updated during the rotation to maintain data integrity. For example, both parties might have to retain and be able to use as identifiers for the relationship the existing DID and the rotated to DID, and their related keys for a period of time until the rotation is complete. + +## Tutorial + +### Name and Version + +DID Rotate 1.0 + +URI: https://didcomm.org/did-rotate/1.0/ + +### Roles + +**rotating_party**: this party is rotating the DID in use for this relationship. They send the `rotate` message. + +**observing_party**: this party is notified of the DID rotation + +### Messages + +#### Rotate + +Message Type URI: https://didcomm.org/did-rotate/1.0/rotate + +`to_did`: The new DID to be used to identify the **rotating_party** + +```json +{ + "@id": "123456780", + "@type": "https://didcomm.org/did-rotate/1.0/rotate", + "to_did": "did:example:newdid", + +} +``` + +The **rotating_party** is expected to receive messages on both the existing and new DIDs and their associated keys for a reasonable period that MUST extend at least until the following `ack` message has been received. + +This message MUST be sent using AuthCrypt or as a signed message in order to establish the provenance of the new DID. In Aries implementations, messages sent within the context of a relationship are by default sent using AuthCrypt. Proper provenance prevents injection attacks that seek to take over a relationship. Any rotate message received without being authcrypted or signed MUST be discarded and not processed. + +DIDComm v1 uses public keys as the outer message identifiers. This means that rotation to a new DID using the same public key will not result in a change for new inbound messages. The **observing_party** must not assume that the new DID uses the same keys as the existing relationship. + +#### Ack + +Message Type URI: https://didcomm.org/did-rotate/1.0/ack + +This message has been adopted from [the `ack` protocol] +(https://github.com/hyperledger/aries-rfcs/tree/main/features/0015-acks). + +This message is still sent to the prior DID to acknowledge the receipt of the rotation. Following messages will be sent to the new DID. + +In order to correctly process out of order messages, the The **observing_party** may choose to receive messages from the old DID for a reasonable period. This allows messages sent before rotation but received after rotation in the case of out of order message delivery. + +In this message, the `thid` (Thread ID) MUST be included to allow the `rotating_party` to correlate it with the sent `rotate` message. + +```json +{ + "@id": "123456780", + "@type": "https://didcomm.org/did-rotate/1.0/ack", + "~thread" : { + "thid": "" + }, + +} +``` + +#### Problem Report + +Message Type URI: https://didcomm.org/did-rotate/1.0/problem-report + +This message has been adopted from [the `report-problem` protocol] +(https://github.com/hyperledger/aries-rfcs/blob/main/features/0035-report-problem/README.md). + +If the **observing_party** receives a `rotate` message with a DID that they cannot resolve, they MUST return a problem-report message. + +The `description` `code` must be set to one of the following: +- **e.did.unresolvable** - used for a DID who's method is supported, but will not resolve +- **e.did.method_unsupported** - used for a DID method for which the `observing_party` does not support resolution. +- **e.did.doc_unsupported** - used for a DID for which the `observing_party` does not find information sufficient for a DIDComm connection in the resolved DID Document. This would include compatible key types and a DIDComm capable service endpoint. + + +Upon receiving this message, the `rotating_party` must not complete the rotation and resolve the issue. Further rotation attempts must happen in a new thread. + +```json +{ + "@type" : "https://didcomm.org/did-rotate/1.0/problem-report", + "@id" : "an identifier that can be used to discuss this error message", + "~thread" : { + "pthid": "" + }, + "description" : { "en": "DID Unresolvable", "code": "e.did.unresolvable" }, + "problem_items" : [ {"did": ""} ], +} +``` + +#### Hangup + +Message Type URI: https://didcomm.org/did-rotate/1.0/hangup + +This message is sent by the **rotating_party** to inform the **observing_party** that they are done with the relationship and will no longer be responding. + +There is no response message. + +Use of this message does not require or indicate that all data has been deleted by either party, just that interaction has ceased. + +```json +{ + "@id": "123456780", + "@type": "https://didcomm.org/did-rotate/1.0/hangup" +} +``` + +## Prior art + +This protocol is inspired by the rotation feature of DIDComm Messaging (DIDComm v2). The implementation differs in important ways. +The DIDComm v2 method is a _post rotate_ operation: the first message sent AFTER the rotation contains the prior DID and a signature authorizing the rotation. This is efficient, but requires the use of a message header and a higher level of integration with message processing. +This protocol is a _pre rotate_ operation: notifying the other party of the new DID in advance is a less efficient but simpler approach. This was done to minimize adoption pain. The pending move to DIDComm v2 will provide the efficiency. + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](/README.md#accepted). + +Name / Link | Implementation Notes +--- | --- + | diff --git a/features/0804-didcomm-rpc/README.md b/features/0804-didcomm-rpc/README.md new file mode 100644 index 000000000..ea9ed8388 --- /dev/null +++ b/features/0804-didcomm-rpc/README.md @@ -0,0 +1,420 @@ +# 0804: DIDComm Remote Procedure Call (DRPC) + +- Authors: [Clecio Varjao](mailto:clecio.varjao@gov.bc.ca) (BC Gov), [Stephen Curran](mailto:swcurran@cloudcompass.ca) (BC Gov), [Akiff Manji](mailto:amanji@petridish.dev) (BC Gov) +- Status: [DEMONSTRATED](/README.md#demonstrated) +- Since: 2024-03-02 +- Status Note: Implemented in an [Aries Cloud Agent Python plugin](https://github.com/hyperledger/aries-acapy-plugins), and [Credo TS](https://github.com/openwallet-foundation/credo-ts) +- Supersedes: +- Start Date: 2023-11-29 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol) + +## Summary + +The DIDComm Remote Procedure Call (DRPC) protocol enables a [JSON-RPC]-based +request-response interaction to be carried out across a DIDComm channel. The +protocol is designed to enable custom interactions between connected agents, and +to allow for the rapid prototyping of experimental DIDComm protocols. An agent +sends a DIDComm message to request a [JSON-RPC] service be invoked by another +agent, and gets back the [JSON-RPC]-format response in subsequent DIDComm +message. The protocol enables any request to be conveyed that the other agent +understands. Out of scope of this protocol is how the requesting agent discovers +the services available from the responding agent, and how the two agents know +the semantics of the specified [JSON-RPC] requests and responses. By using +DIDComm between the requesting and responding agents, the security and privacy +benefits of DIDComm are accomplished, and the generic parameters of the requests +allow for flexibility in how and where the protocol can be used. + +[JSON-RPC]: https://www.jsonrpc.org/specification + +## Motivation + +There are several use cases that are driving the initial need for this protocol. + +### App Attestation + +A mobile wallet needs to get an [app attestation] verifiable credential from +the wallet publisher. To do that, the wallet and publisher need to exchange +information specific to to the attestation process with the Google and Apple +stores. The sequence is as follows: + +- The wallet decides (for some reason) it needs an App Attestation credential + from its publisher. +- If not already available, a DIDComm connection between the wallet and the + attestation service is created. +- The wallet uses the DRPC protocol to request a nonce from the service to be + used in the attestation. The service responds with the nonce. +- The wallet uses a new instance of the DRPC protocol to request the attestation + be performed. The service responds with the status of the attestation process. +- The service completes the business process by initiating an Issue Credential + process to issue an attestation verifiable credential. + +The wallet and service are using instances of three protocols (two DRPC and one +Issue Credential) to carry out a full business process. Each participant must +have knowledge of the full business process--there is nothing inherent in the +DRPC protocol about this process, or how it is being used. The DRPC protocol is +included to provide a generic request-response mechanism that alleviates the +need for formalizing special purpose protocols. + +> App attestation is a likely candidate for a having its own DIDComm protocol. +> This use of DRPC is ideal for developing and experimenting with the necessary +> agent interactions before deciding on if a use-specific protocol is needed and +> its semantics. + +[app attestation]: https://developer.apple.com/documentation/devicecheck + +### Video Verification Service + +A second example is using the DRPC protocol is to implement a custom video +verification service that is used by a specific mobile wallet implementation and +a proprietary backend service prior to issuing a credential to the wallet. Since +the interactions are to a proprietary service, so an open specification does not +make sense, but the use of DIDComm is valuable. In this example, the wallet +communicates over DIDComm to a Credential Issuer agent that (during +verification) proxies the requests/responses to a backend ("behind the +firewall") service. The wallet is implemented to use DRPC protocol instances to +initiate the verification and receive the actions needed to carry out the steps +of the verification (take picture, take video, instruct movements, etc.), +sending to the Issuer agent the necessary data. The Issuer conveys the requests +to the verification service and the responses back to the mobile wallet. At the +end of the process, the Issuer can see the result of the process, and decide on +the next actions between it and the mobile wallet, such as issuing a credential. + +Again, after using the DRPC protocol for developing and experimenting with the +implementation, the creators of the protocol can decide to formalize their own +custom, end-to-end protocol, or continue to use the DRPC protocol instances. +Important is that they can begin development without doing any Aries frameworks +customizations or plugins by using DRPC. + +## Tutorial + +### Name and Version + +This is the DRPC protocol. It is uniquely identified by the URI: + + "https://didcomm.org/drpc/1.0" + +### Key Concepts + +> This RFC assumes that you are familiar with [DID communication]. + +[DID communication]: /concepts/0005-didcomm/README.md + +The protocol consists of a DIDComm `request` message carrying an arbitrary +[JSON-RPC] request to a responding agent, and a second message that carries the +result of processing the request back to the client of the first message. The +interpretation of the request, how to carry out the request, the content of the +response, and the interpretation of the response, are all up to the business +logic (controllers) of the participating agents. There is no discovery of remote +services offered by agents--it is assumed that the two participants are aware of +the DRPC capabilities of one another through some other means. For example, from +the [App Attestation use case](#app-attestation), functionality to carry out the +app attestation process, and the service to use it is built into the mobile wallet. + +Those unfamiliar with [JSON-RPC], the `` is that it is a very simple +request response protocol using JSON where the only data shared is: + +- a `method` that defines what needs to be done, +- some `params` in JSON that are up to the requester/server to agree on, and +- an (optional) `id` to connect the response to the request. + +The response is likewise simple: + +- a `result` item if the invocation completed successful containing the return results, +- an `error` item if the invocation failed, containing details about the failure, and +- the `id` from the request. + +An example of a simple [JSON-RPC] request/response pair from the specification is: + +```json +--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1} +<-- {"jsonrpc": "2.0", "result": 19, "id": 1} +``` + +A [JSON-RPC] request may be a batch of requests, each with a different `id` value, +and the response a similar array, with an entry for each of the requests. + +[JSON-RPC] follows a similar "parameters defined by the message type" pattern as +DIDComm. As a result, in this protocol we do not need to add any special +handling around the `params` such as Base64 encoding, signing, headers and so +on, as the parties interacting with the protocol by definition must have a +shared understanding of the content of the `params` and can define any special +handling needed amongst themselves. + +It is expected (although not required) that an Aries Framework receiving a DRPC +message will simply pass to its associated "business logic" (controller) the +request from the client, and wait on the controller to provide the response +content to be sent back to the original client. Apart from the messaging processing +applied to all inbound and outbound messages, the Aries Framework will not +perform any of the actual processing of the request. + +### Roles + +There are two roles, adopted from the [JSON-RPC] specification, in the protocol +`client` and `server`: + +- The `client` initiates the protocol, sending a request to the `server`. +- The `server` carries out the request however they see fit. The `server` + may process the request themselves, or might invoke another service to process + the request. The `server` might be unable or unwilling to carry out the + request. +- The `server` returns the response from the request in a message to the `client`. + +### States + +#### Client States + +The `client` agent goes through the following states: + +- request-sent +- completed + +The state transition table for the `client` is: + +| State / Events | Send Request | Receive Response | +| ----------------------- | ---------------------------------- | ------------------------------- | +| *Start* | Transition to
**request-sent** | | +| request-sent | | Transition to
**complete** | +| completed | | | +| problem-report received | | Transition to
**abandoned** | +| abandoned | | | + +#### Server States + +The `server` agent goes through the following states: + +- request-received +- completed + +The state transition table for the `server` is: + +| State / Events | Receive Request | Send Response or Problem Report | +| ---------------- | -------------------------------------- | ------------------------------- | +| *Start* | Transition to
**request-received** | | +| request-received | | Transition to
**complete** | +| completed | | | + +### Messages + +The following are the messages in the DRPC protocol. The `response` message +handles all positive responses, so the `ack` ([RFC 0015 ACKs]) message is +**NOT** adopted by this protocol. The [RFC 0035 Report Problem] is adopted by +this protocol in the event that a `request` is not recognizable as a [JSON-RPC] +message and as such, a [JSON-RPC] response message cannot be created. See the +details below in the [Problem Report Message](#problem-report-message) section. + +[RFC 0015 ACKs]: ../features/0015-acks/README.md +[RFC 0035 Report Problem]: ../features/0035-report-problem/README.md + +#### Request Message + +The `request` message is sent by the `client` to initiate the protocol. The +message contains the [JSON-RPC] information necessary for the `server` to +process the request, prepare the response, and send the response message back to +the `client`. It is assumed the `client` knows what types of requests the +`server` is prepared to receive and process. If the `server` does not know how +to process the error, [JSON-RPC] has a standard response, outlined in the +[response message](#response-message) section below. How the `client` and +`server` coordinate that understanding is out of scope of this protocol. + +The `request` message uses the same JSON items as [JSON-RPC], skipping the +`id` in favor of the existing DIDComm `@id` and thread handling. + +```jsonc + { + "@type": "https://didcomm.org/drpc/1.0/request", + "@id": "2a0ec6db-471d-42ed-84ee-f9544db9da4b", + "request" : {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1} + } +``` + +The items in the message are as follows: + +- `@type` -- required, must be as above +- `@id` -- required, must be as defined in [RFC 0005 DIDComm] +- `request` -- **required**, an item containing a [JSON-RPC] request JSON structure. + - `request` **MUST** be either a single [JSON-RPC] request, or an array of [JSON-RPC] requests. + - Each [JSON-RPC] request **MUST** have the `jsonrpc` and `method` items. + - Each [JSON-RPC] request **MAY** have the `params` and `id` items. + - See the details below about the handling of `notification` [JSON-RPC] requests, requests where the `id` field is omitted. + - See the [JSON-RPC] specification for details about the `jsonrpc`, `method`, `params` and `id` JSON items. + +Per the [JSON-RPC] specification, if the `id` field of a [JSON-RPC] request is omitted, the `server` should not respond. In this DRPC DIDComm protocol, the `server` is always expected to send a `response`, but **MUST NOT** include +a [JSON-RPC] response for any [JSON-RPC] request for which the `id` is omitted. This is covered further +in the [response message](#response-message) section (below). + +#### Response Message + +A `response` message is sent by the `server` to following the +processing of the request to convey the output of the processing to the +`client`. As with the `request` the format mostly exactly that of a +[JSON-RPC] response. + +If the `request` is unrecognizable as a [JSON-RPC] message such that a +[JSON-RPC] message cannot be generated, the `server` SHOULD send a [RFC 0035 +Report Problem] message to the `client`. + +It is assumed the `client` understands what the contents of the +`response` message means in the context of the protocol instance. How the +`client` and `server` coordinate that understanding is out of scope of this +protocol. + +```jsonc + + { + "@type": "https://didcomm.org/drpc/1.0/response", + "@id": "63d6f6cf-b723-4eaf-874b-ae13f3e3e5c5", + "response": {"jsonrpc": "2.0", "result": 19, "id": 1} + } +``` + +The items in the message are as follows: + +- `@type` -- required, must be as above +- `@id` -- required, must be as defined in [RFC 0005 DIDComm] +- `response` -- **required**, an item containing a [JSON-RPC] response JSON structure. + - `response` **MUST** be either single (possibly empty) [JSON-RPC] response, + or an array of [JSON-RPC] responses. + - If all of the [JSON-RPC] requests in the `request` message are + *notifications* (e.g., the `id` item is omitted), the DIDComm `response` + message **MUST** be sent back with the value: `"response" : {}`. + - Each [JSON-RPC] response **MUST** have the `jsonrpc` and `id` items, and either a `result` or `error` item. + - See the [JSON-RPC] specification for details about the `jsonrpc`, `id`, `result` and `error` JSON items. + +As with all DIDComm messages that are not the first in a protocol instance, a +`~thread` decorator **MUST** be included in the `response` message. + +The special handling of the "all [JSON-RPC] requests are notifications" +described above is to simplify the DRPC handling to know when a DRPC protocol +instance is complete. If a `response` message is not always required, the DRPC +handler would have to inspect the `request` message to look for `id`s to +determine when the protocol completes. + +If the `server` does not understand how to process a given [JSON-RPC] request, a +`response` error **SHOULD** be returned (as per the [JSON-RPC] specification) with: + +- `error.code` value `-32601`, +- `error.message` set to `Method not found`, and +- no `error.data` item. + +#### Problem Report Message + +A [RFC 0035 Report Problem] message **SHOULD** be sent by the `server` instead +of a `response` message only if the `request` is unrecognizable as a [JSON-RPC] message. +An [JSON-RPC] errors **MUST** be provided to the `client` by the `server` via the +`response` message, not a `problem-report`. The `client` **MUST NOT** +respond to a `response` message, even if the `response` message is not a valid +[JSON-RPC] response. This is because once the `server` sends the `response`, the +protocol is in the `completed` state (from the `server`'s perspective) and so +is subject to deletion. As such, a follow up `problem-report` message would have +an invalid `thid` (thread ID) and (at best) be thrown away by the `server`. + +### Constraints + +The primary constraint with this protocol is that the two parties using the +protocol must understand one another--what [JSON-RPC] request(s) to use, what +parameters to provide, how to process the those requests, what the `response` +means, and so on. It is not a protocol to be used between arbitrary parties, but +rather one where the parties have knowledge outside of DIDComm of one another +and their mutual capabilities. + +On the other hand, that constraint enables great flexibility for explicitly +collaborating agents (such as a mobile wallet and the agent of its manufacturer) +to accomplish request-response transactions over DIDComm without +needing to define additional DIDComm protocols. More complex interactions can be +accomplished by carrying out a sequence of DRPC protocol instances between +agents. + +The flexibility the DRPC protocol allows for experimenting with specific +interactions between agents that could later evolve into formal DIDComm "fit for +purpose" protocols. + +## Reference + +### Codes Catalog + +A [JSON-RPC] request codes catalog *could* be developed over time and be +included in this part of the RFC. This might an intermediate step in transitioning +a given interaction implemented using DRPC into formally specified interaction. +On the other hand, simply defining a full DIDComm protocol will often be a far +better approach. + +At this time, there are no codes to be cataloged. + +## Drawbacks + +Anything that can be done by using the DRPC protocol can be accomplished by a +formally defined protocol specific to the task to be accomplished. The advantage +of the DRPC protocol is that pairs of agent instances that are explicitly +collaborating can use this protocol without having to first define a +task-specific protocol. + +## Rationale and alternatives + +We considered not supporting the *notification* and *batch* forms of the +[JSON-RPC] specification, and decided it made sense to allow for the full +support of the [JSON-RPC] specification, including requests of those forms. That +said, we also found that the concept of **not** having a DRPC `response` message +in some (likely, rare) cases based on the contents of the `request` JSON item +(e.g., when all of the `id`s are omitted from the [JSON-RPC] requests) would +unnecessarily complicate the DIDComm protocol instance handling about when it is +complete. As a result, a DRPC `response` message is always required. + +This design builds on the experience of implementations of this kind of feature +using [RFC 0095 Basic Message] and [RFC 0335 HTTP Over DIDComm]. This design +tries to build off the learnings gained from both of those implementations. + +Based on feedback to an original version of the RFC, we looked as well at +using [gRPC] as the core of this protocol, versus [JSON-RPC]. Our assessment +was that [gRPC] was a much heavier weight mechanism that required more effort +between parties to define and implement what will often be a very simple +request-response transaction -- at the level of defining a DIDComm protocol. + +[gRPC]: https://grpc.io/ + +The use of `params` and leaving the content and semantics of the params up to +the `client` and `server` means that they can define the appropriate handling of +the parameters. This eliminates the need for the protocol to define, for +example, that some data needs to be Base64 encoding for transmission, or if some +values need to be cryptographically signed. Such details are left to the +participants and how they are using the protocol. + +## Prior art + +This protocol has similar goals to the [RFC 0335 HTTP Over DIDComm] protocol, +but takes a lighter weight, more flexible approach. We expect that implementing +HTTP over DIDComm using this protocol will be as easy as using [RFC 0335 HTTP +Over DIDComm], where the [JSON-RPC] request's `params` data structure holds the +`headers` and `body` elements for the HTTP request. On the other hand, using the +explicit [RFC 0335 HTTP Over DIDComm] is might be a better choice if it is +available and exactly what is needed. + +[RFC 0335 HTTP Over DIDComm]: /features/0335-http-over-didcomm/README.md + +One of the example use cases for this protocol has been implemented by "hijacking" the +[RFC 0095 Basic Message] protocol to carry out the needed request/response actions. This +approach is less than ideal in that: + +- That is not the intended use of [RFC 0095 Basic Message], which is to send a + basic, human consumable message to the other agent. +- The request method and parameters have to be encoded into the basic message. +- The [RFC 0095 Basic Message] protocol is a single message protocols, so each + request-response interaction requires two instances of the protocol, and for + the controllers to manage connecting the interactions together. + +[RFC 0095 Basic Message]: /features/0095-basic-message/README.md + +## Unresolved questions + +- Should we include the idea of a `request` having a goal code ([RFC 0519 Goal Codes])? + +[RFC 0519 Goal Codes]: /concepts/0519-goal-codes/README.md + +## Implementations + +The following lists the implementations (if any) of this RFC. Please do a pull request to add your implementation. If the implementation is open source, include a link to the repo or to the implementation within the repo. Please be consistent in the "Name" field so that a mechanical processing of the RFCs can generate a list of all RFCs supported by an Aries implementation. + +*Implementation Notes* [may need to include a link to test results](README.md). + +Name / Link | Implementation Notes +--- | --- + | diff --git a/features/0809-w3c-data-integrity-credential-attachment/README.md b/features/0809-w3c-data-integrity-credential-attachment/README.md new file mode 100644 index 000000000..3b6acab82 --- /dev/null +++ b/features/0809-w3c-data-integrity-credential-attachment/README.md @@ -0,0 +1,321 @@ +# Aries RFC 0809: W3C Verifiable Credential Data Integrity Attachment format for requesting and issuing credentials + +- Authors: Timo Glastra (Animo Solutions) +- Status: [DEMONSTRATED](/README.md#demonstrated) +- Since: 2024-01-10 +- Status Note: Implemented in [Aries Cloud Agent Python](https://github.com/hyperledger/aries-cloudagent-python) and [Credo](https://github.com/openwallet-foundation/credo-ts) +- Supersedes: [Aries RFC 0593: JSON-LD Credential Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md) +- Start Date: 2023-12-18 +- Tags: [feature](/tags.md#feature), [protocol](/tags.md#protocol), [credentials](/tags.md#credentials), [test-anomaly](/tags.md#test-anomaly) + +## Summary + +This RFC registers an attachment format for use in the [issue-credential V2](../0453-issue-credential-v2/README.md) protocol based on W3C Verifiable Credentials with [Data Integrity Proofs](https://www.w3.org/TR/vc-data-integrity/) from the [VC Data Model](https://www.w3.org/TR/vc-data-model/#linked-data-proofs). + +## Motivation + +The Issue Credential protocol needs an attachment format to be able to exchange W3C verifiable credentials. It is desirable to make use of specifications developed in an open standards body, such as the [Credential Manifest](https://identity.foundation/credential-manifest/) for which the attachment format is described in [RFC 0511: Credential-Manifest Attachment format](../0511-dif-cred-manifest-attach/README.md). However, the _Credential Manifest_ is not finished and ready yet, and therefore there is a need to bridge the gap between standards. + +## Tutorial + +Complete examples of messages are provided in the [reference section](#reference). + +## Reference + +### Credential Offer Attachment Format + +Format identifier: `didcomm/w3c-di-vc-offer@v0.1` + +```json +{ + "data_model_versions_supported": ["1.1", "2.0"], + "binding_required": true, + "binding_method": { + "anoncreds_link_secret": { + "nonce": "1234", + "cred_def_id": "did:key:z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT/credential-definition", + "key_correctness_proof": "" + }, + "didcomm_signed_attachment": { + "algs_supported": ["EdDSA"], + "did_methods_supported": ["key", "web"], + "nonce": "1234" + } + }, + "credential": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://w3id.org/security/data-integrity/v2", + { + "@vocab": "https://www.w3.org/ns/credentials/issuer-dependent#" + } + ], + "type": ["VerifiableCredential"], + "issuer": "did:key:z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT", + "issuanceDate": "2024-01-10T04:44:29.563418Z", + "credentialSubject": { + "height": 175, + "age": 28, + "name": "Alex", + "sex": "male" + } + } +} +``` + +- `data_model_versions_supported` - Required. List of strings indicating the supported VC Data Model versions. The list MUST contain at least one value. The values MUST be a valid data model version. Current supported values include `1.1` and `2.0`. +- `binding_required` - Optional. Boolean indicating whether the credential MUST be bound to the holder. If omitted, the credential is not required to be bound to the holder. If set to `true`, the credential MUST be bound to the holder using at least one of the binding methods defined in `binding_method`. +- `binding_method` - Required if `binding_required` is true. Object containing key-value pairs of binding methods supported by the issuer to bind the credential to a holder. If the value is omitted, this indicates the issuer does not support any binding methods for issuance of the credential. See [Binding Methods](#binding-methods) for a registry of default binding methods supported as part of this RFC. +- `credential` - Required. The credential to be issued. The credential MUST be compliant with the **first** `data_model_versions_supported` entry version of VC Data Model, except for the omission of a set required keys that may only be known at the time of issuance. See [Credential Offer Exceptions](#credential-offer-exceptions) for a list of exceptions. The credential MUST NOT contain any proofs. Some properties MAY be omitted if they will only be available at time of issuance, such as `issuanceDate`, `issuer`, `credentialSubject.id`, `credentialStatus`, `credentialStatus.id`. + +#### Credential Offer Exceptions + +To allow for validation of the `credential` according to the corresponding VC Data Model version, the `credential` in the offer MUST be conformant to the corresponding VC Data Model version, except for the exceptions listed below. This still allows the credential to be validated, knowing which deviations are possible. + +The list of exception is as follows: + +- `issuanceDate` (v1.1) or `validFrom` (v2.0) can be omitted, or set to a placeholder value. +- `issuer` (or `issuer.id` if issuer is an object) can be omitted +- `credentialSubject.id` can be omitted +- `credentialStatus` + - Either the whole `credentialStatus` can be omitted + - OR the `credentialStatus.type` can be present, but other required fields that are dynamic can be omitted (such as the `statusListIndex` and `statusListCredential` in case of [Bitstring Status List](https://www.w3.org/TR/vc-bitstring-status-list/)) + +### Credential Request Attachment Format + +Format identifier: `didcomm/w3c-di-vc-request@v0.1` + +This format is used to request a verifiable credential. The JSON structure might look like this: + +```json +{ + "data_model_version": "2.0", + "binding_proof": { + "anoncreds_link_secret": { + "entropy": "", + "cred_def_id": "did:key:z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT/credential-definition", + "blinded_ms": {}, + "blinded_ms_corectness_proof": {}, + "nonce": "" + }, + "didcomm_signed_attachment": { + "attachment_id": "<@id of the attachment>" + } + } +} +``` + +- `data_model_version` - Required. The data model version of the credential to be issued. The value MUST be a valid data model version and match one of the values from the `data_model_versions_supported` offer. +- `binding_proof` - Required if `binding_required` is `true` in the offer. Object containing key-value pairs of proofs for the binding to the holder. The keys MUST match keys of the `binding_method` object from the offer. See [Binding Methods](#binding-methods) for a registry of default binding methods supported as part of this RFC. + +### Credential Attachment Format + +Format identifier: `didcomm/w3c-di-vc@v0.1` + +This format is used to transmit a verifiable credential. The JSON structure might look like this: + +```json +{ + "credential": { + // vc with proof object or array + } +} +``` + +- `credential` - The signed credential. MUST be a valid verifiable credential object with one or more proofs and MUST conform to VC Data Model version as defined in the `data_model_version` of the request. + +It is up to the issuer to the pick an appropriate cryptographic suite to sign the credential. The issuer may use the cryptographic binding material provided by the holder to select the cryptographic suite. For example, when the `anoncreds_link_secret` binding method is used, the issuer should use an `DataIntegrityProof` with the `anoncredsvc-2023` cryptographic suite. When a holder provides a signed attachment as part of the binding proof using the `EdDSA` JWA alg, the issuer could use a `DateIntegrityProof` with the `eddsa-rdfc-2022` cryptographic suite. However, it is not required for the cryptographic suite used for the signature on the credential to be in any way related to the cryptographic suite used for the binding proof, unless the binding method explicitly requires this (for example the `anoncreds_link_secret` binding method). + +A complete [`issue-credential` message from the Issue Credential protocol 2.0](../0453-issue-credential-v2/README.md#issue-credential) might look like this: + +```json +{ + "@id": "284d3996-ba85-45d9-964b-9fd5805517b6", + "@type": "https://didcomm.org/issue-credential/2.0/issue-credential", + "comment": "", + "formats": [ + { + "attach_id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8", + "format": "didcomm/w3c-di-vc@v0.1" + } + ], + "credentials~attach": [ + { + "@id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgICAgICAgIkBjb250ZXogWwogICAgICAg...(clipped)...RNVmR0SXFXZhWXgySkJBIgAgfQogICAgICAgIH0=" + } + } + ] +} +``` + +### Binding Methods + +The attachment format supports different methods to bind the credential to the receiver of the credential. In the offer message the issuer can indicate which binding methods are supported in the `binding_methods` object. Each key represents the id of the supported binding method. + +This section defines a set of binding methods supported by this attachment format, but other binding methods may be used. Based on the binding method, the request needs to include a `binding_proof` object where the key matches the key of the binding method from the offer. + +#### AnonCreds Link Secret + +Identifier: `anoncreds_link_secret` + +This binding method is intended to be used in combination with a credential containing an AnonCreds proof. + +##### Binding Method in Offer + +The structure of the binding method in the offer MUST match the structure of the [Credential Offer](https://hyperledger.github.io/anoncreds-spec/#credential-offer) as defiend in the AonCreds specification, with the exclusion of the `schema_id` key. + +```jsonc +{ + "nonce": "1234", + "cred_def_id": "did:key:z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT/credential-definition", + "key_correctness_proof": { + /* key correctness proof object */ + } +} +``` + +##### Binding Proof in Request + +The structure of the binding proof in the request MUST match the structure of the [Credential Request](https://hyperledger.github.io/anoncreds-spec/#credential-request) as defined in the AnonCreds specification. + +```jsonc +{ + "anoncreds_link_secret": { + "entropy": "", + "blinded_ms": { + /* blinded ms object */ + }, + "blinded_ms_corectness_proof": { + /* blinded ms correctness proof object */ + }, + "nonce": "" + } +} +``` + +##### Binding in Credential + +The issued credential should be bound to the holder by including the blinded link secret in the credential as defined in the [Issue Credential section](https://hyperledger.github.io/anoncreds-spec/#issue-credential) of the AnonCreds specification. Credential bound using the AnonCreds link secret binding method MUST contain an proof with `proof.type` value of `DataIntegrityProof` and `cryptosuite` value of `anoncredsvc-2023`, and conform to the [AnonCreds W3C Verifiable Credential Representation](https://hyperledger.github.io/anoncreds-spec/#w3c-verifiable-credentials-representation). + +#### DIDComm Signed Attachment + +Identifier: `didcomm_signed_attachment` + +This binding method leverages [DIDComm signed attachments](https://github.com/hyperledger/aries-rfcs/blob/main/concepts/0017-attachments/README.md#signing-attachments) to bind a credential to a specific key and/or identifier. + +##### Binding Method in Offer + +```jsonc +{ + "didcomm_signed_attachment": { + "algs_supported": ["EdDSA"], + "did_methods_supported": ["key"], + "nonce": "b19439b0-4dc9-4c28-b796-99d17034fb5c" + } +} +``` + +- `algs_supported` - Required. List of strings indicating the Json Web Algorithms supported by the issuer for verifying the signed attachment. The list MUST contain at least one value. The values MUST be a valid algorithm identifier as defined in the [JSON Web Signature and Encryption Algorithms](https://www.iana.org/assignments/jose/jose.xhtml#web-signature-encryption-algorithms) registry. +- `did_methods_supported` - Required. List of strings indicating which did methods are supported by the issuer for binding the credential to the holder. The list MUST contain at least one value. Values should ONLY include the method identifier of the did method. Examples values include `key` or `web`. +- `nonce` - Required. Nonce to be used in the request to prevent replay attacks of the signed attachment. + +##### Binding Proof in Request + +The binding proof in the request points to an appended attachment containing the signed attachment. + +```json +{ + "didcomm_signed_attachment": { + "attachment_id": "<@id of the attachment>" + } +} +``` + +- `attachment_id` - The id of the appended attachment included in the request message that contains the signed attachment. + +###### Signed Attachment Content + +The attachment MUST be signed by including a signature in the `jws` field of the attachment. The data MUST be a JSON document encoded in the `base64` field of the attachment. The structure of the signed attachment is described below. + +**JWS Payload** + +```json +{ + "nonce": "", +} +``` + +- `nonce` - Required. The `nonce` from the `didcomm_signed_attachment` object within `binding_method` from the credential offer + +**Protected Header** + +```json +{ + "alg": "EdDSA", + "kid": "did:key:z6MkkwiqX7BvkBbi37aNx2vJkCEYSKgHd2Jcgh4AUhi4YY1u#z6MkkwiqX7BvkBbi37aNx2vJkCEYSKgHd2Jcgh4AUhi4YY1u" +} +``` + +- `alg`: REQUIRED. A digital signature algorithm identifier such as per IANA "JSON Web Signature and Encryption Algorithms" registry. MUST NOT be none or an identifier for a symmetric algorithm (MAC). MUST match one of the `algs_supported` entries from the offer `binding_method` object. +- `kid`: REQUIRED. JOSE Header containing the DID URL pointing to a specific key in a did document. The did method of the DID URL MUST match with one of the `did_methods_supported` from the offer `binding_method` object. + +A signed binding request attachment appended to a request message might look like this: + +```json +{ + "@id": "284d3996-ba85-45d9-964b-9fd5805517b6", + "@type": "https://didcomm.org/issue-credential/2.0/request-credential", + "comment": "", + "formats": [ + { + "attach_id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8", + "format": "didcomm/w3c-di-vc-request@v0.1" + } + ], + "~attach": [ + { + "@id": "123", + "mime-type": "application/json", + "data": { + "base64": "", + "jws": { + "protected": "eyJhbGciOiJFZERTQSIsImlhdCI6MTU4Mzg4... (bytes omitted)", + "signature": "3dZWsuru7QAVFUCtTd0s7uc1peYEijx4eyt5... (bytes omitted)" + } + } + } + ], + "credentials~attach": [ + { + "@id": "5b38af88-d36f-4f77-bb7a-2f04ab806eb8", + "mime-type": "application/json", + "data": { + "base64": "ewogICAgICAgICAgIkBjb250ZXogWwogICAgICAg...(clipped)...RNVmR0SXFXZhWXgySkJBIgAgfQogICAgICAgIH0=" + } + } + ] +} +``` + +##### Binding in Credential + +The issued credential should be bound to the holder by including the did in the credential as `credentialSubject.id` or `holder`. + +## Drawbacks + +- While it has a similar setup and structure compared to OpenID for Verifiable Credential Issuance, this attachment format only focuses on issuance of W3C Verifiable Credentials. Therefore another (but probably quite similar) attachment format needs to be defined to support issuance of non-W3C VCs +- There is currently no way for an issuer or holder to indicate which cryptographic suites they support for the signature of the credential. Currently it's at the discretion of the issuer to decide which cryptographic suite to use. In a future (minor) version we can add an optional way for a) the issuer to indicate which cryptographic suites they support, and b) the holder to indicate which cryptographic suites they support. +- There is currently no attachment format defined for a credential proposal. This makes it impossible for a holder to initiate the issuance of a credential using this attachment format. In a future (minor) version the proposal attachment format can be added. + +## Rationale and alternatives + +[RFC 0593: JSON-LD Credential Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md), [W3C VC API](https://w3c-ccg.github.io/vc-api/) allows issuance of credentials using only linked data signatures, while [RFC 0592: Indy Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0592-indy-attachments/README.md) supports issuance of AnonCreds credentials. This attachment format aims to support issuance of both previous attachment formats (while for AnonCreds it now being in the W3C model), as well as supporting additional features such as issuance W3C JWT VCs, credentials with multiple proofs, and cryptographic binding of the credential to the holder. + +## Prior art + +The attachment format in this RFC is heavily inspired by [RFC 0593: JSON-LD Credential Attachment](https://github.com/hyperledger/aries-rfcs/blob/main/features/0593-json-ld-cred-attach/README.md), [W3C VC API](https://w3c-ccg.github.io/vc-api/) and [OpenID for Verifiable Credential Issuance](https://openid.net/specs/openid-4-verifiable-credential-issuance-1_0.html). + +## Unresolved questions diff --git a/index.md b/index.md index 75cbe8c84..227bd313f 100644 --- a/index.md +++ b/index.md @@ -1,107 +1,141 @@ # Aries RFCs by Status ## [ADOPTED](README.md#adopted) - -## [ACCEPTED](README.md#accepted) * [0003: Protocols](concepts/0003-protocols/README.md) (2019-04-01, [10 impls](concepts/0003-protocols/README.md#implementations) — [`concept`](/tags.md#concept)) -* [0004: Agents](concepts/0004-agents/README.md) (2019-01-15, [10 impls](concepts/0004-agents/README.md#implementations) — [`concept`](/tags.md#concept)) * [0005: DID Communication](concepts/0005-didcomm/README.md) (2019-11-21, [10 impls](concepts/0005-didcomm/README.md#implementations) — [`concept`](/tags.md#concept)) -* [0006: SSI Notation](concepts/0006-ssi-notation/README.md) (2018-09-01, [1 impl](concepts/0006-ssi-notation/README.md#implementations) — [`concept`](/tags.md#concept)) * [0008: Message ID and Threading](concepts/0008-message-id-and-threading/README.md) (2018-10-01, [5 impls](concepts/0008-message-id-and-threading/README.md#implementations) — [`concept`](/tags.md#concept)) * [0011: Decorators](concepts/0011-decorators/README.md) (2019-01-31, [10 impls](concepts/0011-decorators/README.md#implementations) — [`concept`](/tags.md#concept) [`decorator`](/tags.md#decorator)) -* [0017: Attachments](concepts/0017-attachments/README.md) (2019-01-31, [2 impls](concepts/0017-attachments/README.md#implementations) — [`concept`](/tags.md#concept)) +* [0015: ACKs](features/0015-acks/README.md) (2024-05-01, [4 impls](features/0015-acks/README.md#implementations) — [`feature`](/tags.md#feature)) +* [0017: Attachments](concepts/0017-attachments/README.md) (2024-05-01, [2 impls](concepts/0017-attachments/README.md#implementations) — [`concept`](/tags.md#concept)) * [0019: Encryption Envelope](features/0019-encryption-envelope/README.md) (2019-05-04, [7 impls](features/0019-encryption-envelope/README.md#implementations) — [`feature`](/tags.md#feature)) * [0020: Message Types](concepts/0020-message-types/README.md) (2019-05-24, [8 impls](concepts/0020-message-types/README.md#implementations) — [`concept`](/tags.md#concept)) +* [0021: DIDComm Message Anatomy](concepts/0021-didcomm-message-anatomy/README.md) (2019-05-25 — [`concept`](/tags.md#concept) [`decorator`](/tags.md#decorator)) +* [0023: DID Exchange v1](features/0023-did-exchange/README.md) (2021-04-15, [1 impl](features/0023-did-exchange/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) * [0025: DIDComm Transports](features/0025-didcomm-transports/README.md) (2019-12-05 — [`feature`](/tags.md#feature)) * [0031: Discover Features Protocol 1.0](features/0031-discover-features/README.md) (2019-05-01, [2 impls](features/0031-discover-features/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) +* [0035: Report Problem Protocol 1.0](features/0035-report-problem/README.md) (2024-05-01, [3 impls](features/0035-report-problem/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) * [0036: Issue Credential Protocol 1.0](features/0036-issue-credential/README.md) (2019-05-28, [1 impl](features/0036-issue-credential/README.md#implementations) — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) * [0037: Present Proof Protocol 1.0](features/0037-present-proof/README.md) (2019-05-28, [1 impl](features/0037-present-proof/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) -* [0046: Mediators and Relays](concepts/0046-mediators-and-relays/README.md) (2019-02-01, [2 impls](concepts/0046-mediators-and-relays/README.md#implementations) — [`concept`](/tags.md#concept)) -* [0047: JSON-LD Compatibility](concepts/0047-json-ld-compatibility/README.md) (2019-02-20 — [`concept`](/tags.md#concept) [`decorator`](/tags.md#decorator)) * [0048: Trust Ping Protocol 1.0](features/0048-trust-ping/README.md) (2019-02-01, [6 impls](features/0048-trust-ping/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) +* [0092: Transports Return Route](features/0092-transport-return-route/README.md) (2024-05-01, [2 impls](features/0092-transport-return-route/README.md#implementations) — [`feature`](/tags.md#feature)) +* [0094: Cross-Domain Messaging](concepts/0094-cross-domain-messaging/README.md) (2024-05-01 — [`concept`](/tags.md#concept)) +* [0095: Basic Message Protocol 1.0](features/0095-basic-message/README.md) (2019-08-06, [6 impls](features/0095-basic-message/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) +* [0160: Connection Protocol](features/0160-connection-protocol/README.md) (2019-08-06, [6 impls](features/0160-connection-protocol/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) +* [0211: Mediator Coordination Protocol](features/0211-route-coordination/README.md) (2024-05-01, [2 impls](features/0211-route-coordination/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) +* [0302: Aries Interop Profile](concepts/0302-aries-interop-profile/README.md) (2021-01-06 — [`concept`](/tags.md#concept)) +* [0360: did:key Usage](features/0360-use-did-key/README.md) (2024-05-01 — [`feature`](/tags.md#feature)) +* [0434: Out-of-Band Protocol 1.1](features/0434-outofband/README.md) (2020-03-01 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) +* [0441: Prover and Verifier Best Practices for Proof Presentation](concepts/0441-present-proof-best-practices/README.md) (2024-05-01 — [`concept`](/tags.md#concept) [`credentials`](/tags.md#credentials)) +* [0453: Issue Credential Protocol 2.0](features/0453-issue-credential-v2/README.md) (2021-04-15 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) +* [0454: Present Proof Protocol 2.0](features/0454-present-proof-v2/README.md) (2021-04-15 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) +* [0496: Transition to the Out of Band Protocol](features/0496-transition-to-oob-and-did-exchange/README.md) (2021-11-24 — [`feature`](/tags.md#feature) [`community-update`](/tags.md#community-update) [`test-anomaly`](/tags.md#test-anomaly)) +* [0510: Presentation-Exchange Attachment format for requesting and presenting proofs](features/0510-dif-pres-exch-attach/README.md) (2020-07-21 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) +* [0557: Discover Features Protocol v2.x](features/0557-discover-features-v2/README.md) (2024-05-01 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) +* [0592: Indy Attachment Formats for Requesting and Presenting Credentials](features/0592-indy-attachments/README.md) (2021-04-15 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) +* [0593: JSON-LD Credential Attachment format for requesting and issuing credentials](features/0593-json-ld-cred-attach/README.md) (2021-04-15 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) + +## [ACCEPTED](README.md#accepted) +* [0004: Agents](concepts/0004-agents/README.md) (2019-01-15, [11 impls](concepts/0004-agents/README.md#implementations) — [`concept`](/tags.md#concept)) +* [0006: SSI Notation](concepts/0006-ssi-notation/README.md) (2018-09-01, [1 impl](concepts/0006-ssi-notation/README.md#implementations) — [`concept`](/tags.md#concept)) +* [0044: DIDComm File and MIME Types](features/0044-didcomm-file-and-mime-types/README.md) (2021-04-15 — [`feature`](/tags.md#feature)) +* [0046: Mediators and Relays](concepts/0046-mediators-and-relays/README.md) (2019-02-01, [3 impls](concepts/0046-mediators-and-relays/README.md#implementations) — [`concept`](/tags.md#concept)) +* [0047: JSON-LD Compatibility](concepts/0047-json-ld-compatibility/README.md) (2019-02-20 — [`concept`](/tags.md#concept) [`decorator`](/tags.md#decorator)) * [0049: Repudiation](concepts/0049-repudiation/README.md) (2019-03-01 — [`concept`](/tags.md#concept)) * [0050: Wallets](concepts/0050-wallets/README.md) (2018-07-01, [1 impl](concepts/0050-wallets/README.md#implementations) — [`concept`](/tags.md#concept)) -* [0092: Transports Return Route](features/0092-transport-return-route/README.md) (2019-12-06, [2 impls](features/0092-transport-return-route/README.md#implementations) — [`feature`](/tags.md#feature)) -* [0094: Cross-Domain Messaging](concepts/0094-cross-domain-messaging/README.md) (2018-10-29 — [`concept`](/tags.md#concept)) -* [0095: Basic Message Protocol 1.0](features/0095-basic-message/README.md) (2019-08-06, [6 impls](features/0095-basic-message/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) -* [0160: Connection Protocol](features/0160-connection-protocol/README.md) (2019-08-06, [5 impls](features/0160-connection-protocol/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`test-anomaly`](/tags.md#test-anomaly)) -* [0250: Rich Schema Objects](concepts/0250-rich-schemas/README.md) (2019-10-08 — [`concept`](/tags.md#concept) [`rich-schemas`](/tags.md#rich-schemas)) -* [0302: Aries Interop Profile](concepts/0302-aries-interop-profile/README.md) (2020-01-30 — [`concept`](/tags.md#concept)) -* [0348: Transition Message Type to HTTPs](features/0348-transition-msg-type-to-https/README.md) (2020-01-30, [12 impls](features/0348-transition-msg-type-to-https/README.md#implementations) — [`feature`](/tags.md#feature) [`community-update`](/tags.md#community-update)) +* [0183: Revocation Notification 1.0](features/0183-revocation-notification/README.md) (2024-05-01 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0519: Goal Codes](concepts/0519-goal-codes/README.md) (2021-04-15 — [`concept`](/tags.md#concept)) +* [0587: Encryption Envelope v2](features/0587-encryption-envelope-v2/README.md) (2021-04-15 — [`feature`](/tags.md#feature)) +* [0646: W3C Credential Exchange using BBS+ Signatures](features/0646-bbs-credentials/README.md) (2021-04-28 — [`feature`](/tags.md#feature)) +* [0685: Pickup Protocol 2.0](features/0685-pickup-v2/README.md) (2024-05-01 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0721: Revocation Notification 2.0](features/0721-revocation-notification-v2/README.md) (2024-05-01 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0793: Unqualified DID Transition](features/0793-unqualfied-dids-transition/README.md) (2023-07-11, [12 impls](features/0793-unqualfied-dids-transition/README.md#implementations) — [`feature`](/tags.md#feature) [`community-update`](/tags.md#community-update)) +* [0794: DID Rotate 1.0](features/0794-did-rotate/README.md) (2024-03-02 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) ## [DEMONSTRATED](README.md#demonstrated) -* [0015: ACKs](features/0015-acks/README.md) (2019-12-26, [4 impls](features/0015-acks/README.md#implementations) — [`feature`](/tags.md#feature)) -* [0023: DID Exchange Protocol 1.0](features/0023-did-exchange/README.md) (2019-05-27, [1 impl](features/0023-did-exchange/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0029: Message Trust Contexts](concepts/0029-message-trust-contexts/README.md) (2019-05-10, [3 impls](concepts/0029-message-trust-contexts/README.md#implementations) — [`concept`](/tags.md#concept)) * [0032: Message Timing](features/0032-message-timing/README.md) (2019-05-01, [1 impl](features/0032-message-timing/README.md#implementations) — [`feature`](/tags.md#feature)) -* [0035: Report Problem Protocol 1.0](features/0035-report-problem/README.md) (2019-04-01, [3 impls](features/0035-report-problem/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0042: LOX -- A more secure pluggable framework for protecting wallet keys](features/0042-lox/README.md) (2019-05-30, [1 impl](features/0042-lox/README.md#implementations) — [`feature`](/tags.md#feature)) * [0043: l10n (Locali[s|z]ation)](features/0043-l10n/README.md) (2019-04-01, [4 impls](features/0043-l10n/README.md#implementations) — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) -* [0051: Decentralized Key Management](concepts/0051-dkms/README.md) (2019-03-29, [2 impls](concepts/0051-dkms/README.md#implementations) — [`concept`](/tags.md#concept)) * [0113: Question Answer Protocol 0.9](features/0113-question-answer/README.md) (2019-07-05, [2 impls](features/0113-question-answer/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0234: Signature Decorator](features/0234-signature-decorator/README.md) (2019-09-27, [3 impls](features/0234-signature-decorator/README.md#implementations) — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) -* [0509: Action Menu Protocol](features/0509-action-menu/README.md) (2020-07-02 , [1 impl](features/0509-action-menu/README.md#implementations) — [`feature`](/tags.md#feature)) +* [0509: Action Menu Protocol](features/0509-action-menu/README.md) (2020-07-02 , [1 impl](features/0509-action-menu/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0748: N-wise DID Exchange Protocol 1.0](features/0748-n-wise-did-exchange/README.md) (2022-08-03, [1 impl](features/0748-n-wise-did-exchange/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0755: Overlays Capture Architecture (OCA) For Aries](features/0755-oca-for-aries/README.md) (2024-03-02 — [`feature`](/tags.md#feature)) +* [0756: OCA for Aries Style Guide](features/0756-oca-for-aries-style-guide/README.md) (2023-01-05 — [`feature`](/tags.md#feature)) +* [0780: Use Data URLs for Images and More in Credential Attributes](features/0780-data-urls-images/README.md) (2024-03-02 — [`feature`](/tags.md#feature)) +* [0804: DIDComm Remote Procedure Call (DRPC)](features/0804-didcomm-rpc/README.md) (2024-03-02 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0809: W3C Verifiable Credential Data Integrity Attachment format for requesting and issuing credentials](features/0809-w3c-data-integrity-credential-attachment/README.md) (2024-01-10 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) ## [PROPOSED](README.md#proposed) -* [0013: Overlays](concepts/0013-overlays/README.md) (2019-05-20 — [`concept`](/tags.md#concept)) -* [0021: DIDComm Message Anatomy](concepts/0021-didcomm-message-anatomy/README.md) (2019-05-25 — [`concept`](/tags.md#concept) [`decorator`](/tags.md#decorator)) -* [0024: DIDComm over XMPP](features/0024-didcomm-over-xmpp/README.md) (2019-06-14 — [`feature`](/tags.md#feature)) * [0028: Introduce Protocol 1.0](features/0028-introduce/README.md) (2019-04-15 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0030: Sync Connection Protocol 1.0](features/0030-sync-connection/README.md) (2019-07-03 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator) [`protocol`](/tags.md#protocol)) * [0034: Message Tracing](features/0034-message-tracing/README.md) (2018-10-24 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) -* [0044: DIDComm File and MIME Types](features/0044-didcomm-file-and-mime-types/README.md) (2019-05-28 — [`feature`](/tags.md#feature)) * [0056: Service Decorator](features/0056-service-decorator/README.md) (2019-06-03 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) * [0066: Non-Repudiable Signature for Cryptographic Envelope](features/0066-non-repudiable-cryptographic-envelope/README.md) (2019-04-15 — [`feature`](/tags.md#feature)) * [0067: DIDComm DID document conventions](features/0067-didcomm-diddoc-conventions/README.md) (2019-06-10 — [`feature`](/tags.md#feature)) * [0074: DIDComm Best Practices](concepts/0074-didcomm-best-practices/README.md) (2019-06-10 — [`concept`](/tags.md#concept)) -* [0075: Payment Decorators](features/0075-payment-decorators/README.md) (2019-06-11 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) * [0103: Indirect Identity Control](concepts/0103-indirect-identity-control/README.md) (2019-06-04 — [`concept`](/tags.md#concept) [`credentials`](/tags.md#credentials)) * [0104: Chained Credentials](concepts/0104-chained-credentials/README.md) (2019-09-09 — [`concept`](/tags.md#concept) [`credentials`](/tags.md#credentials)) -* [0114: Predefined Identities](features/0114-predefined-identities/README.md) (2019-07-10 — [`feature`](/tags.md#feature)) -* [0116: Evidence Exchange Protocol 0.9](features/0116-evidence-exchange/README.md) (2019-07-26 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0124: DID Resolution Protocol 0.9](features/0124-did-resolution-protocol/README.md) (2019-07-13 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0167: Data Consent Lifecycle](concepts/0167-data-consent-lifecycle/README.md) (2019-08-07 (updated 2019-03-16) — [`concept`](/tags.md#concept)) -* [0183: Revocation Notification 1.0](features/0183-revocation-notification/README.md) (2019-08-12 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0193: Coin Flip Protocol 1.0 ](features/0193-coin-flip/README.md) (2019-08-19 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0207: Credential Fraud Threat Model](concepts/0207-credential-fraud-threat-model/README.md) (2019-08-30 — [`concept`](/tags.md#concept) [`credentials`](/tags.md#credentials)) -* [0211: Mediator Coordination Protocol](features/0211-route-coordination/README.md) (2019-09-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0212: Pickup Protocol](features/0212-pickup/README.md) (2019-09-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0213: Transfer Policy Protocol](features/0213-transfer-policy/README.md) (2019-09-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0214: "Help Me Discover" Protocol](features/0214-help-me-discover/README.md) (2019-09-10 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0217: Linkable Message Paths](concepts/0217-linkable-message-paths/README.md) (2019-09-10 — [`concept`](/tags.md#concept)) * [0231: Biometric Service Provider](concepts/0231-biometric-service-provider/README.md) (2019-09-24 — [`concept`](/tags.md#concept)) -* [0249: Aries Rich Schema Contexts](features/0249-rich-schema-contexts/README.md) (2019-10-08 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) -* [0257: Private Credential Issuance](concepts/0257-private-credential-issuance/README.md) (2019-10-16 — [`concept`](/tags.md#concept) [`protocol`](/tags.md#protocol)) -* [0268: Unified DIDCOMM Deeplinking](concepts/0268-unified-didcomm-agent-deeplinking/README.md) (2019-10-23 — [`concept`](/tags.md#concept) [`agents`](/tags.md#agents) [`mobile`](/tags.md#mobile)) +* [0268: Unified DIDCOMM Deeplinking](concepts/0268-unified-didcomm-agent-deeplinking/README.md) (2019-10-23 — [`concept`](/tags.md#concept)) * [0270: Interop Test Suite](concepts/0270-interop-test-suite/README.md) (2019-10-25 — [`concept`](/tags.md#concept)) -* [0281: Aries Rich Schemas](features/0281-rich-schemas/README.md) (2019-10-30 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) -* [0289: The Trust Over IP Stack](concepts/0289-toip-stack/README.md) (2019-11-04 — [`concept`](/tags.md#concept) [`stack`](/tags.md#stack) [`trust layer`](/tags.md#trust layer) [`governance framework`](/tags.md#governance framework)) -* [0309: DIDAuthZ](features/0309-didauthz/README.md) (2019-11-14 — [`feature`](/tags.md#feature) [`credentials`](/tags.md#credentials)) -* [0317: Please ACK Decorator](features/0317-please-ack/README.md) (2019-12-26 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) -* [0327: Crypto service Protocol 1.0](features/0327-crypto-service/README.md) (2019-11-20 (date you submit your PR) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0334: JWE envelope 1.0](features/0334-jwe-envelope/README.md) (2019-11-28 — [`feature`](/tags.md#feature)) -* [0335: HTTP Over DIDComm](features/0335-http-over-didcomm/README.md) (2019-12-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0345: Community Coordinated Update](concepts/0345-community-coordinated-update/README.md) (2019-12-26 (date you submit your PR) — [`concept`](/tags.md#concept)) -* [0346: DIDCOMM BETWEEN TWO MOBILE AGENTS USING CLOUD AGENT MEDIATOR](concepts/0346-didcomm-between-two-mobile-agents/README.md) (2019-06-23 — [`concept`](/tags.md#concept)) +* [0346: DIDComm Between Two Mobile Agents Using Cloud Agent Mediator](concepts/0346-didcomm-between-two-mobile-agents/README.md) (2019-06-23 — [`concept`](/tags.md#concept)) * [0347: Proof Negotiation](features/0347-proof-negotiation/README.md) (2019-12-13 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) -* [0351: Purpose Decorator](features/0351-purpose-decorator/README.md) (2019-12-16 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) -* [0360: did:key Usage](features/0360-use-did-key/README.md) (2019-12-17 — [`feature`](/tags.md#feature)) -* [0418: Aries Rich Schema Encoding Objects](features/0418-rich-schema-encoding/README.md) (2020-02-10 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) -* [0420: Rich Schema Objects Common](concepts/0420-rich-schemas-common/README.md) (2020-02-13 — [`concept`](/tags.md#concept) [`rich-schemas`](/tags.md#rich-schemas)) -* [0428: Prerequisites to Issue Rich Credential](features/0428-prepare-issue-rich-credential/README.md) (2020-02-20 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) -* [0429: Prerequisites to Request Rich Presentation](features/0429-prepare-req-rich-pres/README.md) (2020-02-21 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) * [0430: Machine-Readable Governance Frameworks](concepts/0430-machine-readable-governance-frameworks/README.md) (2020-02-24 — [`concept`](/tags.md#concept)) -* [0434: Out-of-Band Protocols](features/0434-outofband/README.md) (2020-03-01 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) * [0440: KMS Architectures ](concepts/0440-kms-architectures/README.md) (2020-03-06 — [`concept`](/tags.md#concept)) -* [0445: Aries Rich Schema Mapping](features/0445-rich-schema-mapping/README.md) (2020-03-16 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) -* [0445: Aries Rich Schema Credential Definition](features/0446-rich-schema-cred-def/README.md) (2020-03-16 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) -* [0453: Issue Credential Protocol 2.0](features/0453-issue-credential-v2/README.md) (2020-03-23 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) -* [0454: Present Proof Protocol 2.0](features/0454-present-proof-v2/README.md) (2020-05-27 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) -* [0510: Presentation-Exchange Attachment format for requesting and presenting proofs](features/0510-dif-pres-exch-attach/README.md) (2020-07-21 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) * [0511: Credential-Manifest Attachment format for requesting and presenting credentials](features/0511-dif-cred-manifest-attach/README.md) (2020-07-22 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) +* [0559: Privacy-Preserving Proof of Uniqueness](concepts/0559-pppu/README.md) (2020-10-21 — [`concept`](/tags.md#concept)) +* [0566: Issuer-Hosted Custodial Agents](concepts/0566-issuer-hosted-custodidal-agents/README.md) (2020-11-16 — [`concept`](/tags.md#concept)) +* [0641: Linking binary objects to credentials using hash based references](features/0641-linking-binary-objects-to-credentials/README.md) (2021-04-22 — [`feature`](/tags.md#feature) [`credentials`](/tags.md#credentials)) +* [0693: Cross-Platform Credential Representation](features/0693-credential-representation/README.md) (2021-07-06 — [`feature`](/tags.md#feature)) +* [0699: Push Notifications apns Protocol 1.0](features/0699-push-notifications-apns/README.md) (2021-10-07 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0700: Out-of-Band through redirect](concepts/0700-oob-through-redirect/README.md) (2021-10-08 — [`concept`](/tags.md#concept) [`decorator`](/tags.md#decorator)) +* [0728: Device Binding Attachments](features/0728-device-binding-attachments/README.md) (2022-04-07 — [`feature`](/tags.md#feature)) +* [0734: Push Notifications fcm Protocol 1.0](features/0734-push-notifications-fcm/README.md) (2022-05-12 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0757: Push Notification](concepts/0757-push-notification/README.md) (2022-11-02 — [`concept`](/tags.md#concept)) +* [0771: AnonCreds Attachment Formats for Requesting and Presenting Credentials](features/0771-anoncreds-attachments/README.md) (2023-02-24 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol) [`credentials`](/tags.md#credentials) [`test-anomaly`](/tags.md#test-anomaly)) +* [0799: Aries Long Term Support Releases](concepts/0799-long-term-support/README.md) (2023-11-07 — [`concept`](/tags.md#concept)) + +## [STALLED](README.md#stalled) +* [0024: DIDComm over XMPP](features/0024-didcomm-over-xmpp/README.md) (2024-04-03 — [`feature`](/tags.md#feature)) +* [0029: Message Trust Contexts](concepts/0029-message-trust-contexts/README.md) (2024-04-03, [3 impls](concepts/0029-message-trust-contexts/README.md#implementations) — [`concept`](/tags.md#concept)) +* [0030: Sync Connection Protocol 1.0](features/0030-sync-connection/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator) [`protocol`](/tags.md#protocol)) +* [0075: Payment Decorators](features/0075-payment-decorators/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) +* [0114: Predefined Identities](features/0114-predefined-identities/README.md) (2024-04-03 — [`feature`](/tags.md#feature)) +* [0116: Evidence Exchange Protocol 0.9](features/0116-evidence-exchange/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0193: Coin Flip Protocol 1.0 ](features/0193-coin-flip/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0207: Credential Fraud Threat Model](concepts/0207-credential-fraud-threat-model/README.md) (2024-04-03 — [`concept`](/tags.md#concept) [`credentials`](/tags.md#credentials)) +* [0217: Linkable Message Paths](concepts/0217-linkable-message-paths/README.md) (2024-04-03 — [`concept`](/tags.md#concept)) +* [0249: Aries Rich Schema Contexts](features/0249-rich-schema-contexts/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) +* [0250: Rich Schema Objects](concepts/0250-rich-schemas/README.md) (2024-04-03 — [`concept`](/tags.md#concept) [`rich-schemas`](/tags.md#rich-schemas)) +* [0257: Private Credential Issuance](concepts/0257-private-credential-issuance/README.md) (2024-04-03 — [`concept`](/tags.md#concept) [`protocol`](/tags.md#protocol)) +* [0281: Aries Rich Schemas](features/0281-rich-schemas/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) +* [0289: The Trust Over IP Stack](concepts/0289-toip-stack/README.md) (2024-04-03 — [`concept`](/tags.md#concept) [`stack`](/tags.md#stack) [`trust layer`](/tags.md#trust layer) [`governance framework`](/tags.md#governance framework)) +* [0309: DIDAuthZ](features/0309-didauthz/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`credentials`](/tags.md#credentials)) +* [0327: Crypto service Protocol 1.0](features/0327-crypto-service/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0334: JWE envelope 1.0](features/0334-jwe-envelope/README.md) (2024-04-03 — [`feature`](/tags.md#feature)) +* [0335: HTTP Over DIDComm](features/0335-http-over-didcomm/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0351: Purpose Decorator](features/0351-purpose-decorator/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) +* [0418: Aries Rich Schema Encoding Objects](features/0418-rich-schema-encoding/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) +* [0420: Rich Schema Objects Common](concepts/0420-rich-schemas-common/README.md) (2024-04-03 — [`concept`](/tags.md#concept) [`rich-schemas`](/tags.md#rich-schemas)) +* [0428: Prerequisites to Issue Rich Credential](features/0428-prepare-issue-rich-credential/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) +* [0429: Prerequisites to Request Rich Presentation](features/0429-prepare-req-rich-pres/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) +* [0445: Aries Rich Schema Mapping](features/0445-rich-schema-mapping/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) +* [0446: Aries Rich Schema Credential Definition](features/0446-rich-schema-cred-def/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`rich-schemas`](/tags.md#rich-schemas)) +* [0478: Coprotocols](concepts/0478-coprotocols/README.md) (2024-04-03 — [`concept`](/tags.md#concept) [`protocol`](/tags.md#protocol)) +* [0482: Coprotocol Protocol 0.5](features/0482-coprotocol-protocol/README.md) (2024-04-03 — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) ## [RETIRED](README.md#retired) +* [0013: Overlays](concepts/0013-overlays/README.md) (2023-01-15 — [`concept`](/tags.md#concept)) +* [0051: Decentralized Key Management](concepts/0051-dkms/README.md) (2024-04-03, [2 impls](concepts/0051-dkms/README.md#implementations) — [`concept`](/tags.md#concept)) +* [0234: Signature Decorator](features/0234-signature-decorator/README.md) (2020-10-14, [3 impls](features/0234-signature-decorator/README.md#implementations) — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) * [0303: V0.1 Credential Exchange (Deprecated)](features/0303-v01-credential-exchange/README.md) (2019-11-12, [4 impls](features/0303-v01-credential-exchange/README.md#implementations) — [`feature`](/tags.md#feature) [`protocol`](/tags.md#protocol)) +* [0317: Please ACK Decorator](features/0317-please-ack/README.md) (2019-12-26 — [`feature`](/tags.md#feature) [`decorator`](/tags.md#decorator)) +* [0348: Transition Message Type to HTTPs](features/0348-transition-msg-type-to-https/README.md) (2020-08-26, [14 impls](features/0348-transition-msg-type-to-https/README.md#implementations) — [`feature`](/tags.md#feature) [`community-update`](/tags.md#community-update)) +* [0627: Static Peer DIDs](features/0627-static-peer-dids/README.md) (2021-04-07 — [`feature`](/tags.md#feature)) >(This file is machine-generated; see [code/generate_index.py](code/generate_index.py).) diff --git a/mkdocs-requirements.txt b/mkdocs-requirements.txt new file mode 100644 index 000000000..05cd7cb50 --- /dev/null +++ b/mkdocs-requirements.txt @@ -0,0 +1,3 @@ + +mkdocs-material==9.5.39 +mike==2.1.3 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..826526691 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,254 @@ +site_name: Hyperledger Aries Interoperability Profiles / RFCs +repo_name: hyperledger/aries-rfcs +repo_url: https://github.com/hyperledger/aries-rfcs +theme: + name: material + # custom_dir: overrides + logo: https://raw.githubusercontent.com/hyperledger/aries-rfcs/main/collateral/Hyperledger_Aries_Logo_White.png + favicon: https://raw.githubusercontent.com/hyperledger/aries-rfcs/main/collateral/favicon.ico + icon: + repo: fontawesome/brands/github + palette: + - primary: green + # Palette toggle for light mode + - media: "(prefers-color-scheme: light)" + scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + # Palette toggle for dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - content.code.copy + - navigation.expand + - navigation.footer + - navigation.instant + - navigation.tabs + - navigation.tabs.sticky + - navigation.top + - navigation.tracking + - toc.follow +# - toc.integrate +markdown_extensions: + - abbr + - admonition + - attr_list + - def_list + - footnotes + - md_in_html + - toc: + permalink: true + toc_depth: 3 + - pymdownx.arithmatex: + generic: true + - pymdownx.betterem: + smart_enable: all + - pymdownx.caret + - pymdownx.details + - pymdownx.emoji: + emoji_generator: !!python/name:material.extensions.emoji.to_svg + emoji_index: !!python/name:material.extensions.emoji.twemoji + - pymdownx.highlight: + anchor_linenums: true + - pymdownx.inlinehilite + - pymdownx.keys + - pymdownx.magiclink: + repo_url_shorthand: true + user: squidfunk + repo: mkdocs-material + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + - pymdownx.tilde +plugins: + - search +# extra: +nav: +- Welcome: + - Welcome: README.md + - All RFCs by Status: RFCindex.md + - RFC Template: 0000-template.md + - Protocol RFC Template: 0000-template-protocol.md +- Governance: + - Maintainers: MAINTAINERS.md + - Contributing: contributing.md + - Submitting Issues: github-issues.md + - License: LICENSE.md + - Security: SECURITY.md +# RFCs by AIP and Status +- AIP 2.0: + - Aries RFC 0003 Protocols: aip2/0003-protocols/README.md + - Aries RFC 0004 Agents: aip2/0004-agents/README.md + - Aries RFC 0005 DID Communication: aip2/0005-didcomm/README.md + - Aries RFC 0008 Message ID and Threading: aip2/0008-message-id-and-threading/README.md + - Aries RFC 0011 Decorators: aip2/0011-decorators/README.md + - Aries RFC 0015 ACKs: aip2/0015-acks/README.md + - Aries RFC 0017 Attachments: aip2/0017-attachments/README.md + - Aries RFC 0019 Encryption Envelope: aip2/0019-encryption-envelope/README.md + - Aries RFC 0020 Message Types: aip2/0020-message-types/README.md + - Aries RFC 0023 DID Exchange Protocol 1.0: aip2/0023-did-exchange/README.md + - Aries RFC 0025 DIDComm Transports: aip2/0025-didcomm-transports/README.md + - Aries RFC 0035 Report Problem Protocol 1.0: aip2/0035-report-problem/README.md + - Aries RFC 0044 DIDComm File and MIME Types: aip2/0044-didcomm-file-and-mime-types/README.md + - Aries RFC 0046 Mediators and Relays: aip2/0046-mediators-and-relays/README.md + - Aries RFC 0047 JSON-LD Compatibility: aip2/0047-json-ld-compatibility/README.md + - Aries RFC 0048 Trust Ping Protocol 1.0: aip2/0048-trust-ping/README.md + - Aries RFC 0050 Wallets: aip2/0050-wallets/README.md + - Aries RFC 0092 Transports Return Route: aip2/0092-transport-return-route/README.md + - Aries RFC 0094 Cross-Domain Messaging: aip2/0094-cross-domain-messaging/README.md + - Aries RFC 0095 Basic Message Protocol 1.0: aip2/0095-basic-message/README.md + - Aries RFC 0183 Revocation Notification 1.0: aip2/0183-revocation-notification/README.md + - 0211 Mediator Coordination Protocol: aip2/0211-route-coordination/README.md + - Aries RFC 0360 did:key Usage: aip2/0360-use-did-key/README.md + - Aries RFC 0434 Out-of-Band Protocol 1.1: aip2/0434-outofband/README.md + - 0441 Prover and Verifier Best Practices for Proof Presentation: aip2/0441-present-proof-best-practices/README.md + - Aries RFC 0453 Issue Credential Protocol 2.0: aip2/0453-issue-credential-v2/README.md + - Aries RFC 0454 Present Proof Protocol 2.0: aip2/0454-present-proof-v2/README.md + - Aries RFC 0510 Presentation-Exchange Attachment format for requesting and presenting proofs: aip2/0510-dif-pres-exch-attach/README.md + - 0519 Goal Codes: aip2/0519-goal-codes/README.md + - Aries RFC 0557 Discover Features Protocol v2.x: aip2/0557-discover-features-v2/README.md + - Aries RFC 0592 Indy Attachment Formats for Requesting and Presenting Credentials: aip2/0592-indy-attachments/README.md + - Aries RFC 0593 JSON-LD Credential Attachment format for requesting and issuing credentials: aip2/0593-json-ld-cred-attach/README.md +- ADOPTED: + - 0003 Protocols: concepts/0003-protocols/README.md + - 0005 DID Communication: concepts/0005-didcomm/README.md + - 0008 Message ID and Threading: concepts/0008-message-id-and-threading/README.md + - 0011 Decorators: concepts/0011-decorators/README.md + - 0015 ACKs: features/0015-acks/README.md + - 0017 Attachments: concepts/0017-attachments/README.md + - 0019 Encryption Envelope: features/0019-encryption-envelope/README.md + - 0020 Message Types: concepts/0020-message-types/README.md + - 0021 DIDComm Message Anatomy: concepts/0021-didcomm-message-anatomy/README.md + - 0023 DID Exchange v1: features/0023-did-exchange/README.md + - 0025 DIDComm Transports: features/0025-didcomm-transports/README.md + - 0031 Discover Features Protocol 1.0: features/0031-discover-features/README.md + - 0035 Report Problem Protocol 1.0: features/0035-report-problem/README.md + - 0036 Issue Credential Protocol 1.0: features/0036-issue-credential/README.md + - 0037 Present Proof Protocol 1.0: features/0037-present-proof/README.md + - 0048 Trust Ping Protocol 1.0: features/0048-trust-ping/README.md + - 0092 Transports Return Route: features/0092-transport-return-route/README.md + - 0094 Cross-Domain Messaging: concepts/0094-cross-domain-messaging/README.md + - 0095 Basic Message Protocol 1.0: features/0095-basic-message/README.md + - 0160 Connection Protocol: features/0160-connection-protocol/README.md + - 0211 Mediator Coordination Protocol: features/0211-route-coordination/README.md + - 0302 Aries Interop Profile: concepts/0302-aries-interop-profile/README.md + - 0360 did:key Usage: features/0360-use-did-key/README.md + - 0434 Out-of-Band Protocol 1.1: features/0434-outofband/README.md + - 0441 Prover and Verifier Best Practices for Proof Presentation: concepts/0441-present-proof-best-practices/README.md + - 0453 Issue Credential Protocol 2.0: features/0453-issue-credential-v2/README.md + - 0454 Present Proof Protocol 2.0: features/0454-present-proof-v2/README.md + - 0496 Transition to the Out of Band Protocol: features/0496-transition-to-oob-and-did-exchange/README.md + - 0510 Presentation-Exchange Attachment format for requesting and presenting proofs: features/0510-dif-pres-exch-attach/README.md + - 0557 Discover Features Protocol v2.x: features/0557-discover-features-v2/README.md + - 0592 Indy Attachment Formats for Requesting and Presenting Credentials: features/0592-indy-attachments/README.md + - 0593 JSON-LD Credential Attachment format for requesting and issuing credentials: features/0593-json-ld-cred-attach/README.md +- ACCEPTED: + - 0004 Agents: concepts/0004-agents/README.md + - 0006 SSI Notation: concepts/0006-ssi-notation/README.md + - 0044 DIDComm File and MIME Types: features/0044-didcomm-file-and-mime-types/README.md + - 0046 Mediators and Relays: concepts/0046-mediators-and-relays/README.md + - 0047 JSON-LD Compatibility: concepts/0047-json-ld-compatibility/README.md + - 0049 Repudiation: concepts/0049-repudiation/README.md + - 0050 Wallets: concepts/0050-wallets/README.md + - 0183 Revocation Notification 1.0: features/0183-revocation-notification/README.md + - 0519 Goal Codes: concepts/0519-goal-codes/README.md + - 0587 Encryption Envelope v2: features/0587-encryption-envelope-v2/README.md + - 0646 W3C Credential Exchange using BBS+ Signatures: features/0646-bbs-credentials/README.md + - 0685 Pickup Protocol 2.0: features/0685-pickup-v2/README.md + - 0721 Revocation Notification 2.0: features/0721-revocation-notification-v2/README.md + - 0793 Unqualified DID Transition: features/0793-unqualfied-dids-transition/README.md + - 0794 DID Rotate 1.0: features/0794-did-rotate/README.md +- DEMONSTRATED: + - 0032 Message Timing: features/0032-message-timing/README.md + - 0042 LOX -- A more secure pluggable framework for protecting wallet keys: features/0042-lox/README.md + - 0043 l10n (Locali[s|z]ation): features/0043-l10n/README.md + - 0113 Question Answer Protocol 0.9: features/0113-question-answer/README.md + - 0509 Action Menu Protocol: features/0509-action-menu/README.md + - 0748 N-wise DID Exchange Protocol 1.0: features/0748-n-wise-did-exchange/README.md + - 0755 Overlays Capture Architecture (OCA) For Aries: features/0755-oca-for-aries/README.md + - 0756 OCA for Aries Style Guide: features/0756-oca-for-aries-style-guide/README.md + - 0780 Use Data URLs for Images and More in Credential Attributes: features/0780-data-urls-images/README.md + - 0804 DIDComm Remote Procedure Call (DRPC): features/0804-didcomm-rpc/README.md + - 0809 W3C Verifiable Credential Data Integrity Attachment format for requesting and issuing credentials: features/0809-w3c-data-integrity-credential-attachment/README.md +- PROPOSED: + - 0028 Introduce Protocol 1.0: features/0028-introduce/README.md + - 0034 Message Tracing: features/0034-message-tracing/README.md + - 0056 Service Decorator: features/0056-service-decorator/README.md + - 0066 Non-Repudiable Signature for Cryptographic Envelope: features/0066-non-repudiable-cryptographic-envelope/README.md + - 0067 DIDComm DID document conventions: features/0067-didcomm-diddoc-conventions/README.md + - 0074 DIDComm Best Practices: concepts/0074-didcomm-best-practices/README.md + - 0103 Indirect Identity Control: concepts/0103-indirect-identity-control/README.md + - 0104 Chained Credentials: concepts/0104-chained-credentials/README.md + - 0124 DID Resolution Protocol 0.9: features/0124-did-resolution-protocol/README.md + - 0167 Data Consent Lifecycle: concepts/0167-data-consent-lifecycle/README.md + - 0212 Pickup Protocol: features/0212-pickup/README.md + - 0213 Transfer Policy Protocol: features/0213-transfer-policy/README.md + - 0214 "Help Me Discover" Protocol: features/0214-help-me-discover/README.md + - 0231 Biometric Service Provider: concepts/0231-biometric-service-provider/README.md + - 0268 Unified DIDCOMM Deeplinking: concepts/0268-unified-didcomm-agent-deeplinking/README.md + - 0270 Interop Test Suite: concepts/0270-interop-test-suite/README.md + - 0345 Community Coordinated Update: concepts/0345-community-coordinated-update/README.md + - 0346 DIDComm Between Two Mobile Agents Using Cloud Agent Mediator: concepts/0346-didcomm-between-two-mobile-agents/README.md + - 0347 Proof Negotiation: features/0347-proof-negotiation/README.md + - 0430 Machine-Readable Governance Frameworks: concepts/0430-machine-readable-governance-frameworks/README.md + - 0440 KMS Architectures : concepts/0440-kms-architectures/README.md + - 0511 Credential-Manifest Attachment format for requesting and presenting credentials: features/0511-dif-cred-manifest-attach/README.md + - 0559 Privacy-Preserving Proof of Uniqueness: concepts/0559-pppu/README.md + - 0566 Issuer-Hosted Custodial Agents: concepts/0566-issuer-hosted-custodidal-agents/README.md + - 0641 Linking binary objects to credentials using hash based references: features/0641-linking-binary-objects-to-credentials/README.md + - 0693 Cross-Platform Credential Representation: features/0693-credential-representation/README.md + - 0699 Push Notifications apns Protocol 1.0: features/0699-push-notifications-apns/README.md + - 0700 Out-of-Band through redirect: concepts/0700-oob-through-redirect/README.md + - 0728 Device Binding Attachments: features/0728-device-binding-attachments/README.md + - 0734 Push Notifications fcm Protocol 1.0: features/0734-push-notifications-fcm/README.md + - 0757 Push Notification: concepts/0757-push-notification/README.md + - 0771 AnonCreds Attachment Formats for Requesting and Presenting Credentials: features/0771-anoncreds-attachments/README.md + - 0799 Aries Long Term Support Releases: concepts/0799-long-term-support/README.md +- STALLED: + - 0024 DIDComm over XMPP: features/0024-didcomm-over-xmpp/README.md + - 0029 Message Trust Contexts: concepts/0029-message-trust-contexts/README.md + - 0030 Sync Connection Protocol 1.0: features/0030-sync-connection/README.md + - 0075 Payment Decorators: features/0075-payment-decorators/README.md + - 0114 Predefined Identities: features/0114-predefined-identities/README.md + - 0116 Evidence Exchange Protocol 0.9: features/0116-evidence-exchange/README.md + - 0193 Coin Flip Protocol 1.0 : features/0193-coin-flip/README.md + - 0207 Credential Fraud Threat Model: concepts/0207-credential-fraud-threat-model/README.md + - 0217 Linkable Message Paths: concepts/0217-linkable-message-paths/README.md + - 0249 Aries Rich Schema Contexts: features/0249-rich-schema-contexts/README.md + - 0250 Rich Schema Objects: concepts/0250-rich-schemas/README.md + - 0257 Private Credential Issuance: concepts/0257-private-credential-issuance/README.md + - 0281 Aries Rich Schemas: features/0281-rich-schemas/README.md + - 0289 The Trust Over IP Stack: concepts/0289-toip-stack/README.md + - 0309 DIDAuthZ: features/0309-didauthz/README.md + - 0327 Crypto service Protocol 1.0: features/0327-crypto-service/README.md + - 0334 JWE envelope 1.0: features/0334-jwe-envelope/README.md + - 0335 HTTP Over DIDComm: features/0335-http-over-didcomm/README.md + - 0351 Purpose Decorator: features/0351-purpose-decorator/README.md + - 0418 Aries Rich Schema Encoding Objects: features/0418-rich-schema-encoding/README.md + - 0420 Rich Schema Objects Common: concepts/0420-rich-schemas-common/README.md + - 0428 Prerequisites to Issue Rich Credential: features/0428-prepare-issue-rich-credential/README.md + - 0429 Prerequisites to Request Rich Presentation: features/0429-prepare-req-rich-pres/README.md + - 0445 Aries Rich Schema Mapping: features/0445-rich-schema-mapping/README.md + - 0446 Aries Rich Schema Credential Definition: features/0446-rich-schema-cred-def/README.md + - 0478 Coprotocols: concepts/0478-coprotocols/README.md + - 0482 Coprotocol Protocol 0.5: features/0482-coprotocol-protocol/README.md +- RETIRED: + - 0013 Overlays: concepts/0013-overlays/README.md + - 0051 Decentralized Key Management: concepts/0051-dkms/README.md + - 0234 Signature Decorator: features/0234-signature-decorator/README.md + - 0303 V0.1 Credential Exchange (Deprecated): features/0303-v01-credential-exchange/README.md + - 0317 Please ACK Decorator: features/0317-please-ack/README.md + - 0348 Transition Message Type to HTTPs: features/0348-transition-msg-type-to-https/README.md + - 0627 Static Peer DIDs: features/0627-static-peer-dids/README.md \ No newline at end of file diff --git a/tags.md b/tags.md index 6ad75f24d..a146fa01e 100644 --- a/tags.md +++ b/tags.md @@ -15,8 +15,7 @@ Defines a specific, concrete feature that [agents](concepts/0004-agents/README.m Defines a general aspect of the Aries mental model, or a pattern that manifests in many different features. ### `community-update` -An RFC that tracks a community-coordinated update, as described in [RFC -0345](../../concepts/0345-community-coordinated-update/README.md). Such updates +An RFC that tracks a community-coordinated update, as described in [RFC 0345](concepts/0345-community-coordinated-update/README.md). Such updates enable independently deployed, interoperable agents to remain interoperable throughout the transition. @@ -24,7 +23,7 @@ throughout the transition. Relates to [verifiable credentials](https://www.w3.org/TR/vc-data-model/). ### `rich-schemas` -Relates to next-generation schemas, such as those used by [https://schema.org](schema.org), as used in verifiable credentials. +Relates to next-generation schemas, such as those used by [https://schema.org](https://schema.org), as used in verifiable credentials. ### `test-anomaly` Violates some aspect of our [policy on writing tests for protocols before allowing their status to progress beyond DEMONSTRATED](/README.md#accepted). RFCs should only carry this tag temporarily, to grandfather something where test improvements are happening in the background. When this tag is applied to an RFC, unit tests run by our CI/CD pipeline will emit a warning rather than an error about missing tests, IFF each implementation that lacks tests formats its notes about test results like this: