§ DIDComm Messaging

Specification Status: Editor’s Draft

Latest published version: identity.foundation/didcomm-messaging/docs/spec

Editors:

Contributors: Daniel Hardman

Participate:
GitHub repo
File a bug
Commit history

Testing: 4


§ Purpose and Scope

The purpose of DIDComm is to provide a secure, private communication methodology built atop the decentralized design of DIDs.

Other robust mechanisms for secure communication already exist. However, most rely on key registries, identity providers, certificate authorities, browser or app vendors, or similarly centralized assumptions. They also tend to be tied to a single transport, making it difficult to use the same solution for human and machine conversations, online and offline, simplex and duplex, across a broad set of modalities. The net result is that they perpetuate an asymmetry between institutions and ordinary people. The former maintain certificates and always-connected servers, and publish APIs under terms and conditions they dictate; the latter suffer with usernames and passwords, poor interoperability, and a Hobson’s choice between privacy and convenience.

DIDComm can fix this. Using DIDComm, individuals on semi-connected mobile devices become full peers of highly available web servers operated by IT experts. Registration is self-service, intermediaries require little trust, and no terms and conditions apply.

DIDComm enables higher-order protocols that inherit its security, privacy, decentralization, and transport independence. Examples include exchanging verifiable credentials, creating and maintaining relationships, buying and selling, scheduling events, negotiating contracts, voting, presenting tickets for travel, applying to employers or schools or banks, arranging healthcare, and playing games. Like web services atop HTTP, the possibilities are endless; unlike web services atop HTTP, many parties can participate without being clients of a central server, and they can use a mixture of connectivity models and technologies.

§ Overview

To understand how DIDComm works, consider a situation where Alice wants to negotiate with Bob to sell something online. Because DIDComm, not direct human communication, is the methodology in this example, Alice’s software agent and Bob’s software agent are going to exchange a series of messages.

Alice may just press a button and be unaware of details, but underneath, her agent begins by preparing a plaintext JSON message about the proposed sale. (The particulars are irrelevant here, but would be described in the spec for a higher-level “sell something” protocol that takes DIDComm as its foundation.) Alice’s agent then looks up Bob’s DID Doc to access two key pieces of information:

Now Alice’s agent uses Bob’s public key to encrypt the plaintext so that only Bob’s agent can read it, adding authentication with its own private key. The agent arranges delivery to Bob. This “arranging” can involve various hops and intermediaries. It can be complex. (See Routing in the Implementers Guide.)

Bob’s agent eventually receives and decrypts the message, authenticating its origin as Alice using her public key. It prepares its response and routes it back using a reciprocal process (plaintext → lookup endpoint and public key for Alice → encrypt with authentication → arrange delivery).

That’s the essence, in the most common scenarios. However, it does not fit all DIDComm interactions:

Before we provide more details, let’s explore what drives the design of DIDComm.

§ Specific Requirements

The DIDComm design attempts to be:

  1. Secure (tamper-proof; uses best-of-breed crypto; allows parties to talk both on and off the record…)
  2. Private (third parties can’t learn who’s communicating about what, when; lets sender be anonymous to recipient)
  3. Decentralized (derives trust for encryption, signing, authn, and authz from control of DIDs rather than oracles like CAs, IDPs, etc; usable at the edge)
  4. Transport-agnostic (usable over HTTPS 1.x and 2.0, WebSockets, BlueTooth, chat, push notifications, AMQP, SMTP, NFC, sneakernet, snail mail; supports both simplex and duplex; works offline; doesn’t assume client-server or synchronous or real-time; allows paired or n-wise or public broadcast usage)
  5. Routable (like email, A can talk to B without a direct connection to B; allows mixed and dynamic transports; passes through mix networks and other generic infrastructure that sees only payload BLOBs)
  6. Interoperable (works across programming languages, blockchains, vendors, OS/platforms, networks, legal jurisdictions, geos, cryptographies, and hardware–as well as across time; avoids vendor lock-in)
  7. Extensible (lets devs start simple without heavy learning or dependencies; customize easily; facilitates higher-level protocols that inherit DIDComm’s guarantees)
  8. Efficient (doesn’t waste bandwidth, battery, storage space, or CPU)

§ Ramifications

As a list of buzz words, this may elicit nods rather than surprise. However, design tradeoffs are inevitable, and several of these items have noteworthy ramifications.

§ Message-Based, Asynchronous, and Simplex

The dominant paradigm in mobile and web development today is duplex request-response. You call an API with certain inputs, and you get back a response with certain outputs over the same channel, shortly thereafter. This is the world of OpenAPI (Swagger), and it has many virtues.

Unfortunately, many agents are not good analogs to web servers. They may be mobile devices that turn off at unpredictable intervals and that lack a stable connection to the network. They may need to work peer-to-peer, when the internet is not available. They may need to interact in time frames of hours or days, not with 30-second timeouts. They may not listen over the same channel that they use to talk.

Because of this, the fundamental paradigm for DIDComm is message-based, asynchronous, and simplex. Agent X sends a message over channel A. Sometime later, it may receive a response from Agent Y over channel B. This is much closer to an email paradigm than a web paradigm.

On top of this foundation, it is possible to build elegant, synchronous request-response interactions. All of us have interacted with a friend who’s emailing or texting us in near-realtime. However, interoperability begins with a least-common-denominator assumption that’s simpler.

§ Message-Level Security, Reciprocal Authentication

The security and privacy goals, and the asynchronous+simplex design decision, break familiar web assumptions in another way. Servers are commonly run by institutions, and we authenticate them with certificates. People and things are usually authenticated to servers by some sort of login process quite different from certificates, and this authentication is cached in a session object that expires. Furthermore, web security is provided at the transport level (TLS); it is not an independent attribute of the messages themselves.

In a partially disconnected world where a communication channel is not assumed to support duplex request-response, and where the security can’t be ignored as a transport problem, traditional TLS, login, and expiring sessions are impractical. Furthermore, centralized servers and certificate authorities perpetuate a power and UX imbalance between servers and clients that doesn’t fit with the peer-oriented DIDComm.

DIDComm uses public key cryptography, not certificates from some parties and passwords from others. Its security guarantees are independent of the transport over which it flows. It is sessionless (though sessions can easily be built atop it). When authentication is required, all parties do it the same way.

§ Processing Model

§ Message Types

This spec discusses messages in three different formats. The casual phrase “DIDComm message” is ambiguous, but usually refers to DIDComm encrypted messages (the outermost box in the diagram below). These will constitute the vast majority of network traffic in most DIDComm deployments, and they are responsible for security guarantees in the system. However, the role of encrypted messages cannot be understood without reference to the simpler formats they contain.

DIDComm envelopes

§ DIDComm Plaintext Messages

A DIDComm message in its plaintext form, not packaged into any protective envelope, is known as a DIDComm plaintext message. Plaintext messages lack confidentiality and integrity guarantees, and are repudiable. They are therefore not normally transported across security boundaries. However, this may be a helpful format to inspect in debuggers, since it exposes underlying semantics, and it is the format used in this spec to give examples of headers and other internals. Depending on ambient security, plaintext may or may not be an appropriate format for DIDComm data at rest.

When higher-level protocols are built atop DIDComm, applications remove the protective envelope(s) and process the plaintext that’s inside. Specs for higher-level protocols typically document message structure and provide examples in this format; protective envelopes are assumed but ignored as a low-level detail.

Applications running one or more DIDComm-based protocols may wish to define their own media types for the protocols they support. Absent such customization, the preferred media type for a generic DIDComm plaintext message SHOULD be application/didcomm-plain+json. This correctly conveys the fact that code handling such content functions at a different level from DIDComm’s security and routing, and that generic JSON tools and actions are likely to be a helpful fallback in processing the content.

DIDComm plaintext messages are also correctly understood as JWM content (see Plaintext Message Structure, below). Thus a media type for JWMs MIGHT be an accurate but more generic way to categorize them. However, not all JWMs are DIDComm messages, so this categorization is suboptimal. Similarly, application/json is true, but overly generic and therefore not recommended.

When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm plaintext messages SHOULD be dcpm, giving a globbing pattern of *.dcpm; this SHOULD be be read as “Star Dot D C P M” or as “D C P M” files. We imagine people will reference this media type by saying, “I am looking at a DIDComm Plaintext Message file”, or “This database record is in DIDComm Plaintext format”, or “Does my editor have a DIDComm Plaintext Message plugin?” A possible icon for this file format depicts green JSON text in a message bubble (svg | 256x256 | 128x128 | 64x64):

DIDComm Plaintext Message Icon

§ DIDComm Signed Message

A DIDComm signed message is a JWS envelope that associates a non-repudiable signature with the plaintext message inside it.

Signed messages are not necessary to provide message integrity (tamper evidence), or to prove the sender to the recipient. Both of these guarantees automatically occur with the authenticated encryption in DIDComm encrypted messages. Signed messages are only necessary when the origin of plaintext must be provable to third parties, or when the sender can’t be proven to the recipient by authenticated encryption because the recipient is not known in advance (e.g., in a broadcast scenario). Adding a signature when one is not needed can degrade rather than enhance security because it relinquishes the sender’s ability to speak off the record. We therefore expect signed messages to be used in a few cases, but not as a matter of course.

When a message is both signed and encrypted, the plaintext is signed, and then the signed envelope is encrypted. The opposite order is not used, since it would imply that the signer committed to opaque data (which is unsafe and undermines non-repudiation).

The media type of a DIDComm signed message SHOULD be application/didcomm-signed+json.

Because a DIDComm signed message is also a JWS, a true but less specific media type MIGHT be application/jose. (Although application/jwt is a registered media type, application/jwe and application/jws are not. This is deliberate.) Using the more generic type is not recommended, as content categorized in this way is unlikely to get the DIDComm-specific handling it needs. Similarly, it is also true but overly generic and therefore not recommended to describe a DIDComm signed message as application/json.

When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm signed messages SHOULD be dcsm, giving a globbing pattern of *.dcsm; this SHOULD be be read as “Star Dot D C S M” or as “D C S M” files. A possible icon for this media type depicts a signed envelope (svg | 256x256 | 128x128 | 64x64):

DIDComm Signed Message Icon

§ DIDComm Encrypted Message

A DIDComm encrypted message hides its content from all but authorized recipients, discloses and proves the sender to exactly and only those recipients, and provides integrity guarantees. It is important in privacy-preserving routing. It is what normally moves over network transports in DIDComm applications, and is the safest format for storing DIDComm data at rest.

The media type of a DIDComm encrypted message SHOULD be application/didcomm-encrypted+json.

Note: If future versions of this spec allow binary encodings, variations like application/didcomm-encrypted+cbor (see CBOR RFC 7049, section 7.5), application/didcomm-encrypted+msgpack, or application/didcomm-encrypted+protobuf may become reasonable. Future DIDComm specs that encompass comm patterns other than messaging — DIDComm multicast or DIDComm streaming, for example — might use a suffix: application/didcomm-encrypted-multicast or similar.

Because a DIDComm encrypted message is also a JWE, a true but less specific media type MIGHT be application/jose. Note how this overlaps with the generic media type of the JWS of a DIDComm Signed Message. As with DIDComm signed Messages, using more generic media types is ambiguous and not recommended.

When persisted as a file or attached as a payload in other contexts, the file extension for DIDComm encrypted messages SHOULD be dcem, giving a globbing pattern of *.dcem; this SHOULD be be read as “Star Dot D C E M” or as “D C E M” files. A possible icon for this file format depicts an envelope with binary overlay, protected by a lock (svg | 256x256 | 128x128 | 64x64):

DIDComm Encrypted Message Icon

§ Plaintext Message Structure

DIDComm plaintext messages are based on JWM (JSON Web Messages). A message has a basic structure that specifies the message type, id, and other attributes common to all messages. These common attributes appear at the top level of a DIDComm message, and are called headers. A message also includes attributes specific to the message type. Type specific message attributes are contained within the body attribute of a message.

Prior to being sent to a recipient, the JWM is usually encrypted into a JWE according to the JWM spec.

The following example shows common elements of a plaintext message. Further details and advanced usage are covered elsewhere in this spec.

{
    "id": "1234567890",
    "type": "<message-type-uri>",
    "from": "did:example:alice",
    "to": ["did:example:bob"],
    "created_time": 1516269022,
    "expires_time": 1516385931,
    "body": {
    	"messagespecificattribute": "and it's value"
	}
}

§ Message Headers

The predefined attributes of a DIDComm Message at the level of its outer packaging (effectively, the “headers” of the message) are as follows:

In the outer packaging of message metadata, DIDComm follows the extensibility pattern established by the JW* family of standards. (It also emulates the design of message headers in SMTP, request headers in HTTP, and labels on physical pieces of mail.) A modest inventory of predefined “header” fields is specified, as shown above. Additional fields with unreserved names can be added at the discretion of producers and consumers of messages; any software that doesn’t understand such fields should ignore them and MUST NOT fail because of their inclusion in a message. This is appropriate for a simple, flat data model.

Aligning with RFC 6648, DIDComm explicitly rejects the X-* headers convention that creates divergent pseudo-standards; if a new header needs broad support, it must be standardized properly. Alternatively, a JSON-LD @context header can be added, providing namespacing for fields other than those predefined in the spec. Since we expect header fields to be small in number and modest in complexity, we expect this sort of powerful extensibility to be unnecessary in most cases.

§ Simple vs. Structured

Headers can be simple (mapping a header name to an integer or a string) or structured (mapping a header name to JSON substructure – an array or JSON object). When defining a new header type, the following guidelines apply:

§ Relationship to JSON-LD

The problem domain of DIDComm intersects with other aspects of decentralized identity, where JSON-LD plays a role in some standards. Thus it may be natural to wonder about DIDComm’s relationship to JSON-LD and to the rich semantics and extensibility features it offers. The short answer is that DIDComm is not dependent on JSON-LD, but it is compatible with it. We expect these two technologies to remain mostly orthogonal.

The body of a message – everything inside the body object – is different. Here, there is substantial variety and complexity. Structures may be sophisticated graphs, represented with nested objects and arrays. JSON-LD is not required at this level, either. However, it is available, and may be appropriate for certain use cases where extensibility is an important feature. JSON-LD usage, if it occurs, SHOULD be a declared feature of a protocol as a whole, not an ad hoc extension to arbitrary individual messages, and MUST be signalled by the inclusion of a @context inside body. Unless a protocol declares a JSON-LD dependency, the same rules apply to JSON-LD-isms as apply to any other unrecognized structure in a DIDComm message: additional fields can be added to any part of message structure, should be ignored if not understood, and MUST NOT be the basis of failure by recipients.

§ DID Rotation

DIDComm is based on DIDs and their associated DID Documents. Changes to keys and endpoints are the concern of each DID method and are utilized but not managed by DIDComm. DID Rotation serves a very specific and narrow need to switch from one DID method to another. This is very common at the beginning of a new DIDComm relationship when a public DID or a temporary DID passed unencrypted is rotated out for a DID chosen for the relationship. As rotation between one DID and another is outside the scope of any DID method, the details of DID Rotation are handled within DIDComm itself.

When a DID is rotated, the new DID is put into immediate use encrypting the message, and one additional attribute is included as a message header:

When a message is received from an unknown DID, the recipient should check for existence of the from_prior header. The JWT in thefrom_prior attribute is used to extract the prior DID (iss) and is checked to verify the validity of the rotation. The recipient then associates the message with context related to the known sender. The new DID and associated DID Document information should be used for further communication.

The validity of the DID rotation is verified by checking the JWT signature against the key indicated in the kid header parameter. The indicated key MUST be authorized in the DID Document of the prior DID (iss).

The from_prior attribute should be included in messages sent until the party rotating receives a message sent to the new DID. If multiple messages are received to containing the rotation headers after being processed by the recipient, they may be ignored.

§ JWT Details

The JWT is constructed as follows, with appropriate values changed.

Header:

{
  "typ": "JWT",
  "alg": "EdDSA",
  "crv": "ED25519",
  "kid": "<key id authorized in prior DID>"
}

Payload:

{
  "sub": "<new DID URI>",
  "iss": "<prior DID URI>",
  "iat": 1516239022 //datetime of the rotation, not message
}

§ Example Message Rotating DID

{
    "id": "1234567890",
    "type": "<message-type-uri>",
    "from": "did:example:alice2",
    "from_prior": "<JWT with sub:did:example:alice2 and iss:did:example:alice>",
    "to": ["did:example:bob"],
    "created_time": 1516269022,
    "expires_time": 1516385931,
    "body": {
    	"messagespecificattribute": "and its value"
	}
}

§ Rotation Limitations

§ Message Encryption

DIDComm supports two types of message encryption: Authenticated Sender Encryption and Anonymous Sender Encryption. Both forms are encrypted to the recipient, but only Authenticated Sender Encryption provides assurances of who the sender is.

The encrypted form of a JWM is a JWE. The JOSE family defines JSON Web Algorithms (JWAs) which standardize certain cryptographic operations that are related to preparing JOSE structures. For the purposes of interoperability, DIDComm messaging does not support all JWAs, rather it takes a subset of the supported algorithms that are applicable for the following cases around secure messaging. These supported algorithms are listed here.

§ Sender Authenticated Encryption

When a sender would like to encrypt a message for a recipient or multiple recipients and also be authenticated such that the recipients can determine they were the party that encrypted the message, the JWA of ECDH-1PU defined by draft SHOULD be used within the structure of a JWE.

For the keys involved in key agreement, the following elliptic curves MUST be supported.

Curve Description
X25519 The underlying curve is actually Curve25519, however when used in the context of Diffie-Hellman the identifier of X25519 is used
P-256 NIST defined P-256 elliptic curve

For content encryption of the message, the following algorithms MUST be supported.

Algorithm(JWA) Description
XC20P XChaCha20Poly1305
A256GCM AES-GCM with a 256 bit key

TODO: Include language about safe nonce considerations.

§ Anonymous Encryption

When a sender would like to encrypt a message for a recipient or multiple recipients but not be authenticated by the recipients as the party who encrypted the message, the JWA of ECDH-ES defined by RFC 7518 SHOULD be used within the structure of a JWE.

For the keys involved in key agreement, the following elliptic curves MUST be supported.

Curve Description
X25519 The underlying curve is actually Curve25519, however when used in the context of Diffie-Hellman the identifier of X25519 is used
P-256 NIST defined P-256 elliptic curve

For content encryption of the message, the following algorithms MUST be supported.

Algorithm(JWA) Description
XC20P XChaCha20Poly1305
A256GCM AES-GCM with a 256 bit key

TODO: Include language about safe nonce considerations.

§ Key Wrapping Algorithms

KW Algorithm Curve (epk crv) key type (epk kty) Description
ECDH-ES+A256KW P-256 EC ECDH-ES key wrapping using key with NIST defined P-256 elliptic curve to create a 256 bits key as defined in 7518
ECDH-ES+A256KW P-384 EC ECDH-ES key wrapping using key with NIST defined P-384 elliptic curve to create a 256 bits key as defined in 7518
ECDH-ES+A256KW P-521 EC ECDH-ES key wrapping using key with NIST defined P-521 elliptic curve to create a 256 bits key as defined in 7518
ECDH-ES+A256KW X25519 OKP ECDH-ES with X25519 (RFC7748 section 5) to create a 256 bits key. The underlying curve is actually Curve25519, however when used in the context of Diffie-Hellman the identifier of X25519 is used
ECDH-1PU+A256KW P-256 EC ECDH-1PU key wrapping using key with NIST defined P-256 elliptic curve to create a 256 bits key as defined in ecdh-1pu
ECDH-1PU+A256KW P-384 EC ECDH-1PU key wrapping using key with NIST defined P-384 elliptic curve to create a 256 bits key as defined in ecdh-1pu
ECDH-1PU+A256KW P-521 EC ECDH-1PU key wrapping using key with NIST defined P-521 elliptic curve to create a 256 bits key as defined in ecdh-1pu
ECDH-1PU+A256KW X25519 OKP ECDH-1PU X25519 (RFC7748 section 5) to create a 256 bits key as defined in ecdh-1pu

§ Perfect Forward Secrecy

Due to the triple Key Derivation algorithm used in ECDH-1PU, all messages sent via DIDComm have weak perfect forward secrecy without any additional security added by the transport layer. In ECDH-1PU this is achieved by encrypting the content encryption key with the output of the hash of the Ze (ECDH of ephemeral key and recipient static key) and Zs (ECDH of static sender key and recipient static key). With Ze bringing the changed derived secret in each message and Zs bringing the repudiable authenticity of each message, the resulting Z (hash of Ze and Zs) carries the properties of weak perfect forward secrecy and repudiable authenticity for each message as well.

§ Examples

While the details of encrypting a JWM into a JWE are included in the JWM spec, a few examples are included here for clarity.

TODO: Add examples here

§ Message Signing

A DIDComm message can be signed, either in conjunction with encryption or independently if the message will remain unencrypted.

If a message is signed and encrypted to add non-repudiation, it must be signed prior to encryption. This is known as a nested JWM.

§ Algorithms

When a sender would like for a message to feature a non-repudiable digital signature the JWA’s defined below can be used within the structure of a JWS.

For digital signatures the following algorithms MUST be verifiable. At least one of the following curves MUST be supported for creating digital signatures.

Algorithm(JWA) Description
EdDSA (with crv=Ed25519) Elliptic curve digital signature with edwards curves and SHA-512
ES256 Elliptic curve digital signature with NIST p-256 curve and SHA-256
ES256K Elliptic curve digital signature with Secp256k1 keys.

§ Construction

Construct a JWS with the following header:

   {"typ":"JWM",
    "kid":"Ef1sFuyOozYm3CEY4iCdwqxiSyXZ5Br-eUDdQXk6jaQ",
    "alg":"ES256"}

The JWS payload is the Base64url encoded JWM.

When transmitted in a normal JWM fashion, the JSON Serialization MUST be used.

§ Verification

When verifying the signature, an additional check must be performed after verifying the JWS. The key used in the signature must be authorized to do so in the Document resolved from the DID in the from attribute. If the key is not authorized for the signature, the signature is invalid.

§ Application

§ Non-Repudiation

DIDComm Encrypted messages are repudiable. If non-repudiation is required for a particular protocol message, the message MUST be signed before encryption.

§ Tamper Resistant OOB Messages

Out of Band Messages may be signed to provide tamper resistance.

§ DID Anchoring

Signing can allow DIDs to be anchored via keys not usable for encrypting DIDComm messages.

§ Examples

TODO: Add examples here

§ Routing

§ Routing Protocol

§ Name and Version

The name of this protocol is “Routing Protocol”, and its version is “2.0”. It is uniquely identified by the PIURI:

https://didcomm.org/routing/2.0

§ Roles

There are 3 roles in the protocol: sender, mediator, and recipient. The sender emits messages of type forward to the mediator. The mediator unpacks (decrypts) the payload of an encrypted forward message and passes on the result (an opaque blob that probably contains a differently encrypted payload) to the recipient.

ordinary sequence

Note: the protocol is one-way; the return route for communication might not exist at all, or if it did, it could invert the roles of sender and receiver and use the same mediator, or it could use one or more different mediators, or it could use no mediator at all. This is a separate concern partly specified by the service endpoints in the DID docs of the sender and receiver, and partly explored in RFC 0092: Transports Return Route.

Note: When the mediator is the routing agent of a single identity subject like Alice, the logical receiver is Alice herself, but the physical receiver may manifest as multiple edge devices (a phone, a laptop, a tablet). From the perspective of this protocol, multiplexing the send from mediator to receiver is out of scope for interoperability–compatible and fully supported, but not required or specified in any way.

In this protocol, the sender and the receiver never interact directly; they only interact via the mediator.

The sender can decorate the forward message in standard DIDComm ways: using ~timing.expires_time, ~timing.delay_milli and ~timing.wait_until_time to introduce timeouts and delays, and so forth. However, the mediator is NOT required to support or implement any of these mixin semantics; only the core forwarding behavior is indispensable. If a mediator sees a decorator that requests behavior it doesn’t support, it MAY return a problem-report to the sender identifying the unsupported feature, but it is not required to do so, any more than other recipients of DIDComm messages would be required to complain about unsupported decorators in messages they receive.

One particular decorator is worth special mention here: ~please_ack. This decorator is intended to be processed by ultimate recipients, not mediators. It imposes a burden of backward-facing communication that mediators should not have. Furthermore, it may be used to probe a delivery chain in a way that risks privacy for the receiver. Therefore, senders SHOULD NOT use this, and mediators SHOULD NOT honor it if present. If a sender wishes to troubleshoot, the message tracing mechanism is recommended.

§ States

Since data flow is normally one-way, and since the scope of the protocol is a single message delivery, a simplistic way to understand it might be as two instances of the stateless notification pattern, unfolding in sequence.

However, this doesn’t quite work on close inspection, because the mediator is at least potentially stateful with respect to any particular message; it needs to be if it wants to implement delayed delivery or retry logic. (Or, as noted earlier, the possibility of sending to multiple physical receivers. Mediators are not required to implement any of these features, but the state machine needs to account for their possibility.) Plus, the notification terminology obscures the sender and receiver roles. So we use the following formalization:

state machines

§ Messages

The only message in this protocol is the forward message. A simple and common version of a forward message might look like this:

{
    "@type": "https://didcomm.org/routing/2.0/forward",
    "to"   : "did:foo:1234abcd",
    "payloads~attach": [
        // One payload
    }
}

A fancier version with many optional attributes has the following potential structure:

{
    "@id": "uuid value" // optional; only useful for tracing
    "@type": "https://didcomm.org/routing/2.0/forward",
    "to"   : "did:foo:1234abcd",
    "payloads~attach": [
        // An array of attached payloads, generally assumed
        // to be DIDComm encrypted envelopes, but theoretically
        // could be other message types as well.
    ],
    // This decorator and everything in it are optional. 
    "~timing": {
        // Usually, delay_milli and wait_until_time don't make
        // sense together; use one or the other but not both. If
        // both do occur, forward shouldn't happen until the later
        // of the two conditions is satisfied.
        "delay_milli": 12345,
        "wait_until_time": "2020-03-25T00:00:00Z",
        // Abandon attempt to forward after this timestamp.
        "expires_time": "2020-03-27T18:25:00Z" 
    },
    // Optional: requests use of mix network instead of direct
    // forward, to enhance privacy.
    "mix": {
        // Likelihood (from 0 to 1) that a random node in a
        // mix network should be the next hop instead of
        // sending the message directly to its final receiver.
        "hop_chance": 0.8,
        // If next receiver is a mix node, multiply hop_chance
        // by this value so hop_chance attenuates for the next
        // receiver. This prevents infinite mixing. Max value =
        // 0.99.
        "hop_decay": 0.2,
        // Likelihood (from 0 to 1) that the message size will
        // be distorted to the next receiver. 
        "noise_chance": 0.5
    }
}

[TODO: describe use of the attn field, and explain why it’s an important construct that allows us to encrypt to all (cryptographic route) but deliver just to the agent most likely to be interested (network route).

[TODO: further revise the following paragraph to clarify that either a key or a DID might be used. Each possibility makes certain tradeoffs, and may be appropriate in certain cases. Keys may be fragile in the face of rotation, and they require a lot of knowledge/maintenance cost for the external mediator. However, DID key references and DIDs may introduce some complications in how the recipient proves control of a DID (a requirement for security, but also a privacy eroder).]

For most external mediators, the value of the to field is likely to be a DID, not a key. However… (see previous TODO note). This hides details about the internals of a sovereign domain from external parties. The sender will have had to multiplex encrypt for all relevant recipient keys, but doesn’t need to know how routing happens to those keys. The mediator and the receiver may have coordinated about how distribution to individual keys takes place (see RFC 0211: Route Coordination), but that is outside the scope of concerns of this protocol.

The attachment(s) in the payloads~attach field are able to use the full power of DIDComm attachments, including features like instructing the receiver to download the payload content from a CDN.

The mix property is discussed next.

§ Rewrapping

Normally, the payload attached to the forward message received by the mediator is transmitted directly to the receiver with no further packaging. However, optionally, the mediator can attach the opaque payload to a new forward message, which then acts as a fresh outer envelope for the second half of the delivery. This rewrapping means that the “onion” of packed messages stays the same size rather than getting smaller as a result of the forward operation:

re-wrapped sequence

Rewrapping mode is invisible to senders, but mediators need to know about it, since they change their behavior as a result. Receivers also need to know about it, because it causes them to receive a double-packaged message instead of a singly-packaged one. The outer envelope is a forward message where to is the receiver itself.

Why is such indirection useful?

These last two characteristics are the foundation of mix networking feature for DIDComm. That feature is the subject of a different RFC; here we only note the existence of the optional feature.

§ Sender Forward Process

  1. Sender Constructs Message.
  2. Sender Encrypts Message to recipient(s).
  3. Wrap Encrypted Message in Forward Message for each Routing Key.
  4. Transmit to serviceEndpoint in the manner specified in the [transports] section.

§ Mediator Process

Prior to using a Mediator, it is the recipient’s responsibility to coordinate with the mediator. Part of this coordination informs them of the to address(es) expected, the endpoint, and any Routing Keys to be used when forwarding messages. That coordination is out of the scope of this spec.

  1. Receives Forward Message.
  2. Retrieves Service Endpoint pre-configured by recipient (to attribute).
  3. Transmit payload message to Service Endpoint in the manner specified in the [transports] section.

The recipient (to attribute of Forward Message) may have pre-configured additional routing keys with the mediator that were not present in the DID Document and therefore unknown to the original sender. If this is the case, the mediator should wrap the attached payload message into an additional Forward message once per routing key. This step is performed between (2) and (3).

§ DID Document Keys

All keys declared in the DID Document’s keyAgreement section should be used as recipients when encrypting a message. The details of key representation are described in the Public Keys section of the DID Core Spec.

Keys used in a signed JWM are declared in the DID Document’s authentication section.

TODO: include details about how DIDComm keys are represented/identified in the DID Document. The DID Core Spec appears light on details and examples of keyAgreement keys. Clarifying language should be included here or there.

§ DID Document Service Endpoint

DIDComm DID Document endpoints have the following format:

{
    "id": "did:example:123456789abcdefghi#didcomm-1",
    "type": "DIDComm",
    "serviceEndpoint": "http://example.com/path",
    "routingKeys": ["did:example:somemediator#somekey"]
}

id: must be unique, as required in DID Core. No special meaning should be inferred from the id chosen.

type: MUST be DIDComm.

serviceEndpoint: MUST contain a URI for a transport specified in the [transports] section of this spec, or a URI from Alternative Endpoints. It MAY be desirable to constraint endpoints from the [transports] section so that they are used only for the reception of DIDComm messages. This can be particularly helpful in cases where auto-detecting message types is inefficient or undesirable.

routingKeys: An optional ordered array of strings referencing keys to be used when preparing the message for transmission as specified in the [Routing] section of this spec.

§ Multiple Endpoints

A DID Document may contain multiple service entries of type DIDComm. Entries are SHOULD be specified in order of receiver preference, but any endpoint MAY be selected by the sender, typically by protocol availability or preference.

§ Alternative Endpoints

In addition to the URIs for [transports], some alternative forms are available.

§ DID

Using a DID for the serviceEndpoint is useful when using a mediator. The DID should be resolved, and services with type of “DIDComm” will contain valid serviceEndpoints. The keyAgreement keys of that DID Document should be appended at the end of the routingKeys section from the message recipient’s DID Document as per the process in [Sender Forward Process]. The key advantage with this approach is that a mediator can rotate keys and update serviceEndpoints without any updates needed to dependent recipients` DID Documents.

A DID representing a mediator SHOULD NOT use alternative endpoints in it’s own DID Document to avoid recursive endpoint resolution. Using only the URIs described in [transports] will prevent such recursion.

Example 1: Mediator

{
    "id": "did:example:123456789abcdefghi#didcomm-1",
    "type": "DIDComm",
    "serviceEndpoint": "did:example:somemediator"
}

The message is encrypted to the recipient, then wrapped in a forward message encrypted to the keyAgreement keys within the did:example:somemediator DID Document, and transmitted to the URIs present in the did:example:somemediator DID Document with type DIDComm.

Example 2: Mediator + Routing Keys

{
    "id": "did:example:123456789abcdefghi#didcomm-1",
    "type": "DIDComm",
    "serviceEndpoint": "did:example:somemediator",
    "routingKeys": ["did:example:anothermediator#somekey"]
}

The message is encrypted to the recipient, then wrapped in a forward message encrypted to did:example:anothermediator#somekey. That forward message is wrapped in a forward message encrypted to keyAgreement keys within the did:example:somemediator DID Document, and transmitted to the URIs present in the did:example:somemediator DID Document with type DIDComm.

§ Queue

TODO: Does the queue fit here as an alternate URI?

[TODO: discuss how routing info is exposed in a DID doc, and how it is conveyed in “ephemeral mode” where no DID doc is available.]

§ Transports

§ Summary

DIDComm Messaging is designed to be transport independent, including message encryption and agent message format. The encryption envelope provides both encryption and authentication, providing trust as a feature of each message. Each transport does have unique features, and we need to standardize how the transport features are (or are not) applied.

§ Delivery

DIDComm Transports serve only as message delivery. No information about the effects or results from a message is transmitted over the same connection.

§ Reference

§ HTTP(S)

HTTP(S) transports are an effective way to send a message to another online agent.

§ WebSocket

Websockets are an efficient way to transmit multiple messages without the overhead of individual requests. This is useful in a high bandwidth situation

With STOMP over WebSocket, the content-type header is application/didcomm-enc-env as in the HTTP(S) message.

TODO:

§ Advanced Message Passing

TODO:

§ Embedded Messages

DIDComm messages may be passed within other messages are protocols when the outer message is passed in a secure way. When messages are passed in this way, they may be passed either as an encrypted message or in plain text. When in plain text format, messages should be represented in json format.

§ Privacy Considerations

When messages are passed in plain text, the privacy and security of the message is subject to the properties of the protocol and transport moving the messages. Extreme care must be taken to protect the message.

§ Connections

A Connection is the practical application of a relationship in DID Communication. Having a connection means that each party in the relationship has a DID for the other parties, and parties can communicate securely using the keys and endpoints within each DID Document.

In order to establish a new connection, Simply exchange a new message between parties. Knowing the DID of the other parties does not indicate any level of trust. Using the connection to establish a foundation of trust is the next step.

§ General Messaging Constructs

§ Protocols

DIDComm serves as a foundational layer for the development of protocols. This spec does not include protocols themselves, but describes the basic requirements and foundational elements.

Each Protocol is uniquely identified by a Protocol Identifier URI, and contains one or more messages identified by a Message Type URI. In addition to serving as a unique identifier, the URIs may be used by a developer to locate documentation.

§ Protocol Identifier URI

A Protocol Identifier URI identifies protocol versions unambiguously. Additionally, Protocol Identifier URIs may be used by a developer to locate documentation about a protocol.

The URI must be composed as follows:

[doc-uri][delim][protocol-name]/[semver]

With ABNF:

protocol-identifier-uri = doc-uri delim protocol-name "/" semver
delim                   = "?" / "/" / "&" / ":" / ";" / "="

Its loose matcher regex is:

(.*?)([a-z0-9._-]+)/(\d[^/]*)/?$

Example Protocol Type URIs:

http://example.com/protocols?which=lets_do_lunch/1.0
http://example.com/protocols/lets_do_lunch/1.0
https://github.com/hyperledger/aries-toolbox/tree/master/docs/admin-invitations/0.1

The goals of this URI are, in descending priority:

The doc-uri portion is any URI that exposes documentation about protocols. A developer should be able to browse to that URI and use human intelligence to look up the named and versioned protocol.

§ Message Type URI

A Message Type URI identifies message types unambiguously. Standardizing its format is important because it is parsed by agents that will map messages to handlers–basically, code will look at this string and say, “Do I have something that can handle this message type inside protocol X version Y?” When that analysis happens, it must do more than compare the string for exact equality; it may need to check for semver compatibility, and it has to compare the protocol name and message type name ignoring case and punctuation.

The URI MUST be composed as follows:

[protocol-identifier-uri] / [message-type-name]

With ABNF:

message-type-uri  = protocol-identifier-uri "/" message-type-name
protocol-identifier-uri = doc-uri delim protocol-name "/" semver
delim                   = "?" / "/" / "&" / ":" / ";" / "="
protocol-name     = identifier
protocol-version  = semver
message-type-name = identifier
identifier        = alpha *(*(alphanum / "_" / "-" / ".") alphanum)

It can be loosely matched and parsed with the following regex:

    (.*?)([a-z0-9._-]+)/(\d[^/]*)/([a-z0-9._-]+)$

A match will have captures groups of (1) = doc-uri, (2) = protocol-name, (3) = protocol-version, and (4) = message-type-name.

The goals of this URI are, in descending priority:

Example Message Type URIs:

http://example.com/protocols?which=lets_do_lunch/1.0/proposal
http://example.com/protocols/lets_do_lunch/1.0/proposal
did:example:1234567890;spec/trust_ping/1.0/ping
https://github.com/hyperledger/aries-toolbox/tree/master/docs/admin-invitations/0.1/create-invitation

§ Out Of Band Messages

§ URL & QR Codes

When passing a DIDComm Message between two parties, it is often useful to present a message in the form of a URL or encoded into the form of a QR code for scanning with a smartphone or other camera. The format for a QR code is simply the encoded URL form of a message.

§ Privacy Considerations

Any information passed via a URL or QR code is unencrypted, and may be observed by another party. This lack of privacy must be minded in two different ways.

First, no private information may be passed in the message. Private information should be passed between parties in encrypted messages only. Any protocol message that contains private information should not be passed via URL or QR code.

Second, any identifiers passed in a message sent via URL or QR code must no longer be considered private. Any DID used or other identifier no longer considered private MUST be rotated over a secure connection if privacy is required.

§ Message Correlation

The id of the message passed in a URL or a QR code is used to as the thread_id on a response sent by the recipient of this message. The response recipient can use the thread_id to correlate it with the original message.

§ Messages

Each message passed this way must be contained within an out-of-band message, as described below.

The out-of-band protocol a single message that is sent by the sender.

§ Invitation: https://didcomm.org/out-of-band/%VER/invitation

{
  "@type": "https://didcomm.org/out-of-band/%VER/invitation",
  "@id": "<id used for context as pthid>",
  "goal_code": "issue-vc",
  "goal": "To issue a Faber College Graduate credential",
  "request~attach": [
    {
        "@id": "request-0",
        "mime-type": "application/json",
        "data": {
            "json": "<json of protocol message>"
        }
    }
  ]
}

The items in the message are:

When encoding a message in a URL or QR code, the sender does not know which protocols are supported by the recipient of the message. Encoding multiple alternative messages is a form of optimistic protocol negotiation that allows multiple supported protocols without coordination

§ Standard Message Encoding

Using a standard message encoding allows for easier interoperability between multiple projects and software platforms. Using a URL for that standard encoding provides a built in fallback flow for users who are unable to automatically process the message. Those new users will load the URL in a browser as a default behavior, and may be presented with instructions on how to install software capable of processing the message. Already onboarded users will be able to process the message without loading in a browser via mobile app URL capture, or via capability detection after being loaded in a browser.

The standard message format is a URL with a Base64URLEncoded plaintext JWM json object as a query parameter.

The URL format is as follows, with some elements described below:

https://<domain>/<path>?_oob=<encodedplaintextjwm>

<domain> and <path> should be kept as short as possible, and the full URL should return human readable instructions when loaded in a browser. This is intended to aid new users. The _oob query parameter is required and is reserved to contain the DIDComm message string. Additional path elements or query parameters are allowed, and can be leveraged to provide coupons or other promise of payment for new users.

_oob is a shortened form of Out of Band, and was chosen to not conflict with query parameter names in use at a particular domain. When the query parameter is detected, it may be assumed to be an Out Of Band message with a reasonably high confidence.

To do: We need to rationalize this approach https:// approach with the use of a special protocol (e.g. didcomm://) that will enable handling of the URL on mobile devices to automatically invoke an installed app on both Android and iOS. A user must be able to process the out-of-band message on the device of the agent (e.g. when the mobile device can’t scan the QR code because it is on a web page on device).

The <encodedplaintextjwm> is a JWM plaintext message that has been base64-url encoded.

encodedplaintextjwm = b64urlencode(<plaintextjwm>)

During encoding, whitespace from the json string should be eliminated to keep the resulting out-of-band message string as short as possible.

§ Example Out-of-Band Message Encoding

Invitation:

{
  "type": "https://didcomm.org/out-of-band/0.1/invitation",
  "id": "69212a3a-d068-4f9d-a2dd-4741bca89af3",
  "from": "did:example:alice",
  "body": {
      "goal_code": "",
      "goal": "",
      "request~attach": [
          {
              "@id": "request-0",
              "mime-type": "application/json",
              "data": {
                  "json": "<json of protocol message>"
              }
          }
      ]
  }
}

Whitespace removed:

{"type":"https://didcomm.org/out-of-band/0.1/invitation","id":"69212a3a-d068-4f9d-a2dd-4741bca89af3","from":"did:example:alice","body":{"goal_code":"","goal": "","request~attach":[{"@id":"request-0","mime-type":"application/json","data":{"json":"<json of protocol message>"}}]}}

Base 64 URL Encoded:

eyJ0eXBlIjoiaHR0cHM6Ly9kaWRjb21tLm9yZy9vdXQtb2YtYmFuZC8wLjEvaW52aXRhdGlvbiIsImlkIjoiNjkyMTJhM2EtZDA2OC00ZjlkLWEyZGQtNDc0MWJjYTg5YWYzIiwiZnJvbSI6ImRpZDpleGFtcGxlOmFsaWNlIiwiYm9keSI6eyJnb2FsX2NvZGUiOiIiLCJnb2FsIjogIiIsInJlcXVlc3R-YXR0YWNoIjpbeyJAaWQiOiJyZXF1ZXN0LTAiLCJtaW1lLXR5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjoiPGpzb24gb2YgcHJvdG9jb2wgbWVzc2FnZT4ifX1dfX0=

Example URL:

http://example.com/path?_oob=eyJ0eXBlIjoiaHR0cHM6Ly9kaWRjb21tLm9yZy9vdXQtb2YtYmFuZC8wLjEvaW52aXRhdGlvbiIsImlkIjoiNjkyMTJhM2EtZDA2OC00ZjlkLWEyZGQtNDc0MWJjYTg5YWYzIiwiZnJvbSI6ImRpZDpleGFtcGxlOmFsaWNlIiwiYm9keSI6eyJnb2FsX2NvZGUiOiIiLCJnb2FsIjogIiIsInJlcXVlc3R-YXR0YWNoIjpbeyJAaWQiOiJyZXF1ZXN0LTAiLCJtaW1lLXR5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjoiPGpzb24gb2YgcHJvdG9jb2wgbWVzc2FnZT4ifX1dfX0=

DIDComm message URLs can be transferred via any method that can send text, including an email, SMS, posting on a website, or QR Code.

Example Email Message:

To: [email protected]
From: [email protected]
Subject: Your request to connect and receive your graduate verifiable credential

Dear Alice,

To receive your Faber College graduation certificate, click here to [connect](http://example.com/path?_oob=eyJ0eXBlIjoiaHR0cHM6Ly9kaWRjb21tLm9yZy9vdXQtb2YtYmFuZC8wLjEvaW52aXRhdGlvbiIsImlkIjoiNjkyMTJhM2EtZDA2OC00ZjlkLWEyZGQtNDc0MWJjYTg5YWYzIiwiZnJvbSI6ImRpZDpleGFtcGxlOmFsaWNlIiwiYm9keSI6eyJnb2FsX2NvZGUiOiIiLCJnb2FsIjogIiIsInJlcXVlc3R-YXR0YWNoIjpbeyJAaWQiOiJyZXF1ZXN0LTAiLCJtaW1lLXR5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjoiPGpzb24gb2YgcHJvdG9jb2wgbWVzc2FnZT4ifX1dfX0= with us, or paste the following into your browser:

http://example.com/path?_oob=eyJ0eXBlIjoiaHR0cHM6Ly9kaWRjb21tLm9yZy9vdXQtb2YtYmFuZC8wLjEvaW52aXRhdGlvbiIsImlkIjoiNjkyMTJhM2EtZDA2OC00ZjlkLWEyZGQtNDc0MWJjYTg5YWYzIiwiZnJvbSI6ImRpZDpleGFtcGxlOmFsaWNlIiwiYm9keSI6eyJnb2FsX2NvZGUiOiIiLCJnb2FsIjogIiIsInJlcXVlc3R-YXR0YWNoIjpbeyJAaWQiOiJyZXF1ZXN0LTAiLCJtaW1lLXR5cGUiOiJhcHBsaWNhdGlvbi9qc29uIiwiZGF0YSI6eyJqc29uIjoiPGpzb24gb2YgcHJvdG9jb2wgbWVzc2FnZT4ifX1dfX0=

If you don't have an identity agent for holding credentials, you will be given instructions on how you can get one.

Thanks,

Faber College
Knowledge is Good

Example URL encoded as a QR Code:

Example QR Code

§ Short URL Message Retrieval

It seems inevitable that the length of some DIDComm messages will be too long to produce a useable QR code. Techniques to avoid unusable QR codes have been presented above, including using attachment links for requests, minimizing the routing of the response and eliminating unnecessary whitespace in the JSON. However, at some point a sender may need generate a very long URL. In that case, a short URL message retrieval redirection should be implemented by the sender as follows:

A usable QR code will always be able to be generated from the shortened form of the URL.

Note: Due to the privacy implications, a standard URL shortening service SHOULD NOT be used.

§ Discover Features Protocol 1.0

§ Summary

Describes how agents can query one another to discover which features it supports, and to what extent.

§ Motivation

Though some agents will support just one protocol and will be statically configured to interact with just one other party, many exciting uses of agents are more dynamic and unpredictable. When Alice and Bob meet, they won’t know in advance which features are supported by one another’s agents. They need a way to find out.

§ Reference

This RFC introduces a protocol for discussing the protocols an agent can handle. The identifier for the message family used by this protocol is discover-features, and the fully qualified URI for its definition is:

https://didcomm.org/discover-features/1.0

§ Roles

There are two roles in the discover-features protocol: requester and responder. The requester asks the responder about the protocols it supports, and the responder answers. Each role uses a single message type.

§ States

This is a classic two-step request~response interaction, so it uses the predefined state machines for any requester and responder:

state machines

§ Messages

§ query Message Type

A discover-features/query message looks like this:

{
    "type": "https://didcomm.org/discover-features/1.0/query",
    "id": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU",
    "body": {
        "query": "https://didcomm.org/tictactoe/1.*"
    }
}

Query messages say, “Please tell me what your capabilities are with respect to the protocols that match this string.” This particular example asks if another agent knows any 1.x versions of the tictactoe protocol.

The query field may use the * wildcard. By itself, a query with just the wildcard says, “I’m interested in anything you want to share with me.” But usually, this wildcard will be to match a prefix that’s a little more specific, as in the example that matches any 1.x version.

Any agent may send another agent this message type at any time. Implementers of agents that intend to support dynamic relationships and rich features are strongly encouraged to implement support for this message, as it is likely to be among the first messages exchanged with a stranger.

§ disclose Message Type

A discover-features/disclose message looks like this:

{
    "type": "https://didcomm.org/discover-features/1.0/disclose",
    "thread_id": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU",
    "body":{
        "protocols": [
            {
                "ptid": "https://didcomm.org/tictactoe/1.0",
                "roles": ["player"]
            }
        ]
    }
}

The protocols field is a JSON array of protocol support descriptor objects that match the query. Each descriptor has a pid that contains a protocol version (fully qualified message family identifier such as https://didcomm.org/tictactoe/1.0), plus a roles array that enumerates the roles the responding agent can play in the associated protocol.

Response messages say, “Here are some protocols I support that matched your query, and some things I can do with each one.”

§ Sparse Responses

Responses do not have to contain exhaustive detail. For example, the following response is probably just as good:

{
  "type": "https://didcomm.org/discover-features/1.0/disclose",
  "thread_id": "yWd8wfYzhmuXX3hmLNaV5bVbAjbWaU",
  "protocols": [
    {"ptid": "https://didcomm.org/tictactoe/1.0"}
  ]
}

The reason why less detail probably suffices is that agents do not need to know everything about one another’s implementations in order to start an interaction–usually the flow will organically reveal what’s needed. For example, the outcome message in the tictactoe protocol isn’t needed until the end, and is optional anyway. Alice can start a tictactoe game with Bob and will eventually see whether he has the right idea about outcome messages.

The missing roles in this response does not say, “I support no roles in this protocol.” It says, “I support the protocol but I’m providing no detail about specific roles.”

Even an empty protocols map does not say, “I support no protocols that match your query.” It says, “I’m not telling you that I support any protocols that match your query.” An agent might not tell another that it supports a protocol for various reasons, including: the trust that it imputes to the other party based on cumulative interactions so far, whether it’s in the middle of upgrading a plugin, whether it’s currently under high load, and so forth. And responses to a discover-features request are not guaranteed to be true forever; agents can be upgraded or downgraded, although they probably won’t churn in their protocol support from moment to moment.

§ Privacy Considerations

Because the regex in a request message can be very inclusive, the discover-features protocol could be used to mine information suitable for agent fingerprinting, in much the same way that browser fingerprinting works. This is antithetical to the ethos of our ecosystem, and represents bad behavior. Agents should use discover-features to answer legitimate questions, and not to build detailed profiles of one another. However, fingerprinting may be attempted anyway.

For agents that want to maintain privacy, several best practices are recommended:

§ Follow selective disclosure.

Only reveal supported features based on trust in the relationship. Even if you support a protocol, you may not wish to use it in every relationship. Don’t tell others about protocols you do not plan to use with them.

Patterns are easier to see in larger data samples. However, a pattern of ultra-minimal data is also a problem, so use good judgment about how forthcoming to be.

§ Trust Ping Protocol 1.0

A standard way for agents to test connectivity, responsiveness, and security of a DIDComm channel.

§ Motivation

Agents are distributed. They are not guaranteed to be connected or running all the time. They support a variety of transports, speak a variety of protocols, and run software from many different vendors.

This can make it very difficult to prove that two agents have a functional pairwise channel. Troubleshooting connectivity, responsiveness, and security is vital.

§ Reference

This protocol is analogous to the familiar ping command in networking–but because it operates over DIDComm, it is transport agnostic and asynchronous, and it can produce insights into privacy and security that a regular ping cannot.

§ Roles

There are two parties in a trust ping: the sender and the receiver. The sender initiates the trust ping. The receiver responds. If the receiver wants to do a ping of their own, they can, but this is a new interaction in which they become the sender.

§ Protocol Type URI

https://didcomm.org/trust_ping/1.0

§ Messages

§ ping

The trust ping interaction begins when sender creates a ping message like this:

{
  "type": "https://didcomm.org/trust_ping/1.0/ping",
  "id": "518be002-de8e-456e-b3d5-8fe472477a86",
  "body": {
      "response_requested": true
  }
}

response_requested: default value is true. If false, the sender is not requesting a ping_response from the receiver. If true, the sender is requesting a response.

§ ping_response

When the message arrives at the receiver, assuming that response_requested is not false, the receiver should reply as quickly as possible with a ping_response message that looks like this:

{
  "type": "https://didcomm.org/trust_ping/1.0/ping_response",
  "id": "e002518b-456e-b3d5-de8e-7a86fe472847",
  "thread_id": "518be002-de8e-456e-b3d5-8fe472477a86"
}

§ Trust

This is the “trust ping protocol”, not just the “ping protocol.” The “trust” in its name comes from several features that the interaction gains by virtue of the properties of the DIDComm messages. A ping and response verify to both parties that the necessary encryption is in place and working properly for the messages to be understood.

§ Reference Implementation

§ Future-Proofing

§ Versioning

This version of the standard is known as “DIDComm v2” — acknowledging the fact that a v1 generation of DIDComm specs was incubated under the Hyperledger Aries project umbrella. The v1 specs are close conceptual cousins, but use a slightly different encryption envelope, and base their plaintext format on arbitrary JSON instead of JWMs.

Future evolutions of the spec will follow semver conventions. Minor updates that add features without breaking compatibility will carry a minor version number update: 2.1, 2.2, and so forth. Breaking changes will prompt a major version change.

§ Extensions

The general mechanism for DIDComm extensibility is the development of DIDComm protocols. In the case where extensibility requires a modification to the base DIDComm spec itself, a DIDComm extension is to be used. An extension adds a self-contained set of conventions or features. Support for DIDComm extensions is optional.

Each DIDComm extension is described in a specification of its own. Software that implements a DIDComm Extension in addition to the DIDComm spec will indicate so via link to the extension spec.

§ Future Work

§ Additional Encodings

DIDComm Messages are JSON encoded (based on the JOSE family of specs) at the encryption, signature, and content level. Future encodings might introduce binary serializations. Each innovation like this MUST specify a deterministic and reliable method for indicating the alternative encoding used.

§ Beyond Messaging

This is a DIDComm messaging spec. Security, privacy, routing, and metadata concepts from this spec could be adapted to other communication styles, including multicast/broadcast and streaming. This will create sister specs to DIDComm Messaging, rather than evolving DIDComm Messaging itself.

§ Post-Quantum Crypto

The designers of DIDComm are aware that DIDComm’s cryptographic methods will need to be upgraded when quantum computing matures. This is because DIDComm makes heavy use of asymmetric elliptic curve mechanisms that depend on the discrete logarithm problem; this computational hardness is likely to be vulnerable to quantum cracking. Similar risks will drive upgrades to TLS, Ethereum, Bitcoin, and many other systems that are considered highly secure today.

Some modest preparations for quantum-resistant DIDComm have already begun. DIDComm is able to use arbitrary DID methods, which should allow approaches that are quantum-secure without changing the general pattern of DIDComm’s interaction with key management technology.

Libraries that provide quantum-resistant algorithms for signing and encryption are now available, but research is needed to determine which approaches are worthy of broad adoption. This is the subject of an ongoing project sponsored by NIST, and of a similar project in the EU.

We expect to update the DIDComm Messaging spec as these projects release mature recommendations and the cryptographic libraries they vet achieve adoption. It is not yet clear whether this will require a breaking change to DIDComm’s encryption envelope or signing formats.

§ References

Table of Contents