did-meliorism August 2022
Steele Informational [Page]
Workgroup:
none
Author:
O. Steele
Transmute

Meliorism DID Method

Abstract

This specification defines Meliorism (did:meliorism), a Decentralized Identifier Method (DIM), conforming to [DID-CORE]. Decentralized Identifiers are useful building blocks for privacy, reputation, permission and knowledge management systems.

This document is under development, if you would like to contribute, please visit: github.com/transmute-industries/did-method-meliorism.

Table of Contents

1. Introduction

Decentralized Identifiers and Decentralized Identifier URLs provide a mechanism for discovering relationships and capabilities associated with identifiers that are derived from cryptographic operations.

Goals for this specification do not include representing new kinds of cryptographic keys, certificate chains, representing new kinds of certified keys or replacing X.509 certificates.

This specification relies on [RFC2397], [RFC6902], [RFC7515], [RFC7517], [RFC7638] and IANA registries established by those specifications.

2. Notational Conventions

The keywords MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, when they appear in this document, are to be interpreted as described in [RFC2119].

3. Terminology

3.1. JWS

A JSON Web Signature as described in [RFC7515].

3.2. JWK

A JSON Web Key as described in [RFC7517].

3.3. Patch

A JSON Patch as described in [RFC6902]

3.4. Signed Patch

A JWS where the payload is a JSON Patch as described in [RFC6902], and the decoded header looks like this:

{
  "jwk": {
    "kty": "OKP",
    "crv": "Ed25519",
    "alg": "EdDSA",
    "x": "hdw9kDgv57oWdkGi1YIqdc18vYXHLMIdFZVJNv1Uzf4"
  },
  "alg": "EdDSA",
  "cty": "application/json-patch+json"
}

3.5. Patch URI

A URI that resolves to either a Signed Patch or a JSON encoded array of Signed Patches.

The Patch URI Scheme MUST be either data, https or ipfs,

3.6. Primary Identifier Key

The JWK that verifies the majority of the JWS encoded Patches. The primary identifier key's kid computed according [RFC7638] is referred to as the majority key identifier.

3.7. Majority Key Identifier

The primary identifier key's kid computed according [RFC7638].

3.8. DID Controller

The entity responsible for managing the latest content of the DID Document.

See W3C DID Controller.

3.9. DID Subject

The entity identified by the DID.

It is common in custodial systems for the DID Controller to be a party trusted by the DID Subject.

It is common in non-custodial systems for the DID Subject to be the DID Controller.

See W3C DID Subject.

3.10. Trust Anchors

The entities responsible for the availability of a Patch URI.

In the case of content schemes such as data this is the content itself.

In the case of content addressing schemes such as ipfs, this is the network of honest nodes.

In the case of https scheme, this is the authority.

A trust anchor might provide services for multiple DID Controllers.

The W3C Verifiable Data Registry for this method is the set of trust anchors that the did controller commits to when constructing their identifier.

4. Identifier Syntax

The format for the did:meliorism method conforms to the [DID-CORE] specification and is simple. It consists of the did:meliorism prefix, followed by a Multihash content identifier encoded according to [multiformats-multihash-05] or the base64url json encoded base document.

The ABNF for the key format is described below:

did-meliorism-format      := did:meliorism:< base-document-content-id / base-document-content >
base-document-content-id  := *base58btc-character
base-document-content     := *base64url-character
base64url-character       := [A-Z] / [a-z] / [0-9] / "-" / "_"
base58btc-character       := [a-km-zA-HJ-NP-Z1-9]

5. Method Operations

5.1. Create

In order to create a new did:meliorism, a base json document:

{
  "patches": [
    "https://a.example/patches/0",
    "https://b.example/patches/21#42",
    "ipfs://QmTwmG3nFqtM5o2F11X9XByYwTJCHeVtPLJroyvQKEXkE3",
    "data:application/jose,eyJqd2siOnsia3R5IjoiT0tQIiwi..."
  ]
}

This document MUST have a patches array.

The patches array MUST NOT be empty and all members must be string encoded URIs.

All URIs MUST start with one of the following prefixes:

  • https://
  • ipfs://
  • data:application/jose,

A decentralized identifier is obtained from the base document.

There are 2 forms for any given base document.

In the short form, the identifier is based on IPFS content address for the base document:

did:meliorism:QmPNzsLMBsz36Bhi13B2KaWNWexdoofaZKVrEbmvsLzmiA

In the long form, the identifier is the base64url encoding of the base document:

did:meliorism:eyJwYXRjaGVzIjpbImh0dHBzOi8vYS5leGFtcGxlL3BhdGNoZXMvMCIsImh0dHBzOi8vYi5leGFtcGxlL3BhdGNoZXMvMSIsImh0dHBzOi8vYy5leGFtcGxlL3BhdGNoZXMvMiJdfQ

5.2. Resolve

In order to resolve a did:meliorism identifier, first the base document must be obtained for the identifier.

If the identifier is in short form, replace did:meliorism: with ipfs:// and resolve the base document from the ipfs network.

If the identifier is in long form, decode the base document from the identifier, ex: JSON.parse( BASE64_URL_DECODE( did.replace(did:meliorism:, '') ) )

Process each of the URLs in the patches member of the base json document, yielding a collection of resolvable and unresolvable signed patches.

If a patch URI contains a fragment, the content MUST be an array and the fragment must be the string encoding of the base 10 index of the relevant signed patch.

For example: https://a.example/patches/0#42 => [..., jws_41, jws_42, jws_43, ...]

If the patch URI contains no fragment, the content is MUST be either: [jws] or jws.

In all cases, dereferencing the URI MUST return a single JWS string, not an array.

From the unresolvable prepare an unresolvable service object of the following format:

{
  // index of the Patch URI in the base document
  "id": "#0",
  "type": "SignedIetfJsonPatch",
  "revoked": true,
  // url of the patch from the base document
  "serviceEndpoint": "https://a.example/patches/0"
}

From the resolvable signed patches obtain the majority key identifier as follows:

  1. Decode each JWS header, and obtain the jwk in the protected header.
  2. Compute an index of kid to jwk where kid is computed according to [RFC7638].
  3. Verify each JWS using the public key in encoded in the protected header.
  4. Count the verifications for each kid and let the majority key identifier be the kid matching the jwk that was used to verify the largest number of signatures.

Filter the resolvable signed patches list to only patches signed by the majority key identifier.

Obtain the method specific didDocumentBase json which is:

{
  "alsoKnownAs": [],
  "verificationMethod": [],
  "authentication": [],
  "assertionMethod": [],
  "capabilityInvocation": [],
  "capabilityDelegation": [],
  "keyAgreement": [],
  "service": []
}

Let the initial didDocument be equal to the didDocumentBase.

Apply each decoded [RFC6902] JSON Patch to the didDocument, and set the result to the didDocument.

For each applied patch construct a resolvable service object of the following format:

{
  // index of the Patch URI in the base document
  "id": "#0",
  "type": "SignedIetfJsonPatch",
  // url of the patch from the base document
  "serviceEndpoint": "https://a.example/patches/0"
}

Combine the resolvable and unresolvable service object arrays as the service array.

Add the did method @context which is:

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    {
      "@vocab": "https://vocab.example#"
    }
  ]
}

Add the id member to the didDocument.

Add the service array to the didDocument

Compute the didDocumentMetadata as follows:

didDocumentMetadata.deactivated is true if all service objects are revoked, and false otherwise.

didDocumentMetadata.disputed is true if all service objects are not revoked, and false otherwise.

didDocumentMetadata.immutable is true if all service objects endpoint members start with ipfs:// or data:application/jose,.

didDocumentMetadata.valid is true if the didDocument JSON matches the normative requirements of [DID-CORE] and the JSON Schema used to validate did:meliorism.

The resolution response object is the didDocument and the didDocumentMetadata.

Here is an example:

{
  "didDocument": {
    "@context": [
      "https://www.w3.org/ns/did/v1",
      {
        "@vocab": "https://vocab.example#"
      }
    ],
    "id": "did:meliorism:QmPNzsLMBsz36Bhi13B2KaWNWexdoofaZKVrEbmvsLzmiA",
    "verificationMethod": [
      {
        "id": "#key-0",
        "type": "JsonWebKey2020",
        "controller": "did:meliorism:QmPNzsLMBsz36Bhi13B2KaWNWexdoofaZKVrEbmvsLzmiA",
        "publicKeyJwk": {
          "kty": "OKP",
          "crv": "Ed25519",
          "alg": "EdDSA",
          "x": "wJNLf0F065a7OnjnLKY55zgGfwgh6T8GSwAyFSD0qVI"
        }
      }
    ],
    "authentication": ["#key-0"],
    "assertionMethod": ["#key-0"],
    "capabilityDelegation": ["#key-0"],
    "capabilityInvocation": ["#key-0"],
    "keyAgreement": ["#key-0"],
    "service": [
      {
        "id": "#0",
        "type": "SignedIetfJsonPatch",
        "serviceEndpoint": "data:application/jose,eyJqd2siOnsia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsImFsZyI..."
      },
      {
        "id": "#1",
        "type": "SignedIetfJsonPatch",
        "serviceEndpoint": "ipfs://QmTwmG3nFqtM5o2F11X9XByYwTJCHeVtPLJroyvQKEXkE3"
      },
      {
        "id": "#2",
        "type": "SignedIetfJsonPatch",
        "revoked": true,
        "serviceEndpoint": "https://c.example/patches/2"
      }
    ]
  },
  "didDocumentMetadata": {
    "valid": true,
    "disputed": true,
    "immutable": false,
    "deactivated": false
  }
}

5.3. Update

To update did:meliorism document, you must compute an [RFC6902] JSON Patch and sign it as a JSON payload.

The protected header MUST include the public key in jwk format used to verify the signature.

This JWS MUST be dereferenced from one of the Patch URIs listed in the base document used to obtain the DID.

In the case that the Patch URI resolves to an array, the Patch URI MUST contain a fragment used to identify the correct JWS member.

In order for the update to be applied, the jwk used to sign the patch must be used to sign the simple majority of the other dereferenced jws json patches.

An unresolvable patch does not count towards the simple majority.

5.4. Deactivate

A did:meliorism is deactivated when all Patch URIs are unresolvable.

6. Privacy and Security Considerations

We need to develop a complete list of security considerations.

6.1. Herd privacy

Depending on the network, a Patch URI resolution might reveal an attempt to resolve the subject identifier to a 3rd party, such as the web origin that is used to host patches.

If the Patch URI resolves to multiple JWS signed json patches, the host can not tell which specific JWS the http client is requesting, which provides a form of herd privacy.

6.2. Phone home

If the Patch URI is unique to the subject identifier and only resolves to a single JWS, the Patch URI resolution history reveals attempts to resolve the subject identifier.

6.3. Centralization

If the Patch URIs for a given identifier all rely on https scheme and are all under the authority of the same origin, that origin controls the identifier.

DID controllers can apply the following strategies to create more decentralized identifiers.

  1. Leverage more than one top level domain when leveraging the https scheme.
  2. Leverage more than one country or region when leveraging the https scheme.
  3. Leverage multiple schemes.
  4. Leverage a larger number of Patch URIs.

6.4. Key rotation

A DID controller can rotate the primary identifier key at any time.

The rotation will not be complete until the majority of the Patch URIs dereference to a JWS signed with the new primary identifier key.

6.5. Revision history

Use something else to manage this... like an endorsement service.

This decentralized identifier method does not support historic queries, for example: discovering if a given key was authoritative 30 years ago.

See [RFC9162] for guidance on maintaining transparency.

7. Test Vectors

This JSON Document contains the test vectors for this DIM.

See ./data/test-vectors.json

8. Appendix

8.1. Relationship to did:key

This did method is better than did key, because it supports services, and builds on existing RFCs.

This method has advantages and disadvantages when compared to did:key.

Advantages:

  • Support for service endpoints
  • Support for key rotation
  • Builds on existing RFCs
  • Leverages content addressing

Disadvantages:

  • More complicated to implement
  • Requires support for multiple URI schemes

8.2. Relationship to did:web

This did method is better than did web, becuase it does not rely on a single origin which is trivial to censor.

This method has advantages and disadvantages when compared to did:web.

Advantages:

  • Builds on existing RFCs
  • More decentralized
  • Capable of surving a colluding minority of trust anchors
  • Leverages digital signatures to prevent tampering by trust anchors
  • Leverages content addressing

Disadvantages:

  • More complicated to implement
  • Requires support for multiple URI schemes

9. Normative References

[DID-CORE]
Sporny, M., Longley, D., Sabadello, M., Reed, D., Steele, O., and C. Allen, "Decentralized Identifiers (DIDs) v1.0", , <https://www.w3.org/TR/did-core/>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC2397]
Masinter, L., "The "data" URL scheme", RFC 2397, DOI 10.17487/RFC2397, , <https://www.rfc-editor.org/info/rfc2397>.
[RFC6902]
Bryan, P., Ed. and M. Nottingham, Ed., "JavaScript Object Notation (JSON) Patch", RFC 6902, DOI 10.17487/RFC6902, , <https://www.rfc-editor.org/info/rfc6902>.
[RFC7515]
Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, , <https://www.rfc-editor.org/info/rfc7515>.
[RFC7517]
Jones, M., "JSON Web Key (JWK)", RFC 7517, DOI 10.17487/RFC7517, , <https://www.rfc-editor.org/info/rfc7517>.
[RFC7638]
Jones, M. and N. Sakimura, "JSON Web Key (JWK) Thumbprint", RFC 7638, DOI 10.17487/RFC7638, , <https://www.rfc-editor.org/info/rfc7638>.
[RFC9162]
Laurie, B., Messeri, E., and R. Stradling, "Certificate Transparency Version 2.0", RFC 9162, DOI 10.17487/RFC9162, , <https://www.rfc-editor.org/info/rfc9162>.
[multiformats-multihash-05]
Benet, J. and M. Sporny, "The Multihash Data Format", , <https://datatracker.ietf.org/doc/draft-multiformats-multihash/05/>.

Author's Address

Orie Steele
Transmute