DID-Linked Resources

Draft Community Group Report,

More details about this document
This version:
https://w3c-ccg.github.io/did-linked-resources
Issue Tracking:
GitHub
Editor:
Alex Tweeddale

Abstract

This specification creates a standardized way of referencing, dereferencing, and fetching digital resources. This includes associating digital resources with Decentralized Identifiers (DIDs) and organizing digital resources into DID-Linked Collections, where each individual resource is identifiable through its own DID URL.

Status of this document

1. Introduction

DID-Linked Resources are digital files that can be retrieved and referenced using a persistent and unique DID URL.

This specification defines common requirements, patterns, algorithms including their request formats and response formats, architectural options, and various considerations for how DID-Linked Resources SHOULD act as persistent identifiers for referencing and retrieving digital Resources (such as data schemas, status lists, trust registries, governance documents, or policy definitions). This specification complements the DID Resolution Specification, including its patterns and algorithms for DID URL resolution and dereferencing.

By using DID URLs which remain conformant with W3C Decentralized Identifiers (DIDs) v1.0 Recommendation [DID-CORE] and the DID Resolution Specification, existing DID Resolvers will be able to dereference these DID URLs to retrieve the identified resources using the DID URL query syntax in this specification.

Note: while this specification defines some base-level functionality for DID URL dereferencing, the actual steps required to communicate with a DID’s verifiable data registry are defined by the applicable DID method specification.

1.1. Conformance

In addition to sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative. The key words MAY, MUST, MUST NOT, OPTIONAL, and SHOULD in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

2. Terminology

DID controller: As defined in [DID-CORE].

DID document: As defined in [DID-CORE].

DID URL: As defined in [DID-CORE].

DID URL Dereferencing: As defined in [DID-CORE].

DID-Linked Resource: Digital files that can be retrieved and referenced using persistent and unique DID URLs.

Resource Collection: An organized and structured set of digital resources, collectively and individually identifiable using persistent and unique DID URLs.

Resource ID: A unique identifier for a specified DID-Linked Resource.

3. DID-Linked Resources

This section explains the context for building DID-Linked Resources, as well as their fundamental components for construction.

3.1. DID-Linked Resources context

The [DID-CORE] specification defines an interoperable standard for DID documents and associated core properties, however it does not currently have a standardized way to specify properties of Resources associated with DIDs, nor how to consistently reference nor retrieve them.

Digital Resources are generally stored on traditional centralized-storage endpoints, but this comes with certain drawbacks:

  1. Digital Resources could be tampered with by compromising the hosting provider: Digital Resources stored at a centralized web endpoint can be compromised and replaced by malicious actors.

  2. Hosting providers could unilaterally cease to host particular clients: Hosting providers could terminate accounts due to factors such as non-payment of fees, violation of Terms of Service, etc.

  3. Single point of failure (SPOF): Even with highly-trusted and sophisticated hosting providers who may not present a risk of infrastructure being compromised, a service outage at the hosting provider can make a Resource anchored on their systems inaccessible.

Despite these issues, many decentralized identity or Digital Credential implementations, even ones that use ledgers or other distributed systems for DIDs, often utilize centralized storage. From the W3C Verifiable Credential Implementation Guide.

Example schema.org address with full URLs:

{
  "@type": "http://schema.org/Person",
  "http://schema.org/address": {
    "@type": "http://schema.org/PostalAddress",
    "http://schema.org/streetAddress": "123 Main St.",
    "http://schema.org/addressLocality": "Blacksburg",
    "http://schema.org/addressRegion": "VA",
    "http://schema.org/postalCode": "24060",
    "http://schema.org/addressCountry": "US"
  }
}

Using traditional web endpoints to store digital resources that are critical for a Verifiable Credential to function, detracts from the proper functioning and utility that persistently-accessible Decentralized Identifiers offer. This has also resulted in inconsistent and unstandardized approaches to storing, referencing, and retrieving digital resources such as schemas, trusted issuer lists and status lists.

3.2. DID-Linked Resources construction

"Resources" SHOULD be identifiable using a Decentralized Identifier (DID) and a permanently-accessible unique identifier to fetch the Resource from a Verifiable Data Registry or other storage endpoint. We refer to this identifier as the "Resource ID".

Using unique identifiers increases confidence that no two identical Resource IDs will ever be created. This is important for ensuring the integrity and unambiguity of each individual DID-Linked Resource. Throughout this specification, we will therefore use UUIDs for the Resource IDs in examples, although different method implementations may specify other Resource ID formats.

The following path-based syntax is an example of how a DID Method may construct a DID URL to point to a DID-Linked Resource:

did:example:<unique-identifier>/resources/<unique-identifier>
Note: The above path-based syntax would be an implementation-specific way of referencing a resource.

3.3. DID-Linked Resource Collections

Resources are organized into groups or sets called "Collections". Each DID may have an associated Collection, and the Collection ID is derived from the unique identifier of the DID.

The most important concept used in this design is that each Collection is identified using a DID and is described using a DID document.

The DID document acts as metadata, providing information about the Collection, such as who is able to update it, when it was created, and what are the latest and/or deprecated versions of Resources within the Collection. For example, the following DID:

did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d

will derive the Collection ID:

0a5b94d0-a417-48ed-a6f5-4abc9e95888d
Note: The Collection ID may take the syntactical form of the DID method that the DID-Linked Resource is associated with.

4. DID-Linked Resources Algorithm

To create a "DID-Linked Resource", you MUST first create a "parent" DID, from which the Collection ID can be derived, and under which the associated Resources will be linked.

Next, to create a digital Resource associated with the "parent" DID, you MUST provide the following Request inputs:

  1. `resourceId`: Generate a new, unique identifier for the Resource

  2. `collectionId`: Specify the Collection ID as the same unique identifier of the parent DID

  3. `resourceName`: Provide a name for the Resource of your choice

  4. `resourceType`: Specify the type of Resource and make reference to the DID Spec Registries to utilise consistent and registered Resource Types.

  5. `data`: pass the Resource file as a path or Base64 encoded in-line.

  6. Sign the transaction using the same Verification Method keys as those within the parent DID Document.

As a response, the DID Document SHOULD append metadata about the DID-Linked Resource into the existing DID Document Metadata.

{
  "@context": "https://w3id.org/did-resolution/v1",
  "didResolutionMetadata": {
    "contentType": "application/did+ld+json",
    "retrieved": "2023-06-23T11:21:20Z",
    "did": {
      "didString": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
      "methodSpecificId": "0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
      "method": "example"
    }
  },
  "didDocument": {
    "@context": [
      "https://www.w3.org/ns/did/v1",
      "https://w3id.org/security/suites/ed25519-2020/v1"
    ],
    "id": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
    "controller": [
      "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d"
    ],
    "verificationMethod": [
      {
        "id": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d#key-1",
        "type": "Ed25519VerificationKey2020",
        "controller": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
        "publicKeyMultibase": "z6Mkphkdz97NJXYSbj7eGDkWR242kP58LEEkVrSseTtAzbWE"
      }
    ],
    "authentication": [
      "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d#key-1"
    ],
    "service": [
      {
        "id": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d#website",
        "type": "LinkedDomains",
        "serviceEndpoint": [
          "https://foo.com"
        ]
      }
    ]
  },
  "didDocumentMetadata": {
    "created": "2023-03-22T07:19:47Z",
    "versionId": "15be3e0f-12e9-4c26-9b60-a02bf5746313",
    "linkedResourceMetadata": [
      {
        "resourceURI": "did:example:0a5b94d0-a417-48ed-a6f5-4abc9e95888d/resources/4e1104f9-2ee9-4bde-adc2-ab8ba72b124a",
        "resourceCollectionId": "0a5b94d0-a417-48ed-a6f5-4abc9e95888d",
        "resourceId": "4e1104f9-2ee9-4bde-adc2-ab8ba72b124a",
        "resourceName": "ExampleResource",
        "resourceType": "StatusList2021Revocation",
        "mediaType": "application/json",
        "resourceVersion": "",
        "created": "2023-03-24T12:13:45Z",
        "checksum": "6819aaecd4073173b159fedf8077c38e14939d03d58e7f4e2a0ddfe034eb2ed4",
        "previousVersionId": null,
        "nextVersionId": null
      }
    ]
  }
}

5. Linking DIDs to Resources and Collections

Multiple Resources can be stored within a Collection and linked to the same DID; for example, this could be new versions of the same Resource over a period of time, or entirely different resources. This enables unique resources to be stored directly on a Verifiable Data Registry (VDR) and be retrievable through DID resolution and DID URL dereferencing.

Once you have created a resource, the DID document will automatically reference the resource and the collection within the `didDocumentMetadata` in a newly defined section called `linkedResourceMetadata`.

6. Architecture Overview

The relationship between DIDs, Resource Collections and Resources is shown in the diagram below:

DID-Linked Resources Architecture Overview

7. Design principles

The following design principles should be taken into consideration. DID-Linked Resources SHOULD:

  1. Use existing, familiar DID Core Spec patterns where possible

  2. Support existing DID Resolvers and principles of DID URL dereferencing

  3. Protect against linkrot for long-term retrieval

  4. Enable resources to be versioned and organized, with individual versions being able to be fetched

  5. Include semantic linkage between DID documents and associated resources (via metadata or otherwise)

8. Resource Request Parameters

The following list defines which specific parameters are required and are optional for a request to create a resource:

Parameter Type Required?
"resourceCollectionId" A String that conforms to a unique identifier format for an associated DID method Yes
"resourceId" A String, such as a UUID, that uniquely identifies the resource Yes
"resourceName" A String that names and identifies a resource. This property, along with the resourceType below, can be used to track version changes within a resource Yes
"resourceType" A String that uniquely identifies the type of resource Yes
"resourceVersion" A String that identifies the version of the resource. This property, along with the resourceName above, can be used to track version changes within a resource No
"alsoKnownAs" An array that describes alternative URIs for the resource No

9. Resource Response Parameters

The following list defines which specific parameters are required and which are optional for a response, following the creation of a Resource:

Parameter Description
resourceUri A string or a map that conforms to the rules of RFC3986 URIs which SHOULD directly lead to a location where the resource can be accessed. For example: did:example:46e2af9a-2ea0-4815-999d-730a6778227c/resources/0f964a80-5d18-4867-83e3-b47f5a756f02.
resourceCollectionId A string that conforms to a method-specific supported unique identifier format. For example, a UUID: 46e2af9a-2ea0-4815-999d-730a6778227c.
resourceId A string that uniquely identifies the resource. For example, a UUID: 0f964a80-5d18-4867-83e3-b47f5a756f02.
resourceName A string that uniquely names and identifies a resource. This property, along with the resourceType below, can be used to track version changes within a resource.
resourceType A string that identifies the type of resource. This property, along with the resourceName above, can be used to track version changes within a resource. Not to be confused with mediaType.
resourceVersion (Optional) A string that identifies the version of the resource. This property is provided by the client and can be any value.
alsoKnownAs (Optional) An array that describes alternative URIs for the resource.
mediaType A string that identifies the IANA-media type of the resource.
created A string that identifies the time the resource was created, as an XML date-time.
updated (Optional) A string that identifies the time the resource was updated, as an XML date-time.
checksum A string that may be used to prove that the resource has not been tampered with.
previousVersionId (Optional) A string that identifies the previous version of the resource.
nextVersionId (Optional) A string that identifies the next version of the resource.

9.1. Discoverability via DIDDoc Metadata

Once a Resource has been created under a Resource Collection, the parent DID document will automatically have an updated `didDocumentMetadata` section, including `linkedResourceMetadata`.

The syntax of the linked Resource metadata is as follows:

"didDocumentMetadata": {
    "created": "2020-12-20T19:17:47Z",
    "updated": "",
    "deactivated": false,
    "versionId": "bdab59b0-66f5-42d3-b809-1829bdcc0408",
    "previousVersion": "",
    "nextVersion": "",
    "linkedResourceMetadata": [
      { // First version of a Resource called PassportSchema
        "resourceURI": "did:example:13d5ad44-9e99-428f-81e9-274458cefddc/resources/44547089-170b-4f5a-bcbc-06e46e0089e4",
        "resourceCollectionId": "13d5ad44-9e99-428f-81e9-274458cefddc", // Common collection ID
        "resourceId": "44547089-170b-4f5a-bcbc-06e46e0089e4", // Old Resource ID and version number
        "resourceName": "PassportSchema", // Resource name must remain the same
        "resourceType": "CL-Schema", // Resource type must remain the same
        "resourceVersion": "1.0.1", // A user-set version
        "mediaType": "application/json",
        "created": "2022-07-19T08:40:00Z",
        "checksum": "7b2022636f6e74656e74223a202274657374206461746122207d0ae3b0c44298", // Old version checksum
        "previousVersionId": "", // empty string, since no previous version
        "nextVersionId": "bb2118f3-5e55-4510-b420-33ef9e1726d2", // Points to next version below
        },
      { // Second version of a Resource called PassportSchema
        "resourceURI": "did:example:13d5ad44-9e99-428f-81e9-274458cefddc/resources/bb2118f3-5e55-4510-b420-33ef9e1726d2",
        "resourceCollectionId": "13d5ad44-9e99-428f-81e9-274458cefddc", // Common collection ID
        "resourceId": "bb2118f3-5e55-4510-b420-33ef9e1726d2", // New Resource ID and version number
        "resourceName": "PassportSchema", // Resource name must remain the same
        "resourceType": "JSONSchema2020", // Resource type must remain the same
        "resourceVersion" "1.0.1" // user-set semantic version control
        "mediaType": "application/json",
        "created": "2022-08-07T08:40:00Z",
        "checksum": "9123dcbb0b42652b0e105956c68d3ca2ff34584f324fa41a29aedd32b883e131", // New version checksum
        "previousVersionId": "44547089-170b-4f5a-bcbc-06e46e0089e4", // Points to previous version above
        "nextVersionId": "0be87654-4a48-4f8e-8789-15ec3589ccdd" // Points to next version. Empty string if no new version
        }
      ]
    }

Importantly, we decided not to populate the `didDocumentMetadata` with the actual resource data, but instead, populate what we refer to as a Resource Preview which contains all the metadata about the associated resources.

9.2. Composition of Resource Preview

Resource previews will appear within DID document metadata. These do not include the actual core data of the resource and only reference the metadata:

Example:

{
  "resourceUri": "did:example:13d5ad44-9e99-428f-81e9-274458cefddc/resources/bb2118f3-5e55-4510-b420-33ef9e1726d2",
  "resourceCollectionId": "13d5ad44-9e99-428f-81e9-274458cefddc",
  "resourceId": "bb2118f3-5e55-4510-b420-33ef9e1726d2",
  "resourceName": "PassportSchema",
  "resourceType": "CL-SChema",
  "resourceVersion": "1.0.1",
  "mediaType": "application/json",
  "created": "2022-04-20T20:19:19Z",
  "checksum": "a7c369ee9da8b25a2d6e93973fa8ca939b75abb6c39799d879a929ebea1adc0a",
  "previousVersionId": "67f2df00-0b6e-404b-8c70-1d63200e6412",
  "nextVersionId": "98922424-c214-4439-b52c-f68ddb450b40",
  "alsoKnownAs": [{
      "uri": "https://example.com/alternative-uri",
      "description": "Alternative URI description"
      },
      {
      "uri": "https://example.com/alternative-uri",
      "description": "Alternative URI description"
      }]
}

10. Resolution and Dereferecing process

This section outlines the process for resolving a DID URL to retrieve the linked resource.

10.1. DID Resolution and Dereferencing

When you resolve a DID you get a DID Document as by DID Core. When you dereference a DID, you may get the DID Document, a portion of a DID document, or the resource at the end of a service endpoint (if the DID contains a service component). You can only resolve a DID to return a DID document, and you can only dereference a DID reference to return a digital resource.

10.2. Resource resolution and dereferencing

Normal DID URL dereferencing can be conceived in two steps:

  1. A DID is resolved to a DID Document;

  2. A resource within / associated with the DID Document is identified, based on the portion of the DID URL that follows the DID (path, query, fragment as defined by the ABNF in section 3.2 of the [DID-CORE] specification.).

Requests to fetch Resources are considered as a DID URL Dereferencing scenario it uses [DID URL paths](https://w3c.github.io/did-core/#path) to lead to a Resource object, rather than a DIDDoc.

On the other hand, Resources metadata requests are handled like DID URL Resolution since the result is a subsection of `didDocumentMetadata` specific to that resource.

10.3. Resource resolution and dereferencing parameters

Here we have an ability to specify different parameters to filter to particular DID-Linked Resources.

Parameter Type Description
resourceId A string that conforms to a method specific unique identifier format. The unique identifier of a particular DID-Linked Resource.
resourceCollectionId A string that conforms to a method specific unique identifier format. Can be used to query all resources associated with a DID if combined with resourceMetadata=true.
resourceName A string. The specific name of a DID-Linked Resource.
resourceType A string. The specific type of a DID-Linked Resource.
resourceVersionTime A JSON String serialized as an XML Datetime normalized to UTC 00:00:00 and without sub-second decimal precision. Used to fetch a version of a resource at a specific point in time.
checksum A string. Used to specify a particular resource checksum to demonstrate it is untampered.
resourceMetadata Boolean. Used to fetch metadata related to a specific resource or group of resources.

Like with DIDDoc query parameters, these can all be chained together to create complex requests for specific DID-Linked Resources at particular points in time or associated with particular DIDDoc versions.

10.4. Rules and logic for handling ambiguous queries

It is important to understand how our resolver logically handles more complex dereferencing requests. We have set some baseline defaults and rules to ensure a logical and consistent experience for clients who use our resolver.

10.4.1. Ambiguity generally throws an error

If the request specifies a parameter where there are multiple potential results, such as where the DID has two resources of the same `resourceType` but `resourceName` is not the same, an error will be thrown because there is not enough information to discern which resource is being requested.

10.4.2. Multiple versions of the same resource

If there are multiple resources with the same `resourceType` and `resourceName` but with different `versionIds,` and there is no parameter specified to fetch a particular version, the resolver will fetch the latest resource by default.

This is because the query is not ambiguous in terms of discerning which set of resources to dereference to, but is only ambiguous in terms of which version of that resource to fetch.

10.4.3. Ambiguity + resourceMetadata=true

If there is an ambiguous query, such as where there are two resources with the same name but different types, AND there is a resourceMetadata=true parameter, resource data pertaining to all the resources which could potentially be seen as being ambiguous will be returned.

For example, in the below example, there are multiple resources with the `resourceType= string`, but with different `resourceName` parameters:

Request format
did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0?resourceType=String&resourceMetadata=true
Response format
{
    "@context": "https://w3id.org/did-resolution/v1",
    "dereferencingMetadata": {
        "contentType": "application/did+ld+json",
        "retrieved": "2023-04-26T15:38:26Z",
        "did": {
            "didString": "did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
            "methodSpecificId": "c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
            "method": "example"
        }
    },
    "contentStream": {
        "created": "2023-01-25T11:58:10.390039347Z",
        "versionId": "e5615fc2-6f13-42b1-989c-49576a574cef",
        "linkedResourceMetadata": [
            {
                "resourceURI": "did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0/resources/9ba3922e-d5f5-4f53-b265-fc0d4e988c77",
                "resourceCollectionId": "c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
                "resourceId": "9ba3922e-d5f5-4f53-b265-fc0d4e988c77",
                "resourceName": "exampleResourceName",
                "resourceType": "exampleResourceType",
                "mediaType": "application/json",
                "resourceVersion": "",
                "created": "2023-01-25T12:08:39.63Z",
                "checksum": "e1dbc03b50bdb995961dc8843df6539b79d03bf49787ed6462189ee97d27eaf3",
                "previousVersionId": null,
                "nextVersionId": null
            },
            {
                "resourceURI": "did:example:c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0/resources/e733ebb7-c8dd-41ed-9d42-33bceea70952",
                "resourceCollectionId": "c1685ca0-1f5b-439c-8eb8-5c0e85ab7cd0",
                "resourceId": "e733ebb7-c8dd-41ed-9d42-33bceea70952",
                "resourceName": "exampleResourceName",
                "resourceType": "exampleResourceType",
                "mediaType": "application/json",
                "resourceVersion": "",
                "created": "2023-01-25T12:04:52.26Z",
                "checksum": "cffd829b06797f85407be9353056db722ca3eca0c05ab0462a42d30f19cdef09",
                "previousVersionId": null,
                "nextVersionId": null
            }
        ]
    },
    "contentMetadata": {}
}

11. Resolution and Dereferecing examples

11.1. ResourceId

`ResourceId` parameter can be used for filtering a particular resource version by specifically identifying its unique ID.

For example:

Request format
did:example:b5d70adf-31ca-4662-aa10-d3a54cd8f06c?resourceId=5e16a3f9-7c6e-4b6b-8e28-20f56780ee25
Response format
{
  "title": "Example Verifiable Credential Schema",
  "description": "Example schema for DID-Linked Resources spec",
  "type": "object",
  "properties": {
    "@context": {
      "description": "Defines semantic context of the Example Credential",
      "type": "array",
        "items": {
          "type": "string",
          "format": "uri"
        }
    }
  }  
}

11.2. ResourceCollectionId

`resourceCollectionId` parameter filters all the resource by `collectionId` field. By default cause we are asking for resources for a particular DID it already includes all the resource with the same `collectionId` and this parameter can used mostly as sanity check. Without `resourceMetadata=true` parameter will return the latest created resource if there is only one resource or an unambiguous resource.

For example:

Request format
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceCollectionId=d8ac0372-0d4b-413e-8ef5-8e8f07822b2c
Response format
{
  "title": "Example Verifiable Credential Schema",
  "description": "Example schema for DID-Linked Resources spec",
  "type": "object",
  "properties": {
    "@context": {
      "description": "Defines semantic context of the Example Credential",
      "type": "array",
        "items": {
          "type": "string",
          "format": "uri"
        }
    }
  }  
}

11.3. ResourceType

This parameter is also just a filter by `Type` field through resources. But there is a corner case if the user asks about exact resource (exact data). If after applying all the parameters in request several resources are left with the same `Name` - the latest one will be responded. Otherwise - error `NotFoundError` will be raised.

For example:

Request format
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceType=exampleResourceType
Response format
{
  "title": "Example Verifiable Credential Schema",
  "description": "Example schema for DID-Linked Resources spec",
  "type": "object",
  "properties": {
    "@context": {
      "description": "Defines semantic context of the Example Credential",
      "type": "array",
        "items": {
          "type": "string",
          "format": "uri"
        }
    }
  }  
}

11.4. ResourceName

Behavior of this parameter is similar with [resourceType](adr-005-did-resolution-and-did-url-dereferencing.md#resourcetype) one. If there is no ambiguous resource, it will be fetched. Otherwise greater specifity is required.

For example:

Request format
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceName=exampleResourceName
Response format
{
  "title": "Example Verifiable Credential Schema",
  "description": "Example schema for DID-Linked Resources spec",
  "type": "object",
  "properties": {
    "@context": {
      "description": "Defines semantic context of the Example Credential",
      "type": "array",
        "items": {
          "type": "string",
          "format": "uri"
        }
    }
  }  
}

11.5. ResourceVersion

This parameter filters by `Version` field. We introduced it with latest network upgrade and can be optionally set to identify a version of a resource with a particular string.

For example:

Request format
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceVersion=b9029cf7-c40b-4850-b9a1-9bfad46a68d7
Response format
{
  "title": "Example Verifiable Credential Schema",
  "description": "Example schema for DID-Linked Resources spec",
  "type": "object",
  "properties": {
    "@context": {
      "description": "Defines semantic context of the Example Credential",
      "type": "array",
        "items": {
          "type": "string",
          "format": "uri"
        }
    }
  }  
}

11.6. ResourceVersionTime

Important: This parameter must always be accompanied by another resource query qualifier.

The main goal here is to get the nearest resource for `resourceVersionTime` value. "Nearest" means that if we are asking for time between `resource1` and `resource2` were created - `resource1` will be returned. In case if requested `resourceVersionTime` is before the first resource created - `NotFoundError` will be returned. The most useful use-case here is checking that some "Credential" (driver’s license) was active at `resourceVersionTime` (was not revoked from Revocation Registry for example).

For example:

Request format
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceVersionTime=2023-02-22T06:58:18.61Z&resourceVersion=1.14.41
Response format
{
  "title": "Example Verifiable Credential Schema",
  "description": "Example schema for DID-Linked Resources spec",
  "version": "1.14.41",
  "type": "object",
  "properties": {
    "@context": {
      "description": "Defines semantic context of the Example Credential",
      "type": "array",
        "items": {
          "type": "string",
          "format": "uri"
        }
    }
  }  
}

11.7. Checksum

It just checks that `checksum` is the same as resource’s metadata and also can used as a sanity check. For example, if the user knows what is exact checksum then it may be checked before actual downloading.

For example:

Request format
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?checksum=27ad51a49f079a6634b18bbc3ac08dd2d91f13fabf72ea8e5d83692fe4820058
Response format
{
  "title": "Example Verifiable Credential Schema",
  "description": "Example schema for DID-Linked Resources spec",
  "version": "1.14.41",
  "type": "object",
  "properties": {
    "@context": {
      "description": "Defines semantic context of the Example Credential",
      "type": "array",
        "items": {
          "type": "string",
          "format": "uri"
        }
    }
  }  
}

11.8. ResourceMetadata

This parameter a kind of modifier which works in the same manner as [metadata](adr-005-did-resolution-and-did-url-dereferencing.md#metadata) but applies to resources. It allows to get only Metadata information about resource(s) without downloading. Also it changes the flow for `resourceType` and `resourceName` parameters and general meaning of this parameter - just filter. So, here it allows to create a chain of parameters and apply all of them to the resourceCollection and get only interested resource metadata. Possible variants:

For example:

Request format
did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceType=exampleSchema&resourceMetadata=true
Response format
{
    "@context": "https://w3id.org/did-resolution/v1",
    "dereferencingMetadata": {
        "contentType": "application/did+ld+json",
        "retrieved": "2023-04-27T11:10:17Z",
        "did": {
            "didString": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
            "methodSpecificId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
            "method": "example"
        }
    },
    "contentStream": {
        "created": "2023-02-21T14:28:47.40Z",
        "versionId": "44f49254-8106-40ee-99ad-e50ac9517346",
        "linkedResourceMetadata": [
            {
                "resourceURI": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c/resources/bae5cb6c-564a-4ed4-8c0e-d5c3b0f8ae0a",
                "resourceCollectionId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
                "resourceId": "bae5cb6c-564a-4ed4-8c0e-d5c3b0f8ae0a",
                "resourceName": "exampleResourceName",
                "resourceType": "exampleResourceType",
                "mediaType": "application/json",
                "resourceVersion": "1.14.41",
                "created": "2023-02-22T08:57:23.34Z",
                "checksum": "93ba6f3c55ee073e6278f98e820776e73cfd9d3e32dc5882507ee8effbdbfadd",
                "previousVersionId": "40829caf-b415-4b1d-91a3-b56dfb6374f4",
                "nextVersionId": null
            },
            {
                "resourceURI": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c/resources/40829caf-b415-4b1d-91a3-b56dfb6374f4",
                "resourceCollectionId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
                "resourceId": "40829caf-b415-4b1d-91a3-b56dfb6374f4",
                "resourceName": "exampleResourceName",
                "resourceType": "exampleResourceType",
                "mediaType": "application/json",
                "resourceVersion": "1.45.24",
                "created": "2023-02-22T08:55:07.54Z",
                "checksum": "2a6af570635ed49a39eae9a9c60ccb40d61466839d4ab2f17432a8ac705da489",
                "previousVersionId": "547abdb3-99f8-4040-b030-3296c4668846",
                "nextVersionId": "bae5cb6c-564a-4ed4-8c0e-d5c3b0f8ae0a"
            },
            {
                "resourceURI": "did:example:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c/resources/547abdb3-99f8-4040-b030-3296c4668846",
                "resourceCollectionId": "d8ac0372-0d4b-413e-8ef5-8e8f07822b2c",
                "resourceId": "547abdb3-99f8-4040-b030-3296c4668846",
                "resourceName": "exampleResourceName",
                "resourceType": "exampleResourceType",
                "mediaType": "application/json",
                "resourceVersion": "1.42.26",
                "created": "2023-02-22T08:54:14.48Z",
                "checksum": "4524f2193da6e5cc28d8a71f268d097891d053d4f206b045347ae117ce70d8ac",
                "previousVersionId": null,
                "nextVersionId": "40829caf-b415-4b1d-91a3-b56dfb6374f4"
            }
        ]
    },
    "contentMetadata": {}
}

12. Security considerations

This section discusses the security considerations associated with linking and dereferencing DID-Linked Resources.

12.1. Access Control

Provides guidance on access control mechanisms for ensuring that only authorized entities can access the linked resources.

12.2. Authenticity and Integrity

Addresses the importance of ensuring the authenticity and integrity of the linked resources. It discusses techniques such as digital signatures and cryptographic proofs to verify the origin and integrity of the resources.

12.3. Confidentiality

Discusses considerations for preserving the confidentiality of the linked resources, especially when accessing them over insecure channels. It suggests techniques such as encryption and secure communication protocols.

13. Privacy considerations

This section explores the privacy considerations associated with DID-Linked Resources.

13.1. Linkability and Pseudonymity

Examines the potential linkability of resources to DIDs and the impact on privacy. It discusses techniques for preserving pseudonymity and minimizing the correlation of identities across different resources.

13.2. Information Exposure

Addresses the risks of unintentional information exposure when dereferencing DID URLs. It provides recommendations for managing and controlling the disclosure of sensitive information.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Index

Terms defined by this specification

References

Normative References

[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119

Informative References

[DID-CORE]
Manu Sporny; et al. Decentralized Identifiers (DIDs) v1.0. URL: https://w3c.github.io/did-core/
[RFC8174]
B. Leiba. Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174