The Veres One Blockchain is a permissionless public ledger designed specifically for the creation and management of decentralized identifiers (DIDs). Veres One DIDs are self-administered identifiers that may be used by people, organizations, and digital devices to establish an identifier that is under their control. Veres One DIDs are useful in ecosystems where one needs to issue, store, and use Verifiable Credentials. This specification defines how a developer may create and manage DIDs in the Veres One Blockchain.

Comments regarding this document are welcome. Please file issues directly on GitHub, or send them to public-credentials@w3.org (subscribe, archives).

Work on this specification has been funded in part by the United States Department of Homeland Security's Science and Technology Directorate under contract HSHQDC-17-C-00019. The content of this specification does not necessarily reflect the position or the policy of the U.S. Government and no official endorsement should be inferred.

Work on this specification has also been supported by the Rebooting the Web of Trust group facilitated by Christopher Allen, Shannon Appelcline, Kiara Robles, Kaliya Young, Brian Weller, Betty Dhamers, and Joe Andrieu.

Work on this specification has also been supported by the Internet Identity Workshop co-founded by Phil Windley, Kaliya Young, and Doc Searls and energized by true believers in the user-centric identity movement.

Introduction

The Veres One Project envisions a world where people and organizations control their identifiers and their identity data. The Veres One Blockchain is a fit-for-purpose blockchain optimized for identity on the Web. The network ecosystem is designed to be self-sufficient through the use of an innovative operational and funding model. The operational model ensures openness, prevents attacks against the network, and financially rewards individuals and organizations that choose to run software to ensure the security of the network. Human dignity demands that every individual be able to participate equally in our increasingly digital society. That means everyone deserves the ability create and administer unique, globally resolvable identifiers. For that reason, the network is global and open to the public; anyone may participate.

The Problem

To date, every identifier you use online does not belong to you; it belongs to someone else.

The Internet was not designed with interoperable identity systems in mind. This inevitably forced websites to create their own solutions, which are not interoperable.

When you sign up to a website, you typically create a username and a password. The website asks you for this information so that it can start to associate data with you. The more benevolent use of this data is to customize an experience suited to your needs. This identifier and data, however, are locked away on the site; they are not portable. Even the global identifiers that websites use, such as your email address, are not owned by you. The email address "you@bigcorp.com" isn’t owned by you, it’s owned by BigCorp. You do not have control over your identifier nor your data.

Since this data is not portable, you must rebuild your identity information -- your identifiers and data -- from scratch on many different websites. Duplicating that information often means sharing more than intended, allowing websites to learn things and infer things about you that you didn’t expect. It also means that each website accumulates toxic data about you, inviting behavior like spam, financial fraud, data siloing, data warehousing, and identity theft. Initiatives like the European Union’s General Data Protection Regulation (GDPR) only increase the pressure to address these problems.

In addition to risks from the information we explicitly share with websites, there is also a vast amount of identity information already out there, with few mechanisms for managing it. This outside information is often combined with the information we share to create surprisingly detailed profiles, used for everything from ad targeting to site customization to custom pricing (not always for lower prices). The result is a strong economic incentive for large data warehousing companies to store and sell your information, often without your consent.

The Vision

The Veres One Blockchain's purpose is to enable all people and organizations in the world to:

  1. create and own their online identifiers, and
  2. control their identity data and with whom they share that data.

Achieving this vision will enable a Web where:

This vision is shared among a large community of people working within global organizations such as the Internet Identity Workshop, World Wide Web Consortium, Internet Engineering Task Force, United Nations ID2020, Decentralized Identity Foundation, and the Rebooting the Web of Trust project. This DID Method specification is a realization of this vision.

Goals

The Veres One Blockchain is a fit-for-purpose blockchain built specifically for Decentralized Identifiers. This specialization enables the blockchain to be faster, more cost effective, and more privacy enhancing compared to existing blockchains that are being repurposed for identity management. The Veres One Blockchain was designed and built with the following goals in mind:

Performance

Based on the goals stated in the previous section, benchmarking has been performed on the reference Veres One implementation that is able to achieve the following performance characteristics.

Benchmarking is a poor substitute for measurements taken over long periods of time in hostile environments such as the public Internet. Attacks, routing inefficiencies, packet drops, misconfigured software, and annoying physical limitations such as the speed of light all contribute to degraded performance in real world settings. This section should be taken with a large grain of salt until we have dependable real world data.

The configuration for the benchmarks used 1 database with 7 electors configured. The database was an AWS AWS i3.large instance consisting of 2 vCPUs, 15.25GB RAM and Local NVME Storage. Each node was an AWS c5.large instance with 2 vCPUs and 4GB RAM.

The Veres One Blockchain uses a leaderless, non-blocking, byzantine fault tolerant consensus algorithm called Continuity. There are 3f+1 nodes in the system where f is the number of byzantine failures the network can tolerate. Since the algorithm is non-blocking and nodes can progress at their own pace, the limiting factor is how quickly events can be gossiped around the network. This approach results in very high throughputs. Transactions are limited by two factors: 1) the fastest 2/3rds of elector's database write speeds and 2) the time it takes to distribute 12f + 1 merge events to every elector in the network, the rate of which is an exponential function.

Metric Capability Description
Throughput 209/sec, 18M/day, 6.6B/year The throughput is a function of how quickly 12f+1 events can be transmitted to each elector. Limiting factors include database write speed, communication speed, and digital signature verification speed.
Consensus Latency ~15-30 seconds The latency is a function of how many electors there are in the system. How many electors there are in the system is a function of the risk tolerance of the network.

Document Organization

This document is organized as follows:

There are two conformance classes described in this specification. The first are clients that use the HTTP API to perform operations. The second are Veres One Nodes, which expose the HTTP API to clients. Clients and Veres One Nodes MUST implement all mandatory features as listed by this specification and SHOULD implement optional features.

Terminology

block
A data structure that contains one or more ledger events.
blockchain
A ledger containing a series of blocks where the ordering of the blocks can be mathematically proven to be correct.
consensus algorithm
An algorithm that enables multiple nodes in a network to make a decision in a deterministic fashion.
cryptographic ledger
A method of recording changes in a state machine where the accuracy of the ledger can be mathematically proven to be correct.
decentralized system
A system in which lower level components operate on local information to accomplish global goals. For example, an ant colony is a decentralized system as there is no central control determining when food must be collected or how new tunnels should be excavated.
decentralized ledger
A cryptographic ledger that uses a consensus algorithm that enables a network of ledger nodes to come to consensus in a decentralized yet deterministic fashion.
event
Any data recorded in a ledger that changes the state machine. Events typically contain operations.
ledger agent
A software program that instructs a ledger node to perform specific actions such as reading or writing data.
ledger node
A software program that reads and writes from particular instance of a ledger by executing algorithms according to the rules of the ledger. The ledger node may be instructed to perform actions on the ledger by a ledger agent.
operation
An instruction to a ledger agent to modify the state machine in a particular way.
state machine
A system that when given a particular input changes from one internal state to another internal state. For example, a computer system that operates a light bulb starts with the light state set to off. When an input to turn the light on is given, the internal computer system state sets the light state to on, thus illuminating the light bulb.

Core Data Model

The Veres One Data model is a graph-based data model. The syntax used for the data model is [[!JSON-LD]], which is based on 18+ years of Linked Data standardization work at the W3C. The ledger portions of the data model build upon the [[!WEB-LEDGER]] specification. The digital signatures and proofs data models build upon the, [[!LD-PROOFS]] and [[!LD-SIGNATURES]] specifications. The Decentralized Identifiers portion of the data model builds upon the [[!DID]] specification.

The Veres One data model

The core data model is fairly simple and consists of a Ledger. The Ledger contains Blocks. The Blocks contain Operations. The Operations contain instructions that modify the state of the ledger. For example, there are Operations to create a DID Document and update a DID Document.

The data model also consists of a state machine that is modified as Operations execute. The state machine can be queried using Veres One DIDs, which will return the current DID Document associated with the Veres One DID.

Basic Concepts

Veres One DID Format

Veres One DIDs have the following format:

The ABNF below needs to be tightened up. For example, it should enforce the UUID format if UUID-based Veres One DIDs are used.

      v1-did        = "did:v1:" v1-did-type ": " v1-identifier
                       [ ";" did-service ] [ "/" did-path ]
                       [ "?" did-query ] [ "#" did-fragment ]
      v1-did-type   = ( "nym" / "uuid" )
      v1-identifier = %x41-5A / %x61-7A / %x5F / %2D
    

There are two primary classes of DID-based identifiers in Veres One. The first type of identifier is called a cryptonym-based identifier. This identifier is a SHA-256 hash of a public key. Cryptonym-based identifiers are not required to be registered on the ledger and may be used as unregistered pseudonymous pairwise identifiers. These identifiers may also be registered on the ledger and MUST contain a authentication key with a public key fingerprint equal to the value of the cryptonym-based identifier.

      did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ
    

The second type of identifier on Veres One is a UUID-based identifier and may be used by entities that want to store metadata on the ledger. These sorts of identifiers are often used, but not limited to, storing and refering to Capabilities and Revocation lists.

      did:v1:uuid:804c6ac3-ce3b-46ce-b134-17175d5bee74
    

Authentication

Authentication is the process the ledger uses to determine if an entity is associated with a DID.

{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
  "authentication": [... array of acceptable authentication suites ...]
}
    

A detailed example of a valid set of authentication credentials follows:

{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
  "authentication": [{
    "type": "Ed25519SignatureAuthentication2018",
    "publicKey": {
      "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#authn-key-1",
      "type": "Ed25519VerificationKey2018",
      "owner": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
      "publicKeyBase58": "HURvcFiZbmtaQQMhkVVoq1JpxxRe8UrBS5wBQMJhXkfM",
    }
  }],
  ...

Authorization

The Veres One Ledger uses Linked Data Object Capabilities to authorize operations to be performed on DID Documents.

Granting a capability is equivalent to giving someone your car keys. Your car doesn't know who the person is with the key, it just knows that when the key is turned in the ignition, the car should start. The benefit of object capabilities is that, unlike a car key, you can set arbitrary restrictions on the usage of a capability. For example, setting an expiration time for the capability, or a geofenced zone in which it can be used.

The Veres One data model supports two types of capability suites, one for granting capabilities and the other for invoking capabilities.

{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
  "grantCapability": [... array of capability grant suites  ...]
  "invokeCapability": [... array of capability invocation suites ...]
}
    

A detailed example of a valid set of authorization capability descriptions follows:

{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
  ...
  "grantCapability": [{
    "type": "Ed25519SignatureCapabilityAuthorization2018",
    "publicKey": {
      "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-grant-key-1",
      "type": "Ed25519VerificationKey2018",
      "owner": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
      "publicKeyBase58": "HURvcFiZbmtaQQMhkVVoq1JpxxRe8UrBS5wBQMJhXkfM"
    }
  }],
  "invokeCapability": [{
    "type": "Ed25519SignatureCapabilityAuthorization2018",
    "publicKey": {
      "id": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-invoke-key-1",
      "type": "Ed25519VerificationKey2018",
      "owner": "did:v1:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
      "publicKeyBase58": "Gu5yfYsbYvmSeSsAbBBNafy9i6G3o5kiX5PxUGPg1iFJ"
    }
  }]
}
    

Operations

Every conforming Veres One Blockchain Node MUST expose at least the following HTTP endpoints:

Service Example URL Description
veresOneOperationsService POST /ledger-agents/123/operations Create or update a DID Document.
veresOneReadService GET /dids/{did} Gets an existing DID Document.

HTTP API Discovery

A website may provide HTTP API endpoint discovery by embedding JSON-LD in their top-most HTML web page (e.g. at https://example.com/):

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Example Website</title>
    <link rel="stylesheet" href="style.css">
    <script src="script.js"></script>
    <script type="application/ld+json">
{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "https://example.com/",
  "name": "Example Website",
  "veresOneOperationsService": "https://example.com/ledger-agents/123/operations",
  "veresOneReadService": "https://example.com/veres-one/dids/"
}
    </script>
  </head>
  <body>
    <!-- page content -->
  </body>
</html>
    

Service descriptions may also be requested via content negotiation. In the following example a JSON-compatible service description is provided (e.g. curl -H "Accept: application/json" https://example.com/):

{
  "@context": "https://w3id.org/veres-one/v1",
  "id": "https://example.com/",
  "name": "Example Website",
  "veresOneOperationsService": "https://example.com/ledger-agents/123/operations",
  "veresOneReadService": "https://example.com/veres-one/dids/"
}
    

Creating a DID

A DID is created by performing an HTTP POST of a signed operation to the veresOneOperationsService. The following HTTP status codes are defined for this service:

HTTP Status Description
202 DID creation request was accepted. The HTTP Location header will contain the URL for the newly created ledger operation. The operation is not guaranteed to succeed. You can check to see if the operation succeeded by requesting the operation, which will eventually refer to an event and a block if it was successful.
400 Operation failed.
409 Create operation failed because a duplicate DID exists.

An example exchange of DID creation request is shown below:

POST /ledger-agents/123/operations HTTP/1.1
Host: example.com
Content-Type: application/ld+json
Content-Length: 1062
Accept: application/ld+json, application/json, text/plain, */*
Accept-Encoding: gzip, deflate

{
  "@context": "https://w3id.org/veres-one/v1",
  "type": "CreateWebLedgerRecord",
  "record": {
    "@context": "https://w3id.org/veres-one/v1",
    "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
    "authentication": [{
      "type": "Ed25519SignatureAuthentication2018",
      "publicKey": {
        "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#authn-key-1",
        "type": "Ed25519SigningKey2018",
        "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
        "publicKeyBase58": "Gu5yfYsbYvmSeSsAbBBNafy9i6G3o5kiX5PxUGPg1iFJ"
      }
    }],
    "grantCapability": [{
      "type": "Ed25519SignatureCapabilityAuthorization2018",
      "publicKey": {
        "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-grant-key-1",
        "type": "Ed25519SigningKey2018",
        "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
        "publicKeyBase58": "HURvcFiZbmtaQQMhkVVoq1JpxxRe8UrBS5wBQMJhXkfM"
      }
    }],
    "invokeCapability": [{
      "type": "Ed25519SignatureCapabilityAuthorization2018",
      "publicKey": {
        "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#ocap-invoke-key-1",
        "type": "Ed25519SigningKey2018",
        "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
        "publicKeyBase58": "FPa3QX9pPk1Qw75CAnhF2Qv2HwuWke4yxbqxzQbU5PLU"
      }
    }]
  },
  "proof": [{
    "type" : "Ed25519Signature2018",
    "created" : "2018-02-24T22:23:44Z",
    "creator" : "did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#ocap-invoke-key-1",
    "capability" : "did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv",
    "capabilityAction" : "RegisterDid",
    "jws" : "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..
      _h3x8FRH6GXbSBGgtqtGRQc_HabNgYSv4M124oFG-1dzi4nJzJyXTXcNt8vb7mJV3fj
      Izyt0jhO8hsmMJWf8Cw",
    "proofPurpose" : "invokeCapability"
  }, {
    "type" : "EquihashProof2018",
    "created" : "2018-02-24T22:23:45Z",
    "equihashParameterK" : 3,
    "equihashParameterN" : 64,
    "nonce" : "AgAAAA==",
    "proofValue" : "AAAVYwABwK8AAME7AAGOjAAAVkIAATc9AAFDLQABrc8="
  }]
}
    

If the creation of the DID was successful, an HTTP 201 status code is expected in return:

HTTP/1.1 202 Accepted
Location: https://ledger.example.com/ledger-agents/123/operations/ni%3A%2F%2F%2Fsha-256%3BXk0ruJlbQTpFOyzbsl_KL8vKQiahMj7t9h-v70BMwAQ
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Date: Fri, 14 Oct 2016 18:35:33 GMT
Connection: keep-alive
Transfer-Encoding: chunked
    

Updating a DID Document

A DID is updated by performing an HTTP POST of a signed DID Document to the veresOneUpdateService. The following HTTP status codes are defined for this service:

HTTP Status Description
200 DID update request was successful.
400 DID update request failed.

An example exchange for a DID update request is shown below:

POST /ledger-agents/123/operations HTTP/1.1
Host: example.com
Content-Type: application/ld+json
Content-Length: 1062
Accept: application/ld+json, application/json, text/plain, */*
Accept-Encoding: gzip, deflate

{
  "@context": "https://w3id.org/veres-one/v1",
  "type": "UpdateWebLedgerRecord",
  "patch": [{
    "op": "add",
    "path": "/authentication",
    "value": {
      "type": "Ed25519SignatureAuthentication2018",
      "publicKey": {
        "id": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ#authn-key-2",
        "type": "Ed25519SigningKey2018",
        "owner": "did:v1:test:nym:4jWHwNdrG9-6jd9I7K1si3kTRneNwftZV9m6rkrAfWQ",
        "publicKeyBase58": "BpJk2oxtkm99ubKqhtLF7fB2fCM1bETgpJLFg8QEuQK2"
      }
    }
  }, {
    "op": "remove",
    "path": "/services/3",
  }],
  "proof": [{
    "type" : "Ed25519Signature2018",
    "created" : "2018-02-24T22:23:42Z",
    "creator" : "did:v1:test:nym:91LAKSKtybvFjUdkTitBVXEF1kz9s24TCARuLfWBKGmw#ocap-invoke-key-1",
    "capability" : "did:v1:test:nym:91LAKSKtybvFjUdkTitBVXEF1kz9s24TCARuLfWBKGmw",
    "capabilityAction" : "RegisterDid",
    "jws" : "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..Ldx
      5HbvS7-SvKTPGbRwBhc5xub95th__2-pphFRZUHFNd4Qs6R3u9j5elQkHciuLhvKB6a0
      fURMa4puZNWLLDg",
    "proofPurpose" : "invokeCapability"
  }, {
    "type": "EquihashProof2017",
    "equihashParameterN": 64,
    "equihashParameterK": 3,
    "nonce": "AQAAAA==",
    "proofValue": "AAAOgAA0jcAEAAXbA1EsQMgAAGfF7TwABAfNiAA78QA="
  }]
}
    

If the update request for the DID Document was successful, an HTTP 202 status code is expected in return:

HTTP/1.1 202 Accepted
Location: https://ledger.example.com/ledger-agents/123/operations/ni%3A%2F%2F%2Fsha-256%TpFOyzbsl_KL83BXk0ruJlbQ9h-v70BMwAQvKQiahMj7t
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Date: Fri, 14 Oct 2016 18:35:33 GMT
Connection: keep-alive
Transfer-Encoding: chunked
    

Security Considerations

Cryptographic Agility

The core consensus algorithm for Veres One utilizes the Ed25519 cryptographic suite. This algorithm is a well vetted and widely deployed cryptographic system that represents the state of the art in modern cryptographic systems. The algorithm depends on the hardness of factoring large numbers, which is expected to become easier given operational quantum computers. These computers are not expected to be feasible in the next decade, but might eventually become feasible.

If new cryptographic primitives are needed, the Veres One consensus algorithm is upgradable in order to provide cryptographic agility. If the current cryptographic system breaks, a new one can be deployed and the consensus algorithm is designed to smoothly upgrade to the new cryptographic system well in advance of the failure of the current cryptographic system.

Censorship Resistance

The consensus mechanism used by the Veres One blockchain is designed to make censoring individuals or organizations incredibly difficult. The consensus algorithm operates on a directed acyclic graph that resembles the Git version control system. Adding new blocks to the blockchain consists of merging various event streams, which are DAGs themselves, into the existing DAG. When an individual wants to perform an operation on the blockchain, they submit that operation to the network. If an attacker wanted to censor that operation, they would have to censor everyone that saw the operation happen on the network. This would lead to censoring not only the individual, but everyone that talked to the individual. While this might be possible to do on small, tightly controlled networks, it is extremely difficult to do on large active networks.

Individual censorship is easily detected by the individual, as operations gossiped to the network are not included in the next block. This sort of censorship has to happen at every node in the network (which is highly unlikely).

If an individual is concerned about censorship, they are urged to gossip with as many nodes in the network as possible. This ensures that any attacker node that desires to censor will be easily detected and the rest of the non-attacking nodes will get the operation into the network.

Privacy Considerations

Identifier-based Correlation

Decentralized Identifiers are global and often long-lived and are thus susceptible to being tracked across multiple interactions. Implementers are urged to be wary of using long lived identifiers where tracking protection is a system requirement. If strong anti-correlation properties and/or strong tracking-protection are required, pairwise identifiers such as the did:key method or bearer tokens are a better design choice.

GDPR Compliance

Veres One is designed to be GDPR compliant. As such, it is very strict with regard to what data can be written to the blockchain and what data is required to exist off-ledger. As a general rule, any field that could possibly encode any personally identifiable information is not allowed. It is still possible to tie this information to a DID by using an external service, pointed to by a service description in the DID Document, that supports the GDPR Right to be Forgotten mandate. This approach is more strict than other blockchains due to privacy failures on other blockchains to keep Personally Identifiable Information offchain. While this approach is more strict, the functionality of appending information to a DID Document in a GDPR compliant manner is still achieved.

Accessibility Considerations

There are a number of accessibility considerations implementers should be aware of when processing data described in this specification. As with any web standards or protocols implementation, ignoring accessibility issues makes this information unusable to a large subset of the population. It is important to follow accessibility guidelines and standards, such as [[WCAG21]], to ensure all people, regardless of ability, can make use of this data. This is especially important when establishing systems utilizing cryptography, which have historically created problems for assistive technologies. While DID Documents stored on Veres One are not allowed to contain human readable information due to GDPR concerns, it is possible to publish extended information to the DID Document through service endpoints and/or other publishing mechanisms. This section relates to extended information that can be associated with a base Veres One DID Document.

This section details the general accessibility considerations to take into account when utilizing this data model.

Data First Approaches

When utilizing this data model to create DID Documents, it is suggested that data model designers use a data first approach. For example, given the choice of using data or a graphical image to depict a some information, designers should express every element of the image in a machine-readable way instead of relying on a viewer's interpretation of the image to convey this information. Using a data first approach is preferred because it provides the foundational elements of building different interfaces for people with varying abilities.

Internationalization Considerations

There are a number of internationalization considerations implementers should be aware of when publishing data described in this specification. As with any web standards or protocols implementation, ignoring internationalization makes it difficult for data to be produced and consumed across a disparate set of languages and societies, which would limit the applicability of the specification and significantly diminish its value as a standard. While DID Documents stored on Veres One are not allowed to contain human readable information due to GDPR concerns, it is possible to publish extended information to the DID Document through service endpoints and/or other publishing mechanisms. This section relates to extended information that can be associated with a base Veres One DID Document.

This section outlines general internationalization considerations to take into account when utilizing this data model.

Language Declarations

When expressing human-readable text content in the data model, it is important for presentation, accessibility, and further processing to specify the language of the text, as follows:

Text direction

When expressing human-readable text content in the data model, it is important to be able to explicitly encode the text direction. JSON and its derived formats use the UTF-8 encoding of [Unicode] for serializing and transmitting text. This enables text direction to be directly determined in simple cases, but the mechanism is insufficient for general use.

[[!JSON-LD]] supports the expression of text layout information using the rdf:HTML string literal type, as described in [[!JSON-LD]] 1.0, Section 4.2.1: Typed Values. This mechanism enables developers to use the internationalization features present in HTML to express language information. For example, consider the following key-value pair:

"nameHtml": "<span dir="rtl" lang="ar">HTML و CSS: تصميم و إنشاء مواقع الويب</span>"
    

If the JSON-LD Context states that any value associated with the nameHtml property is of type rdf:HTML, then software agents have sufficient information to deterministically identify the text direction of the language.

Ruby Text

In some situations it is common to use Ruby characters to ensure text information is clear and as useful as possible. [[!JSON-LD]] support for HTML data allows text to be encoded with ruby, supporting these cases.

Further Information

The W3C Internationalisation document [string-meta] gives more information about the need to be able to provide reliable metadata about text to support internationalization.

Appendix A: Examples

Typical DID Document

The following is a complete example of a typical Veres One DID Document:

{
  "@context":"https://w3id.org/veres-one/v1",
  "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv",
  "authentication":[{
    "type":"Ed25519SignatureAuthentication2018",
    "publicKey":[
      {
        "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#authn-key-1",
        "type":"Ed25519VerificationKey2018",
        "owner":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv",
        "publicKeyBase58":"5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv"
      }
    ]
  }],
  "grantCapability":[{
    "type":"Ed25519SignatureCapabilityAuthorization2018",
    "publicKey":[
      {
        "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#ocap-grant-key-1",
        "type":"Ed25519VerificationKey2018",
        "owner":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv",
        "publicKeyBase58":"6kQvEZxCiMMVaV4ywczC1LbXGiG3Gv27hVvs4gd7CGLH"
      }
    ]
  }],
  "invokeCapability":[{
    "type":"Ed25519SignatureCapabilityAuthorization2018",
    "publicKey":[
      {
        "id":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv#ocap-invoke-key-1",
        "type":"Ed25519VerificationKey2018",
        "owner":"did:v1:test:nym:5YSwjvBZqDbYQkoRG7jD7bCKifVdHBtxHMrATZyTX8xv",
        "publicKeyBase58":"AEht5v3xudqJs9qo5jC88fAsAGhPr6zLYJ3yfuKsAY7K"
      }
    ]
  }]
}
    

Legacy DID Document

The Veres One ledger was launched in 2015, predated this specification, and as a result has a number of legacy objects that developers should be aware of. The typical format for these objects are shown below:

{
  "@context": "https://w3id.org/identity/v1",
  "id": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460",
  "idp": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1",
  "accessControl": {
    "writePermission": [{
        "id": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460/keys/1",
        "type": "CryptographicKey"
    }, {
        "id": "did:d1d1d1d1-d1d1-d1d1-d1d1-d1d1d1d1d1d1",
        "type": "Identity"
    }]
  },
  "publicKey": [{
    "id": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460/keys/1",
    "type": "CryptographicKey",
    "owner": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\r\nMIIBIjA...DAQAB\r\n-----END PUBLIC KEY-----\r\n",
    "@context": "https://w3id.org/identity/v1"
  }],
  "signature": {
    "type": "LinkedDataSignature2015",
    "created": "2017-07-25T17:29:49Z",
    "creator": "did:8743453f-e45e-4ac6-b85f-4513ba4c1460/keys/1",
    "signatureValue": "LJoxpV...daOLHbA=="
  }
}