<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC7230 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7230.xml">
<!ENTITY RFC7519 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7519.xml">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<?rfc strict="yes" ?>
<?rfc toc="yes" ?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc rfcedstyle="no" ?>
<?rfc iprnotified="no" ?>
<?rfc colonspace="yes" ?>
<rfc category="std" docName="draft-wendt-modern-drip-01" ipr="trust200902">

 <front>
   <title abbrev="DRiP">Distributed Registry Protocol</title>

   <author fullname="Harsha Bellur" initials="H." surname="Bellur">
     <organization>Comcast</organization>

     <address>
       <postal>
         <street>One Comcast Center</street>
         <city>Philadelphia</city>
         <region>PA</region>
         <code>19103</code>
         <country>USA</country>
       </postal>
       <email>Harsha_Bellur@cable.comcast.com</email>
     </address>
   </author>

   <author fullname="Chris Wendt" initials="C." surname="Wendt" role="editor">
     <organization>Comcast</organization>

     <address>
       <postal>
         <street>One Comcast Center</street>
         <city>Philadelphia</city>
         <region>PA</region>
         <code>19103</code>
         <country>USA</country>
       </postal>
       <email>chris-ietf@chriswendt.net</email>
     </address>
   </author>

   <date month="July" year="2016" />

   <area>ART</area>

   <workgroup>Internet Engineering Task Force</workgroup>

   <keyword></keyword>

   <abstract>
     <t>This document describes a protocol for allowing a distributed set of nodes to synchronize a set of information in real-time with minimal amount of delay. This is useful for registry types of information like identity and telephone numbers with associated routing and ownership information and could be extended to support other distributed real-time information updates as well.</t>
   </abstract>
 </front>

 <middle>
   <section title="Introduction">
     <t>This document describes the Distributed Registry Protocol (DRiP).  DRiP defines a set of peer protocols for how an arbitrary number of nodes arranged in a distributed mesh architecture can be used to synchronize data in real-time across a network.</t>
     
     <section title="Terminology">
       <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in <xref target="RFC2119">RFC 2119</xref>.</t>
       <t>
         <list style="hanging" hangIndent='6'>
           <t hangText="Initiator Node:">
             <vspace />
             A node that initiates data propagation.</t>
           <t hangText="Receiver Node:">
             <vspace />
             A node that forwards the propagated key-value data.</t>
         </list>
       </t>
     </section>
   </section>
     
   <section title="DRiP Overview" anchor="drip_overview">
     <t>DRiP uses a mix of a gossip protocol with update counters for distribution of key-value data with the addition of a voting system to avoid race conditions on writing of key-value data.</t>
   </section>
       
   <section title="Distributed MESH Architecture" anchor="distributed_mesh_architecture">
     <t>The DRiP architecture is based on a peer-to-peer communication model where a given node associated with a data store is not necessarily aware of the total number of nodes in the entire network. Minimally, every node should reachable by at least one multi-node path from every other node. Each node in the DRiP network maintains a list of peer nodes from which it receives and transmits updates. Information is propagated by forwarding to it's peer nodes until the information received by a node has already been received.</t>
     <figure align="center">
       <artwork align="left"> <![CDATA[
 ___           ___                         ___           ___ 
|DB |_________|DB |                       |DB |_________|DB |
|___|         |___|                       |___|         |___|
  |   Data      |                           |   Data      |  
  |   Store     |                           |   Store     |  
 _|_  Cluster  _|_                         _|_  Cluster  _|_ 
|DB |_________|DB |                       |DB |_________|DB |
|___|         |___|                       |___|         |___|
                  \                       /
                   \                     /
                   _\___     DRIP     _ /__
                  |Node |------------|Node |
                  |  A  |    HTTPS   |  C  |
                  |_____|            |_____|
                      \H           H/
                      D\T         T/D
                       R\T       P/R 
                        I\P     P/I  
                         P\S   S/P   
                         __\__ /   DRIP     _____  
                        |Node |------------|Node |
                        |  B  |   HTTPS    |  D  |
                        |_____|            |_____|
                       /                   /
    ___           ___ /                 __/_          ___ 
   |DB |_________|DB |                 |DB |_________|DB |
   |___|         |___|                 |___|         |___|
     |   Data      |                     |   Data      |  
     |   Store     |                     |   Store     |  
    _|_  Cluster  _|_                   _|_  Cluster  _|_ 
   |DB |_________|DB |                 |DB |_________|DB |
   |___|         |___|                 |___|         |___|
       ]]></artwork>
       <postamble>Distributed Mesh Architecture</postamble>
     </figure>
   </section>
   <section title="DRiP procedures" anchor="drip_procedures">
     <section title="Distributed Registry Rules" anchor="distributed_registry_rules">
       <t>All nodes in the distributed mesh MUST agree upon a specific key-value data model. The choice of data store is implementation specific.</t>
       <t>All nodes MUST be configured with at least one peer node before propagation.</t>
       <t>A node MUST ignore any updates or commands it receives from other nodes that are not configured as peer nodes.</t>
       <t>All nodes MUST send a periodic heartbeat or keep-alive message via HTTPS to the respective peer nodes. If a heartbeat is not received the peer node is removed from the list of active peer nodes.</t>
     </section>
     <section title="Node State" anchor="node_state">
       <t>The peer node should maintain a state that defines whether it is active, inactive, or synchronizing key-value data with a peer node.</t>
       <t>The node should proactively tell it's peer nodes its state by sending the following POST messages.  The GET query is available for nodes to query the state of peer nodes.</t>
       	<section title="API - POST /node/:nodeid/active" anchor="post_node_nodeid_active">
			<t>Example (using cURL)</t>
			<t>Request</t>
			<figure>
				<artwork> <![CDATA[
	$ curl -i -H "DRiP-Node-ID: nodeA" -H "Authorization: eyJ0e..."
  	    -X POST https://nodearegistry.com/node/nodeA/active
				]]></artwork>
			</figure>
			<t>Response</t>
			<figure>
				<artwork> <![CDATA[
	HTTP/1.1 200 OK
				]]></artwork>
			</figure>          
       </section>
       <section title="API - POST /node/:nodeid/inactive" anchor="post_node_nodeid_inactive">
			<t>Example (using cURL)</t>
			<t>Request</t>
			<figure>
				<artwork> <![CDATA[
	$ curl -i -H "DRiP-Node-ID: nodeA" -H "Authorization: eyJ0e..."
  	    -X POST https://nodearegistry.com/node/nodeA/inactive
				]]></artwork>
			</figure>
			<t>Response</t>
			<figure>
				<artwork> <![CDATA[
	HTTP/1.1 200 OK
				]]></artwork>
			</figure>  
       </section>
       <section title="API - GET /state" anchor="get_state">
         <t>Description:</t>
         <t>A node should query the state of its peer node before it initiates a sync operation. This request responds with either "active" or "sync" or no response, if in "inactive" state.</t>
			<t>Example (using cURL)</t>
			<t>Request</t>
			<figure>
				<artwork> <![CDATA[
	$ curl -i -H "DRiP-Node-ID: nodeA" -H "Authorization: eyJ0e..."
  	    -X GET https://nodearegistry.com/state
				]]></artwork>
			</figure>
			<t>Response</t>
			<figure>
				<artwork> <![CDATA[
	HTTP/1.1 200 OK with the following JSON object.
				]]></artwork>
			</figure>     
			<texttable>
         		<ttcol align="center" width="20%">Property</ttcol>
         		<ttcol align="left">Description</ttcol>
         		<c>state</c>
         		<c>"active" or "inactive" or "sync"</c>
       		</texttable>   
		 </section>
     </section>
     <section title="Custom HTTP header fields" anchor="custom_http_header_fields">
       <t>Custom HTTP header fields will be used to carry node specific information.</t>
       <texttable>
         <ttcol align="center" width="20%">Field Name</ttcol>
         <ttcol align="left">Description</ttcol>
         <c>DRiP-Node-ID</c>
         <c>Each node in the mesh MUST have a unique identifier. An Initiator node MUST set its own node ID as the field value. A Receiver Node MUST NOT change the DRiP-Node-ID field value as it forward the HTTPS request to its peer nodes.</c>
       </texttable>
       <t>
         <list style="hanging" hangIndent='6'>
           <t hangText="Example:">
             <vspace />
             DRiP-Node-ID: xyz</t>
         </list>
       </t>
       <texttable> 
         <ttcol align="center" width="20%">Field Name</ttcol>
         <ttcol align="left">Description</ttcol>
         <c>DRiP-Node-Counter</c>
         <c>Every node maintains a count of the number of times it initiates key-value data propagation. This counter MUST be an unsigned type, typically, a 64 bit integer. The Initiator node MUST set this count as the field value. A Receiver Node MUST NOT change the DRiP-Node-Counter field value as it forward the HTTPS request to its peer nodes.</c>
       </texttable>
       <t>
         <list style="hanging" hangIndent='6'>
           <t hangText="Example:">
             <vspace />
             DRiP-Node-Counter: 123</t>
         </list>
       </t>
       <texttable> 
         <ttcol align="center" width="20%">Field Name</ttcol>
         <ttcol align="left">Description</ttcol>        
         <c>DRiP-Node-Counter-reset</c>
         <c>A node can reset the count (to zero) of the number of times it initiates key-value data propagation. If the counter value is reset, prior to initiating data propagation, then this field value MUST be set to true. Otherwise, it MUST be set to false, at all times. A typical use case to reset the counter value is when the counter (of unsigned type) value wraps around. The Initiator node MUST set this field value to either true or false. A Receiver Node MUST NOT change the DRiP-Node-Counter-reset field value as it forward the HTTPS request to its peer nodes.</c>
       </texttable>
       <t>
         <list style="hanging" hangIndent='6'>
           <t hangText="Example:">
             <vspace />
             DRiP-Node-Counter-reset: false</t>
         </list>
       </t>
       <texttable> 
         <ttcol align="center" width="20%">Field Name</ttcol>
         <ttcol align="left">Description</ttcol>         
         <c>DRiP-Transaction-Type</c>
         <c>The Initiator node MUST set this field value to be either "update" or "sync". A Receiver Node MUST NOT change the DRiP-Transaction-Type field value as it forward the HTTPS request to its peer nodes.</c>
       </texttable>
       <t>
         <list style="hanging" hangIndent='6'>
           <t hangText="Example:">
             <vspace />
             DRiP-Transaction-Type: update</t>
         </list>
       </t>
       <texttable> 
         <ttcol align="center" width="20%">Field Name</ttcol>
         <ttcol align="left">Description</ttcol> 
         <c>DRiP-Sync-Complete</c>
         <c>For sync transaction type, the Initiator node MUST set this field value to be true, if synchronization is complete. Otherwise, this field value MUST be set to false.</c>
       </texttable>
       <t>
         <list style="hanging" hangIndent='6'>
           <t hangText="Example:">
             <vspace />
             DRiP-Sync-Complete: false</t>
         </list>
       </t>
     </section>
     <section title="Key-Value Data Propagation Rules" anchor="key-value_data_propagation_rules">
       <t>A node propagates key-value data to all its peer nodes except the the node from which it received data. For example, in Figure 1, when node B receives key-value data from node A, it will propagate the data received to nodes C and D but not back to node A.</t>
       <t>For each transaction type (Update or Sync), the following set of actions MUST take place when a node receives a HTTPS request with propagated key-value data:</t>
       <t>
         <list style="symbols">
           <t>If DRiP-Node-ID field value (in the HTTP header) contains Initiator node ID that has never been seen, both DRiP-Node-ID and DRiP-Node-Counter field values MUST be stored for future reference and the key-value data is propagated to all peer nodes.</t>
           <t>If DRiP-Node-ID field value (in the HTTP header) matches with a stored node ID and DRiP-Node-Counter-reset field value is false.
             <list style="symbols">
               <t>The received key-value data MUST be propagated to the peer nodes if DRiP-Node-Counter field value is greater than the saved counter value. The DRiP-Node-Counter field value MUST be saved as the new counter for the stored node ID.</t>
               <t>If DRiP-Node-Counter field value is less than or equal to saved counter value, then the key-value data has already been received and MUST NOT be propagated to peer nodes. This ensures that propagation stops when all nodes have received the key-value data from the Initiator node.</t>
             </list>
           </t>
           <t>If DRiP-Node-ID field value matches with a stored node ID and DRiP-Node-Counter-reset field value is true:
             <list style="symbols">
               <t>The received key-value data MUST be propagated to the peer nodes. The DRiP-Node-Counter field value MUST be saved as the new counter for the stored node ID.</t>
             </list>
           </t>
         </list>
       </t>
     </section>
     <section title="Key-Value Data Update" anchor="key-value_data_update">
       <t>When an Initiator node has new data it wants to propagate to the distributed mesh, it initiates an Update. The Update consists of a two-phase commit (2PC) procedure in order to guarantee there are no race conditions for updating the same key's data, as well as for any error conditions in the distributed mesh that would cause the update to not complete for all nodes in the network.</t>
       <t>The two phases are called the "voting" phase and the "commit" phase.</t>
       <figure align="center">
         <artwork align="center"> <![CDATA[
                          _________ 
 ----------------------->|         |
|                        | Waiting |
|                        | For     |
|   ---------------------| Events  |
|  | (Update,            |_________|
|  |  Start Timer)           
|  |                            --------------------------------  
|  |                           | Received Update From Peer Node |
|  |                           |                                |
|  |             ______________|_  If key matches an            |
|  |            |                |  in-progress update          |
|   ----------->|                |  vote "no".                  |
|               | Waiting For    |  Otherwise, vote "yes".      |
|               | Response From  |                              |
|               | Peer Nodes     |<-----------------------------
|               |                |                                
|           ----|                |----                            
|  Timer   |    |________________|    |                           
|  Expired |                          | Received Votes
|          |                          | From All Peer 
|          |                          | Nodes         
|          |      _______________     |
|          |    |                |    |
|          |    |                |    |
|           --->|                |<---
|               |  Validating    |    
| (If all Votes |  Votes         |    
|  are "YES",   |                |    
| propagate     |                |        
| commit)       |                |        
 ---------------|________________|              
         ]]></artwork>
         <postamble>Update State Diagram</postamble>
       </figure>
       <section title="Voting Phase" anchor="voting_phase">
         <t>The voting phase is the phase where all nodes are queried to "vote" whether they are aware of any potential conflict that would cause the transaction not to complete.</t>
         <t>The Initiator node MUST set a timeout period to get response from its peer nodes.</t>
         <t>The peer nodes known to the initiator node will continue propagate the information to their peer nodes and so on. However, these peer nodes beyond the initiator node will no longer need to keep track of the time interval for responses. A node will stop continuing to propagate information when it determines it has received the same information again. This can be determined by keeping track of the counter and originating node id.</t>
         <t>If all peer nodes vote "yes", then the second phase or commit phase in the local node is initiated. If any node in the distributed mesh votes "no" or if the timeout period expires and all peer nodes have not responded, then the commit of the information MUST NOT be completed. No action is taken for responses received after the timeout period.</t>
         <t>Note: The voting procedure is intentionally split into two separate full HTTP transactions for reliability.</t>
         <figure align="center">
           <artwork align="center"> <![CDATA[
 ___           ___      ___           ___      ___           ___ 
|DB |_________|DB |    |DB |_________|DB |    |DB |_________|DB |
|___|         |___|    |___|         |___|    |___|         |___|
  |   Data      |        |   Data      |        |   Data      |  
  |   Store     |        |   Store     |        |   Store     |  
 _|_  Cluster  _|_      _|_  Cluster  _|_      _|_  Cluster  _|_ 
|DB |_________|DB |    |DB |_________|DB |    |DB |_________|DB |
|___|         |___|    |___|         |___|    |___|         |___|
    \                     \                      |
     \                     \                     |
     _\___    Vote(HTTPS)  _\___    Vote(HTTPS)  |____
    |Node |  <----------  |Node |  ---------->  |Node |
    |  B  |---------------|  A  |---------------|  C  |
    |_____|  ---------->  |_____|  <----------  |_____|
               Yes/No                Yes/No     
           ]]></artwork>
           <postamble>Voting Phase</postamble>
         </figure>
         <section title="API - POST /voting" anchor="post_voting">
           <t>Request:</t>
           <t>POST /voting</t>
           <t>Description:</t>
           <t>A post from either Initiator node or subsequent peer nodes to request a vote of "yes" or "no" whether the key-value data could be committed without error or conflict.</t>
           <t>Example (using cURL)</t>
           <t>Request</t>
           <figure>
             <artwork> <![CDATA[
   $ curl -i -H "Content-Type: application/json" -H "DRiP-Node-ID: 
       nodeA" -H "DRiP-Node-Counter: 1234" -H 
       "DRiP-Node-Counter-reset: false" -X POST -d '{<key-value 
       data>}' https://nodebregistry.com/voting
           ]]></artwork>
           </figure>
           <t>Response</t>
           <figure>
             <artwork> <![CDATA[
     HTTP/1.1 200 OK
           ]]></artwork>
           </figure>
         </section>
         <section title="POST /votingphase/node/:nodeid/response/:response">
           <t>Request:</t>
           <t>POST /voting/peernode/:nodeid/response/:response</t>
           <t>Description:</t>
           <t>A POST from peer node back to node with response of vote.</t>
           <t>Example (using cURL)</t>
           <t>Request</t>
           <figure>
             <artwork> <![CDATA[               
  $ curl -i -X POST http://nodearegistry.com/node/nodeA/response/yes
             ]]></artwork>
           </figure>
           <t>Response</t>
           <figure>
             <artwork> <![CDATA[
     HTTP/1.1 200 OK
             ]]></artwork>
           </figure>
         </section>
       </section>
       <section title="Commit Phase" anchor="commit_phase">
         <t>The Initiator node, that originated the gossip, upon receiving a successful aggregated "yes" vote from all the peer nodes should start the commit phase. This node MUST commit the data to its data store. Subsequently, this information is propagated to all the nodes so that each node in the mesh will commit the same information in their respective data stores.</t>
         <figure align="center">
           <artwork align="center"> <![CDATA[
   ___           ___                         ___           ___ 
  |DB |_________|DB |                       |DB |_________|DB |
  |___|         |___|                       |___|         |___|
    |   Data      |                           |   Data      |  
    |   Store     |                           |   Store     |  
   _|_  Cluster  _|_                         _|_  Cluster  _|_ 
  |DB |_________|DB |                       |DB |_________|DB |
  |___|         |___|                       |___|         |___|
                    \                       /
                     \COMMIT               /COMMIT
                     _\___     COMMIT   _ /__
                    |Node |------------|Node |
                    |  A  |    HTTPS   |  C  |
                    |_____|            |_____|
                        \H           H/
                         \T         T/
                    COMMIT\T       P/COMMIT 
                           \P     P/  
                            \S   S/   
                           __\__ /  COMMIT    _____  
                          |Node |------------|Node |
                          |  B  |   HTTPS    |  D  |
                          |_____|            |_____|
                         /                   /
                        /COMMIT             /COMMIT
      ___           ___/                  _/__          ___ 
     |DB |_________|DB |                 |DB |_________|DB |
     |___|         |___|                 |___|         |___|
       |   Data      |                     |   Data      |  
       |   Store     |                     |   Store     |  
      _|_  Cluster  _|_                   _|_  Cluster  _|_ 
     |DB |_________|DB |                 |DB |_________|DB |
     |___|         |___|                 |___|         |___|
   
           ]]></artwork>
           <postamble>Commit Phase</postamble>
         </figure>
         <section title="API - POST /commit" anchor="post_commit">
           <t>Request:</t>
           <t>POST /commit</t>
           <t>Description:</t>
           <t>A commit message is sent from Initiator or subsequent peer nodes to signal the Receiver node to commit the data to its data store.</t>
           <t>Example (using cURL)</t>
           <t>Request</t>
           <figure>
             <artwork> <![CDATA[
  $ curl -i -H "Content-Type: application/json" -H "DRiP-Node-ID: 
     nodeA" -H "DRiP-Node-Counter: 1234" -H 
     "DRiP-Node-Counter-reset: false" -X POST -d
     '<key-value data>' https://nodebregistry.com/commit
           ]]></artwork>
           </figure>
           <t>Response</t>
           <figure>
             <artwork> <![CDATA[
   HTTP/1.1 200 OK
             ]]></artwork>
           </figure>
         </section>
       </section>
     </section>
     <section title="Node Sync Operation" anchor="node_sync_operation">
       <t>A node, either newly added to the distributed mesh or put back into service after being inactive, will get the state of a peer node to determine if it is in "active" state. If so, the node can immediately initiate a Sync transaction. The peer node MUST start propagating a comprehensive and complete set of key-value data from its data store.</t>
       <t>The two phase commit does NOT apply here as the contents of the initiating node's data store is either outdated or empty. During this phase (HTTPS requests received will have DRiP-Sync-Complete field value set to false), this node SHOULD NOT become an Initiator node to provision data. While this transaction is going on, this node MUST vote "yes" to all real-time updates. The commits corresponding to the Updates should also be completed and reflected in the data store.</t>
       <section title="API - PUT /sync/node/:nodeid" anchor="put_sync_node_nodeid">
         <t>Request:</t>
         <t>PUT /sync/node/:nodeid</t>
         <t>Description:</t>
         <t>API call for initiating a full registry synchronization from node to peer-node.</t>
         <t>Example (using cURL)</t>
         <t>Request</t>
         <figure>
           <artwork> <![CDATA[
	$ curl -i  -H "DRiP-Node-ID: nodeA" -H "Authorization: eyJ0e..."
		-X POST https://peernode.com/sync/node/nodeA
         ]]></artwork>
         </figure>
         <t>Response</t>
         <figure>
           <artwork> <![CDATA[
   HTTP/1.1 200 OK
           ]]></artwork>
         </figure>
       </section>
     </section>
     <section title="Heartbeat" anchor="Heartbeat">
       	<t>Periodic heartbeats are required for a node to determine it's visibility to the rest of it's peer nodes and whether it should put itself in "inactive" mode.  The proceedure for heartbeats is as follows.</t>
       	<t>A node sends periodic heartbeat requests to its peer nodes with an indication of its state. These heartbeat requests are not to be propagated beyond the peer nodes.</t>
       	<t>If all of its peer nodes cannot be reached or do not respond with 200 OK, then the node that sent the heartbeat request will set its own state to "inactive". This is based on the reasonable assumption that none of the peer nodes are able to communicate with this node until a new heartbeat request is sucessful. Once in the inactive state, the node will</t>
        	<t>
        		<list style="symbols">
              		<t>not propagate any incoming key-value data</t>
              		<t>not update any incoming key-value data</t>
              		<t>continue to send the periodic heartbeat requests to its peer nodes. If any one responds with 200 OK, then the node will move its state to "synchronizing" and will re-synchronize its data with any active peer node as detailed in section 4.6</t>
            	</list> 
          	</t>
          	<t>In addition, any one or more peer nodes that cannot be reached or did not respond with 200 OK should not be used to propagate key-value data until it responds (with 200 OK) to the heartbeat request.</t>
			<section title='API - POST /heartbeat/node/:nodeid' anchor="api_heartbeat">
         		<t>Example (using cURL)</t>
         		<t>Request</t>
         		<figure>
           			<artwork> <![CDATA[
	$ curl -i  -H "DRiP-Node-ID: nodeA" -H "Authorization: eyJ0e..."
		-X POST -d '<state>' https://peernode.com/heartbeat/node/nodeA
         			]]></artwork>
         		</figure>
         		<t>Response</t>
         		<figure>
           			<artwork> <![CDATA[
   HTTP/1.1 200 OK
           			]]></artwork>
         		</figure>          
          	</section>
     	</section>
     	<section title="Key-Value Data Update Entitlement Verification" anchor="key-value_data_update_entitlement_verification">
       <t>When a node owner would like to create or modify particular key-value data, generally in the context of a registry, there MAY be a verification procedure that key-value data write or modification can be performed. This could include validating whether key-value data is entitled to be written, modified or subsequently propagated based on application policy. For example, identity or telephone number ownership or porting. The exact mechanics of this are out of scope of this document and are generally application specific.</t>
     </section>
   </section>
   <section title="Security Considerations" anchor="security_considerations">
     <section title="HTTPS" anchor="https">
       <t>All nodes MUST perform HTTP transactions using TLS as defined in <xref target="RFC7230"></xref>.</t>
     </section>
     <section title="Authorization" anchor="authorization">
       <t>All nodes MUST validate their authority to consume the HTTP APIs of a peer node by adding a JSON Web Token (JWT) value <xref target="RFC7519"></xref> in the Authorization request-header field.</t>
       <t>The creation and verification of the JWT should be based on a digital signature. For most distributed registry scenerios where the owner of a node may not have a direct relationship with another node owner, a PKI based certificate approach is highly suggested. For protection against replay attacks, the claim set SHOULD contain an "iat" claim and the signature should be verified to be signed by the expected owner of the peer node. The "iat" claim identifies the time at which the JWT was issued and can be used to validate when the time of the transaction occurred.</t>
     </section>
     <section title="Payload Validation" anchor="payload_validation">
     	<t>In addition to the DRiP level protocol protection, it is highly suggested to sign and validate part or all of the JSON update payloads to the originator of the update.
DRiP does not define anything regarding the contents of the payload, so this document does not address this in any way.</t>
     </section>
   </section>
 </middle>
 
 <back>
   <references title="References">
     <reference anchor="RFC2119" target="http://www.rfc-editor.org/info/rfc2119">
       <front>
         <title>
         Key words for use in RFCs to Indicate Requirement Levels
         </title>
         <author initials="S." surname="Bradner" fullname="S. Bradner">
           <organization/>
         </author>
         <date year="1997" month="March"/>
       </front>
       <seriesInfo name="BCP" value="14"/>
       <seriesInfo name="RFC" value="2119"/>
       <seriesInfo name="DOI" value="10.17487/RFC2119"/>
     </reference>
     <reference anchor="RFC7230" target="http://www.rfc-editor.org/info/rfc7230">
       <front>
         <title>
           Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing
         </title>
         <author initials="R." surname="Fielding" fullname="R. Fielding" role="editor">
           <organization/>
         </author>
         <author initials="J." surname="Reschke" fullname="J. Reschke" role="editor">
           <organization/>
         </author>
         <date year="2014" month="June"/>
       </front>
       <seriesInfo name="RFC" value="7230"/>
       <seriesInfo name="DOI" value="10.17487/RFC7230"/>
     </reference>
     	  <reference anchor="RFC7519" target="http://www.rfc-editor.org/info/rfc7519">
		<front>
		  <title>JSON Web Token (JWT)</title>
		  <author initials="M." surname="Jones" fullname="M. Jones">
			<organization/>
		  </author>
		  <author initials="J." surname="Bradley" fullname="J. Bradley">
			<organization/>
		  </author>
		  <author initials="N." surname="Sakimura" fullname="N. Sakimura">
			<organization/>
		  </author>
		  <date year="2015" month="May"/>
		</front>
		<seriesInfo name="RFC" value="7519"/>
		<seriesInfo name="DOI" value="10.17487/RFC7519"/>
	  </reference>
   </references>
 </back>
</rfc>