├── .gitignore
├── Bounty Program.md
├── Browser Integration.md
├── Claim Lifecycle.md
├── Credential Exchange Message Formats Survey.md
├── DID Trust Establishment.md
├── Decentralize App and Service Architectures.md
├── Hub Commit Strategies.md
├── Hub Encryption Proposal - Draft 1.pdf
├── Hub-based Claim Flows.md
├── LICENSE
├── Recommended Profile Descriptors.md
└── did-authn
└── siop
├── assets
├── did-authn-siop-profile-flow.plantuml
└── did_authn_siop_profile_flow.png
└── did-authn-siop-profile.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/modules.xml
2 | .idea/papers.iml
3 | .idea/vcs.xml
4 | .idea/workspace.xml
5 |
--------------------------------------------------------------------------------
/Bounty Program.md:
--------------------------------------------------------------------------------
1 | # DIF Bounty Program
2 |
3 | In order to engage with contributors in the wider identity ecosystem, and expose critical technical components for more targeted development and review, DIF may offer bounties for specific completion of open source components, shared libraries, and vulnerability discovery/fixes.
4 |
5 | Bounties can either be sourced through a DIF-wide consensus that authorizes a bounty, or any member who seeks to advance a component within DIF via the bounty mechanism to draw in maximum community involvement by leveraging DIF's position in the ecosystem.
6 |
7 | ## Template for Bounty Offering
8 |
9 | **Problem Statement**: Describe the user/technical problem with appropriate user stories and technical descriptions.
10 |
11 | **Scope**: Describe the scope of the engagement with concrete details and objective boundaries, including what is not within the scope of work for the engagement.
12 |
13 | **Deliverables & Acceptance Criteria**: As specifically as possible, describe the deliverables expected both during and at the conclusion of the engagement. Detail any acceptance criteria, and specify how acceptance will be judged.
14 |
15 | **Duration**: What is the expected timeline, including dates for delivery, milestones, and progress reports.
16 |
17 | **Payment**: List the terms for payment, with any associated time-bound references to milestones and procedural requirements.
18 |
19 | ## Posting the Bounty
20 |
21 | All bounty proposals will coordinate with the DIF Steering Committee to post the description and details to DIF's website. DIF will aid in gathering inquiries and help in evaluation. In the case a bounty is being sponsored by a DIF Member company or external organization, DIF and the sponsor may wish to collaborate on management of the bounty.
22 |
23 | ## Community Updates
24 |
25 | DIF and/or the bounty sponsors may wish to circulate updates to the community on the progress and outcome of a bounty offering. DIF can coordinate with the internal member group managing the bounty, or bounty sponsors, to draft and broadcast messaging about bounty status updates. It is generally advised that updates be broadcast to the community in accordance with the milestones set out in a bounty's definition document.
26 |
27 | --------
28 |
29 | *For an examplar of a bounty description document, see this BC Government bounty offering: https://bcdevexchange.org/opportunities/cwu/opp-initial-reference-implementation-of-decentralized-authentication--did-auth--and-authorization-mechanisms*
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Browser Integration.md:
--------------------------------------------------------------------------------
1 |
2 | # Browser Needs for DID
3 |
4 | The following encompass the initial set of modifications to the browser the DID initiative needs to maximize the value of DID technology for users across platforms and devices.
5 |
6 | ## Generic DID APIs
7 |
8 | ### Custom Protocol Handler API
9 |
10 | The browser should provide a robust API that allows user-selected apps, origins, or entities to register handlers and hooks for custom protocols (most notably for this work: register as a handler for the `did:`, `hub:`, and `ipfs:` protocols). This includes the following min-bar features:
11 |
12 | - Registration of custom protocol handlers (for our needs: `did:`, `hub:`, and `ipfs:`)
13 | - Ability for the user to designate an app, origin, or entity as the default handler, or exclusive handler, for a particular protocol
14 | - Access to all forms of requests, interactions, invocations related to use of protocol
15 | - Notably: observation and interdiction of `fetch()` requests, `src`/`href` resolutions, etc.
16 |
17 | For examples of the type of hooks we seek, the closest thing in the platform currently is the Web Extension `webRequest` interface, which provides many of the interdiction points we would need for robust protocol handling: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest
18 |
19 | Additionally, there is a parallel desire/proposal from the Distributed Web group of browser vendor representatives to add this type of API: https://arewedistributedyet.com/programmable-custom-protocol-handlers/
20 |
21 | ### DIDs as Distinct Origins
22 |
23 | Modify origin scoping and handling components of the browser to recognize different DIDs as distinct origins, and apply the same separation and protections afforded to top-level DNS origins: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
24 |
25 | A similar need has been expressed by the Distributed Web group of browser vendor representatives: https://arewedistributedyet.com/control-origin-security-context/
26 |
27 | ### CSP Additions
28 |
29 | Update the Web's [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) declarations and APIs to include recognition of DID origins, and add a set of additional features:
30 |
31 | - Modify the [`connect-src`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/connect-src) directive to allow passage of a single DID, which all request and execution interfaces are limited to.
32 |
33 | ### DID Permission Requests
34 |
35 | DIDs and DID-based apps need a way to request permissions from the DID owner they are interacting with. We need an interface that allows the calling DID to request permissioned access to the target DID's personal datastore. The following is a strawman example to provide a rough idea of what is needed:
36 |
37 | #### `navigator.did.requestPermissions(PROPS)`
38 |
39 | | Property | Value | Description |
40 | | ------ | ----------- | ----------- |
41 | | `PROPS.did` | String | OPTIONAL - A specific DID string to request permissions against. (by default it allows the user to select whatever DID they wish to grant permissions against) |
42 | | `PROPS.keyFunctions` | Object | Functions required for signing and communicating the permission request to the DID owner's Hub. |
43 | | `PROPS.permissions` | Array | An array of DIF Identity Hub Permissions descriptor objects. |
44 |
45 | The request should return a Promise, with the following `then`/`catch` profile:
46 |
47 | #### *`Promise.then(PERMISSION_GRANT)`*
48 |
49 | A `PermissionGrant` object provides details about the permission grant, including:
50 |
51 | | Property | Value | Description |
52 | | ------ | ----------- | ----------- |
53 | | `GRANT.did` | string | The DID a grant was permissioned for. |
54 | | `GRANT.permissions` | Array | An array of the permissions that were granted - which may not have been all the permissions requested. |
55 |
56 | #### *`Promise.catch(ERROR)`*
57 |
58 | A `PermissionGrant` object provides details about the permission grant, including:
59 |
60 | | Property | Value | Description |
61 | | ------ | ----------- | ----------- |
62 | | `ERROR.type` | string | Either a generic error, or a string signifying permission denial. |
63 | | `ERROR.reason` | string | The reason for permission denial. |
64 | | `ERROR.blocked` | boolean | An indication that the user will not accept further permission requests via ad hoc attempts by the requesting DID. |
65 |
66 | ### Service Worker Modifications
67 |
68 | [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) should, in accordance with the Origin modifications described above, be augmented to allow a DID to register a Service Worker that communicates with the DID owner's User Agent to handle and cache DID-related requests/data as it would regular HTTP/DNS-based requests.
69 |
70 | ### DID Data Disclosure Requests
71 |
72 | DIDs and origins should be able to request identity data/information from the user, and need a way to invoke such a request. This could be facilitated via the following strawman interface:
73 |
74 | #### `navigator.did.requestData({@type: ProofSet})`
75 |
76 | | Property | Value | Description |
77 | | ------ | ----------- | ----------- |
78 | | `ProofSet` | OBject | DIF-specified proof object that describes a set of data, information, or other proofs that the requesting entity would like the user to provide in response. |
79 |
80 | The request should return a Promise, with a successful resolution regardless of the outcome of acceptance by the DID owner of any one (or more) permissions. Upon successful resolution the Promise value should be an object that contains two properties:
81 |
82 | | Property | Value | Description |
83 | | ------ | ----------- | ----------- |
84 | | `RESOLVED.granted` | Array | An array of the permissions that were granted from the requested set. |
85 | | `RESOLVED.denied` | Array | An array of the permissions that were denied from the requested set. |
86 |
87 | ## Support for Personal Apps
88 |
89 | Unlike apps of today, the combination of the DID layer's technical components make a new 'Personal App' paradigm possible: developers can create apps that store their data in a user's personal datastore, instead of a centralized application server. Additionally, for apps with compatible requirements (e.g. to-do list), a developer could write a truly serverless app where they only write clientside code and interact with the user's personal datastore, without any backend code at all. This latter variant is something of a Holy Grail for developers, which many would welcome.
90 |
91 | DID-based apps are based on the following differences from traditional Progressive Web App model:
92 |
93 | 1. Instead of a DNS origin being the source of an app, an app developer creates a DID that represents their app, which is treated as a distinct origin.
94 | 2. Unlike a PWA install with client/local-centric permissions, the user's agent application (which could be the browser or an external app) signs a permission that allows the DID-based app to access various interfaces of the user's personal datastore.
95 |
96 | ### App Manifest Additions
97 |
98 | Currently the [App Manifest](https://developer.mozilla.org/en-US/docs/Web/Manifest) expects a DNS origin as the source of the application. We need this modded to recognize a DID as the application source, and ensure that the code passed to the client representing that DID-based app is signed by the DID it claims to be from.
99 |
100 | ### App Execution Requirements
101 |
102 | DID-based apps are essentially a bundle of code signed by a DID the user has permitted to access certain features of a DID they own. To ensure that the code is safe and executed properly, the browser should perform the following actions:
103 |
104 | 1. Ensure that the code bundle is signed by the DID it claims to be from
105 | 2. Provide a means for the user's DID User Agent to handle various protocol-specific requests (via its protocol handler hooks) that are raised from the app's running code. For example: ability to view responses for local caching of data.
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/Claim Lifecycle.md:
--------------------------------------------------------------------------------
1 | # Claim Lifecycle
2 |
3 | To begin with an end in mind, the following examples detail various scenarios our technical components, standards, and implementations should enable for users, issuers, and relying parties.
4 |
5 | ### Basic Claim Use
6 |
7 | 1. Alice is traveling in a foreign country and doesn't have cell service turned on to save money. She walks up to a high tech beer and wine vending machine and decides to buy a drink, which will not sell to her without verifying her age.
8 |
9 | 2. The machine prompts Alice for 21+ claim presentation via a Bluetooth transmission. The transmission includes an object that specifies what claims it will accept, and when her phone locates a set of probable claims, asks her to choose whether to disclose one to the machine - in this case, the Proof of Age claim.
10 |
11 | 3. Alice discloses a 21+ claim to the machine, it authenticates that she is the Subject and is a valid signature from the Issuer (via keys fetched from the Universal Resolver), then proceeds to dispense her drink.
12 |
13 |
14 |
15 | ### Mutli-Step, Mutli-Party Claim Use
16 |
17 | While some claims are relatively simple exchanges where the Subject passes data to the Issuer that is deterministic and can return with claim issuance or rejection, other claims have complex multi-step and/or asynchronous processes that may require task-based flows with a persistent state that last for an indeterminate duration until the task is completed.
18 |
19 | 1. To illustrate a more advanced case, consider the case of a home purchase offer flow. The initial bid comes from the seller, and be a signed offer object that includes the price and a contingency that a licensed inspector can review and clear the property of any issues.
20 |
21 | 2. The seller may respond with a signature that approves the offer, and agrees to the contingency, or can respond with a different price. This may require several accrued offer/counter loops, all of which are accrued in the auditable offer object that is modified on each leg.
22 |
23 | 3. Once an offer price is signed by both parties, the task is frozen until the inspection is completed. The inspector arrives at the property, finds nothing wrong, and signs the offer object with his own DID, which can even sign into the offer object proof that he is licensed.
24 |
25 | 4. All parties involved in the sale can now leverage a high-precision verifiable proof of all that transpired. This may be used at other points during the sale, or at any future time when the details of the exchange may be relevant for verification or review.
26 |
27 |
28 |
29 | ---
30 |
31 | ## How do I find claims I to acquire?
32 |
33 | Intro: To model the lifecycle of claims, we begin with acquisition. Acquiring a claim may frequently require self-attested data input, claims from third-parties, and even multi-step asynchronous flows to complete issuance.
34 |
35 | The Identity Hub datastore scheme allows for deterministic location of all types of semantic data objects, via its Collections interface.
36 |
37 | 1. The first thing we need in claim issuance is a data format that allows an issuer to describe what raw data, prerequisite claims, and other details are required for the issuer to successfully process a request - like a manifest for what a claim requires.
38 |
39 | 2. Because a Claim Manifest is just a type of semantic data object, Identity Hubs can expose them just as they would any other data type. This means you can crawl DIDs and make requests to their Hubs to find all publicly available Claim Manifests they expose. There is no requirement to crawl all DIDs to locate claims; you can create more direct claim registration-style services, where DID owners directly request inclusion of the claims they offer (which are fetched from their Hub using the same set of interfaces).
40 |
41 | 3. The way to best understand how finding claim manifests works (as with any other semantic object its owner publicly exposes), is to imagine the DID Resolver (which provides a directory-style cache of all known DIDs) as the white pages, wherein the DIDs are phone numbers you can call. At the other end of the line is the Identity Hub, which you can ask for specific semantic objects. In this way, you can call every number in the white pages and ask the owner "Hey, do you have any claim manifests you'd like to share?"
42 |
43 |
44 |
45 | ```sequence
46 | participant Claim Crawler/Registry as CC
47 | participant Universal Resolver as UR
48 | participant Identity Hubs as IH
49 |
50 | CC-->UR: 1. Request all public DIDs
51 | UR-->CC: 2. Return stream of DIDs
52 | CC-->IH: 3. Request ClaimManifests from each DID's Hub
53 | IH-->CC: 4. Respond with any ClaimManifests the DID wants to share
54 | ```
55 |
56 | ### Comparing Claim Manifest Options
57 |
58 | Intro: There are two options under consideration for describing what an individual claim is and codifying all that is required to generate it: DIF's Claim Manifest format and use of modified and extended OIDC claim formats/properties. The two approach the problem from two different angles:
59 |
60 | | |
Extended OIDC Aggregated Claims
|
DIF Claim Manifests
|
61 | | :-: | - | - |
62 | | **Description** | OIDC has some basic claim description formats/properties, and the thinking is that it might be easier for devs familiar with OIDC to digest something that looks similar. | The description and requirements for generating a claim can be quite complex, and various requirements in a description may have options/relationships that are difficult to express within an OIDC format that was never designed for this part of the claim lifecycle. |
63 | | **Spec** | https://openid.net/specs/openid-connect-core-1_0.html#Claims | https://hackmd.io/q-selsVyQQ-1p1LK7mHJxw |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | ### Claim Property/Value Definitions
73 |
74 | There are no existing claim definition formats that approach the level of detail needed for flexible generation of custom claim schemas with Issuer-defined properties and values.
75 |
76 | It is advisable to use an existing format/specification, such as JSON Schema, to precisely define the properties and values of claim schemas.
77 |
78 | | |
JSON Schema
|
79 | | :-: | - |
80 | | **Description** | JSON Schema is a vocabulary that allows you to annotate and validate JSON documents. |
81 | | **Spec** | https://cswr.github.io/JsonSchema/spec/introduction/ |
82 | | **Example** | https://hackmd.io/5xlPH_Q3Q_iAqDupZDxPug?view#2-Claim-Definition |
83 |
84 | ### DID Proof of Control (Auth)
85 |
86 | In all the following examples presented, the initial exchanges between the entities may depend on authenticating that the user is the controller of a DID.
87 |
88 | To do this, we have built an OIDC-compatible authentication flow/library that allow entities to prove control of a DID in a way that works with the existing standards in use today: https://github.com/decentralized-identity/did-auth-jose
89 |
90 | ---
91 |
92 | ## How do I acquire a claim from an issuer?
93 |
94 | 1. User Agent apps present users with claims they can request from Issuers, which are represented by Claim Manifests that are found by crawling Identity Hubs or explicit ingestion into a UA's directory (as noted above). Alice, a DID user, chooses to initiate the claim request with the Issuer.
95 |
96 | 2. The Issuer's ClaimManifest specifies a set of data and prerequisite claims Alice needs to submit in order for the Issuer to process her claim request. Alice's UA presents her with an interface that helps her input the right data and select relevant prerequisite claims.
97 |
98 | 3. When Alice has filled out all the fields to meet the requirements, her request is sent to the Identity Hub of the Issuer for processing, which the Enterprise Agent handles. The EA is a headless agent with code that handles business logic and activities specific to an Issuer, Assuming Alice filled out the fields correctly and sent acceptable prerequisite claims, the Issuer will return her an MDL claim.
99 |
100 |
101 |
102 | ### Claim Delivery Targets: User Agent vs Identity Hub
103 |
104 | There are two options issuers have for delivering the claims they generate for users: the User Agent wallet app on a user's device, or one of the user's Identity Hub instances. There are different scenarios where one or the other make more sense, depending on the constraints of the use case. Regardless of which is selected, the response should be a DeliverClaimAction, so that it can be handled the same way by either of the targets.
105 |
106 | | User Agent | Identity Hub |
107 | | - | - |
108 | | An issuer who is delivering a claim as a final act in a direct, sustained negotiation flow between its Identity Hub/Enterprise Agent and the User Agent app of a user will most likely want to deliver the claim directly to the User Agent already involved in the flow. This would provide more immediate deliver and user awareness of completion, without having to make a needless hop from the Hub to the UA of the user. | In other cases, a claim may be generated as part of a multi-step, long-lived claim generation flow where there is no sustained connection between the UA and the Hub/EA of the Issuer. In these cases, the Issuer has no simple way to reestablish connection with the UA (likely a mobile device) when the claim generation process is completed. In this situation, the best option is to use the DID of the user to locate their Identity Hub instance(s) and deliver the claim there, which the UA will gain awareness of when the two perform their next sync exchange. |
109 |
110 | ### Claim Negotiation/Storage: Action Exchange vs Collections Write
111 |
112 | Much like the targets for deliver (UAs and Hubs), there are two ways a claim data object can be added to a user's Hub: the Action interface or acquisition of a permission from the user to directly write to their Collection object storage. It's helpful to understand each interface and in what situations you might use one or the other:
113 |
114 | | | Collections | Actions |
115 | | :-: | - | - |
116 | | **Description** | Collections storage is the end destination for all objects that are persisted in Hubs, but outside of specific flows (e.g. Actions) an external entity must acquire permissions to write data directly to the schema/object-specific areas of Collections. Collections is just data storage, with no negotiation or interactive exchange capabilities. This is generally the interface you'd use if your use case involved the need for direct, non-interactive, long-lasting write ability, or you wanted to write/update data multiple times without the user being prompted to allow the activity. | The Actions interface can be thought of as an email inbox of sorts, where the objects an external entity sends to it are semantically typed and intended to invoke specific task/activity flows in response. In the case of claims, claim-specific Action objects allow an entity to negotiate claim acquisition, which may have differing steps and long, asynchronous idle periods between each, depending on the type of claim and its lifecycle. Actions are also used to deliver claims, all without having to acquire a permission for deeper, persistent access to the Collections CRUD interfaces. |
117 | | **Spec** | [Collections Interface](https://github.com/decentralized-identity/identity-hub/blob/master/explainer.md#collections) | [Actions Interface](https://github.com/decentralized-identity/identity-hub/blob/master/explainer.md#actions) |
118 |
--------------------------------------------------------------------------------
/Credential Exchange Message Formats Survey.md:
--------------------------------------------------------------------------------
1 | # Credentials / Claims Exchange message formats
2 |
3 | **Table of Contents**
4 |
5 | - [About this document/approach](#about-this-document-approach)
6 | - [Categories](#categories)
7 | - [Expressiveness/Features](#expressiveness-features)
8 | - [Design Questions](#design-questions)
9 | * [Filters/Constraints](#filters-constraints)
10 | * [Should we consider Verifiable Credential Exchange a special case of data exchange?](#should-we-consider-verifiable-credential-exchange-a-special-case-of-data-exchange-)
11 | * [Vocabulary](#vocabulary)
12 | - [Category 1 examples](#category-1-examples)
13 | * [uPort Verifiable Credential Request/Response](#uport-verifiable-credential-request-response)
14 | * [uPort Selective Disclosure Request/Response (used in DID Auth)](#uport-selective-disclosure-request-response--used-in-did-auth-)
15 | * [Jolocom Credential Request/Response](#jolocom-credential-request-response)
16 | * [Credential Handler API](#credential-handler-api)
17 | * [ID Hub Search and Read Requests](#id-hub-search-and-read-requests)
18 | + [Query Request/Response](#query-request-response)
19 | + [Read Request/Response](#read-request-response)
20 | - [ID Hub Write (Store) Request/Response (TODO: Categorize)](#id-hub-write--store--request-response--todo--categorize-)
21 | - [Sidetree VCs (TODO: categorize)](#sidetree-vcs--todo--categorize-)
22 | - [HIPE (TODO: categorize)](#hipe--todo--categorize-)
23 | - [Civic](#civic)
24 | * [Credential Commons](#credential-commons)
25 | * [DSR - Dynamic Scope Request](#dsr---dynamic-scope-request)
26 | * [ID Validator Toolkit (e.g. Issuer Toolkit)](#id-validator-toolkit--eg-issuer-toolkit-)
27 | - [Questions/TODO](#questions-todo)
28 | - [General References](#general-references)
29 |
30 | Table of contents generated with markdown-toc
31 |
32 |
33 | ## About this document/approach
34 |
35 | Previously, the DIF Claims/Credentials Working Group proposed a general [Credentials Exchange Manifest](https://github.com/decentralized-identity/credential-manifest/blob/master/explainer.md); however, before going too far along that path, we wanted to better understand existing approaches. That will help ensure our format is sufficiently expressive and flexible, and meet our goals of promoting interop.
36 |
37 | This document is simply an effort to gather "what's out there" so we can categorize and generalize.
38 |
39 | Currently, efforts like DID auth are having to focus on message formats in addition to protocols -- even message formats dealing with claims exchange (see uPort selective disclosure/DID auth). We'd also like to identify when this is happening so we can iterats on them in the Claims/Credentials group.
40 |
41 | Because of that, we'll be reviewing existing claims exchange protocols/formats that member companies have documented, including where they appear as part of protocols like DID Auth. References are at the end.
42 |
43 |
44 | ## Categories
45 |
46 | Based on review so far, it looks like we need interoperable message formats for Claims manifests/Claims (request/response) associated with:
47 | 1. Credential exchange
48 | - Example: RP requesting VCs/VPs (or data?) from holder
49 | - In some cases, this may be part of a DID Auth flow
50 | 2. Subject/holder requesting claims issuance
51 |
52 |
53 | ## Expressiveness/Features
54 | Still deciding scope for initial interop POC, but eventually design should accommodate all.
55 |
56 | Initial list:
57 | - Selection of fields / entire claim
58 | - Verifiable Presentation, or just VCs?
59 | - ZKP (out of scope for initial phase)
60 | - Filter to issuers
61 | - Revocation actions
62 | - Icons
63 |
64 | ## Design Questions
65 |
66 | ### Filters/Constraints
67 |
68 | There will be a need for claims filters (by type, fields, etc), as shown in a couple of examples below, but we should be careful to not re-invent the wheel and create something restrictive.
69 |
70 | We could consider something LISP S-expressions.
71 | ```
72 | ["AND",
73 | {"var1" : "value1"},
74 | ["OR",
75 | { "var2" : "value2" },
76 | { "var3" : "value3" }
77 | ]
78 | ]
79 | ```
80 |
81 | A JSON library attempting something similar is [JSONLogic](http://jsonlogic.com/)
82 |
83 | **Note** Jolocom appears to use a similar style. DIF's previously-published Claim Metadata format looked home-grown...
84 |
85 | ### Should we consider Verifiable Credential Exchange a special case of data exchange?
86 |
87 | Identity hub examples are included below, because there is a fuzzy area between requesting *unverified* claim data and other user data.
88 |
89 | A possible approach is for claims exchange to be a special case of data exchange.
90 |
91 | ### Vocabulary
92 |
93 | How do we let a requestor specify desired vocabulary/types? Current approaches seem ambiguous/confusing.
94 |
95 | I think it is just a special case of Filters/Constraints
96 |
97 | ## Category 1 examples
98 |
99 | Note that responses take the form of Verifiable Credentials/Presentations, but examples are included to the demonstrate different wrappers/envelopes
100 |
101 | ### uPort Verifiable Credential Request/Response
102 |
103 | Format: JWT
104 | Details: https://github.com/uport-project/specs/blob/develop/messages/verificationreq.md
105 |
106 | About: The issuer is requesting the holder's wallet/agent to present a signed claim containing _exactly_ the field `name` and respond with a payload like the following
107 |
108 | Example request:
109 | ```
110 | {
111 | "type":"verReq",
112 | "iss":"did:uport:REQUESTING_APP_OR_USER",
113 | "aud":"did:uport:VERIFYING_APP_OR_USER",
114 | "sub":"did:uport:SUBJECT_OF_VERIFIED_CLAIM",
115 | "riss":"did:uport:IDENTITY_THAT_WILL_SIGN_THE_CLAIM",
116 | "unsignedClaim": {
117 | "name":"Bob Smith"
118 | },
119 | "callback":"https://example.com",
120 | "rexp": 123456789
121 | }
122 | ```
123 |
124 | Example response:
125 |
126 | ```
127 | {
128 | "iss":"did:uport:VERIFYING_APP_OR_USER",
129 | "sub":"did:uport:SUBJECT_OF_VERIFIED_CLAIM",
130 | "claim": {
131 | "name":"Bob Smith"
132 | },
133 | "exp": 123456789
134 | }
135 | ```
136 |
137 |
138 | Observations:
139 | - Potential for reuse:
140 | - `iss`, `iat`, `exp` are shared with Share Request, and _should_ be fairly standard across JWTs
141 | - Concerns:
142 | - It's not clear what's happening if the holder has a claim containing a superset of the requested field. uPort mentions a best practice of narrow claims, but we can't carry this assumption
143 | - Asking for a field independent of types; is there an assumption of shared context?
144 |
145 | ### uPort Selective Disclosure Request/Response (used in DID Auth)
146 |
147 | **Note**: I would argue any claims-based aspects of DID auth belong with Claims/Credentials effort
148 |
149 | Format: JWT
150 | Details:
151 | - https://github.com/uport-project/specs/blob/develop/messages/sharereq.md
152 | - https://github.com/uport-project/specs/blob/develop/messages/shareresp.md
153 |
154 | ```
155 | {
156 | iss: 'did:web:somesite.com',
157 | type: 'shareReq',
158 | claims: {
159 | verifiable: {
160 | email: {
161 | iss: [
162 | {
163 | did: 'did:web:uport.claims',
164 | url: 'https://uport.claims/email'
165 | },
166 | {
167 | did: 'did:web:sobol.io',
168 | url: 'https://sobol.io/verify'
169 | }
170 | ],
171 | reason: 'Whe need to be able to email you'
172 | },
173 | nationalIdentity: {
174 | essential: true,
175 | iss: [
176 | {
177 | did: 'did:web:idverifier.claims',
178 | url: 'https://idverifier.example'
179 | }
180 | ],
181 | reason: 'To legally be able to open your account'
182 | }
183 | },
184 | user_info: {
185 | name: { essential: true, reason: "Show your name to other users"},
186 | country: null
187 | }
188 | }
189 | }
190 | ```
191 |
192 | Response example:
193 | ```
194 | {
195 | "iss":"did:ethr:0x012abcd...",
196 | "vc": ["Verified Claim JWT 1", "Verified Claim JWT 2"]
197 | }
198 | ```
199 |
200 |
201 | Observations:
202 | - Inconsistency with the above example; i.e. `claims` as requested claims vs `unsignedClaim` in previous example. Also they should allow similar options, like filtering by issuer
203 | - `essential` -- is a boolean ok, or do we need multi-valued. If booleam rename to required? what should default be?
204 | - `callback` not shown here but available as optional field, like previous example
205 |
206 |
207 | ### Jolocom Credential Request/Response
208 |
209 |
210 | Format: JWT
211 |
212 | Reference: https://jolocom-lib.readthedocs.io/en/latest/interactionFlows.html
213 |
214 | Example request:
215 |
216 | ```
217 | {
218 | "typ": "JWT",
219 | "alg": "ES256K"
220 | }
221 | {
222 | "iat": 1528997842275,
223 | "requestedCredentials": [
224 | {
225 | "type": ["Credential", "ProofOfEmailCredential"],
226 | "constraints": {
227 | "and": [
228 | { "==": [ true, true ] },
229 | { "!=": [ { "var": "issuer" }, { "var": "claim.id" } ] }
230 | ]
231 | }
232 | }
233 | ],
234 | "requesterIdentity": "did:jolo:b310d293aeac8a5ca680232b96901fe85988fde2860a1a5db69b49762923cc88",
235 | "callbackURL": "https://demo-sso.jolocom.com/proxy/authentication/aws6i"
236 | }
237 | ```
238 |
239 | Example response:
240 | ```
241 | {
242 | '@context': [ ... ],
243 | ...
244 | issuer: 'did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777',
245 | claim: {
246 | email: 'example@example.com',
247 | id: 'did:jolo:6d6f636b207375626a656374206469646d6f636b207375626a65637420646964'
248 | },
249 | proof: EcdsaLinkedDataSignature {
250 | ...
251 | creator: 'did:jolo:b2d5d8d6cc140033419b54a237a5db51710439f9f462d1fc98f698eca7ce9777#keys-1'
252 | ...
253 | }
254 | ```
255 |
256 | Observations:
257 | - can express constraints, logical operators
258 | - In the request, `type` appears to be requested type; that's a little confusing.
259 | - Response looks like a straightforward VC. It's out of date, but easily portable
260 |
261 |
262 | ### Credential Handler API
263 |
264 | Format: JSON-LD
265 |
266 | Details: https://w3c-ccg.github.io/credential-handler-api/
267 |
268 | Credential Storage (Registration) and Request. Uses notion of credential "hints"
269 | ```
270 | {
271 | {
272 | name: "My social account: pat@example.com",
273 | enabledTypes: ["VerifiableProfile"],
274 | icons: [{
275 | src: "icon/lowres.webp",
276 | sizes: "48x48",
277 | type: "image/webp"
278 | }],
279 | match: {
280 | VerifiableProfile: {
281 | id: 'did:method1:1234-1234-1234-1234'
282 | }
283 | }
284 | }
285 | ```
286 |
287 | ```
288 | {
289 | name: "My business account: pat@business.example.com",
290 | enabledTypes: ["VerifiableProfile"],
291 | match: {
292 | VerifiableProfile: {
293 | id: 'did:method1:1234-1234-1234-1235'
294 | }
295 | }
296 | }
297 | ```
298 |
299 | About/Scope: imperative API enabling a website to request a user’s credentials from a user agent, and to help the user agent correctly store user credentials for future use. User agents implementing that API prompt the user to select a way to handle a credential request, after which the user agent returns a credential to the originating site. This specification defines capabilities that enable third-party Web applications to handle credential requests and storage.
300 |
301 | ### ID Hub Search and Read Requests
302 |
303 | If you squint enough, VC exchange requests look like a special case of data exchange requests that occur, e.g. in Identity Hub operations
304 |
305 | Identity Hub has 2 relevant requests (search and read). Consider whether there are opportunities to unify/align these requests and how these can be shared with credential exchange.
306 |
307 |
308 |
309 | #### Query Request/Response
310 |
311 | ```
312 | {
313 | "@context": "https://schema.identity.foundation/0.1",
314 | "@type": "ObjectQueryRequest",
315 | "iss": "did:foo:123abc",
316 | "sub": "did:bar:456def",
317 | "aud": "did:baz:789ghi",
318 | "query": {
319 | "interface": "Collections",
320 | "context": "http://schema.org",
321 | "type": "MusicPlaylist",
322 |
323 | // Optional object_id filters
324 | "object_id": ["3a9de008f526d239..", "a8f3e7..."]
325 | }
326 | }
327 | ```
328 | ```
329 | {
330 | "@context": "https://schema.identity.foundation/0.1",
331 | "@type": "ObjectQueryResponse",
332 | "developer_message": "completely optional",
333 | "objects": [
334 | {
335 | // object metadata
336 | "interface": "Collections",
337 | "context": "http://schema.org",
338 | "type": "MusicPlaylist",
339 | "id": "3a9de008f526d239...",
340 | "created_by": "did:foo:123abc",
341 | "created_at": "2018-10-24T18:39:10.10:00Z",
342 | "sub": "did:foo:123abc",
343 | "commit_strategy": "basic",
344 | "meta": {
345 | "tags": ["classic rock", "rock", "rock n roll"],
346 | "cache-intent": "full"
347 | }
348 | },
349 | // ...more objects
350 | ]
351 |
352 | // potential pagination token
353 | "skip_token": "ajfl43241nnn1p;u9390",
354 | }
355 | ```
356 |
357 | #### Read Request/Response
358 |
359 | ```
360 | {
361 | "@context": "https://schema.identity.foundation/0.1",
362 | "@type": "CommitQueryRequest",
363 | "iss": "did:foo:123abc",
364 | "sub": "did:bar:456def",
365 | "aud": "did:baz:789ghi",
366 | "query": {
367 | "object_id": ["3a9de008f526d239..."],
368 | "revision": ["abc", "def", ...]
369 | },
370 | }
371 | ```
372 |
373 | ```
374 | {
375 | "@context": "https://schema.identity.foundation/0.1",
376 | "@type": "CommitQueryResponse",
377 | "developer_message": "completely optional",
378 | "commits": [
379 | {
380 | protected: "ewogICJpbnRlcmZhY2UiO...",
381 | header: {
382 | "iss": "did:foo:123abc",
383 | // Hubs may add additional information to the unprotected headers for convenience
384 | "rev": "aHashOfTheCommit",
385 | },
386 | payload: "ewogICJAY29udGV4dCI6ICdo...",
387 | signature: "b7V2UpDPytr-kMnM_YjiQ3E0J2..."
388 | },
389 | // ...
390 | ],
391 |
392 | // potential pagination token
393 | "skip_token": "ajfl43241nnn1p;u9390",
394 | }
395 | ```
396 |
397 | TODO: See also Profiles, and more in ID Hub docs
398 |
399 |
400 |
401 |
402 | ## ID Hub Write (Store) Request/Response (TODO: Categorize)
403 |
404 | ```
405 | // JWT headers
406 | {
407 | "alg": "RS256",
408 | "kid": "did:foo:123abc#key-abc",
409 | "interface": "Collections",
410 | "context": "https://schema.org",
411 | "type": "MusicPlaylist",
412 | "operation": "create",
413 | "committed_at": "2018-10-24T18:39:10.10:00Z",
414 | "commit_strategy": "basic",
415 | "sub": "did:bar:456def",
416 |
417 | // Example metadata about the object that is intended to be "public"
418 | "meta": {
419 | "tags": ["classic rock", "rock", "rock n roll"],
420 | "cache-intent": "full"
421 | }
422 | }
423 |
424 | // JWT body
425 | {
426 | "@context": "http://schema.org/",
427 | "@type": "MusicPlaylist",
428 | "description": "The best rock of the 60s, 70s, and 80s",
429 | "tracks": ["..."],
430 | }
431 | ```
432 |
433 | ```
434 | {
435 | "@context": "https://schema.identity.foundation/0.1",
436 | "@type": "WriteResponse",
437 | "developer_message": "completely optional message from the hub",
438 | "revisions": ["aHashOfTheCommitSubmitted"]
439 | }
440 | ```
441 |
442 |
443 |
444 | ## Sidetree VCs (TODO: categorize)
445 |
446 | Details: https://hackmd.io/tx8Z0mIRS-aK84Gx4xIzfg?view
447 |
448 |
449 | - Create operation: payload is a Verifiable Credential
450 | - Update operations: expressed as JSON Patch operations on the VC
451 |
452 | ## HIPE (TODO: categorize)
453 | https://github.com/hyperledger/indy-hipe/blob/c761c583b1e01c1e9d3ceda2b03b35336fdc8cc1/text/anoncreds-protocol/README.md
454 |
455 | ## Civic
456 | Civic utilized draft specifications of DIDs and Verifiable Credentials in their product pipeline. Civic Technologies makes the open-source components of their implementation accessible to interested parties with an MIT License via identity.com. Generally the following Libraries exists:
457 |
458 | ### Credential Commons
459 | URL: https://github.com/identity-com/credential-commons
460 | This Javascript Library provides functionality around Verifiable Credentials (VC), a W3C standard. Enables Validators to issue, Credential Wallets to verify, filter and Requesters to verify credentials.
461 |
462 | Civic does not provide a Proof implementation for the issued Verifiable Credentials, but abstracts that via an interface implementation. E.g. interested parties are able to use Credential-Commons and provide their own implementation around JWT token proofs or JSON-LD Proofs. Internally Civic uses a proprietary implementation of VC Proofs declared via
463 | ```
464 | ...
465 | "proof": {
466 | "type": "CivicMerkleProof2018",
467 | ...
468 | ```
469 | Credential Commons furthermore defines a global definitions file for claims and credentials that can be referenced in Presentation Requests or Credential Manifests. (https://github.com/identity-com/credential-commons/blob/master/src/claim/definitions.js)
470 |
471 | ### DSR - Dynamic Scope Request
472 |
473 |
474 | ### ID Validator Toolkit (e.g. Issuer Toolkit)
475 | URL: This component is not public yet.
476 |
477 | The IDV Toolkit is a modular framework that allows an issuer of Verifiable Credential to host an endpoint to validate an users input and issue verifiable credentials to an interested party.
478 | At Identity.com potential issuers are discovered via the Identity.com Marketplace, but this is not a prerequisite for hosting and issuing credentials. The discovery of Issuers and their respective Toolkits can be agnostic from the Identity.com Marketplace.
479 |
480 | The IDV Validator Toolkit announces requirements for issuing an Verifiable Credential to a user via a Verification Process that looks similar to this:
481 |
482 | ```
483 | {
484 | "id": "3e51e979-bcdd-4eda-ba78-ee8fbccb6ace",
485 | "processUrl": "/processes/3e51e979-bcdd-4eda-ba78-ee8fbccb6ace",
486 | "state": {
487 | "status": "COMPLETE",
488 | "ucaVersion": "1",
489 | "credential": "credential-cvc:IdDocument-v1",
490 | "ucas": {
491 | "email": {
492 | "name": "cvc:Type:email",
493 | "status": "ACCEPTED",
494 | "value": {
495 | "username": "martin-test",
496 | "domain": {
497 | "tld": "com",
498 | "name": "civic"
499 | }
500 | },
501 | "retriesRemaining": 0,
502 | "suggestedIndex": 0
503 | },
504 | "document": {
505 | "name": "cvc:Document:flow",
506 | "parameters": {
507 | "applicantId": "XXX",
508 | "secrets": {
509 | "apiKey": "XXX"
510 | },
511 | "front": "{\"Bucket\":\"ugimages-dev\",\"ContentMD5\":\"3765ac6d6fb8a2edfdec6863de4552b2\",\"Key\":\"docs/2019/5/2/45bd574b-088e-4d87-bab3-85a1f96b6ba0.jpg\"}"
512 | },
513 | "status": "ACCEPTED",
514 | "value": "upload",
515 | "retriesRemaining": 0,
516 | "suggestedIndex": 1
517 | },
518 | ...
519 | ```
520 |
521 | In a Validation Process an ID Validator expresses the requirements to an external entity by exposing UCA "User Collectible Attributes" that are defined in an Identity.com specific Library. Entities can submit these UCA (e.g. an E-Mail, a document, a phone number, a validation token) in order to validate information dynamically with the ID Validator.
522 |
523 | After a successful Validation process the ID Validator can issue the requested Credential to the User.
524 |
525 | Entity Authentication is done via JWT HTTP Bearer Tokens of the respective DID Keys.
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 | ## Questions/TODO
534 |
535 | - From DIF meeting: revocation in scope?
536 | - VC Statuses https://w3c.github.io/vc-data-model/#status
537 | - Credential Disputes: https://w3c.github.io/vc-data-model/#disputes
538 | - "Refresh" Service: https://w3c.github.io/vc-data-model/#refreshing
539 | - Filter by terms-of-use?
540 | - Also see these, and consider framing categories in light of these: https://w3c.github.io/vc-data-model/#subject-holder-relationships
541 |
542 | ## General References
543 | - [DID Auth](https://github.com/WebOfTrustInfo/rwot6-santabarbara/blob/master/final-documents/did-auth.md)
544 | - [SSI Layers and Implementations](https://docs.google.com/spreadsheets/d/1IZjsriCsSgERIg29sR-NEQhHNT2n1Td3I3YsuHtVUHo/edit#gid=1201785801)
545 |
--------------------------------------------------------------------------------
/DID Trust Establishment.md:
--------------------------------------------------------------------------------
1 | # DID Trust Establishment
2 |
3 | A list of ideas and proposals for establishing trust in and between DIDs.
4 |
5 | ## Domain-to-DID Linkage
6 |
7 | One common form of trust we would like to support is the ability of a DID to prove ownership of a DNS domain. There are a few possible options for doing this, but the following two are relatively straightforward to accomplish without any complex protocol code:
8 |
9 | ### DNS URI Record
10 |
11 | The URI record type is arguably the closest fit for declaring a DID relationship in a DNS Zone File. In talking with Markus, there was some exploration done in this area that participated in with a few folks from DNS working groups. You can read their proposal here: https://datatracker.ietf.org/doc/draft-mayrhofer-did-dns/?include_text=1
12 |
13 | Here is an example of what they currently propose:
14 |
15 | _did.example.net. IN URI 100 10 "did:ion:1234abcd"
16 |
17 | The group that worked on this proposal assumed that you would resolve the DID referenced in the URI Record and locate a matching domain in its DID Document, to create a two-way verification of the linkage. The issue with this approach is that validation based on inclusion of a domain entry in a DID Document forces a potentially significant amount of unnecessary data into the DID Document, consuming the DID network's scarce resources. Instead, I propose adding a signature to the URI record's DID value that allows an observer to prove the DID owner signed the matching domain string to authorize the association.
18 |
19 | Here is an example of my proposed modification:
20 |
21 | _did.example.net. IN URI 100 10 "did:ion:1234abcd?sig=3Yj4De#key-1"
22 |
23 | The signature is over the value of the domain name string specified in the URI record's Name string (at the start of the record, on the left), and the DID Document key descriptor ID of the key it was signed with.
24 |
25 | ### `Well-Known` URI
26 |
27 | Another option is to register a new `/.well-known` URI with IANA. Here is the current list of IANA-registered Well-Known URIs: https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml
28 |
29 | We could register a URI of `/.well-known/did`, which could be a JSON file of the following format:
30 |
31 | ```jsonld=
32 | {
33 | "did:ion:1234abcd": {
34 | "key": "key-1",
35 | "signature": "3Yj4De..."
36 | },
37 | "did:ion:5678efgh": { ... }
38 | }
39 | ```
40 |
41 | ## DID-to-DID Trust Expression
42 |
43 | Another area of interest is how DIDs communicate trust or distrust of other DIDs. There are many possible ways to accomplish the conveyance of trust in another entity, but whatever we pick must be _universally_ knowable, so that you can locate trust information quickly and easily across all entities in the ecosystem.
44 |
45 | ### Exposing TrustLists via Identity Hubs
46 |
47 | One way to expose and digest the trust/distrust of DIDs is to allow DIDs a way to expose publicly resolvable data that describes how they view another entity. To do this, we can leverage another piece of decentralized identity infrastructure: Identity Hubs.
48 |
49 | Identity Hubs feature an interface for exposing public data via semantic formats, called Collections. The Collections interface allows a DID owner to store any type of data within it, the only requirement is that the data be semantically typed and declared to the Hub, for proper segmentation within the datastore.
50 |
51 | #### `TrustList` Schema
52 |
53 | The first thing we need to establish for using an Identity Hub as the means of conveying trust information, is what schema the information with be encoded in. The following proposes a schema for a `TrustList`, which allows a DID owner to declare a list of DIDs and trust context details that scope the trust intent.
54 |
55 | ```jsonld=
56 | {
57 | "@context": "schema.identity.foundation/hub",
58 | "@type": "TrustList",
59 | "scope": "known-entity",
60 | "entities": {
61 | "did:foo:123": {
62 | "sentiment": "positive"
63 | },
64 | "did:foo:456": {
65 | "sentiment": "negative"
66 | }
67 | }
68 | }
69 | ```
70 |
71 |
--------------------------------------------------------------------------------
/Decentralize App and Service Architectures.md:
--------------------------------------------------------------------------------
1 | # Decentralized App and Service Architectures
2 |
3 | An ambition of many developers and organizations in the decentralized identity ecosystem is to create new app and service models by leveraging foundational technical components of the DID stack. Identity is a critical bit for any application or service, which DIDs and DID Methods themselves provide, but when paired with personal datastores (e.g. DIF Identity Hubs) and other components, one can create new classes of apps and service that introduce new capabilities and novel properties.
4 |
5 | ## DWAs - DID-based PWAs
6 |
7 | Progressive Web Apps (PWAs) is a W3C Web standard that is now becoming ubiquitous across devices and platforms. PWAs enable the developer of a web-based application to 'install' that app from the app's domain/subdomain. PWAs have the ability to store data locally, work offline (via Service Workers), and provide the sort of app UI experience one typically associates with a native, platform-specific app.
8 |
9 | PWAs are inherently centralized, given the root of their trust and existence is based on a DNS domain, furthermore, PWA developers generally use their own specific infrastructure to store data generated in the app by users. PWAs and their standard installation, offline capabilities, and UI integration with existing platforms is desireable, and if possible, we should build on, not in conflict with, this valuable standard.
10 |
11 | There are two primary ways we can extend the PWA model into 'DWAs', or Decentralized Web Apps:
12 |
13 | 1. Anchor the trust and existence of an app in the app's global DID, not DNS. This will allow the app and users of the app to continue interacting with it, even if the app's DNS domain is ever lost or interdicted in some way.
14 |
15 | 2. By integrating DIDs into the PWA model, apps will inherently have access to other components of the DID stack, but most notably: Identity Hubs. With a connection to a user's Identity Hub, an app can now store its data with the user themselves, vs spreading data across countless servers that each are subject to different environments of lesser security and privacy.
16 |
17 | ### Setting up DID/Domain linkage for a DWA
18 |
19 | ```sequence
20 | participant Resolver as UR
21 | participant User Hub as UH
22 | participant Wallet as UA
23 | participant Browser/PWA as WEB
24 | participant PWA Server as PWA
25 |
26 | Note right of PWA: 1. Dev signs domain assertion
27 | Note right of PWA: 2. Dev places claim at /.well-known/did
28 | WEB->PWA: 3. Alice installs the PWA
29 | WEB->WEB: 4. Instance creates a DID
30 | WEB->UA: 5. Instance requests permissions
31 | UA->PWA: 6. Fetch /.well-known/did claim
32 | UA->UR: 7. Resolve DID Doc
33 | UA->UA: 8. Validate claim
34 | UA->UA: 9. Display permission prompt
35 | UA->UH: 10. Sets permission in Hub
36 | UA->WEB: 11. Returns user to PWA experience
37 | ```
38 |
39 | ### DWA writing to a user's Identity Hub
40 |
41 | ```sequence
42 | participant User Hub as UH
43 | participant Browser/PWA as WEB
44 |
45 | WEB->WEB: 1. App instance creates a Hub request
46 | WEB->UH: 2. Sends request to user's Hub
47 | UH->UH: 3. Checks previously created DID and permissions
48 | UH->UH: 4. Stores the data from the instance
49 | ```
--------------------------------------------------------------------------------
/Hub Commit Strategies.md:
--------------------------------------------------------------------------------
1 | Hub Commit Strategies
2 | ===
3 |
4 | ## Abstract
5 |
6 | After further disucssion around our [previous storage/replication concept](https://hackmd.io/OInEIRLxQY2s48tze0E7IQ), we would like to advance an updated proposal which we hope will accomodate a wider variety of Hub scenarios and permit future enhancements.
7 |
8 | Rather than mandating a particular merge algorithm / CRDT for Hub data, we propose to allow the merge algorithm to be configurable at the per-object level through the introduction of "commit strategies".
9 |
10 |
11 | ## Background
12 |
13 | Our team has spent some time debating the potential approaches to hub replication. In particular, we have discussed the tradeoffs between two main proposals:
14 |
15 | - Our [previous proposal for storage and replication](https://hackmd.io/OInEIRLxQY2s48tze0E7IQ), which relies on a straightforward CRDT-inspired protocol that favors simplicity over robust merge capabilities.
16 |
17 | - A suggestion to use the protocol designed by the [Automerge library](https://github.com/automerge/automerge), which offers automatic merging of complete JSON structures using an innovative CRDT, at the expense of some additional complexity and storage overhead.
18 |
19 | We came to the conclusion that there is no one-size-fits-all merge algorithm that efficiently meets the needs of all the scenarios we envision (see appendix for example scenarios). Furthermore, the generic nature of Hubs mean that future scenarios will undoubtedly materialize whose needs we cannot yet even predict.
20 |
21 | For these reasons, we believe it makes sense to implement an extensible storage model, where Hubs can support multiple merge algorithms.
22 |
23 | ## Proposal
24 |
25 | Rather than mandating a single merge algorithm for all Hub objects, we propose to define a standard set of "commit strategies" which can be chosen at a per-object level.
26 |
27 | All of the proposals discussed so far involve the same base mechanics:
28 |
29 | 1. Objects are represented by an append-only set of immutable commits
30 | 2. The current object state is derived by running some deterministic algorithm over the set of currently known commits
31 | 3. The algorithm requires some sort of commit metadata (timestamp, vector clocks, etc.)
32 |
33 | A commit strategy defines a particular imlementation of the concepts above. It defines the deterministic merge algorithm, as well as the structure and metadata of each commit that the algorithm will operate over. This includes details like whether each commit will store the full object state or some sort of delta.
34 |
35 | When creating a Hub object, the client must specify the commit strategy to be used, and provide an initial commit in the appropriate format. All further updates to that object must follow the same strategy.
36 |
37 | A client may support only a partial set of commit strategies, especially since more may be added in the future. When communicating with a Hub, the client should indicate which strategies it supports, and the Hub should only expose compatible objects to that client.
38 |
39 | Each Hub strategy is represented by a string identifer, and the set of available strategies will be community-defined.
40 |
41 |
42 |
43 | ### Initial strategies
44 |
45 | Initially we suggest two strategies:
46 |
47 | - The `basic` strategy uses a simple last-writer-wins algorithm based on the client-provided timestamp of each commit. This is identical to our [previous proposal](https://hackmd.io/OInEIRLxQY2s48tze0E7IQ) when using only the `state` field of each commit.
48 |
49 | - The `automerge` strategy uses the protocol designed by the [Automerge library](https://github.com/automerge/automerge) to allow deterministic merging of arbitrary JSON documents.
50 |
51 | Further strategies can be defined in the future as additional use cases are identified.
52 |
53 | #### Basic strategy
54 |
55 | The basic strategy follows the algorithm identified in our [earlier proposal](https://hackmd.io/OInEIRLxQY2s48tze0E7IQ), with the slight change that each commit must contain the full state of the object (the patch-based delta system is replaced with the `automerge` strategy described below).
56 |
57 | Essentially, each commit contains the complete current state of the object, and the commit with the highest client-provided timestamp is deemed to be the final state.
58 |
59 | This strategy offers:
60 |
61 | - A straightforward implementation which can easily be supported across languages
62 | - Easily understandable behavior when commits are infrequent or only from a single actor
63 | - Support for garbage collection of older history
64 |
65 | However, the inability to cleanly merge updates together makes it unsuitable for scenarios involving active collaboration or extended offline editing.
66 |
67 | ##### Sample update commit:
68 |
69 | :::warning
70 | The exact commit structure is still under discussion; the examples here are intended as a visual aid and not a definitive specification.
71 | :::
72 |
73 | Example of an object update using the `basic ` strategy:
74 |
75 | ```json
76 | {
77 | "rev": "fe4fd3240ff1c68a85730b3cf35742c8a241a0a70bd98e8869b4b593",
78 | "operation": "update",
79 | "committed_at": 1530309810,
80 | "parents": ["3a9de008f526d239d89905e2203fa484f6e68dfc096a7c051eb80f15"],
81 | "object": "3a9de008f526d239d89905e2203fa484f6e68dfc096a7c051eb80f15",
82 | "strategy": "basic",
83 | "state": {
84 | "meta": {
85 | "@context": "http://schema.org",
86 | "@type": "MusicPlaylist",
87 | "name": "Sample playlist",
88 | },
89 | "data": {
90 | "@context": "http://identity.foundation",
91 | "@type": "EncryptedPayload",
92 | "encryptedData": "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQ..."
93 | }
94 | }
95 | }
96 | ```
97 |
98 | #### Automerge strategy
99 |
100 | With the `automerge` strategy, each commit stores a serialized list of modifications in the format designed by the [Automerge library](https://github.com/automerge/automerge). These commits can be deterministically merged together using the protocol implemented by this same library.
101 |
102 | Automerge offers several advantages over our previous proposal, which suggested JSON Path for diff-based merges:
103 |
104 | - An identity-based merge (rather than a diff-based one) offers a more intuitive developer experience and reduces the chance of unexpected interactions.
105 | - In the case of an unavoidable conflict, a winning change is chosen deterministically, and losing changes are available in a `_conflicts` property for easy inspection.
106 | - Vector clocks offer a more accurate way to track change causality.
107 |
108 | However, these advantages come with some tradeoffs:
109 |
110 | - Although the concept is intuitive, the algorithm implementation is relatively complex and requires additional effort to port cross-platform.
111 | - An object's complete history is always persisted, which increases storage overhead. However, the creator believes a garbage collection mechanism is possible.
112 |
113 | With the `automerge` strategy, each commit stores a list of changes made during that commit, as well as some additional metadata including a vector clock.
114 |
115 | To reconstruct the current object state, the changes from all known commits are run through the Automerge algorithm, which uses the vector clock embedded in each commit to deterministically merge the changes into a final state.
116 |
117 | Our implementation will need to handle the presence of both plaintext (metadata) and encrypted (payload) data. There are a couple of options for this:
118 |
119 | - We could use two side-by-side standard Automerge change lists, one in plaintext and one encrypted. As long as the same actor ID is used for changes to both lists, the algorithm should resolve to a consistent set of changes.
120 |
121 | - Alternatively, we could define a custom serialization format containing two separate change lists (one encrypted, one plaintext) and a shared actor ID, sequence number, and message. The client can then decrypt this format and transform it into the format expected by the Automerge library.
122 |
123 | ##### Sample update commit:
124 |
125 | ```json
126 | {
127 | "rev": "fe4fd3240ff1c68a85730b3cf35742c8a241a0a70bd98e8869b4b593",
128 | "operation": "update",
129 | "committed_at": 1530309810,
130 | "object": "3a9de008f526d239d89905e2203fa484f6e68dfc096a7c051eb80f15",
131 | "strategy": "automerge",
132 | "changes": [
133 | {
134 | "ops": [
135 | {
136 | "action": "makeList",
137 | "obj": "aae86acc-e210-4512-92dd-1e163b1de9af"
138 | },
139 | {
140 | "action": "ins",
141 | "obj": "aae86acc-e210-4512-92dd-1e163b1de9af",
142 | "key": "_head",
143 | "elem": 1
144 | },
145 | {
146 | "action": "set",
147 | "obj": "aae86acc-e210-4512-92dd-1e163b1de9af",
148 | "key": "49322644-49f7-48a2-adb3-9d2cfec142e7:1",
149 | "value": "abc"
150 | },
151 | {
152 | "action": "ins",
153 | "obj": "aae86acc-e210-4512-92dd-1e163b1de9af",
154 | "key": "49322644-49f7-48a2-adb3-9d2cfec142e7:1",
155 | "elem": 2
156 | },
157 | {
158 | "action": "set",
159 | "obj": "aae86acc-e210-4512-92dd-1e163b1de9af",
160 | "key": "49322644-49f7-48a2-adb3-9d2cfec142e7:2",
161 | "value": "def"
162 | },
163 | {
164 | "action": "link",
165 | "obj": "00000000-0000-0000-0000-000000000000",
166 | "key": "someArray",
167 | "value": "aae86acc-e210-4512-92dd-1e163b1de9af"
168 | }
169 | ],
170 | "actor": "49322644-49f7-48a2-adb3-9d2cfec142e7",
171 | "seq": 1,
172 | "deps": {},
173 | "message": "Create an array"
174 | },
175 | {
176 | "ops": [
177 | {
178 | "action": "ins",
179 | "obj": "aae86acc-e210-4512-92dd-1e163b1de9af",
180 | "key": "49322644-49f7-48a2-adb3-9d2cfec142e7:1",
181 | "elem": 3
182 | },
183 | {
184 | "action": "set",
185 | "obj": "aae86acc-e210-4512-92dd-1e163b1de9af",
186 | "key": "49322644-49f7-48a2-adb3-9d2cfec142e7:3",
187 | "value": "123"
188 | }
189 | ],
190 | "actor": "49322644-49f7-48a2-adb3-9d2cfec142e7",
191 | "seq": 2,
192 | "deps": {},
193 | "message": "Splice an item"
194 | }
195 | ]
196 | }
197 | ```
198 |
199 | :::warning
200 | Open question: Allow multiple changes in each commit, or force one commit per change?
201 | :::
202 | :::warning
203 | Open question: Should verify that two Automerge objects edited in parallel will always both resolve to the same actor's changes
204 | :::
205 |
206 | ### Hub support
207 |
208 | Hubs will be able to store objects using unknown strategies, since the Hub's main responsibility is to accept, store, and return commit data as requested. However, Hubs will likely need to implement most strategies in order to make use of certain objects (e.g. permissions) and provide indexing of metadata.
209 |
210 | Our intention is to initially focus on supporting the `basic` strategy in the Hub, which will lay the foundation for progress to be made in other areas that rely on storage (e.g. permissions) and accelerate delivery of end-to-end scenarios.
211 |
212 | However, we plan to simultaneously add support for the `automerge` strategy in the JavaScript Hub implementation. We believe this is key to ensureing we design a generic and reusable storage interface that does not rely on specific properties of the `basic` strategy.
213 |
214 | Usage of the Automerge strategy is expected to be small at first, due to the additional effort of re-implementing the algorithm in each language-specific Hub SDK. However we hope to have Automerge as a fully-supported strategy by the time that Hubs are fully available for production use.
215 |
216 | ### Client support
217 |
218 | To meet our privacy goals, the decryption and thus the merging of commits must take place client side. This means support for each commit strategy must be re-implemented in the client library of every supported language/platform.
219 |
220 | When communicating with a Hub, client apps and SDKs should specify the commit strategies which they support. Hub objects written with incompatible strategies should be ignored.
221 |
222 | Initially we intend to implement `basic` and `automerge` support in the JavaScript SDK, as a JavaScript implementation of Automerge is already available. Implementations in other languages will focus on supporting the `basic` strategy at first, as porting the Automerge algorithm will require additional effort.
223 |
224 |
225 | ## Appendix
226 |
227 | ### Scenarios
228 |
229 | When comparing potential merge algorithms, we found that we could already envision scenarios where one approach or the other had a clear advantage:
230 |
231 | - An IOT device wishing to push frequent updates to an object (e.g. a smart thermostat updating the current temperature) might be fine with last-writer-wins semantics, especially if only one actor will ever write to the object.
232 |
233 | In this case, Automerge's state tracking overhead and lack of garbage collection could result in an unnecessary amount of overhead.
234 |
235 | - Simultaneous or close-in-time collaboration (e.g. on the medical record of a patient undergoing multiple tests in one day) requires robust merging of commits to ensure that multiple users can make edits without overwriting each other's work. This scenario is handled very well by Automerge.
236 |
237 | Additionally, we can envision some future scenarios where we may want to add a new commit strategy:
238 |
239 | - Collaborative document editing, which works best with character-level tracking of insertions and deletions, would benefit from a separate commit strategy that's specifically designed for this use case.
240 |
241 |
242 |
243 |
--------------------------------------------------------------------------------
/Hub Encryption Proposal - Draft 1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/decentralized-identity/papers/f6bbfd5bf9075671945df4e178a7caaa2d8c886e/Hub Encryption Proposal - Draft 1.pdf
--------------------------------------------------------------------------------
/Hub-based Claim Flows.md:
--------------------------------------------------------------------------------
1 |
2 | ### 1. Alice browses available claims of an Issuer
3 |
4 | ```sequence
5 | participant Alice UA as UA
6 | participant Issuer Hub as IH
7 |
8 | UA->IH: 1. Alice queries Collections for CredentialManifests
9 | IH->UA: 2. Returns all CredentialManifests Alice has access to
10 | ```
11 |
12 | ### 2. Alice synchronously obtains a claim
13 |
14 | ```sequence
15 | participant Alice Hub as AH
16 | participant Alice UA as UA
17 | participant Issuer Hub as IH
18 | participant Issuer EA as EA
19 |
20 | UA->IH: 1. Alice sends RequestClaimAction
21 | IH->EA: 2. Issuer processes claim request
22 | EA->IH: 3. Generates IssueClaimAction
23 | IH->UA: 4. Responds with IssueClaimAction
24 | UA->AH: 5. Accepts and stores claim
25 | ```
26 |
27 | ### 3. Alice obtains a claim in an aync flow
28 |
29 | ```sequence
30 | participant Alice Hub as AH
31 | participant Alice UA as UA
32 | participant Issuer Hub as IH
33 | participant Issuer EA as EA
34 |
35 | UA->IH: 1. Alice sends RequestClaimAction
36 | IH->EA: 2. Issuer processes claim request
37 | EA->AH: 3. Delivers IssueClaimAction when finished
38 | AH->UA: 4. Alice is notified of delivery
39 | UA->AH: 5. Alice accepts and stores claim
40 | ```
41 |
42 | ### 4. One of Alice's credential inputs is invalid
43 |
44 | ```sequence
45 | participant Alice UA as UA
46 | participant Issuer Hub as IH
47 | participant Issuer EA as EA
48 |
49 | UA->IH: 1. Alice sends RequestClaimAction
50 | IH->EA: 2. Issuer processes claim request
51 | EA->EA: 3. One of the claim inputs fails
52 | EA->IH: 4. Generates a DenyClaimAction
53 | IH->UA: 5. Responds with DenyClaimAction
54 | UA->UA: 6. Alice retries or accepts rejection
55 | ```
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Recommended Profile Descriptors.md:
--------------------------------------------------------------------------------
1 | # Recommended DID Profile Descriptors
2 |
3 | The following is a list of recommended descriptors to use when conveying what type of entity a DID represents. Members of the Decentralized Identity Foundation compiled this list based on examination of descriptors commonly used to represent entities across industry verticals and existing system that include semantic role definitions.
4 |
5 | >NOTE: Use of the dash (`-`) character in the `Vertical` columns below indicates the descriptor is not from an industry-specific schema and can be used across vertical contexts.
6 |
7 | ## Descriptors by Entity Type
8 |
9 | ### Humans
10 |
11 | | Descriptor(s) | Schema | Vertical |
12 | | ------ | ------ | :------: |
13 | | [Person](https://schema.org/Person) | schema.org | - |
14 |
15 | ### Organizations
16 |
17 | There are numerous descriptors across various industry-specific schemas that are commonly used to describe different types of organizations. The user/manager responsible for determining the entity association for a given organization should select the descriptor that is most common in the vertical in which their organization is typically classified.
18 |
19 | | Descriptor(s) | Schema | Vertical |
20 | | ------ | ------ | :------: |
21 | | [Organization](https://schema.org/Organization) | schema.org | - |
22 | | [Corporation](https://schema.org/Corporation) | schema.org | - |
23 | | [LocalBusiness](https://schema.org/LocalBusiness) | schema.org | - |
24 | | [Organization](http://hl7.org/fhir/organization) | hl7.org/fhir | Medical |
25 | | [Organization](https://www.gs1.org/voc/Organization) | gs1.org | Supply Chain |
26 |
27 | ### Products & Assets
28 |
29 | Any type of product, excluding intangibles and service-based offerings.
30 |
31 | | Descriptor(s) | Schema | Vertical |
32 | | ------ | ------ | :------: |
33 | | [Product](https://www.gs1.org/voc/Product) | gs1.org | Supply Chain |
34 | | [Product](https://schema.org/Product) | schema.org | - |
35 |
36 | ### Apps
37 |
38 | | Descriptor(s) | Schema | Vertical |
39 | | ------ | ------ | :------: |
40 | | [SoftwareApplication](https://schema.org/SoftwareApplication) | schema.org | - |
41 | | [MobileApplication](https://schema.org/MobileApplication) | schema.org | - |
42 | | [WebApplication](https://schema.org/WebApplication) | schema.org | - |
43 | | [VideoGame](https://schema.org/VideoGame) | schema.org | - |
44 |
45 | ### Services
46 |
47 | Any type of service offering.
48 |
49 | | Descriptor(s) | Schema | Vertical |
50 | | ------ | ------ | :------: |
51 | | [Service](https://schema.org/Service) | schema.org | - |
52 |
53 | ### Industry Vertical: Code Developer
54 |
55 | | Descriptor(s) | Schema | Vertical |
56 | | ------ | ------ | :------: |
57 | | [codeRepository](https://schema.org/codeRepository) | schema.org | - |
58 | | [SoftwareSourceCode](https://schema.org/SoftwareSourceCode) | schema.org | - |
59 |
60 | ## Profile Object Examples
61 |
62 | The `descriptors` property can be an array of objects from different schemas that contribute to the description of what the DID-linked entity is. User Agents and consuming entities should assume a 0-index ascending order of primacy.
63 |
64 | > NOTE: The `Profile` object wrapper defined by DIF's Identity Hub schema is not intended to define/contains a large number of properties that describe the target entity. Doing so should be left to the descriptor objects provided in the `descriptors` array.
65 |
66 | ```javascript
67 | {
68 | "@context": "https://identity.foundation/schemas/hub",
69 | "@type": "Profile",
70 | "did": "did:foo:123"
71 | "name": "Jeff Lebowski",
72 | "nickname": "The Dude",
73 | "email": "ilovebowling@email.com",
74 | "picture": IMG_URL,
75 | "descriptors": [
76 | {
77 | "@context": "http://schema.org",
78 | "@type": "Person",
79 | "name": "Jeffrey Lebowski",
80 | "description": "That's just, like, your opinion, man.",
81 | "address": {
82 | "@type": "PostalAddress",
83 | "streetAddress": "5227 Santa Monica Boulevard",
84 | "addressLocality": "Los Angeles",
85 | "addressRegion": "CA"
86 | }
87 | },
88 | {...}
89 | ]
90 | }
91 |
92 | // Person profile, without top-level props
93 |
94 | {
95 | "@context": "https://identity.foundation/schemas/hub",
96 | "@type": "Profile",
97 | "did": "did:sov:456"
98 | "descriptors": [
99 | {
100 | "@context": "http://schema.org",
101 | "@type": "Person",
102 | "name": "Jeffrey Lebowski",
103 | "description": "That's just, like, your opinion, man.",
104 | "address": {
105 | "@type": "PostalAddress",
106 | "streetAddress": "5227 Santa Monica Boulevard",
107 | "addressLocality": "Los Angeles",
108 | "addressRegion": "CA"
109 | }
110 | },
111 | {...}
112 | ]
113 | }
114 | ```
115 |
116 |
117 |
--------------------------------------------------------------------------------
/did-authn/siop/assets/did-authn-siop-profile-flow.plantuml:
--------------------------------------------------------------------------------
1 | @startuml
2 |
3 | skinparam monochrome true
4 |
5 | participant User as User
6 | participant "User Agent" as UA
7 | participant RP as RP
8 | participant "SIOP" as IW
9 |
10 | User -> UA : opens user agent and enters URL
11 | UA -> RP : HTTPS requests web page
12 | RP --> UA : web page
13 | UA --> User : ACK
14 | User -> UA : clicks on "Sign-in with SSI" button
15 | UA -> RP : HTTPS /sign-in request
16 | RP -> RP : generate
17 |
18 | Note over User, IW: SIOP protocol
19 | RP --> UA : 302: openid://?
20 | UA -> IW : openid://?
21 | IW -> IW : OIDC validation
22 | IW -> IW : DID AuthN validation
23 | IW --> User : (optional and out-of-scope) prompt to authenticate
24 | User -> IW : (optional and out-of-scope) out-of-band authn
25 | IW -> IW : generate
26 | Note over IW, UA: according to response_mode
27 | IW --> UA : /callback
28 |
29 | Note right of UA: depends on response_mode
30 | UA -> RP : HTTPS /callback
31 | RP -> RP : OIDC validation
32 | RP -> RP : DID AuthN validation
33 |
34 | Note over User, IW: SIOP protocol ends here
35 |
36 | RP --> UA : success web page
37 | UA --> User : ACK
38 | @enduml
39 |
40 |
--------------------------------------------------------------------------------
/did-authn/siop/assets/did_authn_siop_profile_flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/decentralized-identity/papers/f6bbfd5bf9075671945df4e178a7caaa2d8c886e/did-authn/siop/assets/did_authn_siop_profile_flow.png
--------------------------------------------------------------------------------
/did-authn/siop/did-authn-siop-profile.md:
--------------------------------------------------------------------------------
1 | # Self-Issued OpenID Connect DID Profile
2 |
3 | The work on "SIOP DID Profile" (SIOP DID) has moved to https://github.com/decentralized-identity/did-siop/
4 |
5 | The deprecated draft spec can be found here: https://identity.foundation/did-siop/
6 |
7 |
--------------------------------------------------------------------------------