§ Decentralized Web Node
Specification Status: Draft
Latest Draft: identity.foundation/decentralized-web-node/spec
Previous Draft: 0.0.1-predraft
Companion Guide v0.0.1
- Chairs
- Andor Kesselman
- Liran Cohen
- Editors:
- Daniel Buchner (Block)
- Tobias Looker (Mattr)
- Contributors:
- Henry Tsai (Microsoft)
- XinAn Xu (Microsoft)
- Moe Jangda (Block)
- Participate:
- GitHub repo
- File a bug
- Commit history
§ Abstract
Most digital activities between people, organizations, devices, and other entities require the exchange of messages and data. For entities to exchange messages and data for credential, app, or service flows, they need an interface through which to store, discover, and fetch data related to the flows and experiences they are participating in. A Decentralized Web Node (DWN) is a data storage and message relay mechanism entities can use to locate public or private permissioned data related to a given Decentralized Identifier (DID). Decentralized Web Nodes are a mesh-like datastore construction that enable an entity to operate multiple nodes that sync to the same state across one another, enabling the owning entity to secure, manage, and transact their data with others without reliance on location or provider-specific infrastructure, interfaces, or routing mechanisms.
§ Status of This Document
Decentralized Web Node is a DRAFT specification under development within the Decentralized Identity Foundation (DIF). It is an active work item of the Secure Data Storage Working Group at DIF. It incorporates requirements and learnings from related work of many active industry players into a shared specification that meets the collective needs of the community.
The specification will be updated to incorporate feedback, from DIF members and the wider community, with a reference implementation being developed within DIF that exercises the features and requirements defined here. We encourage reviewers to submit GitHub Issues as the means by which to communicate feedback and contributions.
§ Terminology
- Decentralized Web Node
- A decentralized personal and application data storage and message relay node, as defined in the DIF Decentralized Web Node specification. Users may have multiple Nodes that replicate their data between them.
- Decentralized Identifiers
- Unique ID URI string and PKI metadata document format for describing the cryptographic keys and other fundamental PKI values linked to a unique, user-controlled, self-sovereign identifier in a target system (e.g., blockchain, distributed ledger).
§ Topology
§ Technical Stack
Decentralized Web Nodes are comprised of the following component layers, each of which is defined in this specification to ensure multiple Decentralized Web Node implementations can be used together and operate as a single logical unit for users.
DID Authentication |
Access & Authorization |
Interface Definitions |
Interface-Specific Processing |
Object Format |
Object Signing / Encryption |
IPLD Multiformats |
§ Protocols
Protocols are used to describe common rules that DWNs will follow when dealing with specific types and structures of data. Through Protocol Definitions a DWN Owner can define how a protocol should behave.
The definition defines types
, as well as their structure
allowing for hierarchial relationships for data types, as well as roles, object capabilities, and enforced limitations such as data payload size.
This will promote interoperability between users and apps, avoiding bespoke implementation details and interactivity often needed within traditional application development.
In this example, a DWN owner can write images and metadata to their own DWN. Some of the rules the protocol enforces:
- Images must have the schema
https://example.com/schemas/image
. - Images must have a dataFormat of
image/png
,image/jpeg
orimage/gif
. - Images cannot exceed a size of
500MB
. - Image Metadata must have a parent Image.
- Image Metadata must have the schema
https://example.com/schemas/metadata
. - Image Metadata must have a dataFormat of
application/json
. - Image Metadata cannot exceed a size of
100KB
.
{
"protocol": "https://example.com/protocol/image-storage",
"types": {
"image": {
"schema": "https://example.com/schemas/image",
"dataFormats": [
"image/png",
"image/jpeg",
"image/gif"
]
},
"metadata": {
"schema": "https://example.com/schemas/metadata",
"dataFormats": [
"application/json"
]
}
},
"structure": {
"image": {
"$size": {
"max": 500000000
},
"metadata": {
"$size": {
"max": 100000
}
}
}
}
}
In this example, we extend the simpler protocol with additional actors via roles. The protocol follows the same rules as the Image Storage protocol with the following additions:
- An Owner can assign a
viewer
role to an external actor. - A Viewer must have the schema
https://example.com/schemas/viewer
. - A Viewer must have the dataFormat of
application/json
. - Only the DWN Owner can add a Viewer.
- A Viewer can
read
andquery
Images as well as Image Metadata. - An Owner can assign a
writer
role to an external actor. - A Writer must have the schema
https://example.com/schemas/writer
. - A Writer must have the dataFormat of
application/json
. - A Writer can
create
Images. - A Writer can
delete
orupdate
Images which they authored. - The Author of an Image can
create
Image Metadata for that Image. - The Author of an Image can
delete
orupdate
the Image Metadata which they authored.
{
"protocol": "https://example.com/protocol/image-sharing",
"types": {
"image": {
"schema": "https://example.com/schemas/image",
"dataFormats": [
"image/png",
"image/jpeg",
"image/gif"
]
},
"metadata": {
"schema": "https://example.com/schemas/metadata",
"dataFormats": [
"application/json"
]
},
"viewer": {
"schema": "https://example.com/schemas/viewer",
"dataFormats": [
"application/json"
]
},
"writer": {
"schema": "https://example.com/schemas/writer",
"dataFormats": [
"application/json"
]
}
},
"structure": {
"viewer": {
"$role": true
},
"writer": {
"$role": true
},
"image": {
"$size": {
"max": 500000000
},
"$actions": [
{
"role": "viewer",
"can": [
"read",
"query"
]
},
{
"role": "writer",
"can": [
"create",
"update",
"delete"
]
}
],
"metadata": {
"$size": {
"max": 100000
},
"$actions": [
{
"role": "viewer",
"can": [
"read",
"query"
]
},
{
"who": "author",
"of": "image",
"can": [
"create",
"update",
"delete"
]
}
]
}
}
}
}
§ Service Endpoints
The following DID Document Service Endpoint entries MUST be present in the DID Document of a target DID for resolution to properly locate the URI for addressing a DID owner’s Decentralized Web Nodes:
{
"id": "did:example:alice",
"service": [{
"id": "#dwn",
"type": "DecentralizedWebNode",
"enc": [
"#dwn-enc"
],
"sig": [
"#dwn-sig"
],
"serviceEndpoint": [
"did:example:host",
"https://dwn.example.com"
]
}]
}
- Service Endpoints MUST contain an
id
property and it MUST be set to#dwn
. - Service Endpoints MUST contain a
type
property and it MUST be set toDecentralizedWebNode
. - Service Endpoints MUST contain a
serviceEndpoint
property and it MUST be set to one of the following:- a
string
value which represents theURL
associated with theDWN
- an array of
string
values, each of which represents theURL
associated with aDWN
- a
- If a Service Endpoint
URL
is aDID
, it MUST NOT not be followed more than 1 level deep when resolving. - Service Endpoints MUST contain an
enc
property which MUST be astring
value or an array ofstring
values, each of which represents akeyId
associated withencrypting
data. - Service Endpoints MUST contain a
sig
property which MUST be astring
value or an array ofstring
values, each of which represents akeyId
associated withsigning
data.
§ Messages
All references to this section are out of date and will need to be updated.
All Decentralized Web Node messaging is transacted via Messages JSON objects. These objects contain message execution parameters, authorization material, authorization signatures, and signing/encryption information. For various purposes Messages rely on IPLD CIDs and DAG APIs.
{ // Request Object
"messages": [ // Message Objects
{
"recordId": GENERATED_CID_STRING,
"descriptor": {
"interface": INTERFACE_STRING,
"method": METHOD_STRING,
"dataCid": DATA_CID_STRING,
"dataFormat": DATA_FORMAT_STRING,
}
},
{...}
]
}
Messages objects MUST be composed as follows:
In order to enable data replication features for a Decentralized Web Node, all Messages MUST be committed to an IPLD DAG in a tree allocated to the DID of the owner after all subtrees are composed and committed. The top-level of Message objects MUST be committed as a DAG CBOR encoded object.
- Message objects MUST contain a
recordId
property, and its value MUST be the stringified Version 1 CID of the initial entry for the logical record in question, generated by running the the following Record ID Generation Process on the initial record entry:- Create a JSON object of the following composition:
- The
recordId
CID generation object MUST contain adescriptorCid
property, and its value MUST be the stringified Version 1 CID of the DAG CBOR encodeddescriptor
object.
- The
- DAG CBOR encode the composed object.
- Generate a Version 1 CID from the DAG CBOR encoded object and output it in its stringified form.
- Create a JSON object of the following composition:
- Message objects MAY contain a
data
property, and if present its value MUST be abase64Url
encoded string of the Message’s data. - Message objects MUST contain a
descriptor
property, and its value MUST be an object composed as follows:- The object MUST contain an
interface
property, and its value MUST be a string that matches a Decentralized Web Node Interface. - The object MUST contain a
method
property, and its value MUST be a string that matches a Decentralized Web Node Interface method. - If the Message has data associated with it, passed directly via the
data
property of the Message or an external channel (e.g. IPFS fetch), thedescriptor
object MUST contain adataCid
property, and its value MUST be the stringified Version 1 CID of the DAG PB encoded data. - If the Message has data associated with it, passed directly via the
data
property of the Message object or through a channel external to the message object, thedescriptor
object MUST contain adataFormat
property, and its value MUST be a string that corresponds with a registered IANA Media Type data format (the most common being plain JSON, which is indicated by setting the value of thedataFormat
property toapplication/json
), or one of the following format strings pending registration:application/vc+jwt
- the data is a JSON Web Token (JWT) [RFC7519] formatted variant of a W3C Verifiable Credential.application/vc+ldp
- the data is a JSON-LD formatted W3C Verifiable Credential.
- The object MUST contain an
Individual Interface methods may describe additional properties that the descriptor
object MUST or MAY contain, which are detailed in the Interfaces section of the specification.
§ Message Authorization
Some messages may require authorization material for processing them in accordance with the permissions a Decentralized Web Node owner has specified. If a message requires authorization it MUST include an authorization
property with a value that is a [RFC7515] General JSON Web Signature (JWS), constructed as follows:
{ // Request Object
"messages": [ // Message Objects
"data": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"recordId": "b65b7r8n7bewv5w6eb7r8n7t78yj7hbevsv567n8r77bv65b7e6vwvd67b6",
"descriptor": {
"interface": "Records",
"method": "Write",
"schema": "https://schema.org/SocialMediaPosting",
"dataCid": CID(data),
"dateCreated": 123456789,
"dataFormat": "application/json"
},
"attestation": {
"payload": "89f5hw458fhw958fq094j9jdq0943j58jfq09j49j40f5qj30jf",
"signatures": [{
"protected": "4d093qj5h3f9j204fq8h5398hf9j24f5q9h83402048h453q",
"signature": "49jq984h97qh3a49j98cq5h38j09jq9853h409jjq09h5q9j4"
}]
},
"authorization": {
"payload": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"signatures": [{
"protected": "f454w56e57r68jrhe56gw45gw35w65w4f5i54c85j84wh5jj8h5",
"signature": "5678nr67e56g45wf546786n9t78r67e45657bern797t8r6e5"
}]
}
},
{...}
]
}
- The JWS MUST include a
protected
property, and its value must be an object composed of the following values:- The object MUST include an
alg
property, and its value MUST be the string representing the algorithm used to verify the signature (as defined by the [RFC7515] JSON Web Signature specification). - The object MUST include a
kid
property, and its value MUST be a DID URL string identifying the key to be used in verifying the signature.
- The object MUST include an
- The JWS MUST include a
payload
property, and its value must be an object composed of the following values:- The object MUST include a
descriptorCid
property, and its value MUST be the stringified Version 1 CID of the DAG CBOR encodeddescriptor
object. - The object MAY include a
permissionsGrantCid
property, and its value MUST be the stringified Version 1 CID of the DAG CBOR encoded Permission Grant being invoked. - If attestation of an object is permitted, the
payload
MAY include anattestationCid
property, and its value MUST be the stringified Version 1 CID of the DAG CBOR encodedattestation
string.
- The object MUST include a
§ Raw Data
If there is no need or desire to sign or encrypt the content of a message (i.e. public repudiable data), the message descriptor
object is the only property required in a Message (with any method-specific properties required). An optional data
property may be passed at the Message level that contains the data associated with the message (when data is desired or required to be present for a given method invocation).
{ // Message
"data": BASE64URL_STRING,
"recordId": "b65b7r8n7bewv5w6eb7r8n7t78yj7hbevsv567n8r77bv65b7e6vwvd67b6",
"descriptor": {
"interface": "Records",
"method": "Write",
"schema": "https://schema.org/InviteAction",
"dataCid": CID(data),
"dateCreated": 123456789,
"dataFormat": "application/json"
}
}
§ Signed Data
If the object is to be attested by a signer (e.g the Node owner via signature with their DID key), the object MUST contain the following additional properties to produce a [RFC7515] General JSON Web Signature (JWS):
{ // Message
"recordId": "b65b7r8n7bewv5w6eb7r8n7t78yj7hbevsv567n8r77bv65b7e6vwvd67b6",
"descriptor": {
"interface": "Records",
"method": "Write",
"schema": "https://schema.org/InviteAction",
"dataCid": CID(data),
"dateCreated": 123456789,
"dataFormat": "application/json"
},
"attestation": {
"payload": "89f5hw458fhw958fq094j9jdq0943j58jfq09j49j40f5qj30jf",
"signatures": [{
"protected": "4d093qj5h3f9j204fq8h5398hf9j24f5q9h83402048h453q",
"signature": "49jq984h97qh3a49j98cq5h38j09jq9853h409jjq09h5q9j4"
}]
}
...
}
The message generating party MUST construct the signed message object as follows:
- The Message object MUST contain an
attestation
property, and its value MUST be a General object representation of a [RFC7515] JSON Web Signature composed as follows:- The object must include a
payload
property, and its value must be the stringified Version 1 CID of the DAG CBOR encodeddescriptor
object, whose composition is defined in the Message Descriptor section of this specification. - The object MUST include a
protected
property, and its value must be an object composed of the following values:- The object MUST include an
alg
property, and its value MUST be the string representing the algorithm used to verify the signature (as defined by the [RFC7515] JSON Web Signature specification). - The object MUST include a
kid
property, and its value MUST be a DID URL string identifying the key to be used in verifying the signature.
- The object MUST include an
- The object MUST include a
signature
property, and its value must be a signature string produced by signing theprotected
andpayload
values, in accordance with the [RFC7515] JSON Web Signature specification.
- The object must include a
§ Response Objects
Responses from Interface method invocations are JSON objects that MUST be constructed as follows:
- The object MAY have a
status
property if an error is produced from a general request-related issue, and if present its value MUST be an object composed of the following properties:- The status object MUST have a
code
property, and its value MUST be an integer set to the HTTP Status Code appropriate for the status of the response. - The status object MAY have a
detail
property, and if present its value MUST be a string that describes a terse summary of the status. It is recommended that the implementer set the message text to the standard title of the HTTP Status Code, when a title/message has already been defined for that code.
- The status object MUST have a
- The object MAY have a
replies
property, and if present its value MUST be an array containing Message Result Objects for all messages that were included in the initiating request object. The Message Result Objects MUST be put in the index order that matches the index of each result’s corresponding request message. Message Result Objects are constructed as follows:- The object MUST have a
status
property, and its value MUST be an object composed of the following properties:- The status object MUST have a
code
property, and its value MUST be an integer set to the HTTP Status Code appropriate for the status of the response. - The status object MAY have a
detail
property, and if present its value MUST be a string that describes a terse summary of the status. It is recommended that the implementer set the message text to the standard title of the HTTP Status Code, when a title/message has already been defined for that code.
- The status object MUST have a
- The object MAY have a
entries
property if the message request was successful. If present, its value MUST be the resulting message entries returned from the invocation of the corresponding message.
- The object MUST have a
§ Request-Level Status Coding
If any of the scenarios described in this section are encountered during general message processing, the implementation must include a request-level status
property, and its value must be an object as defined below.
Target DID not found
If the DID targeted by a request object is not found within the Decentralized Web Node, the implementation MUST produce a request-level status
with the code 404
, and SHOULD use Target DID not found within the Decentralized Web Node
as the status detail
value.
Response Example:
{
"status": {
"code": 404,
"detail": "Target DID not found within the Decentralized Web Node"
}
}
General request-level processing errors
If a general request-level error in processing occurs that is not covered by one of the specific status cases above and prevent the implementation from correctly evaluating the request, the implementation MUST produce a request-level status
with the code 500
, and SHOULD use The request cannot not be processed
as the status detail
value.
Response Example:
{
"status": {
"code": 500,
"detail": "The request could not be processed correctly"
}
}
§ Message-Level Status Coding
If any of the scenarios described in this section are encountered during the processing of an individual message, the implementation must include a message-level status
property, and its value must be an object as defined below.
Message succeeded for query/read-type interface that expects results
If a message is processed correctly and a set of result entries
is expected, the implementation MUST include a message-level status
object with its code
property set to 200
, and SHOULD use The message was successfully processed
as the status detail
value.
If no results are found, the status
remains 200
, and the implementation MUST return an empty entries
array.
Request Example:
{ // Request Object
"messages": [ // Message Objects
{
"descriptor": {
"interface": "Records",
"method": "Query",
"schema": "https://schema.org/SocialMediaPosting"
}
},
...
]
}
Response Example:
{
"replies": [
{
"status": { "code": 200, "detail": "OK" },
"entries": [...]
}
]
}
Improperly constructed message
If a message is malformed or constructed with invalid properties/values, the implementation MUST include a message-level status
object with its code
property set to 400
, and SHOULD use The message was malformed or improperly constructed
as the status detail
value.
Request Example:
{ // Request Object
"messages": [ // Message Objects
{
"descriptorization": {
"interface": "Records",
"method": "Query",
"schemata": "https://schema.org/SocialMediaPosting"
}
}
]
}
Response Example:
{
"replies": [
{
"status": { "code": 400, "detail": "The message was malformed or improperly constructed" }
}
]
}
Message failed authorization requirements
If a message fails to meet authorization requirements during processing, the implementation MUST include a message-level status
object with its code
property set to 401
, and SHOULD use The message failed authorization requirements
as the status detail
value.
Request Example:
{ // Request Object
"messages": [ // Message Objects
{ // Message
"descriptor": {
"interface": "Records",
"method": "Write",
"recordId": "b6464162-84af-4aab-aff5-f1f8438dfc1e",
"dataCid": CID(data),
"dateCreated": 123456789,
"schema": "https://schema.org/SocialMediaPosting",
"dataFormat": "application/json"
}
^ `authorization` PROPERTY MISSING
}
]
}
Response Example:
{
"replies": [
{
"status": { "code": 401, "detail": "OK" }
}
]
}
Interface is not implemented
If a message attempts to invoke an interface method
that is not the implementation does not support, the implementation MUST include a message-level status
object with its code
property set to 501
, and SHOULD use The interface method is not implemented
as the status detail
value.
Request Example:
{ // Request Object
"messages": [ // Message Objects
{ // Message
"descriptor": {
"interface": "Records",
"method": "Write",
"recordId": "b6464162-84af-4aab-aff5-f1f8438dfc1e",
"dataCid": CID(data),
"schema": "https://schema.org/LikeAction",
"dataFormat": "application/json"
}
}
]
}
Response Example:
{
"replies": [
{
"status": {
"code": 501,
"detail": "The interface method is not implemented"
}
}
]
}
Resource consumption limit exceeded
If the DWeb Node instance receiving the request has determined that the rate of resource consumption has exceeded its tolerances and cannot process the request, the instance MUST respond with the following status entry:
Response Example:
{
"replies": [
{
"status": {
"code": 429,
"detail": "Resource consumption has exceeded tolerances"
}
}
]
}
§ Interfaces
§ Records
To maximize decentralized app and service interoperability, the Records interface of Decentralized Web Nodes provides a mechanism to store data relative to shared schemas. By storing data in accordance with a given schema, which may be well-known in a given vertical or industry, apps and services can leverage the same datasets across one another, enabling a cohesive, cross-platform, cross-device, cross-app experience for users.
§ RecordsRead
RecordsRead
messages are JSON objects that include general Message Descriptor properties and the following additional properties, which MUST be composed as follows:
- The message object MUST contain a
descriptor
property, and its value MUST be a JSON object composed as follows:- The object MUST contain an
interface
property, and its value MUST be the stringRecords
. - The object MUST contain a
method
property, and its value MUST be the stringRead
. - The object MUST contain a
messageTimestamp
property, and its value MUST be of type string property, and its value MUST be an [RFC3339] ISO 8601 timestamp that MUST be set and interpreted as the time theRecordsRead
record itself was created by the requester. - The object MUST contain a
recordId
property, and its value MUST be therecordId
of the logical record with which the entry corresponds.
- The object MUST contain an
A reference of the json schema can be found in the schemas directory of the specification.
{
"descriptor": {
"recordId": "b65b7r8n7bewv5w6eb7r8n7t78yj7hbevsv567n8r77bv65b7e6vwvd67b6",
"messageTimestamp": "2002-10-02T10:00:00-05:00Z",
"method": "Read",
"interface": "Records"
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://identity.foundation/dwn/json-schemas/records-read.json",
"type": "object",
"additionalProperties": false,
"required": [
"descriptor"
],
"properties": {
"authorization": {
"$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json"
},
"descriptor": {
"type": "object",
"additionalProperties": false,
"required": [
"interface",
"method",
"messageTimestamp",
"recordId"
],
"properties": {
"interface": {
"enum": [
"Records"
],
"type": "string"
},
"method": {
"enum": [
"Read"
],
"type": "string"
},
"messageTimestamp": {
"type": "string"
},
"recordId": {
"type": "string"
}
}
}
}
}
§ RecordsQuery
RecordsQuery
messages are JSON objects that include general Message Descriptor properties and the following additional properties, which must be composed as follows:
- The message object MUST contain a
descriptor
property, and its value MUST be a JSON object composed as follows:- The object MUST contain an
interface
property, and its value MUST be the stringRecords
. - The object MUST contain a
method
property, and its value MUST be the stringQuery
. - The object MUST contain a
messageTimestamp
property, and its value MUST be of type string property, and its value MUST be an [RFC3339] ISO 8601 timestamp that MUST be set and interpreted as the time theRecordsQuery
message was created by the requester. - The object MAY contain a
filter
property, and if present its value MUST be an object that MAY contain the following properties:- The object MAY contain a
attester
property representing the creator of theRecord(s)
did. If present its value MUST be a string in the form of a DID. - The object MAY contain a
receipient
property representing the recipient of theRecord(s)
DID If present its value MUST be a string in the form of a DID. - The object MAY contain a
schema
property, and if present its value Must be a URI string that indicates the schema of the associated data. - The object MAY contain a
recordId
property, and its value MUST be a Computed Record ID. - The object MAY contain a
parentId
property determined from the protocol definition, and if present its value MUST be a string that represents the computed record of the parent object. - The object MAY contain a
contextId
property, and its value MUST be the deterministic ID for a contextually linked set of objects. - The object MAY contain a
dateCreated
property. If present, it MUST include thefrom
andto
property described as a string range in the ISO 8601 format. - The object MAY contain a
protocol
property, and its value MUST be a URI that denotes the Protocol an object is a part of.- If the object contains a
protocol
property the object MUST also contain aprotocolVersion
property, and its value Must be a SemVer string that denotes the version of the Protocol the object is a part of.
- If the object contains a
- The object MAY contain a
dataFormat
property, and its value MUST be a string that indicates the format of the data in accordance with its MIME type designation. The most common format is JSON, which is indicated by setting the value of thedataFormat
property toapplication/json
. - The object MAY contain a
dateSort
field, and if present its value MUST be one of the following strings:createdAscending
: return results in order from the earliestdateCreated
value to the latest.createdDescending
: return results in order from the latestdateCreated
value to the earliest.publishedAscending
: return results in order from the earliestdatePublished
value to the latest.publishedDescending
: return results in order from the latestdatePublished
value to the earliest.
- The object MAY contain a
- The object MUST contain an
::: Get a single object by its ID reference:
{ // Message
"descriptor": {
"interface": "Records",
"method": "Query",
"filter": {
"recordId": "b6464162-84af-4aab-aff5-f1f8438dfc1e"
}
}
}
::: Get an object of a given schema type:
{ // Message
"descriptor": {
"interface": "Records",
"method": "Query",
"filter": {
"schema": "https://schema.org/MusicPlaylist"
}
}
}
::: Get all objects of a given schema type:
{ // Message
"descriptor": {
"interface": "Records",
"method": "Query",
"dateSort": "createdDescending",
"filter": {
"dataFormat": "image/gif"
}
}
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://identity.foundation/dwn/json-schemas/records-query.json",
"type": "object",
"additionalProperties": false,
"required": [
"descriptor"
],
"properties": {
"authorization": {
"$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json"
},
"descriptor": {
"type": "object",
"additionalProperties": false,
"required": [
"interface",
"method",
"messageTimestamp",
"filter"
],
"properties": {
"interface": {
"enum": [
"Records"
],
"type": "string"
},
"method": {
"enum": [
"Query"
],
"type": "string"
},
"messageTimestamp": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/definitions/date-time"
},
"filter": {
"type": "object",
"minProperties": 1,
"additionalProperties": false,
"properties": {
"protocol": {
"type": "string"
},
"attester": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/definitions/did"
},
"recipient": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/definitions/did"
},
"contextId": {
"type": "string"
},
"schema": {
"type": "string"
},
"recordId": {
"type": "string"
},
"parentId": {
"type": "string"
},
"dataFormat": {
"type": "string"
},
"dateCreated": {
"type": "object",
"minProperties": 1,
"additionalProperties": false,
"properties": {
"from": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/definitions/date-time"
},
"to": {
"$ref": "https://identity.foundation/dwn/json-schemas/defs.json#/definitions/date-time"
}
}
}
}
},
"dateSort": {
"enum": [
"createdAscending",
"createdDescending",
"publishedAscending",
"publishedDescending"
],
"type": "string"
}
}
}
}
}
§ RecordsWrite
RecordsWrite
messages are JSON objects that include general Message Descriptor properties and the following additional properties, which must be composed as follows:
- The message object MUST contain a
recordId
property, and its value MUST be therecordId
of the logical record the entry corresponds with. If the message is the initial entry for a new record, the value MUST be set to the resulting string from the Record ID Generation Process. - If the message object is attached to a Protocol, and its value MUST be a Computed Context ID. If the message is not attached to a Protocol, it MUST NOT contain a
contextId
property. - The message object MUST contain a
descriptor
property, and its value MUST be a JSON object composed as follows:-
The object MUST contain an
interface
property, and its value MUST be the stringRecords
. -
The object MUST contain a
method
property, and its value MUST be the stringWrite
. -
The object MUST include a
parentId
property if the currently active entry for the record is aRecordsDelete
or aCollectionWrite
that has a declared a Commit Strategy. The object MUST NOT contain aparentId
under any other circumstance. If present, the value of theparentId
property MUST be the stringified Version 1 CID of the DAG CBOR encodeddescriptor
object of the previousRecordsWrite
orRecordsDelete
entry the message is intending to overwrite. -
The object MAY contain a
protocol
property, and its value Must be a URI that denotes the Protocol an object is a part of.- If the object contains a
protocol
property the object MUST also contain aprotocolVersion
property, and its value Must be a SemVer string that denotes the version of the Protocol the object is a part of.
- If the object contains a
-
The object MAY contain a
schema
property, and if present its value Must be a URI string that indicates the schema of the associated data and MUST be treated as an immutable value for the lifetime of the logical record. -
The object MAY contain a
commitStrategy
property, and if present its value Must be a string from the table of registered Commit Strategies. -
The object MAY contain a
published
property, and if present its value Must be a boolean indicating the record’s publication state. A value oftrue
indicates the record has been published for public queries and consumption without requiring authorization. A value offalse
or the absence of the property indicates the record MUST NOT be served in response to public queries that lack proper authorization. -
The object MAY contain an
encryption
property; the object MUST contain theencryption
property if the data is encrypted. The absence of this property indicates the data is not encrypted. If present, its value MUST be a JSON object composed as follows:- The object MUST contain an
algorithm
string property denoting the symmetric encryption algorithm used to encrypt this message. Use the algorithm list names published in the IANA JOSE Algorithms registry. - The object MUST contain an
initializationVector
property and its value MUST be abase64Url
encoded string of the initialization vector used for the symmetric encryption. - The object MUST contain a
keyEncryption
property and its value MUST be an array of encrypted key objects described as follows:- The object MUST contain a
derivationScheme
property and it MUST have one of the following values:protocolPath
protocolContext
- The object MUST contain a
rootKeyId
property and it MUST have a string value representing the fully qualified key ID of the root key used in deriving the public key that encrypts the symmetric encryption key. - The object MUST contain an
algorithm
string property denoting the asymmetric encryption algorithm used to encrypt the symmetric encryption key. - The object MAY contain other custom properties needed by the encryption chosen algorithm, such as
ephemeralPublicKey
,initializationVector
,messageAuthenticationCode
, etc. - The object MUST contain an
encryptedKey
property and its value MUST be abase64Url
encoded string of the encrypted symmetric key used to encrypt the data. - The object MAY contain a
derivedPublicKey
property; if present its value MUST be an object representing the derived public key used to encrypt the symmetric key in JWK format as per [RFC7517].
- The object MUST contain a
- The object MUST contain an
-
The object MUST contain a
dateCreated
property, and its value MUST be an [RFC3339] ISO 8601 timestamp that MUST be set and interpreted as the time theRecordsWrite
was created by the DID owner or another permitted party. -
The object MAY contain a
datePublished
property; if present, its value MUST be an [RFC3339] ISO 8601 timestamp that MUST be set and interpreted as the time theRecordsWrite
was published by the DID owner or another permitted party.
-
{ // Message
"recordId": "b65b7r8n7bewv5w6eb7r8n7t78yj7hbevsv567n8r77bv65b7e6vwvd67b6",
"descriptor": { // Message Descriptor
"parentId": CID(PREVIOUS_DESCRIPTOR),
"dataCid": CID(data),
"dateCreated": 123456789,
"published": true,
"encryption": "jwe",
"interface": "Records",
"method": "Write",
"schema": "https://schema.org/SocialMediaPosting",
"commitStrategy": "json-merge",
"dataFormat": DATA_FORMAT
}
}
§ RecordsSubscribe
TODO
§ RecordsDelete
RecordsDelete
messages are JSON objects that include general Message Descriptor properties and the following additional properties, which must be composed as follows:
-
The object MUST contain a
prune
property, and its value MUST be a boolean indicating whether to purge any children records (true
) or to only tombstone the deleted record (false
). -
The message object MUST contain a
descriptor
property, and its value MUST be a JSON object composed as follows:- The object MUST contain an
interface
property, and its value MUST be the stringRecords
. - The object MUST contain a
method
property, and its value MUST be the stringDelete
. - The object MUST contain a
recordId
property, and its value MUST be therecordId
of the logical record the entry corresponds with. - The object MUST contain a
prune
property, and its value MUST be a boolean that signals whether descendent records should be pruned. - The object MUST contain a
messageTimestamp
property, and its value MUST be of type string property, and its value MUST be an [RFC3339] ISO 8601 timestamp that MUST be set and interpreted as the time theRecordsDelete
record itself was created by the requester.
- The object MUST contain an
::: Sample Records Delete
{
"descriptor": {
"recordId": "b65b7r8n7bewv5w6eb7r8n7t78yj7hbevsv567n8r77bv65b7e6vwvd67b6",
"messageTimestamp": "2002-10-02T10:00:00-05:00Z",
"interface": "Records",
"method": "Delete",
"prune": false
}
}
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://identity.foundation/dwn/json-schemas/records-delete.json",
"type": "object",
"additionalProperties": false,
"required": [
"authorization",
"descriptor"
],
"properties": {
"authorization": {
"$ref": "https://identity.foundation/dwn/json-schemas/authorization-delegated-grant.json"
},
"descriptor": {
"type": "object",
"additionalProperties": false,
"required": [
"interface",
"method",
"messageTimestamp",
"recordId",
"prune"
],
"properties": {
"interface": {
"enum": [
"Records"
],
"type": "string"
},
"method": {
"enum": [
"Delete"
],
"type": "string"
},
"messageTimestamp": {
"type": "string"
},
"recordId": {
"type": "string"
},
"prune": {
"type": "boolean"
}
}
}
}
}
§ Computed Context IDs
Detail how IDs are computed for record contexts.
§ Retained Record Processing
Retained messages in the Records interface are those that may be stored against the specific record they are associated with. Within the Records interface the RecordsWrite
, RecordsCommit
, RecordsDelete
messages are among the set that may be retained to determine the history and current data state of a record. A conforming implementation MUST perform the following steps to process retained messages:
§ If the message is a RecordsWrite
:
- Generate the message’s Entry ID by performing the Record ID Generation Process.
- IF the generated Entry ID matches the
recordId
value of the message –- IF Initial Entry exists for a record, store the entry as the Initial Entry for the record
- IF no Initial Entry exists and cease any further processing.
- ELSE the message may be an overwriting entry for the record; continue processing.
- IF the generated Entry ID matches the
- If a message is not the Initial Entry, its
descriptor
MUST contain aparentId
to determine the entry’s position in the record’s lineage. If aparentId
is present proceed with processing, else discard the record and cease processing. - Ensure all immutable values from the Initial Entry remained unchanged if present in the inbound message. If any have been mutated, discard the message and cease processing.
- Retrieve the Latest Checkpoint Entry, which will be either the Initial Entry or the latest
RecordsDelete
, and compare theparentId
value of the inbound message to the Entry ID of the Latest Checkpoint Entry derived from running the Record ID Generation Process on it. If the values match, proceed with processing, if the values do not match discard the message and cease processing. - If an existing
RecordsWrite
entry linked to the Latest Checkpoint Entry is not present and thedateCreated
value of the inbound message is greater than the Latest Checkpoint Entry, store the message as the Latest Entry and cease processing, else discard the inbound message and cease processing. - If an exiting
RecordsWrite
entry linked to the Latest Checkpoint Entry is present all of the following conditions must be true: - If all of the following conditions for Step 6 are true, store the inbound message as the Latest Entry and discard the existing
RecordsWrite
entry that was attached to the Latest Checkpoint Entry.
§ If the message is a RecordsDelete
:
- Ensure the record specified by the inbound message’s
recordId
exists. If it does not, discard the message and cease processing. - Ensure all immutable values from the Initial Entry remained unchanged if present in the inbound message. If any have been mutated, discard the message and cease processing.
- Fetch the active
RecordsDelete
entry that exists for the record. If no such entry is present, proceed to the next step. If an activeRecordsDelete
entry for the record is present, thedateCreated
value of the inbound message MUST be greater than the activeRecordsDelete
entry; if it is not, discard the message and cease processing. - Store the message as the Latest Checkpoint Entry, delete all messages back to the Initial Entry, including their data, and cease processing.
- If the
descriptor
propertyprune
is set to the valuetrue
, delete all the descendent messages associated with therecordId
.
§ Protocols
DWeb Nodes are designed to act the substrate upon which a wide variety of decentralized applications and services can be written. With an interface like Records alone, a DWeb Node owner and those they permission can write isolated records, but that alone is not enough to support and facilitate decentralized apps. Protocols introduces a mechanism for declaratively encoding an app or service’s underlying protocol rules, including segmentation of records, relationships between records, data-level requirements, and constraints on how participants interact with a protocol. With the DWeb Node Protocols mechanism, one can model the underpinning protocols for a vast array of use cases in a way that enables interop-by-default between app implementations that ride on top of them.
§ ProtocolsConfigure
ProtocolsConfigure
messages are JSON objects that include general Message Descriptor properties and the following additional properties, which must be composed as follows:
{
"interface": "Protocols", // required
"method": "Configure", // required
"protocolVersion": "1.0.0", // required
"definition": { PROTOCOL_DEFINITION_OBJ }, // optional
}
- The message object MUST contain a
recordId
property, and its value MUST be therecordId
of the logical record the entry corresponds with. - The message object MUST contain a
descriptor
property, and its value MUST be a JSON object composed as follows:- The object MUST contain an
interface
property, and its value MUST be the stringProtocols
. - The object MUST contain a
method
property, and its value MUST be the stringConfigure
. - The object MUST contain a
definition
property, and its value Must be a Protocol Definition object.
- The object MUST contain an
§ Protocol Definitions
Protocol Definition objects are declarative rules within ProtocolConfigure
messages that specify the types, relationships, and interactions that are permitted under a given protocol installed in a DWeb Node. Inbound callers who wish to interact with a protocol must adhere to these rules, which DWeb Nodes enforce.
{
"interface": "Protocols",
"method": "Configure",
"definition": {
"protocol": "https://decentralized-social-example.org/protocol/",
"published": true,
"types": {
"post": {
"schema": "https://decentralized-social-example.org/schemas/post",
"dataFormat": ["application/json"],
},
"reply": {
"schema": "https://decentralized-social-example.org/schemas/reply",
"dataFormat": ["application/json"],
},
"image": {
"dataFormat": ["image/jpeg", "image/png", "image/gif"],
}
},
"structure": {
"post": {
"$actions": [{
"who": "anyone",
"can": "read",
}],
"reply": {
"$actions":[{
"who": "anyone",
"can": "write",
}],
"image": {
"$actions": [{
"who": "anyone",
"can": "read",
},{
"who": "author",
"of": "reply",
"can": "write",
}]
}
},
"image": {
"$actions":[{
"who": "anyone",
"can": "read",
}, {
"who": "author",
"of": "post",
"can": "write",
}]
}
}
}
}
}
- The Protocols Definition object MUST contain a
protocol
property, and its value Must be a URI that denotes the Protocol the configuration pertains to. - The Protocols Definition MUST contain a
published
property, and its value Must be a boolean indicating theProtocolConfiguration
’s publication state. - The Protocols Definition object MUST contain a
types
property, and its value MUST be an object composed as follows:- The keys of the object MUST be a string that represents the underlying type.
- The values representing those keys within the object MUST be an object composed as follows:
- The object MUST contain a
dataFormats
property, and its value MUST be an array of strings that indicate the format of the data in accordance with its MIME type designation. The most common format is JSON, which is indicated by setting the value of thedataFormats
property to['application/json]
. - The object MAY contain a
schema
property, and if present its value MUST be a valid URI string that identifies the protocol the definition pertains to.
- The object MUST contain a
- The Protocols Definition object MUST contain a
structure
property, and its value MUST be a Record Rules object whose keys match the labels defined in the Protocols Definition object. This object is recursive, allowing subsequent record relationships to be defined within. Labeled members of the object are composed as follows:- The keys of the object MUST be a string that matches one of the
types
- The values representing those keys within the object MUST be an object composed as follows:
-
The object MAY contain an
$actions
property and its value MUST be an array of rule set objects described as follows:- The object MUST contain a
who
property and it MUST have one of the following values:anyone
author
recipient
- The object MUST contain a
can
property and it MUST have a value of eitherread
orwrite
- The object MAY contain a
of
property and it MUST have a string value that references one of thetypes
- The object MUST contain a
-
The object MAY contain an
$encryption
property to enable record encryption using the Protocol Path derivation scheme. If present, its value MUST be an object composed as follows:- The object MUST contain a
publicKeyJwk
property representing a public key as per [RFC7517]. This is the public key that a sender uses to encrypt the symmetric private key used to encrypt the Decentralized Web Node message. - The object MUST contain a
rootKeyId
property and it MUST be the fully qualified key ID of the root key used to derive thepublicKeyJwk
using the protocol-path key derivation scheme.
- The object MUST contain a
-
- The keys of the object MUST be a string that matches one of the
§ Processing Instructions
When processing a ProtocolsConfigure
message, a conforming implementation MUST perform the following steps:
- If the message has a
lastConfiguration
property, ensure the referenced CID value links to a valid previous configuration for the specified protocol + version; - If the message:
2a. Does not contain a
protocolDefinition
property, process the configuration as if the protocol + version is closed for interaction. 2b. Does contain aprotocolDefinition
property, perform any indexing, setup, or optimization processes required to begin enforcing it within the implementation. - Store the configuration.
§ ProtocolsQuery
The ProtocolsQuery
interface method allows an outside entity to query for any active protocols the owner has an active configuration for.
{
"interface": "Protocols",
"method": "Query",
"filter": {
"protocol": "identity.foundation/protocols/credential-issuance",
"versions": ["1.0.0", "2.0.0"]
}
}
§ Decentralized Web Node Protocol Languague
Please see the following JSON Schema to describe the DWN Protocol Language:
- The protocol MUST have a
protocol
property, which represents a URI that uniquely identifies the protocol. - The protocol MAY have a
published
property. Published attribute indicates whether theprotocol
should be public. - The protocol MUST have a
types
section, which represents a set of objects, with their intended data format.- Each type MUST have a
schema
property, which MAY represent a resolvable URI for a JSON Schema of the object. For example, the post object MAY resolve to https://social-media.xyz/schemas/postSchema. - Each type MUST have a
dataFormats
property, which MUST be an array of size at least 1. ThesedataFormats
are recommended to be of the IANA Media Types, for exampletext/plain
orapplication/json
.
- Each type MUST have a
- The protocol MUST have a
structure
section. The structure section defines the interaction rules of the protocol, and it must be a set of objects.- Each object in the structure has the following properties:
- It MUST have an
$actions
property. The$actions
property is an object that describes the interaction rules of the object. The$actions
property MUST have the following definition: - It MUST have a
who
property, which MUST be set to one of the following values:anyone
author
recipient
.
- It MUST have an
of
property, which is a string property that represents the scope of the$action
. For example,anyone OF post
means that anyone scoped to thepost
object. - It MUST have an
can
property, which MUST be one of the following values:create
delete
query
subscribe
read
updated
co-delete
co-update
::: Protocol Definition Structure – JSON Schema
{
"$id": "https://identity.foundation/dwn/json-schemas/protocol-definition.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"required": [
"protocol",
"published",
"types",
"structure"
],
"properties": {
"protocol": {
"type": "string"
},
"published": {
"type": "boolean"
},
"types": {
"type": "object",
"patternProperties": {
".*": {
"type": "object",
"additionalProperties": false,
"properties": {
"schema": {
"type": "string"
},
"dataFormats": {
"type": "array",
"minItems": 1,
"items": {
"type": "string"
}
}
}
}
}
},
"structure": {
"type": "object",
"patternProperties": {
".*": {
"$ref": "https://identity.foundation/dwn/json-schemas/protocol-rule-set.json"
}
}
}
}
::: Protocol Rule Set – JSON Schema
{
"$id": "https://identity.foundation/dwn/json-schemas/protocol-rule-set.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"properties": {
"$encryption": {
"type": "object",
"additionalProperties": false,
"properties": {
"rootKeyId": {
"type": "string"
},
"publicKeyJwk": {
"$ref": "https://identity.foundation/dwn/json-schemas/public-jwk.json"
}
}
},
"$actions": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"oneOf": [
{
"required": [
"who",
"can"
],
"additionalProperties": false,
"properties": {
"who": {
"type": "string",
"enum": [
"anyone",
"author",
"recipient"
]
},
"of": {
"type": "string"
},
"can": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"enum": [
"co-delete",
"co-update",
"create",
"delete",
"read",
"update"
]
}
}
}
},
{
"required": [
"role",
"can"
],
"properties": {
"role": {
"$comment": "Must be the protocol path of a role record type",
"type": "string"
},
"can": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"enum": [
"co-delete",
"co-update",
"create",
"delete",
"query",
"subscribe",
"read",
"update"
]
}
}
}
}
]
}
},
"$role": {
"$comment": "When `true`, this turns a record into `role` that may be used within a context/sub-context",
"type": "boolean"
},
"$size": {
"type": "object",
"additionalProperties": false,
"properties": {
"min": {
"type": "number",
"minimum": 0
},
"max": {
"type": "number",
"minimum": 0
}
}
}
},
"patternProperties": {
"^[^$].*": {
"$ref": "https://identity.foundation/dwn/json-schemas/protocol-rule-set.json"
}
}
}
§ Sync
The Sync interface and its methods allow different Decentralized Web Nodes to communicate and sync on the state of the data they contain, including replication of messages and files.
§ Permissions
Detail how Permissions are requested, granted, revoked and processed
Permissions are managed via a first-class DWN protocol https://tbd.website/dwn/permissions
with the following definition:
{
"published":true,
"protocol":"https://tbd.website/dwn/permissions",
"types":{
"request":{
"dataFormats":[
"application/json"
]
},
"grant":{
"dataFormats":[
"application/json"
]
},
"revocation":{
"dataFormats":[
"application/json"
]
}
},
"structure":{
"request":{
"$size":{
"max":10000
},
"$actions":[
{
"who":"anyone",
"can":[
"create"
]
}
]
},
"grant":{
"$size":{
"max":10000
},
"$actions":[
{
"who":"recipient",
"of":"grant",
"can":[
"read",
"query"
]
}
],
"revocation":{
"$size":{
"max":10000
},
"$actions":[
{
"who":"anyone",
"can":[
"read"
]
}
]
}
}
}
}
§ PermissionRequest
Detail PermissionRequests
§ PermissionGrant
Detail PermissionGrant
§ PermissionRevocation
Detail PermissionRevocation
§ Encryption
Each Decentralized Web Node (DWN) supports encryption at the individual message level. Encryption of data is performed using a symmetric key unique to each message. The symmetric key is then encrypted with one or more public keys derived using the HMAC-based Key Derivation Function as specified in [RFC5869] together with one of the key derivation path schemes defined in this specification. Each key derivation path scheme is optimized for a particular usage pattern of the Decentralized Web Node. Application and protocol developers can select schemes that best fit their requirements.
Encrypted messages must include an encryption
property. This property contains the encrypted symmetric key(s) and metadata related to asymmetric key derivation. The encryption
property allows the recipient, who possesses the corresponding private key, to decrypt the symmetric key and, consequently, the message data itself. For complete details on the encryption
property, refer to RecordsWrite.
To enable encryption within a protocol, developers must declare the $encryption
property in the protocol’s definition as detailed in Protocol Definitions.
§ Key Derivation Path Schemes
§ Protocol Path Scheme
This scheme enables the owner of a Decentralized Web Node to derive and specify public keys at each level of the protocol path hierarchy, facilitating incoming encrypted communication from others without the need for additional bootstrapping.
Due to the hierarchical nature of the keys, the private key corresponding to any given protocol path can decrypt all records in the descending protocol paths. This feature allows protocol designers to strategically distribute the private key at specific protocol path levels based on their specific requirements.
The hierarchical derivation path segments of this scheme must follow the structure:
["protocolPath", <protocol-url>, <root-level-record-type>, <next-level-record-type>, ...]
§ Protocol Context Scheme
This scheme allows the initiator of a new record context to derive and specify a public key that encrypts all symmetric keys within the context. The holder of the corresponding context derived private key can decrypt all messages within the context.
Under this scheme, a recommended pattern for distributing the private key to a participant is to include the encrypted private key in the participant’s role record itself. This encryption uses the public key declared in the recipient’s own instance of the configuration of the same protocol. This approach ensures that all essential cryptographic materials remain within the record context hierarchy.
The derivation path segments of this scheme must use the structure below:
["protocolContext", <root-context-id>]
§ Supported Encryption Schemes
A conforming implementation MUST be capable of encrypting and decrypting data stored in Decentralized Web Nodes using the following combinations of cryptographic schemes. Each scheme is a pair, wherein the symmetric keys are used to encrypt the data being protected, then subsequently shared with permitted recipients via encryption of the symmetric keys using the asymmetric key of each recipient.
Asymmetric Key | Symmetric Key |
---|---|
ECIES-ES256K |
AES-CTR |
X25519 |
AES-GCM |
X25519 |
XSalsa20-Poly1305 |
§ Supported Encryption Formats
A conforming implementation MUST be capable of encrypting and decrypting data stored in Decentralized Web Nodes using the following combinations of cryptographic schemes. Each scheme is a pair, wherein the symmetric keys are used to encrypt the data being protected, then subsequently shared with permitted recipients via encryption of the symmetric keys using the asymmetric key of each recipient.
Label | Format |
---|---|
jwe |
AES-GCM |
X25519 |
XSalsa20-Poly1305 |
§ Normative References
- RFC3339
- Date and Time on the Internet: Timestamps. G. Klyne; C. Newman; 2002-07. Status: Proposed Standard.
- RFC5869
- HMAC-based Extract-and-Expand Key Derivation Function (HKDF). H. Krawczyk; P. Eronen; 2010-05. Status: Informational.
- RFC7515
- JSON Web Signature (JWS). M. Jones; J. Bradley; N. Sakimura; 2015-05. Status: Proposed Standard.
- RFC7517
- JSON Web Key (JWK). M. Jones; 2015-05. Status: Proposed Standard.
- RFC7519
- JSON Web Token (JWT). M. Jones; J. Bradley; N. Sakimura; 2015-05. Status: Proposed Standard.