]>
&title; &name; &version;-&stage; Standards Track Work Product &this-loc;/&name;-&version;-&stage;.xml &this-loc;/&name;-&version;-&stage;.pdf &this-loc;/&name;-&version;-&stage;.html &previous-loc;/&name;-&pversion;.xml &previous-loc;/&name;-&pversion;.pdf &previous-loc;/&name;-&pversion;.html &latest-loc;/&name;.xml &latest-loc;/&name;.pdf &latest-loc;/&name;.html OASIS XDI TC MarkusSabadello Danube Tech markus@danubetech.com DrummondReed XDI.org drummond.reed@xdi.org &pubdate; 2015 OASIS Open, Inc. All Rights Reserved. Additional artifacts This prose specification is one component of a Work Product which also includes: Related work This document is primarily based on a set of proposals that had been collected by the OASIS XDI TC on its associated wiki at https://wiki.oasis-open.org/xdi/. Abstract This working draft is for reviewer comment only and is not yet a standards document or published at OASIS. This specification defines the abstract pattern for transmitting XDI messages between peers. Citation format When referencing this specification the following citation format should be used: OASIS-XDI-Messaging-V1.0 OASIS XDI Messaging V1.0 &pubdate;. OASIS &standard;. &latest-loc;/&name;.html. Notices Copyright © OASIS® Open 2015. All Rights Reserved. All capitalized terms in the following text have the meanings assigned to them in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The full Policy may be found at http://www.oasis-open.org/who/intellectualproperty.php. This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published, and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this section are included on all such copies and derivative works. However, this document itself may not be modified in any way, including by removing the copyright notice or references to OASIS, except as needed for the purpose of developing any document or deliverable produced by an OASIS Technical Committee (in which case the rules applicable to copyrights, as set forth in the OASIS IPR Policy, must be followed) or as required to translate it into languages other than English. The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns. This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. OASIS requests that any OASIS Party or any other party that believes it has patent claims that would necessarily be infringed by implementations of this OASIS Committee Specification or OASIS Standard, to notify OASIS TC Administrator and provide an indication of its willingness to grant patent licenses to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification. OASIS invites any party to contact the OASIS TC Administrator if it is aware of a claim of ownership of any patent claims that would necessarily be infringed by implementations of this specification by a patent holder that is not willing to provide a license to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification. OASIS may include such claims on its website, but disclaims any obligation to do so. OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS' procedures with respect to rights in any document or deliverable produced by an OASIS Technical Committee can be found on the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this OASIS Committee Specification or OASIS Standard, can be obtained from the OASIS TC Administrator. OASIS makes no representation that any information or list of intellectual property rights will at any time be complete, or that any claims in such list are, in fact, Essential Claims. The name "OASIS" is a trademark of OASIS, the owner and developer of this specification, and should be used only to refer to the organization and its official outputs. OASIS welcomes reference to, and implementation and use of, specifications, while reserving the right to enforce its marks against misleading uses. Please see http://www.oasis-open.org/who/trademark.php for above guidance.
Introduction This specification defines the abstract pattern for transmitting XDI messages between peers. This builds on the basic XDI graph model (see ).
Key words The key words must, must not, required, shall, shall not, should, should not, recommended, may, and optional are to be interpreted as described in . Note that for reasons of style, these words are not capitalized in this document.
Normative References OASIS-XDI-Core-V1.0 &pubdate; <ulink url="../../xdi-core-1.0/xdi-core-1.0-wd01.xml">OASIS XDI 1.0 Core Specification</ulink> Joseph Boyle, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-core.html. OASIS-XDI-Discovery-V1.0 &pubdate; <ulink url="../../xdi-discovery-1.0/xdi-discovery-1.0-wd01.xml">OASIS XDI 1.0 Discovery Specification</ulink> Markus Sabadello, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-discovery.html. OASIS-XDI-Bindings-V1.0 &pubdate; <ulink url="../../xdi-bindings-1.0/xdi-bindings-1.0-wd01.xml">OASIS XDI 1.0 Bindings Specification</ulink> Markus Sabadello, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-bindings.html. OASIS-XDI-Link-Contracts-V1.0 &pubdate; <ulink url="../../xdi-link-contracts-1.0/xdi-link-contracts-1.0-wd01.xml">OASIS XDI 1.0 Link Contracts Specification</ulink> Dan Blum, Markus Sabadello, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-link-contracts.html. OASIS-XDI-Security-Mechanisms-V1.0 &pubdate; <ulink url="../../xdi-security-mechanisms-1.0/xdi-security-mechanisms-1.0-wd01.xml">OASIS XDI 1.0 Security Mechanisms Specification</ulink> Markus Sabadello, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-security-mechanisms.html. OASIS-XDI-Privacy-Mechanisms-V1.0 &pubdate; <ulink url="../../xdi-privacy-mechanisms-1.0/xdi-privacy-mechanisms-1.0-wd01.xml">OASIS XDI 1.0 Privacy Mechanisms Specification</ulink> Markus Sabadello, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-privacy.html. RFC 2119March 1997 <ulink url="http://www.ietf.org/rfc/rfc2119.txt">Key words for use in RFCs to Indicate Requirement Levels</ulink> S. Bradner. IETF (Internet Engineering Task Force) RFC 6749October 2012 <ulink url="http://www.ietf.org/rfc/rfc6749.txt">The OAuth 2.0 Authorization Framework</ulink> D. Hardt , IETF (Internet Engineering Task Force) RFC 6750October 2012 <ulink url="http://www.ietf.org/rfc/rfc6750.txt">The OAuth 2.0 Authorization Framework: Bearer Token Usage</ulink> M. Jones. D. Hardt, IETF (Internet Engineering Task Force)
Non-Normative References
XDI Messaging XDI messaging is the mechanism for transmitting messages between peers, for the purpose of exchanging data between the graphs for which the peers are authoritative. Every message is transmitted from a sending peer to a receiving peer. The XDI messaging process consists of round-trips, each one of which involves a request message which is followed by a corresponding response. A peer sending a request message is called requesting peer (or short requester). A peer sending a response is called responding peer (or short responder). A request message contains one or more request operations, which can perform queries and/or apply modifications to a graph for which the responder is authoritative. This graph is called the target graph. When a request message is executed by the responder against the target graph, a result graph is generated, which represents the result of the request operations. The result graph MAY be empty. A response sent from the responder to the requester may either simply be the result graph itself, or it may be a response message, which contains within itself the result graph. The following diagram illustrates the basic pattern of all XDI messaging round-trips:
XDI Messaging Terminology
For the request message, the requester is the sending peer, and the responder is the receiving peer. For the response, the responder is the sending peer, and the requester is the receiving peer. A message is itself a context node in a graph, so it can be addressed, serialized, stored, shared, and controlled by link contracts. When a graph containing one or more messages is serialized and transmitted between peers, then that graph is called a message envelope.
Bindings XDI messaging is defined in an abstract way and does not rely on any specific network topology or protocol. The XDI Bindings specification defines three concrete ways how messages can be transmitted over a network: XDI Direct Binding: Request and response messages are transmitted between the requester and the responder via HTTP POST operations. XDI Browser Binding: Request and response messages are transmitted between the requester and the responder via a web browser and a sequence of HTTP form submit and redirect operations. XDI Websocket Binding: Request and response messages are transmitted between the requester and the responder via Websocket sessions. From an abstract XDI messaging perspective, any peer can act as a requester and responder. In the context of specific bindings, a distinction can be made between XDI endpoints and XDI agents. An XDI endpoint is a peer that – within the context of a specific binding – has an endpoint URI on a network. The three bindings above all require such endpoint URIs, which are discoverable given the XDI peer address (see ). An XDI endpoint can always act as both requesting peer and responding peer. An XDI agent is a peer that – within the context of a specific binding – does not have an endpoint URI on a network. In many situations and bindings, an XDI agent can only act as a requesting peer. One exception is the XDI Websocket Binding. Once a Websocket connection has been established between two peers, they may both act as both requesting peer and responding peer, even if one of them is an XDI agent without its own endpoint URI on a network.
Messages A message is represented as an XDI entity in a graph. It is a member of an entity collection identified by a [$msg] context, under an entity that is authoritative for the message. That entity is called the sender of the message. The identifier of the member is called the message ID: <--sender-->[$msg]<--message-id--> Example message by XDI sender =!:uuid:1111, with message ID *!:uuid:m-1: =!:uuid:1111[$msg]*!:uuid:m-1 Every message SHOULD have an immutable address. To express order, the ordered/unordered reference pattern (see ) MAY be used: =!:uuid:1111[$msg]@~0/$ref/=!:uuid:1111[$msg]*!:uuid:m-1 A context node representing a message contains various statements that make up the semantics and purpose of the message. Following are the statements that are common to both request messages and response messages (shown in statement format). This is called the common message pattern. Labels in <--this-form--> represent pattern variables. SENDING PEER <--sender-->[$msg]<--message-id-->/$from/<--receiving-peer--> RECEIVING PEER <--sender-->[$msg]<--message-id-->/$to/<--receiving-peer--> MESSAGE TYPE AND VERSION <--sender-->[$msg]<--message-id-->/$is#/<--message-type-->[$v]<--version-number-->$xdi[$v]@1$msg CORRELATION STATEMENT <--sender-->[$msg]<--message-id-->/$is$msg/<--previous-sender-->[$msg]<--previous-message-id--> TIMESTAMP <--sender-->[$msg]<--message-id--><$t>/&/<--timestamp--> AUTHENTICATION TOKEN <--sender-->[$msg]<--message-id--><--token-type--><$token>/&/<--token--> AUTHENTICATION SIGNATURE <--sender-->[$msg]<--message-id--><--signature-type--><$sig>/&/<--signature--> MESSAGE PARAMETERS <--sender-->[$msg]<--message-id--><--parameter-->/&/<--parameter-value--> Where: <--sender--> is the XDI address of the sender that creates the message. <--message-id--> is an entity instance that is the unique ID of the message in the context of the [$msg] collection of messages sent by the sender. <--sending-peer--> is the XDI peer (XDI endpoint or agent) sending this message. <--receiving-peer--> is the XDI peer (XDI endpoint or agent) receiving this message. <--message-type--> is an optional XDI address specifying a message type. <--version-number--> is the message type version, expressed as an ordered instance of a [$v] collection. <--timestamp--> is the timestamp of the message in XML datetime format as specified by the '''$t''' entry in the XDI $ Dictionary. <--token-type--> is the XDI address defining the type of token provided for message authentication. <--token--> is the literal token value provided for authentication. <--signature-type--> is the context defining the type of signature provided for authentication. <--signature--> is the literal signature value provided for authentication as required by the referenced link contract. <--parameter--> is a message parameter. <--parameter-value--> is the value of a message parameter.
Sender A message MUST have a sender that creates the message. This XDI address may be any valid XDI entity (e.g., person, organization, thing, device, service, etc.)
Message ID A message MUST have a message ID. The message ID value may be sequential, or based on timestamps, or a random UUID, or use any other algorithm that provides uniqueness in this context. Sending peers MUST use a different message ID for every message. Receiving peers MAY enforce uniqueness of message IDs.
Sending Peer A message MUST have exactly one sending peer, which identifies the XDI agent or XDI endpoint that is the sender of the message. Example sending peer: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) A sending peer MAY appear in the context of one or more other peers. This expresses a "past path" (or "routing history") of peers the message has previously passed through on the way to its receiving peer(s). For example, if a message is sent by an XDI agent to an XDI endpoint, which then forwards it, then the sending peer is the XDI endpoint in the context of the XDI agent. Example sending peer: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(*!:uuid:8888)(=!:uuid:1111)
Receiving Peer A message MUST have at least one receiving peer, and MAY have multiple receiving peers, which identify the XDI agent(s) and XDI endpoint(s) that are the receiver(s) of the message. Depending on the binding being used, it may be possible or required to discover an endpoint URI for this peer (see ). Example receiving peer: =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) A receiving peer MAY appear in the context of one or more other peers. This expresses a "future path" (or "routing instruction") of peers the message is meant to pass through on the way to its receiving peer(s). For example, if a message is meant to be sent to an XDI agent via an XDI endpoint, the receiving peer is the XDI agent in the context of the XDI endpoint. Example receiving peer: =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222)(*!:uuid:9999)
Message Type and Version A message MAY have a message type and message version.
Correlation statement A message MAY have one or more correlation statements, also known as thread statements. The purpose of such statements is to express that this message is in some way related to a previous message. For a response message, at least one correlation statement is REQUIRED in order to express that the response message is related to the request message. For a request message, a correlation statement MAY express that the request message is related to previous request or response message. A correlation statement is identified by a $is$msg relational arc between messages. This identifier MAY be specialized to express additional semantics about how two messages are related. Example correlation statement: =!:uuid:2222[$msg]*!:uuid:m-2/$is$msg/=!:uuid:1111[$msg]*!:uuid:m-1
Timestamp A message MAY have a timestamp to indicate at which point in time a requester sent the message. Receiving peers MAY enforce policies requiring the message <--timestamp--> value to be within a certain tolerance.
Authentication Token A message MAY be authenticated with a token as defined in section 1.4 of . The token type <$secret> may be used for shared secrets. Any valid XDI literal value may be used as a shared secret. The token type <$bearer> may be used for bearer tokens as defined by . Other token types as registered with the IANA OAuth Access Token Types Registry defined in section 11.1 of .
Authentication Signature A message MAY be signed for authentication. See .
Message Parameters A message MAY have one or more message parameters that govern how the message is executed. A message parameter MUST be interpreted to apply only to the message that contains it. The following message parameter is defined by this specification:
<$msg> The <$msg> message parameter MUST only be used with request messages. The parameter instructs the responder to send a response message rather than simply the result graph as a response, after the request message has been executed. Valid values are true and false. If this message parameter is not present, the default value is false. Example: =!:uuid:1111[$msg]*!:uuid:m-1<$msg>/&/true
Request Messages A request message MUST conform to the common message pattern (see ). In addition, request messages extend the common message pattern with the following request message pattern (shown in statement format): LINK CONTRACT ADDRESS <--sender-->[$msg]<--message-id-->/$contract/<--link-contract-address--> MESSAGE POLICY <--sender-->[$msg]<--message-id-->$do$if<--boolean-context-->/<--boolean-operator-->/<--condition--> OPERATION PARAMETERS <--sender-->[$msg]<--message-id--><--operation--><--parameter-->/&/<--parameter-value--> VARIABLE ADDRESS ASSIGNMENT <--sender-->[$msg]<--message-id--><--operation--><--variable-->/$is/<--variable-value--> VARIABLE LITERAL ASSIGNMENT <--sender-->[$msg]<--message-id--><--operation--><--variable-->/&/"<--variable-value-->" OPERATION ON ADDRESS <--sender-->[$msg]<--message-id-->$do/<--operation-->/<--target-address--> OPERATION ON INNER GRAPH (<--sender-->[$msg]<--message-id-->$do/<--operation-->)<--target-inner-graph--> Where: <--link-contract-address--> is the XDI address of the link contract authorizing the requested operation on the requested object graph. This MUST be either: a) a $contract entity singleton or: b) a [$contract] entity class followed by an entity instance. See the XDI Policy specification: . <--boolean-context--> is defined in . <--operation--> is defined in . <--condition--> is defined in . <--operation--> is the request operation ($get, $set, $add, $mod, $del, $connect, $send, $push, $do). A request operation may be executed on an address or on an inner root. There may be one or more operations in a message. <--parameter--> is an operation parameter. <--parameter-value--> is the value of an operation parameter. <--target-address--> is an XDI address that the operation is executed on. <--target-inner-graph--> is an XDI inner graph containing statements that the operation is executed on. Example request message: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) =!:uuid:1111[$msg]*!:uuid:m-1/$contract/(=!:uuid:2222/=!:uuid:1111)$get[$contract]*!:uuid:3333 =!:uuid:1111[$msg]*!:uuid:m-1$do/$get/=!:uuid:2222<#email>
Link Contract Address Request messages MUST include a <--link-contract-address--> reference to the XDI link contract authorizing that message. See the [[Link Contract Pattern]]. Requiring the <--link-contract--> reference in an XDI message makes it much more efficient for XDI servers to perform authentication and authorization, because they know which link contract to evaluate. (For a public link contract, the value of <--link-contract--> is $public$contract.) Request messages MUST be executed only if the [[XdiPolicyExpression|link contract policies]] evaluates to true.
Message Policy A request message MAY have a policy to specify conditions for its execution at an XDI endpoint. If an XDI message includes a <--sender-->[$msg]<--id-->$do$if sub context, the set of message policy statements in this context MUST be evaluated by the XDI endpoint. Request messages MUST be executed only if the [[XdiPolicyExpression|link contract policies]] evaluates to true. For privacy reasons, a message policy may only access parts of the target graph which it has $get access to under the link contract referenced in the message.
Operation Parameters A request operation MAY have one or more operation parameters that govern how the request operation is executed. An operation parameter MUST apply only to the request operation that contains it. The following operation parameters are defined by this specification.
<$deref> The <$deref> MUST only be used with the $get operation. The parameter controls whether the responder automatically dereferences $ref statements in a result graph. Valid values are true and false. If this parameter is not present, the default value is false. Example: =!:uuid:1111[$msg]*!:uuid:m-1$get<$deref>/&/true
<$proxy> The <$proxy> MUST only be used with the $get operation. The parameter controls whether the responder acts as a proxy to complete discovery of an XDI context for which the responder is not itself authoritative. Valid values are true and false. If this parameter is not present, the default value is false. Example: =!:uuid:1111[$msg]*!:uuid:m-1$get<$proxy>/&/true
Variable Assignment A request operation MAY have one or more variable assignments that are used when the request operation is executed. A variable assignment MUST apply only to the request operation that contains it. For certain operations it is REQUIRED that variables are assigned values. For certain operations it is OPTIONAL that variables are assigned values. See the definitions of individual operation for information whether it uses variables, which variables it uses, how they are used, and whether it is required or optional to assign values to the variables. Example: =!:uuid:1111[$msg]*!:uuid:m-1$connect{$get}/$is/=!:uuid:2222<#email>
Response Every request message MUST have a corresponding response which is transmitted back from the responder to the requester, in a way defined by the binding that is being used. There are two types of responses. Result graphs and response messages. If the <$msg> message parameter (see ) is absent or set to false, then the response MUST be a result graph. If the <$msg> message parameter is set to true, then the response MUST be a response message.
Result Graph A result graph consists of the result statements of a request operation. The result graph is not itself a message and therefore does not conform to the common message pattern (see ). Every request operation has its own result graph. If a request message contains multiple request operations, and/or a request message envelope contains multiple request messages, then a combined result graph is created that is the union of all result graphs. Example result graph: =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111
Response Message A response message MUST conform to the common message pattern (see ). In addition, response messages extend the common message pattern with the following response message pattern (shown in statement format): OPERATION RESULT GRAPHS (<--sender-->[$msg]<--message-id-->/<--operation-->)<--result-graph--> DEFERRED PUSH CONTRACTS (<--sender-->[$msg]<--message-id-->/$defer$push)<--deferred-push-contracts-->
Operation Result Graphs The result graphs of the request operations are included in the response message using inner root nodes as follows: For each request operation in the request message, an inner root node is created in the response message to represent the result graph of that particular request operation. The subject of the inner root node's XDI address is the XDI address of the request message to which the response message corresponds. The predicate of the inner root node's XDI address is the identifier of the request operation to which the result graph corresponds. The inner graph under the inner root node is the result graph of the request operation. Example response message with a result graph: =!:uuid:2222[$msg]*!:uuid:m-2/$from/(=!:uuid:2222) =!:uuid:2222[$msg]*!:uuid:m-2/$to/(=!:uuid:1111) =!:uuid:2222[$msg]*!:uuid:m-2/$is$msg/=!:uuid:1111[$msg]*!:uuid:m-1 (=!:uuid:2222[$msg]*!:uuid:m-2/$get)=!:uuid:2222<#email>/&/"bob@email.com" (=!:uuid:2222[$msg]*!:uuid:m-2/$get)=!:uuid:2222/#friend/=!:uuid:1111
Deferred Push Contracts EDITORIAL NOTE: Maybe some parts of this section should be moved to . A response message may have one or more deferred push contracts, which indicate that a result graph is not yet available, and that a request message has therefore been deferred. Deferred push contracts are push contracts (see ) that are used for pushing the result of a deferred message to the requester once it is available. A request operation may be deferred for the following reasons: One or more operations in the request message are executed asynchronously. The result graph of the operation(s) will be pushed once execution is complete. One or more operations in the request message cannot be executed at the moment. They will be executed as soon as possible, and the result graph of the operation(s) will be pushed once execution is complete. The request message is deferred due to link contract policy (see ). It is expected to be approved or rejected at a future point in time (see and ). For other reasons that are out of scope of this specification. In the above cases, deferred push contracts are created automatically in the responder's target graph and returned in the response message. To create a deferred push contract, the link contract instantiation function (see ) is invoked with the following input parameters: The link contract template is $defer$push{$contract} (see ). The variable {$from} is assigned the sending peer of the request operation (see ). The variable {$to} is assigned the receiving peer of the request operation (see ). The variable {$push} is assigned the address of the context(s) of the result graph that are not yet available. The instance flag set to "instance" Example instantiated deferred push contract: (=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do/$push/=!:uuid:2222<#email> (=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2/$to/(=!:uuid:1111) (=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do$if$and/$true){$from}/$is/=!:uuid:2222 (=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do$if$and/$true){$msg}<$sig><$valid>/&/true (=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do$if$and/$true){$msg}/$is$msg/=!:uuid:1111[$msg]*!:uuid:m-1 A response message MAY contain both a result graph and a deferred push contract, indicating that a partial result is available immediately, and that additional results will be available in the future. A response message MAY contain more than one deferred push contract, if the result graph will be delivered in multiple pushes. Example response message with a deferred push contract: =!:uuid:2222[$msg]*!:uuid:m-2/$from/(=!:uuid:2222) =!:uuid:2222[$msg]*!:uuid:m-2/$to/(=!:uuid:1111) =!:uuid:2222[$msg]*!:uuid:m-2/$is$msg/=!:uuid:1111[$msg]*!:uuid:m-1 (=!:uuid:2222[$msg]*!:uuid:m-2/$defer$push)(=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do/$push/=!:uuid:2222<#email> (=!:uuid:2222[$msg]*!:uuid:m-2/$defer$push)(=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2/$to/(=!:uuid:1111) (=!:uuid:2222[$msg]*!:uuid:m-2/$defer$push)(=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do$if$and/$true){$from}/$is/=!:uuid:2222 (=!:uuid:2222[$msg]*!:uuid:m-2/$defer$push)(=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do$if$and/$true){$msg}<$sig><$valid>/&/true (=!:uuid:2222[$msg]*!:uuid:m-2/$defer$push)(=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:d-2$do$if$and/$true){$msg}/$is$msg/=!:uuid:1111[$msg]*!:uuid:m-1
Operations Operations constitute the body of an XDI message. A request message MUST contain at least one operation statement. To successfully complete execution of a request message, a responder MUST complete execution of each operation requested in each operation statement in the message. Depending on: a) the operation, and b) whether the operation target is an XDI address or an inner graph, the following operations and behaviors are possible: XDI Operations Overviewon addresson inner graph$getretrieves graph/subgraphretrieves individual contextual/relational/literal statement(s)$setcreates or modifies context node plus parent context node(s) if neededcreates or modifies individual contextual/relational/literal statement(s) plus parent context nodes(s) if needed$addcreates new context node plus parent context node(s) if neededcreates new individual contextual/relational/literal statement(s) plus parent context nodes(s) if needed$mod(invalid)modifies existing literal statement(s)$deldeletes context node and subgraphdeletes individual contextual/relational/literal statement(s) plus subgraph(s)$connectrequests instantiation of a link contractrequests instantiation of a link contract$sendrequests sending of an inner messagerequests sending of an inner message$pushdelivers a notification based on a push link contractdelivers a notification based on a push link contract$do(unspecified)(unspecified)
<code>$get</code> operation The $get operation retrieves XDI statements from a target graph and does not make changes to that graph.
<code>$get</code> applied to an address The result graph contains the subgraph at the provided address if it exists. If the subgraph does not exist, the result graph is empty. Example: Given the following target graph: //+!:uuid:0000 =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111 And the following $get operation on address =!:uuid:2222: =!:uuid:1111[$msg]*!:uuid:m-1$do/$get/=!:uuid:2222 The result graph will be: =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111
<code>$get</code> applied to an inner graph The result graph contains the provided statements of the inner graph if they exist. If the statements do not exist, the result graph is empty (this is not considered an error). Example: Given the following target graph: //+!:uuid:0000 =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111 And the following $get operation on statement =!:uuid:2222/#friend/=!:uuid:1111: (=!:uuid:1111[$msg]*!:uuid:m-1$do/$get)=!:uuid:2222/#friend/=!:uuid:1111 The result graph will be: =!:uuid:2222/#friend/=!:uuid:1111
<code>$set</code> operation The $set operation creates or modifies data in a target graph. Unless an error occurs, the result graph is the empty graph.
<code>$set</code> applied to an address This operation creates a context node at the provided address, as well as any parent context node(s) as needed. If the context node exists already, the operation has no effect (this is not considered an error). Example: Given the following target graph: //+!:uuid:0000 //=!:uuid:2222 And the following $set operation on address =!:uuid:2222<#email>: =!:uuid:1111[$msg]*!:uuid:m-1$do/$set/=!:uuid:2222<#email> The target graph after the operation will be: //+!:uuid:0000 =!:uuid:2222//<#email>
<code>$set</code> applied to an inner graph This operation creates the provided statements of the inner graph, as well as any parent context nodes(s) as needed. If a statement exists already, the operation has no effect on this statement (this is not considered an error). Example: Given the following target graph: //+!:uuid:0000 =!:uuid:2222<//#email> And the following $set operation on statements =!:uuid:2222<#email>/&/"bob@email.com" and =!:uuid:2222/#friend/=!:uuid:1111: (=!:uuid:1111[$msg]*!:uuid:m-1$do/$set)=!:uuid:2222<#email>/&/"bob@email.com" (=!:uuid:1111[$msg]*!:uuid:m-1$do/$set)=!:uuid:2222/#friend/=!:uuid:1111 The target graph after the operation will be: //+!:uuid:0000 =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111
<code>$add</code> operation The $add operation creates data in a target graph. Unless an error occurs, the result graph is the empty graph. If the operation is applied to data which already exists, it generates an error (this is what distinguishes $add from $set).
<code>$add</code> applied to an address This operation creates a context node at the provided address, as well as any parent context node(s) as needed. If the context node exists already, the operation generates an error. Example: Given the following target graph: //+!:uuid:0000 //=!:uuid:2222 And the following $add operation on address =!:uuid:2222<#email>: =!:uuid:1111[$msg]*!:uuid:m-1$do/$add/=!:uuid:2222<#email> The target graph after the operation will be: //+!:uuid:0000 =!:uuid:2222//<#email>
<code>$add</code> applied to an inner graph This operation creates the provided statements of the inner graph, as well as any parent context nodes(s) as needed. If a statement exists already, the operation generates an error. Example: Given the following target graph: //+!:uuid:0000 =!:uuid:2222<//#email> And the following $add operation on statements =!:uuid:2222<#email>/&/"bob@email.com" and =!:uuid:2222/#friend/=!:uuid:1111: (=!:uuid:1111[$msg]*!:uuid:m-1$do/$add)=!:uuid:2222<#email>/&/"bob@email.com" (=!:uuid:1111[$msg]*!:uuid:m-1$do/$add)=!:uuid:2222/#friend/=!:uuid:1111 The target graph after the operation will be: //+!:uuid:0000 =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111
<code>$mod</code> operation The $mod operation modifies data in a target graph. Unless an error occurs, the result graph is the empty graph. If the operation is applied to data which does not exist, it generates an error (this is what distinguishes $mod from $set).
<code>$mod</code> applied to an address This operation on an address is not defined and generates an error.
<code>$mod</code> applied to an inner graph This operation is only defined on literal statements and generates an error otherwise. It modifies the value of an existing literal statement. If the context node that contains the literal does not exist, the operation generates an error. Example: Given the following target graph: //+!:uuid:0000 =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111 And the following $mod operation on statement =!:uuid:2222<#email>/&/"alice@new.com": (=!:uuid:1111[$msg]*!:uuid:m-1$do/$mod)=!:uuid:2222<#email>/&/"bob@new.com" The target graph after the operation will be: =!:uuid:2222<#email>/&/"bob@new.com"
<code>$del</code> operation The $del operation deletes data from a target graph. Unless an error occurs, the result graph is the empty graph.
<code>$del</code> applied to an address This operation deletes a context node at the provided address, as well as its entire subgraph. If the context node does not exist, the operation has no effect (this is not considered an error). Example: Given the following target graph: //+!:uuid:0000 =!:uuid:2222<#email>/&/"bob@email.com" =!:uuid:2222/#friend/=!:uuid:1111 And the following $del operation on target address =!:uuid:1111<#email>: =!:uuid:1111[$msg]*!:uuid:m-1$do/$del/=!:uuid:2222<#email> The target graph after the operation will be: //+!:uuid:0000 =!:uuid:2222/#friend/=!:uuid:1111
<code>$del</code> applied to an inner graph This operation deletes the provided statements of the inner graph. For a contextual statement, the operation also deletes the entire subgraph of the context node. For a relational statement, the operation deletes neither the source context node nor the target context node of the relation, only the relation itself. If a statement does not exist, the operation has no effect (this is not considered an error). Example: Given the following target graph: //+!:uuid:0000 =!:uuid:2222/#friend/=!:uuid:1111 And the following $del operation on statement =!:uuid:2222/#friend/=!:uuid:1111: (=!:uuid:1111[$msg]*!:uuid:m-1$do/$del)=!:uuid:2222/#friend/=!:uuid:1111 The target graph after the operation will be: //+!:uuid:0000 //=!:uuid:2222 //=!:uuid:1111
<code>$connect</code> operation The $connect operation requests instantiation of a link contract.
<code>$connect</code> applied to an address The provided address MUST be the address of a link contract template. The link contract template MUST be discovered from this address (see ). Example: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) =!:uuid:1111[$msg]*!:uuid:m-1$do/$connect/$get{$contract} =!:uuid:1111[$msg]*!:uuid:m-1$connect{$get}/$is/=!:uuid:2222<#email>
<code>$connect</code> applied to an inner graph The provided inner graph MUST contain one or more link contract templates. Example: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) (=!:uuid:1111[$msg]*!:uuid:m-1$do/$connect)$get{$contract}$do/$get/{$get} (=!:uuid:1111[$msg]*!:uuid:m-1$do/$connect)($get{$contract}$do$if$and/$true){{$from}}/$is/{$from} (=!:uuid:1111[$msg]*!:uuid:m-1$do/$connect)($get{$contract}$do$if$and/$true){{$msg}}<$sig><$valid>/&/true =!:uuid:1111[$msg]*!:uuid:m-1$connect{$get}/$is/=!:uuid:2222<#email>
Executing the <code>$connect</code> Operation To execute the $connect operation, link contract(s) are instantiated from the link contract template(s). The link contract instantiation function (see ) is invoked with the following input parameters: The link contract template(s) are provided by the $connect operation as described above. The variable {$from} is assigned the sending peer of the $connect operation (see ). The variable {$to} is assigned the receiving peer of the $connect operation (see ). Additional variable assignments required by the link contract template MUST be provided by the $connect operation (see ). The instance flag set to "instance" (TODO: how can a $connect operation specify this flag?) The instantiated link contract is written into the target graph. The result graph is the empty graph.
<code>$send</code> operation The $send operation requests sending of an inner message.
<code>$send</code> applied to an address The provided address MUST be either the address of a message or the address of a message template. If the provided address is the address of a message, then the message MUST be discovered from this address (see ). This message is called the inner request message. Example: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) =!:uuid:1111[$msg]*!:uuid:m-1$do/$send/=!:uuid:2222[$msg]*!:uuid:m-2 If the provided address is the address of a message template, then the message template MUST be discovered from this address (see ). The message template is used to instantiate a message. This message is called inner request message. The message instantiation function (see ) is invoked with the following input parameters: The message template is provided by the $send operation as described above. The variable {$from} is assigned the receiving peer of the $send operation (see ). The variable {$to} MUST be provided by the $send operation (see ). The variable {$contract} MUST be provided by the $send operation (see ). Additional variable assignments required by the message template MUST be provided by the $send operation (see ). Example: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) =!:uuid:1111[$msg]*!:uuid:m-1$do/$send/$get{$msg} =!:uuid:1111[$msg]*!:uuid:m-1$send{$to}/$is/=!:uuid:3333 =!:uuid:1111[$msg]*!:uuid:m-1$send{$contract}/$is/(=!:uuid:3333/=!:uuid:2222)$get$contract =!:uuid:1111[$msg]*!:uuid:m-1$send{$get}/$is/=!:uuid:3333<#email>
<code>$send</code> applied to an inner graph The provided inner graph MUST contain one or more messages. These messages are called inner request messages. Example: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2/$from/(=!:uuid:2222) (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2/$to/(=!:uuid:3333) (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2/$contract/(=!:uuid:3333/=!:uuid:2222)$get$contract (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2$do/$get/=!:uuid:3333<#email>
Executing the <code>$send</code> Operation To execute the $send operation, a new XDI messaging round-trip is initiated in order to send the inner request message(s). The original request message containing the $send operation is called the outer request message. The requester of the outer request message is called the outer requester. The responder of the outer request message is called the outer responder. The requester of the inner request message is called the inner requester. The responder of the inner request message is called the inner responder. This new XDI messaging round-trip is executed between the inner requester and the inner responder. An inner message may itself contain one or more $send request operations which in turn have their own inner messages. This results in a chain of multiple inner messages. The $send operation is the basis for many common messaging patterns (see ). TODO: describe here how a original responder delivers inner messages to the inner responder. TODO: describe how the inner message is sent, i.e. the role of XDI discovery, bindings, and routing. TODO: describe how a inner message may be manipulated before being sent (either due to XDI attributes, or endpoint configuration, e.g. to add signature). TODO: describe how link contracts authorize inner messages (should this be in XDI policy?)
<code>$push</code> operation The $push operation represents a notification triggered by a push contract (see ). This operation is specified in TODO: "light"/"content" terminology?
<code>$push</code> applied to an address The provided address indicates a light push. The provided address MUST be the address of the context that has changed.
<code>$push</code> applied to an inner graph The provided inner graph indicates a content push. The provided inner graph MUST be the message that triggered the push contract.
Executing the <code>$push</code> Operation TODO: Describe here how a subscriber executes incoming push messages from a publisher. Note that when a push message is executed against a subscriber's target graph, it may itself fulfill the conditions in , which in turn results in a new push message. This can cause a chain reaction of push messages sent between an arbitrary number of peers. When a push contract is in place, it SHOULD exist both in the publishing peer's graph and in the subscribing peer's graph. The existence of the push contract in the subscribing peer's graph serves as authorization for incoming pushes from the publishing peer's graph. TODO: authorization should be covered in XDI policy, not here
<code>$do</code> operation This operation provides an extensibility mechanism for performing potentially complex operations on a target graph that are not defined by this specification. Such complex operations may be sequences composed of basic operations, or follow an external logic that cannot be reproduced by basic operations at all. For example, an operation called $do#cleanup may be defined to "clean up", i.e. delete, various parts of a graph, according to a pre-defined set of rules. Implementors SHOULD document exactly how such operations behave when applied to addresses and inner graphs, and provide examples, following the pattern used in this specification to document the basic operations.
Message Execution A message envelope MAY contain more than one message subgraph. A message MAY contain more than one operation statement. An XDI endpoint MUST execute all messages in a message envelope. An XDI endpoint MUST execute all operation statements within a message.
Order In the XDI graph model as a whole, XDI statements are unordered. Messages within a message envelope (i.e., within the <--sender-->[$msg] collection) MAY be explicitly ordered by appending the @~<--digit-->ordering context to the <--sender-->[$msg]!<--id--> context. Operation statements within a message (i.e., as objects of the <--operation--> predicate) MAY be explicitly ordered by appending the @~<--digit--> ordering context to the <--operation--> predicate. Explicit ordering of messages and operations is OPTIONAL for an XDI client. Support for explicit ordering of messages and operations is REQUIRED for an XDI endpoint. If explicit ordering of messages and operations is not used, then an XDI endpoint MUST NOT make guarantees about the order in which messages in a message envelope are executed, or about the order in which operations in a message are executed. An XDI endpoint MUST guarantee that all operations in one message are executed before operations in another message are executed.
Message Instantiation Message instantiation is a function which instantiates a new message from a message template. This function may be invoked in the following ways: When the $send operation is executed on an address of a message template (see ). Through other mechanisms that are out of scope of this specification. The function's input parameters are: A message template identified by a {$msg} context. A variable assignment for the variable {$from}. This is used as the sending peer of the instantiated message (see ). A variable assignment for the variable {$to}. This is used as the receiving peer of the instantiated message (see ). A variable assignment for the variable {$contract}. This is used as the address of the link contract of the instantiated message (see ). A list of additional variable assignments that may be required by the message template. The function's output is an instantiated message. The function operates as follows: TODO: formal description of the message instantiation function Example: Given the following input parameters: The message template is $get{$msg} (see ). The variable {$from} is assigned the value =!:uuid:2222. The variable {$to} is assigned the value =!:uuid:3333. The variable {$contract} is assigned the value (=!:uuid:3333/=!:uuid:2222)$get$contract. The variable {$get} is assigned the value =!:uuid:3333<#email>. Then the instantiated message is as follows: =!:uuid:2222[$msg]*!:uuid:m-2/$from/(=!:uuid:2222) =!:uuid:2222[$msg]*!:uuid:m-2/$to/(=!:uuid:3333) =!:uuid:2222[$msg]*!:uuid:m-2/$contract/(=!:uuid:3333/=!:uuid:2222)$get$contract =!:uuid:2222[$msg]*!:uuid:m-2$do/$get/=!:uuid:3333<#email>
Error Handling Rules EDITORIAL NOTE: This section is not ready for review. The template for an error message is: ERROR TIMESTAMP $error<$t>/&/<--timestamp--> ERROR CODES $error/$contract/<--error-code--> <error-statement> is an inner graph of error statements pertaining to the message. The dictionary for XDI error code statements is still being defined. See MessagingErrorCode.
Error Codes EDITORIAL NOTE: This section is not ready for review. Error codes NameCodeExplanation Request unknown$false/$error/$request$unknownRequest format is unknown. (E.g. request does not contain operation xdi statement.) Can't process request$false/$error/$request$cant$processGeneral error, such as internal exception, db connection failure, or other not described by another error. Request forbidden$false/$error/$request$forbiddenOperations in request are not allowed by link contract sent by client. Supported auth type$false/$error/$supported$auth$type$AUTHTYPERequest was denied together with $request$forbidden error code with supported auth types must be returned to let client know, maybe it used wrong auth type. Authorization data invalid$false/$error/$auth$data$invalidE.g. OpenID token is expired or invalid. Node does not have child$false/$error/$node$does$not$have$child$get operation requested node that does not have child, so nothing to return. Graph not found$false/$error/$graph$not$foundGraph with specified id was not found on XDI Server.
Transactional Integrity EDITORIAL NOTE: This section is not ready for review. The XDI TC has discussed [[https://en.wikipedia.org/wiki/Database_transaction|transactional integrity]], including ACID and BASE, but has not yet determined the requirements that XDI messaging will need to support.
Acknowledgements This specification was written with the generous and appreciated assistance of Dollar Words This appendix contains formal definitions of the XDI dollar words introduced by this specification. Examples This appendix contains XDI messaging examples. Standard Message Templates The message templates defined in this section MUST be recognized by XDI processors to be part of the common graph. They can be used for message instantiation (see ).
Standard Get Message Template The purpose of the standard get message template is to execute a $get operation on a certain subgraph identified by the {$get} variable. The standard get message template: $get{$msg}$do/$get/{$get} Example instantiated get message: =!:uuid:1111[$msg]*!:uuid:m-1$do/$get/=!:uuid:2222<#email>
Common Messaging Patterns This section describes a number of non-normative messaging patterns that build on the various operations defined by this specification. These patterns are designed for various common data sharing and communication use cases.
Invitations An invitation is a $send request operation with an inner message whose responder is equal to the requester of the outer message. In other words, it is a way for a requester to "invite" a responder to send a request back to the original requester. The requester of the $send operation (and thus the responder of the inner message) is called inviting peer (or short inviter). The responder of the $send operation (and thus the requester of the inner message) is called invited peer (or short invitee). In many cases, the inner message contains a $connect request operation. This enables a requester to "invite" a responder to send a request for a new link contract to the original requester. The invitation typically references the invitee's send link contract (see ). The inviter typically sets up an instance of the standard message digest link contract template (see ) to ensure that the inner message – if accepted by the invitee – is automatically approved when received by the inviter. Example message digest link contract instance set up by the inviter: (=!:uuid:1111/=!:uuid:2222)$msg$digest$contract$do/$all/ (=!:uuid:1111/=!:uuid:2222)($msg$digest$contract$do$if/$true){$msg}<$digest>/&/"...digest..." Example invitation from inviter =!:uuid:1111 to invitee =!:uuid:2222: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) =!:uuid:1111[$msg]*!:uuid:m-1/$contract/(=!:uuid:2222/$send)$contract (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2/$to/(=!:uuid:1111) (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2/$contract/(=!:uuid:1111/=!:uuid:2222)$msg$digest$contract (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2$do/$connect/$get{$contract} (=!:uuid:1111[$msg]*!:uuid:m-1$do/$send)=!:uuid:2222[$msg]*!:uuid:m-2$connect{$get}/$is/=!:uuid:1111<#email>
Masquerading Masquerading is a $send request operation with an inner message whose requester is different from the responder of the outer message. In other words, it is a way for a requester to ask a responder to "masquerade" as an arbitrary peer when sending the inner message.
Approval of a Deferred Request Message If a request message is deferred due to link contract policy (see ), it can be approved by "re-sending" it as an inner message of a new $send request operation. The outer message of the $send operation is called approval message. The responder of an outer message (the approval message) is equal to responder of the inner message (the deferred message). In many cases, the requester and responder of an approval message are equal, and the root link contract is used. In other words, an XDI actor approves a deferred message that was sent to its own graph. Note that the approval message will trigger the deferred push contract (see ) that was automatically created for the deferred request message. Example request message deferred due to link contract policy: =!:uuid:1111[$msg]*!:uuid:m-1/$from/(=!:uuid:1111) =!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) =!:uuid:1111[$msg]*!:uuid:m-1/$contract/(=!:uuid:2222/$connect)$contract =!:uuid:1111[$msg]*!:uuid:m-1$do/$connect/$get{$contract} =!:uuid:1111[$msg]*!:uuid:m-1$connect{$get}/$is/=!:uuid:2222<#email> Example approval message: =!:uuid:2222[$msg]*!:uuid:m-2/$from/(=!:uuid:2222) =!:uuid:2222[$msg]*!:uuid:m-2/$to/(=!:uuid:2222) =!:uuid:2222[$msg]*!:uuid:m-2/$contract/(=!:uuid:2222/=!:uuid:2222)$contract (=!:uuid:2222[$msg]*!:uuid:m-2$do/$send)=!:uuid:1111[$msg]*!:uuid:m-1/$to/(=!:uuid:2222) (=!:uuid:2222[$msg]*!:uuid:m-2$do/$send)=!:uuid:1111[$msg]*!:uuid:m-1/$contract/(=!:uuid:2222/$connect)$contract (=!:uuid:2222[$msg]*!:uuid:m-2$do/$send)=!:uuid:1111[$msg]*!:uuid:m-1$do/$connect/$get{$contract} (=!:uuid:2222[$msg]*!:uuid:m-2$do/$send)=!:uuid:1111[$msg]*!:uuid:m-1$connect{$get}/$is/=!:uuid:2222<#email>
Rejection of a Deferred Request Message If a request message is deferred due to link contract policy Example
Delegation TODO: Describe how one peer can be a delegate of another peer. TODO: Common example is an XDI agent acting as a delegate of an XDI endpoint. TODO: Maybe mention app clouds and app instances and app sessions.