Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added DID resolution and dereferencing contracts. #253

Closed
wants to merge 10 commits into from
332 changes: 307 additions & 25 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,33 @@ <h2>DID Documents</h2>
</section>

<section>
<h2>DID Resolvers and DID Resolution</h2>
<h2>DID Resolution and DID URL Dereferencing</h2>

<p>
<a>DID resolution</a> is the function of processing a <a>DID</a> by
executing a <a>DID method</a> to return a <a>DID document</a>
and additional metadata, in a conformant representation.
A <a>DID resolver</a> is a software and/or hardware component that is capable of
executing the <a>DID resolution</a> function for at least one
<a>DID method</a>.
</p>

<p>
<a>DID URL dereferencing</a> is the function of processing a <a>DID URL</a> and returning
a resource, which might or might not be a <a>DID document</a>, along with additional
metadata. A <a>DID URL dereferencer</a> is a software and/or hardware component that
is capable of executing the <a>DID URL dereferencing</a> function. Generally, a
<a>DID URL dereferencer</a> executes <a>DID resolution</a> on the <a>DID</a> portion of a
<a>DID URL</a> to obtain a <a>DID document</a>. The <a>DID URL dereferencer</a> then can perform
additional dereferencing on the <a>DID document</a> using the full <a>DID URL</a>,
if necessary.
</p>

<p>
The general inputs and outputs of the <a>DID resolution</a> and <a>DID URL dereferencing</a> functions
are specified in the <a href="#resolution"></a> section of this document. Additional considerations
for the implementation of these functions are covered in [[?DID-RESOLUTION]].
</p>
</section>

<section>
Expand Down Expand Up @@ -938,18 +964,19 @@ <h2>Generic DID URL Parameters</h2>
</p>

<p>
Adding a DID parameter to a DID URL means that the parameter becomes part of
an identifier for a resource (the DID document or other). Alternatively, the
DID resolution and the DID URL dereferencing processes can also be influenced
by passing options to a <a>DID resolver</a> that are not part of the DID URL.
Adding a DID parameter to a <a>DID URL</a> means that the parameter becomes part of
an identifier for a resource (the <a>DID document</a> or other). Alternatively, the
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
an identifier for a resource (the <a>DID document</a> or other). Alternatively, the
an identifier for a resource. Alternatively, the

The parenthetical is vague enough to confuse, sentence is fine w/o it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was text not changed by this pull request apart from adding the link.

<a>DID resolution</a> and the <a>DID URL dereferencing</a> functions can also be influenced
by passing input metadata to a <a>DID resolver</a> that are not part of the DID URL.
(See <a href="#meadata-structure"></a>).
Such options could for example control caching or the desired encoding of a
resolution result. This is comparable to HTTP, where certain parameters could
either be included in an HTTP URL, or alternatively passed as HTTP headers
during the dereferencing process. The important distinction is that DID
parameters that are part of the <a>DID URL</a> should be used to specify
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
parameters that are part of the <a>DID URL</a> should be used to specify
parameters that are part of the <a>DID URL</a> are used to specify

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These changes are editorial fixes outside this pull request and therefore I am not inclined to include them in order to keep pull this pull request smaller and more focused. Please submit a separate pull request to change this language instead of addressing it here.

<i>what resource is being identified</i>, whereas <a>DID resolver</a> options
<i>what resource is being identified</i>, whereas <a>DID resolution</a> options
that are not part of the <a>DID URL</a> should be use to control <i>how that
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
that are not part of the <a>DID URL</a> should be use to control <i>how that
that are not part of the <a>DID URL</a> are used to control <i>how that

Copy link
Member

Choose a reason for hiding this comment

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

Feels like this is language that existed when matrix params were a thing. Now that they're not... the language feels clumsy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above: These changes are editorial fixes outside this pull request and therefore I am not inclined to include them in order to keep pull this pull request smaller and more focused. Please submit a separate pull request to change this language instead of addressing it here.

resource is dereferenced</i>.
resource is resolved or dereferenced</i>.
</p>

<p>
Expand Down Expand Up @@ -1076,11 +1103,11 @@ <h2>Fragment</h2>
document</a> to identify a component of the document (for example, a unique
<a>public key description</a> or <a>service endpoint</a>). <a>DID fragment</a>
syntax and semantics are identical to a generic URI fragment and MUST conform
to <a data-cite="RFC3986#section-3.5">RFC&nbsp;3986, section 3.5</a>. To resolve
to <a data-cite="RFC3986#section-3.5">RFC&nbsp;3986, section 3.5</a>. To dereference
a <a>DID fragment</a> reference, the complete <a>DID URL</a> including the
<a>DID fragment</a> MUST be used as input to the <a>DID URL</a> dereferencing
algorithm for the target component in the <a>DID document</a> object. For more
information, see [[?DID-RESOLUTION]].
<a>DID fragment</a> MUST be used as input to the <a>DID URL dereferencing</a>
function for the target component in the <a>DID document</a> object. For more
information, see <a href="#did-url-dereferencing"></a>.
</p>

<p>
Expand Down Expand Up @@ -1238,7 +1265,7 @@ <h2>DID Subject</h2>
<p class="note">
<a>DID method</a> specifications can create intermediate representations of a
<a>DID document</a> that do not contain the <code>id</code> key, such as when a
<a>DID resolver</a> is performing resolution. However, the fully resolved
<a>DID resolver</a> is performing <a>DID resolution</a>. However, the fully resolved
<a>DID document</a> always contains a valid <code>id</code> property. The value
of <code>id</code> in the resolved <a>DID document</a> is expected to match the
<a>DID</a> that was resolved.
Expand Down Expand Up @@ -1990,7 +2017,8 @@ <h1>Core Representations</h1>
<p>
Producers MUST indicate which representation of a document has been used via a media type
in the document's metadata. Consumers MUST determine which representation a document is in
via a media type in the document's metadata. Consumers MUST NOT determine the representation
via the <code>content-type</code> DID resolver metadata field. (See <a href="#did-resolution"></a>).
Consumers MUST NOT determine the representation
of a document through its content alone.
</p>

Expand Down Expand Up @@ -2018,8 +2046,8 @@ <h2>
</h2>

<p>
When producing and consuming DID documents that are in plain JSON (as noted by
the document metadata), the following rules MUST be followed.
When producing and consuming DID documents that are in plain JSON (as indicated by
a <code>content-type</code> of <code>application/json+did</code> in the resolver metadata), the following rules MUST be followed.
</p>

<section>
Expand Down Expand Up @@ -2160,8 +2188,8 @@ <h2>
</p>

<p>
When producing and consuming DID documents that are in JSON-LD (as noted by
the document metadata), the following rules MUST be followed.
When producing and consuming DID documents that are in JSON-LD (as indicated by
a <code>content-type</code> of <code>application/jsonld+did</code> in the resolver metadata), the following rules MUST be followed.
</p>

<ul>
Expand Down Expand Up @@ -2543,18 +2571,272 @@ <h1>
</h1>

<p>
A <a>DID resolver</a> is a software or hardware component with an API for
resolving <a>DIDs</a> of at least one <a>DID method</a>. It executes the read
operation for the <a>DID method</a> corresponding to the <a>DID</a> being
resolved to obtain the authoritative <a>DID document</a>. For more information,
see Section <a href="#read-verify"></a>.
This section defines the inputs and outputs of the
<a>DID resolution</a> and <a>DID URL dereferencing</a> functions. The
exact implementation of these functions is out of scope for this specification,
but some considerations for implementors are available in [[?DID-RESOLUTION]].
</p>

<p>
The interfaces and algorithms for resolving <a>DIDs</a> and dereferencing
<a>DID URLs</a> are specified in [[?DID-RESOLUTION]].
All conformant <a>DID resolvers</a> MUST implement the <a>DID resolution</a> function
for at least one <a>DID method</a> and be able to return a <a>DID document</a> in
at least one conformant representation. All conformant <a>DID URL dereferencers</a>
MUST implement dereferencing for at least one conformant representation type.
</p>

<section>
<h2>
DID Resolution
</h2>

<p>
The <a>DID resolution</a> function resolves a <a>DID</a> into a <a>DID document</a>
by using the "Read" operation of the applicable <a>DID method</a>. (See <a href="#read-verify"></a>.)
The details of how this process is accomplished is outside the scope of this
specification, but all implementations MUST implement a function in the form:
</p>

<p>
<code>resolve ( did, input-metadata ) -> ( did-document, did-document-metadata, did-resolution-metadata )</code>
</p>

<p>
The inputs of this function are a <a>DID</a> and a set of input metadata. The
<a>DID</a> is REQUIRED. Note that if the caller of this function wishes to resolve a <a>DID URL</a>,
the caller MUST first transform the <a>DID URL</a> into a bare <a>DID</a>,
including removal of any fragment. The input metadata are a map of key-value
string pairs as described in <a href="#metadata-structure"></a>.
The input metadata are REQUIRED but the map MAY be empty. Concrete <a>bindings</a> MUST NOT
define additional inputs to this function.
</p>

<p>
The possible keys for the input metadata are defined by the DID Core Registry [[?DID-CORE-REGISTRY]]. This specification
defines the following keys and values:

<dl>
<dt>accept</dt>
<dd>The MIME type of the preferred representation of the <a>DID document</a>. The <a>DID resolver</a> MAY
use this value to determine the representation of the returned <a>DID document</a> if such a
representation is supported and available.</dd>
</dl>
</p>

Copy link
Member

Choose a reason for hiding this comment

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

Isn't it possible to allow for a plural here, ie, a resolver may list several mime types that are accepted (say, JSON or CBOR). This is pretty much like the HTTP Accept header after all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that for this specific field a plural value makes sense. Supporting it is another story that's less clear. I think we've got a few choices here:

  1. we allow multiple accept fields. I am strongly against this because it breaks the model described here, which currently maps nicely to JSON objects and other simple data structures like a Java Map interface
  2. We allow rich objects like arrays as the values. I am strongly against this because it breaks the simple model here, and I think keeping the values as plain strings is going to be important in interoperability across multiple platforms and systems where different data structures aren't as prevalent. We also don't want to get into a world of recursive objects for the metadata.
  3. We allow the field itself to define an internal syntax to express multiple values. This is already allowed by the surrounding text, but it's just that this field needs to define what that means. We can do comma separation, space separation, or just take the ABNF from the HTTP Accept header. I am in favor of this approach, but would suggest we add a new issue to define the details outside of this pull request.


<p>
The <a>DID resolver</a> executes the "Read" operation of the <a>DID method</a> as described in
<a href="#read-verify"></a>. If successful, the outputs of this function MUST contain a <a>DID document</a>,
a set of metadata for the DID document (which MAY be empty), and a set of metadata for the resolution process. If
the function results in an error, the outputs MUST contain a set of metadata for the resolution process.
</p>

<p>
The <a>DID document</a> is returned as a byte stream of a conformant representation
as determined and supported by the <a>DID resolver</a>. The caller of the <a>DID resolution</a> function
can then parse and process the <a>DID document</a> from this byte stream. The <a>DID document</a> is
REQUIRED unless an error is returned by the <a>DID resolution</a> function.
</p>

<p>
When a <a>DID document</a> is returned, the <code>DID document metadata</code> is returned as a map of
key-value string pairs as described in <a href="#metadata-structure"></a>. This metadata
contains information about the input <a>DID</a> and the returned <a>DID document</a>. This metadata
typically does not change between invocations of the <a>DID resolution</a> function. The keys and
possible values for this metadata are defined in the DID Core Registry [[?DID-CORE-REGISTRY]].
The <a>DID Document metadata</a> MAY be empty.
</p>

<p class="issue" data-number="203">
The contents of the DID document metadata still needs to be defined within this document.
</p>

<p>
The <code>DID resolution metadata</code> is returned as a map of key-value string pairs as described in
<a href="#metadata-structure"></a>. This metadata contains information about the results of
the resolution process. This metadata typically changes between invocations of the <a>DID resolution</a>
function. The keys and possible values for this metadata are defined by the DID Core Registry [[?DID-CORE-REGISTRY]]. This
specification defines the following keys and values:

<dl>
<dt>content-type</dt>
<dd>The mime-type of the returned conformant representation of the <a>DID document</a> if successful.
The <a>DID resolver</a> MUST supply this value when a <a>DID document</a>
is returned. The caller of the resolution function MUST use this value when determining how to
parse and process the byte stream returned by this function into
<a>DID document</a>.</dd>

<dt>error</dt>
<dd>The error code from the resolution process. The <a>DID resolver</a> MUST supply
this value when there is an error. The possible values
this field are defined by the DID Core Registry [[?DID-CORE-REGISTRY]]. This specification defines the following
error values:

<dl>
<dt>invalid-did</dt>
jricher marked this conversation as resolved.
Show resolved Hide resolved
<dd>The <a>DID</a> supplied to the <a>DID resolution</a> function does not
conform to valid syntax. (See <a href="#did-syntax"></a>.)</dd>

<dt>unauthorized</dt>
<dd>The caller is not authorized to resolve this <a>DID</a> with
this <a>DID resolver</a>.</dd>
</dl>

</dd>

</dl>
</p>

</section>

<section>
<h2>
DID URL Dereferencing
Copy link
Member

Choose a reason for hiding this comment

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

Skipping review of this section, as the review comments for the section above are the same. Please make edits to this section based on the edits to the previous section.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As above, I strongly disagree with @msporny 's suggested edits and direction.

</h2>

<p>
The <a>DID URL dereferencing</a> function dereferences a <a>DID URL</a> into content
represented by that <a>DID URL</a> based on the <a>DID document</a> represented by
the <a>DID</a> within the <a>DID URL</a>. This content MAY be a <a>DID document</a>, a
portion of a <a>DID document</a>, a service endpoint, or some other data. The details of the implementation of this function
are outside the scope of this specification, but all implementations MUST provide
a function of the following form:
</p>

<p>
<code>dereference ( did-url, input-options ) -> ( content, did-document-metadata, did-dereference-metadata )</code>
</p>


<div class="note">
It would be possible to define dereferencing in terms of a DID URL
and a fully parsed and modeled DID document, where the resolution process could happen externally
to the dereferencer. The problem with this is that the caller could potentially
dereference a URL against a document that the DID within the DID URL does
not represent.
</div>

<p>
The inputs to this function are a <a>DID URL</a> and a set of input metadata. The
<a>DID URL</a> is REQUIRED and MAY be any valid <a>DID URL</a>, including a fragment.
The input metadata are a map of key-value string pairs as
described in <a href="#metadata-structure"></a>. The input metadata are REQUIRED but
the map MAY be empty. Concrete <a>bindings</a> MUST NOT define additional
inputs to this function.
</p>

<p>
The possible keys for the input metadata are defined by the DID Core Registry [[?DID-CORE-REGISTRY]].
</p>

<p>
The <a>DID URL dereferencer</a> first MUST resolve the <a>DID</a> within the
<a>DID URL</a> into a <a>DID document</a> using a <a>DID resolution</a> process.
The <a>DID URL dereferencer</a> MUST parse the resulting <a>DID document</a>
from its conformant representation to allow for additional processing.
</p>

<p>
The <a>DID URL dereferencer</a> MUST perform any additional processing indicated
by the <a>DID URL</a>, such as resolving a fragment into an element. If no additional processing is
required by the <a>DID URL</a>, the <a>DID document</a> is returned as the
<code>content</code>.
</p>

<p>
The <code>DID dereference metadata</code> is returned as a map of key-value string pairs as described in
<a href="#metadata-structure"></a>. The metadata structure is REQUIRED and MUST NOT be empty.
This metadata contains information about the results of
the dereferencing process. This metadata typically changes between invocations of the <a>DID URL dereferencing</a>
function. The keys and possible values for this metadata are defined by the DID Core Registry [[?DID-CORE-REGISTRY]]. This
specification defines the following keys and values:

<dl>
<dt>content-type</dt>
<dd>The mime-type of the returned content if successful.</dd>

<dt>error</dt>
<dd>The error code from the dereferencing process. The <a>DID resolver</a> MUST supply
this value when there is an error. The possible values
this field are defined by the DID Core Registry [[?DID-CORE-REGISTRY]]. This specification defines the following
error values:

<dl>
<dt>invalid-url</dt>
<dd>The <a>DID URL</a> supplied to the <a>DID URL dereferencing</a> function does not
conform to valid syntax. (See <a href="#did-url-syntax"></a>.)</dd>
</dl>

</dd>

</dl>
</p>

<p>
The <code>content</code> of this function's output is a byte stream of data. This byte stream MAY
represent a <a>DID document</a> in a conformant representation, a portion of a <a>DID document</a>
in a conformant representation, the results of calling a service
endpoint, or something else determined by the <a>DID method</a> and its services.
</p>

<p>
If the returned <code>content</code> is a <a>DID document</a>, the <a>DID URL dereferencer</a> MAY
return an additional set of DID document metadata, as described in <a href="#did-resolution"></a>.
</p>

</section>

<section>
<h2>
Metadata structure
</h2>

<div class="issue" data-number="58">
There needs to be a registry established for handling input metadata and rules defined for
how to handle an unknown input metadata name. A similar issue applies for all metadata structures
returned from these functions.
</div>

<p>
Metadata structures are maps of key-value string pairs. All keys within this map
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Metadata structures are maps of key-value string pairs. All keys within this map
Metadata structures are maps of property-value string pairs. All properties within this map

Copy link
Member

Choose a reason for hiding this comment

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

Either property-value or name-value... prefer property-value as that's what's used elsewhere... forget the issue number, but this is being actively discussed.

Copy link
Member

Choose a reason for hiding this comment

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

issue #204 for anyone reading and looking for reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will leave as is pending resolution of #204 which can change it to be consistent through the document.

MUST be UTF-8 unicode strings. The keys of this map MUST NOT be repeated within
a given metadata structure. The keys of this map MUST be compared in a
case-insensitive way and the case MAY be transformed. The values of this map
Copy link
Member

Choose a reason for hiding this comment

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

-1 to case-insensitive comparison. I understand why it's desired, but modern software practices often do matching based on case sensitivity... this is a strange rule. What is the reason it exists? We're worried about developers not understanding case-sensitive matching?

Copy link
Contributor Author

@jricher jricher Apr 16, 2020

Choose a reason for hiding this comment

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

This is how HTTP header names are compared. I don't see it as a necessary feature as long as a binding is still required to have a deterministic mapping between the key and the binding's representation.

Copy link
Member

Choose a reason for hiding this comment

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

This is how HTTP header names are compared.

Yeah, and I question whether or not we should let esoteric HTTP things leak into this spec. There are arguments for and against, but that design in HTTP comes from a time when case sensitivity didn't matter as much as it does today.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not convinced that it matters more or less today, and so I'd be fine with rolling that back if the WG wants to go that way.

MUST be retained as an exact string without transformation.
</p>

<p>
All <a>bindings</a> MUST provide a way for the caller of the function to input or
receive the map of key-value string pairs as described in this specification. The
exact representation of these metadata structures as part of a protocol or serialization
is out of scope for this specification. For example, an HTTP-based binding can
use HTTP headers of an HTTP request to convey input metadata and HTTP headers of an
HTTP response to convey document and resolver metadata. Alternatively, a fully
JSON-based binding can use a JSON object to represent the metadata structures.
</p>

<p>
The keys and values MAY be transformed by the <a>binding</a> for transport
in a deterministic and reversible fashion. For example, the <code>content-type</code>
<a>DID resolution</a> metadata element could be represented as a text header
in a binding:
</p>

<p>
<code>DID-CONTENT-TYPE: application/json+did</code>
</p>

<p>
In this example, the key <code>content-type</code> has had the string <code>DID-</code>
prepended to it and the key text is uppercased. When returned from the function, this transformation
would be reversed to provide the value <code>application/json+did</code> under the key
<code>content-type</code> to the caller. Implementations of these functions MUST NOT
require the caller to transform its inputs into the implementation's underlying
transmission formats. In other words, the caller need not
know the underlying representation of the metadata used by the implementation of
the function in order to call the function.
</p>
</section>

</section>

<section class="informative">
Expand Down
Loading