]>
&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 DanBlum Respect Network dan.blum@respect.network MarkusSabadello Danube Tech markus@danubetech.com DrummondReed XDI.org drummond.reed@xdi.org &pubdate; 2017 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 standard structure and vocabulary of XDI authorization statements, including XDI link contracts and policy expressions, so they are portable across all XDI endpoints.. Citation format When referencing this specification the following citation format should be used: OASIS-XDI-Link-Contracts-V1.0 OASIS XDI Link Contracts V1.0 &pubdate;. OASIS &standard;. &latest-loc;/&name;.html. Notices Copyright © OASIS® Open 2017. 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 standard structure and vocabulary of XDI authorization statements, including XDI link contracts and policy expressions, so they are portable across all XDI endpoints. This builds on the basic XDI graph model (see ) and on XDI Messaging (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-v1.0-csd01.xml">OASIS XDI 1.0 Core Specification</ulink> Joseph Boyle, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-core.html. OASIS-XDI-Messaging-V1.0 &pubdate; <ulink url="../xdi-messaging-1.0/xdi-messaging-1.0-wd04.xml">OASIS XDI 1.0 Messaging Specification</ulink> Markus Sabadello, Drummond Reed. OASIS &standard;. &latest-loc;/xdi-messaging.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-Cryptography-V1.0 &pubdate; <ulink url="../xdi-cryptography-1.0/xdi-cryptography-1.0-wd01.xml">OASIS XDI 1.0 Cryptography Specification</ulink> Markus Sabadello. OASIS &standard;. &latest-loc;/xdi-cryptographic-profiles.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 Link Contracts To meet the security and privacy requirements of XDI-based systems acting for different authorities, the XDI protocol enables systems to precisely describe access and usage rights to the data they control. In order for these rights to be enforced uniformly by all XDI authorities to which they are granted, XDI authorization is described in XDI itself. This includes the ability to express any policy governing authorization and for policies to reference data, variables, relations, and other statements in the relevant XDI graphs. XDI’s primary policy building blocks are a protocol for message operations, a policy expression syntax (using boolean constructs) and the link contract. The link contract is an access control mechanism designed to work equally well in either a centralized, or distributed (peer to peer) model.
Terminology XDI policy: The rules and practices by which XDI authorities protect information graphs from unauthorized access operations, or unauthorized usage. Authorizing authority (AA): The entity or organization controlling an XDI graph to which it may authorize access. Requesting authority (RA): An entity or organization requesting access to an AA’s graph. Operational policies: Control access to the graph. They can be specified in XDI link contracts or XDI messages and optionally make use of conditional policy expressions. Usage policies: Specify RA’s permissions to use data from the AA’s graph once the data is accessed. In many cases the obligation to honor a usage policy must be specified in a legal (or other) agreement for it to be effective. Conditional policy expressions: Boolean reserved words and patterns for use in XDI policies. Other policy variables: Time and other variables may be used in policy expressions. XDI message: An XDI subgraph exchanged between XDI authorities to accomplish an XDI operation ($get, $set, $del) against information in a target graph. Link contract: An XDI subgraph used for access control, or authorization between an AA and an RA. It is a machine-readable agreement describing data shared and permissions granted by one XDI authority to another. A link contract describes both the policy that must be satisfied by an XDI message to be accepted and the permissions granted to the RA if those conditions are met. Link contracts may be used to apply and enforce any type of policy over shared data and messages, including security, privacy, re-sharing, synchronization, and termination. The parties to the instantiation of a link contract are: Authorizing Authority (AA): the XDI authority authorizing a link contract granting permissions to an XDI graph. Requesting Authority (RA): the XDI authority requesting a link contract to obtain permissions to an XDI graph. Template Authority (TA): the XDI authority publishing a link contract template, which may or may not be the requesting authority or authorizing authority.
Link Contract Model By default, no one has access to data in an XDI graph unless access is granted through a link contract. An XDI authority SHOULD create a root link contract to express its access rights to its whole graph. If parts of the graph are to be shared publicly with external services, the controlling authority SHOULD create a public link contract allowing anonymous access to them. If parts of the graph are to be shared with other authorities, the controlling authority can create generic or specific link contract instances for them through link contract instantiation exchanges. The permissions granted by link contracts may cover any desired context(s) or statement(s) in a graph. Some link contracts such as root link contracts (see ) may grant permissions that cover an entire graph. All access to a graph occurs via XDI messages. XDI messages may be submitted to the graph for policy evaluation through local APIs or over a network interface. An XDI graph may be controlled by one authority yet contain sub-graphs that are controlled by other authorities. These sub-graphs are expressed as peer roots to mark them clearly as originating from another authority. When the two authorities choose to cooperate, the authority containing the subgraph should respect the originating authority’s link contracts. Per the XDI policy model, all access to graphs is controlled through link contracts. Some of these are general link contracts – such as the root link contract and the public link contract – to set default policies over a broad graph context. Other link contracts enable relationships with specific external authorities (such as an individual person) or generic types of authorities (such as "all customers" or "all friends"). Link contracts reflecting relationships among authorities can be created from link contract templates through the link contract instantiation process (see ). TODO: Add language about legal aspects as well as human-readable parts of link contracts.
Link Contracts A link contract is represented as an XDI entity in a graph. It may be either an entity singleton identified by a $contract context: (<--AA-->/<--RA-->)<--TA--><--ID-->$contract Or it may be a member of an entity collection identified by a [$contract] context. (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id--> A context node representing a link contract contains various statements that make up the semantics and purpose of the link contract. Following are the statements that are common to all link contracts (shown in statement format). This is called the common link contract pattern. Labels in <--this-form--> represent pattern variables. Note: This pattern uses the collection form [$contract]<--link-contract-id-->, although the singleton form $contract can equally be used. (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$do/<--permission-->/<--AA--><--object-graph--> (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$do$if/<--execution-policy--> (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$defer$if/<--defer-policy--> (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$defer$push$if/<--defer-push-policy--> (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$use$if/<--usage-policy--> (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$del$if/<--deletion-policy--> (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$msg/<--trigger-message--> (<--AA-->/<--RA-->)<--TA--><--ID-->[$contract]<--link-contract-id-->$msg$do$if/<--trigger-policy--> Where: <--AA--> is the XDI address of the authorizing authority. <--RA--> is the XDI address of the requesting authority. <--TA--> is the XDI address of the template authority. <--ID--> is an OPTIONAL context for specialization of the singleton $contract or collection [$contract]<--link-contract-id-->. It can serve as a "qualifier" or "tag" that describes the intention of the link contract, e.g. #registration. <--link-contract-id--> is a unique immutable ID for a member of a link contract collection. <--permission--> is an permission granted by this link contract (e.g., $get, $set, $del, or $do<--extension-->). <--object-graph--> is the XDI graph that is the object of the operations permitted by the link contract. <--execution-policy--> is an XDI policy that decides if a request message gets executed. <--defer-policy--> is an XDI policy that decides if a request message gets deferred. <--defer-push-policy--> is an XDI policy that decides if a request message gets deferred with a push link contract. <--usage-policy--> is an XDI policy that expresses the purpose for which the link contract may be used. <--deletion-policy--> is an XDI policy that decides if the link contract gets deleted. <--trigger-message--> is an XDI message that gets executed if decided by the <--trigger-policy-->. <--trigger-policy--> is an XDI policy that decides if the <--trigger-message--> gets executed. TODO: Describe "generic" (<--AA-->/<--RA-->) vs. "specific" (<--AA-->/<--class-->) link contracts. TODO: Describe link contracts involving groups.
Permissions Each relational <--permission--> predicate in the $contract or [$contract]<--link-contract-id--> context MUST define a permission granted by the link contract to a request message. The <--object-graph--> of each <--permission--> predicate defines the context(s) or statement(s) that are covered by the permission.
Execution Policy A link contract MAY contain an execution policy. This policy is evaluated to decide if a request message gets executed by a responder. Evaluation of this policy (see ) is part of the overall link contract evaluation process (see ). For example, an execution policy might require a requester using the link contract to: Be an employee of a company. Be under or over a certain age. Have a certain reputation or trust level.
Defer Policy A link contract MAY contain a defer policy. This policy is evaluated to decide if a request message gets deferred by a responder. Evaluation of this policy (see ) is part of the overall link contract evaluation process (see ).
Defer Push Policy A link contract MAY contain a defer push policy. This policy is evaluated to decide if a request message gets deferred by a responder, and a push link contract is created. Evaluation of this policy (see ) is part of the overall link contract evaluation process (see ).
Usage Policy Link contract instances MUST grant required usage permissions (otherwise no LC instance would be created). TODO: Describe how the usage policy works.
Deletion Policy A link contract MAY contain a deletion policy. This policy is evaluated to decide if the link contract gets deleted. This policy has no effect on the current request message, i.e. the request message can still get executed or deferred even if the link contract gets deleted. This policy is independent of other policies, i.e. is evaluated whether the current request message is executed, deferred, or rejected. Evaluation of this policy (see ) is part of the overall link contract evaluation process (see ).
Trigger Message A link contract MAY contain a trigger message. This XDI message gets executed if decided by the trigger policy. It may apply operations to modify the link contract itself or other parts of the target graph. Evaluation of this policy (see ) is part of the overall link contract evaluation process (see ).
Trigger Policy A link contract MAY contain a trigger policy. This policy is evaluated to decide if the trigger message gets executed. This policy has no effect on the current request message. This policy is independent of other policies, i.e. it is evaluated whether the current request message is executed, deferred, or rejected. Evaluation of this policy (see ) is part of the overall link contract evaluation process (see ).
Other Parameters Link contracts meant to serve official or business purposes that may have compliance or other legal significance SHOULD be time stamped, versioned and signed and contain a copy of the generating LC template for audit purposes. Note: $v (version) could be used as well if a link contract instance was changed (which is allowed as long as it is not violating the template).
Link Contract Templates A link contract template is represented as an XDI entity in a graph. It is an entity singleton identified by a {$contract} context: <--TA--><--ID-->{$contract} Where: <--TA--> is the XDI address of the template authority. <--ID--> is an OPTIONAL context for specialization of the singleton {$contract}. It can serve as a "qualifier" or "tag" that describes the intention of the link contract template, e.g. #registration. A context node representing a link contract template contains various statements that make up the semantics and purpose of the link contract template. Following are the statements that are common to all link contract templates (shown in statement format). Labels in <--this-form--> represent pattern variables. <--TA--><--ID-->{$contract}$do/<--permission-->/{$to}<--object-graph-->
Permissions Each relational <--permission--> predicate in the {$contract} context MUST define a permission granted by the link contract template to a request message. A template can indicate whether a requested permission is mandatory or optional using the reserved word $required. <--TA--><--ID-->{$contract}$do/<--operation-->/{$to}<--object-graph--><$required>/&/true ##mandatory <--TA--><--ID-->{$contract}/<--operation-->/{$to}<--object-graph--><$required>/&/false ## optional TODO: bad syntax here
Stating Policy Expressions A link contract template MAY contain one or more policy expression branches. They express the policies requested that an AA apply to allow or deny XDI messages that claim to be authorized under the link contract. <--TA--><--ID-->{$contract}$do$if/<--policy expression-->
Requesting Usage Permissions An operational permission leaving usage permissions unspecified is, in effect, requesting blanket permissions. RAs SHOULD request more specific usage permissions for the data in an <--object-graph--> using the $use reserved word and the $opt reserved word in their link contract template. Additionally, RA’s SHOULD use the $required and $default reserved words for an opt-in patterns. <--TA--><--ID-->{$contract}$use{<$opt>}<$required>/&/true ## opt in is required <--TA--><--ID-->{$contract}$use{<$opt>}<$default>/&/false <--TA--><--ID-->{$contract}$use{<$opt>}<--language-->//&/"human readable explanation"
Other Attributes Templates for link contracts meant to serve official or business purposes that may have compliance or other legal significance SHOULD be labeled, time stamped, signed and/or version-numbered. <--TA--><--ID-->{$contract}<--language-context-->//&/"human readable label" <--TA--><--ID-->{$contract}<$template><$add>{<$t>}//&/<--UTC time--> <--TA--><--ID-->{$contract}<-- signature-context --> TBD: version
Policies An XDI policy contains a set of conditions that are used by XDI link contracts and XDI messages. An XDI policy is always evaluated in an evaluation context, and the result is always the boolean value true or false. Policies are used for different purposes in XDI: A link contract's execution policy, defer policy, defer push policy, deletion policy, and trigger policy are part of the link contract and therefore the target graph. They enable an XDI endpoint to decide if a request message is authorized and how it is handled. A message policy is part of the request message. It provides a way for an XDI client to request execution of the request message only if certain conditions are met. XDI link contract policies and XDI message policies are evaluated by the XDI endpoint that hosts the target graph and receives the request message. A data usage policy controls usage of the requested data outside the scope of XDI enforcement. Data usage policies are attached to a link contract controlling access to part of the target graph. XDI data usage policies are evaluated by the authority that holds the data to which the XDI data usage policy applies. This may be the XDI endpoint that hosts the target graph, or it may be any other XDI endpoint or XDI client which has retrieved the data (and the XDI data usage policy along with it). Note: More work on data usage policies may come in the future, including the possibility of attaching them to the data itself rather than the link contract. Usage policies are supported in this working draft primarily as a basic privacy mechanism to prevent undesired copying of data when RAs and AAs are part of a trust framework supporting these policies. Policy expressions MUST follow the patterns and include applicable reserved words as specified below.
Policy Expression Pattern A policy MUST consist of one or more XDI statements in the following pattern: <--policy-context-->$if<--boolean-context-->/<--boolean-operator-->/<--condition--> Where: <--policy-context--> is the context of the policy expression, e.g. an XDI link contract or an XDI message. <--boolean-context--> is an optional hierarchy of subcontexts expressing the XDI boolean operators ($and, $or, $not) needed to construct a boolean logic tree. <--boolean-operator--> is either $true or $false and expressed whether a condition must be true or false. <--condition--> is either a comparison condition ($is, $equals, $matches, $greater, $lesser), or an arbitrary XDI statement.
<code>$if</code> Policy Context $if defines the root context node of a policy subgraph. $if MUST be a child context of a $contract context (the root context of an XDI link contract or the operation context of an XDI message). $if MUST be an entity singleton. $if MAY have zero or more boolean subcontexts. $if MAY have zero or more operator predicates. $if evaluates to true, if ANY of its boolean subcontexts evaluate to true, OR ANY of its operator predicates evaluate to true. $if evaluates to false, if it has neither boolean subcontexts nor operator predicates.
Boolean Contexts
<code>$and</code> Boolean Context $and is the boolean context expressing logical conjunction. $and MAY be an entity singleton for a single logical conjunction. $and MUST be an entity collection if there are multiple logical conjunctions that must be evaluated independently. $and MAY have zero or more boolean subcontexts. $and MAY have zero or more operator predicates. $and evaluates to true, if ALL of its boolean subcontexts evaluate to true, AND ALL of its operator predicates evaluate to true $and evaluates to true, if it has neither boolean subcontexts nor operator predicates.
<code>$or</code> Boolean Context $or is the boolean context defining logical disjunction. $or MAY be an entity singleton for a single logical disjunction. $or MUST be an entity collection if there are multiple logical disjunctions that must be evaluated independently. $or MAY have zero or more boolean subcontexts. $or MAY have zero or more operator predicates. $or evaluates to true, if ANY of its boolean subcontexts evaluate to true, OR ANY of its operator predicates evaluate to true. $or evaluates to false, if it has neither boolean subcontexts nor operator predicates.
<code>$not</code> Boolean Context $not is the boolean context defining logical negation. $not MAY be an entity singleton for a single logical negation. $not MUST be an entity collection if there are multiple logical negations that must be evaluated independently. $not MUST either have exactly one boolean subcontext, OR have exactly one operator predicate. $not evaluates to true, if its single boolean subcontext evaluates to false, OR its single operator predicate evaluates to false. $not evaluates to false, if it has neither boolean subcontexts nor operator predicates.
Boolean Operators
<code>$true</code> Operator $true is the boolean operator expressing that a condition statement MUST be true. $true evaluates to true, if its condition statement evaluates to true.
<code>$false</code> Operator $false is the boolean operator expressing that a condition statement MUST be false. $false evaluates to true, if its condition statement evaluates to false.
Conditions
<code>$is</code> Condition $is expresses that the subject and object nodes of the condition represent the same logical entity (see the EquivalenceLinks proposal). $is evaluates to true, if the subject node and object node of the condition represent the same logical entity.
<code>$equals</code> Condition $equals expresses that the subject and object nodes of the condition have the same literal values. $equals evaluates to true, if both the subject node and object node of the condition identify an XDI literal, AND the literal values are equivalent.
<code>$matches</code> Condition $matches expresses that the literal value of the subject node of the condition matches the regular expression specified in the literal value of the object node of the condition. [TODO: define which regular expression syntax to use] $matches evaluates to true, if both the subject node and object node of the condition identify an XDI literal, AND the literal value of the subject node of the condition matches the regular expression specified in the literal value of the object node of the condition.
<code>$greater</code> Condition $greater expresses that the literal value of the subject node of the condition must be greater than the literal value of the object node of the condition. $greater evaluates to true, if both the subject node and object node of the condition identify an XDI literal, AND both literal values are numerical, AND the numerical literal value of the subject node is greater than the numerical literal value of the object node.
<code>$lesser</code> Condition $lesser expresses that the literal value of the subject node of the condition must be lesser than the literal value of the object node of the condition. $lesser evaluates to true, if both the subject node and object node of the condition identify an XDI literal, AND both literal values are numerical, AND the numerical literal value of the subject node is lesser than the numerical literal value of the object node.
Statement Condition If a condition is used that does not correspond to any of comparison conditions ($is, $equals, $greater, $lesser), it is considered to be an arbitrary XDI statement. The statement condition evaluates to true, if the statement exists in the target graph.
Usage Permissions The following reserved words are proposed for usage policy expression, also called usage permissions. See the example section for the use of the $use branch within a detailed link contract instantiation scenario.
<code>$use</code> Included within a link contract instance to specify the context of usage. Uses the $opt, $required, $default and other reserved words. The $use pattern makes use of $opt and other patterns.
<code>$opt</code> Included within a $use subgraph support the opt-in process associated with a link contract giving a requesting authority access to data.
<code>$required</code> Provides a mechanism within $opt for the requesting authority to declared whether a requested data item is optional or required. Note that a request for a link contract granting access to data may contain multiple elements, some optional and some required for the operation to succeed.
<code>$default</code> Specifies whether the usage permission is $true or $false by default (e.g. opt-in or opt-out).
Link Contract Evaluation TODO
Policy Evaluation In order to evaluate a policy to either true or false, an evaluation context has to be defined. This evaluation context depends on the purpose of the policy that is being evaluated. At a minimum, an evaluation context MUST define a policy evaluation graph that is used as a basis to evaluate the policy's conditions. An evaluation context typically also supplies values for variables that are used by the policy. For a link contract's execution policy, defer policy, and defer push policy, as well as for a message policy, the evaluation context is defined as follows: The policy evaluation graph is defined to be the target graph of the request message that is being executed. The value of the {$from} variable is defined to be the sender of the request message. During the policy evaluation process, {$from} MUST be replaced by the XDI address of the sender of the request message. The value of the {$msg} variable is defined to be the context of the request message. During the policy evaluation process, {$msg} MUST be replaced by the context of the request message. For a data usage policy, the evaluation context is constructed as follows: The policy evaluation graph is defined to be the graph that contains the data usage policy.
Link Contract Instantiation Link contract instantiation is a function which instantiates a new link contract from a link contract template. This function may be invoked in the following ways: When the $connect operation is executed (see ). When a request message is deferred (see ). Through other mechanisms that are out of scope of this specification. The function's input parameters are: A link contract template identified by a {$contract} context. A variable assignment for the variable {$from}. This becomes the requesting authority of the instantiated link contract. A variable assignment for the variable {$to}. This becomes the authorizing authority of the instantiated link contract. A list of additional variable assignments that may be required by the link contract template. An instance flag that states whether the link contract is instantiated as a $contract entity singleton or as an instance in a [$contract] entity collection. The function's output is an instantiated link contract. The function operates as follows: TODO: formal description of the link contract instantiation function Example: Given the following input parameters: The link contract template is $get{$contract} (see ). The variable {$from} is assigned the value =!:uuid:1111. This is the same variable used for the sender of an XDI message. The variable {$to} is assigned the value =!:uuid:2222. This is the same variable used for the receiver of an XDI message. The variable {$get} is assigned the value =!:uuid:2222<#email>. The instance flag is set to "entity singleton". Then the instantiated link contract is as follows: (=!:uuid:2222/=!:uuid:1111)$get$contract$do/$get/=!:uuid:2222<#email> (=!:uuid:2222/=!:uuid:1111)($get$contract$do$if$and/$true){$from}/$is/=!:uuid:1111 (=!:uuid:2222/=!:uuid:1111)($get$contract$do$if$and/$true){$msg}<$sig><$valid>/&/true
Push Link Contracts A push link contract is a link contract that establishes a publish/subscribe relationship between peers. It enables a peer called publishing peer (or short publisher) to notify one or more other peers called subscribing peers (or short subscribers) of changes in a graph for which the publisher is authoritative. A publish/subscribe relationship between a publishing authority and a subscribing authority is modeled as a link contract with certain properties. This link contract is called a push link contract (or short push contract). A push contract conforms to the link contract pattern (see ), and in addition MUST meet the following conditions: The link contract's authorizing authority is the publisher. The link contract's requesting authority is the subscriber. The link contract contains one or more $push permissions. The link contract MAY contain permissions other than $push. The link contract MAY contain one or more push target endpoint URIs. The link contract MAY contain the content flag which specifies whether a subscriber wishes to use light pushes or content pushes. Following is the basic structure of a push contract. Labels in <--this-form--> represent template variables. (<--publisher-->/<--subscriber-->)$contract$do/$push/<--target-address--> (<--publisher-->/<--subscriber-->)$contract/$to/<--subscriber--> (<--publisher-->/<--subscriber-->)($contract/$push)<$xdi><$uri>/&/"<--subscriber endpoint-->" (<--publisher-->/<--subscriber-->)($contract/$push)<$content>/&/<--light-or-content-push--> If the push contract does not contain at least one push target endpoint URI, the subscriber's XDI endpoint MUST be discovered using the XDI Discovery protocol. This XDI endpoint MUST then be used as the single push target endpoint URI of the push contract. If the content flag is absent, the default value false (i.e. use light pushes) MUST be assumed. Like all link contracts, push contracts are unidirectional and only apply to data in the authorizing authority's graph. In order to set up a bi- or multidirectional publish/subscribe relationship, two or more push contracts can be created in which multiple peers simultaneously fulfill the publisher and subscriber roles.
Triggering a Push Link Contract A push contract is triggered when the following conditions are met: An operation is executed against a graph that contains one or more push contracts. The operation is not a $get operation. The target of the operation is a sub-context of any context that is the target of a $push permission of at least one of the push contracts in the graph. When a push contract is triggered, it initiates one or more XDI messaging round-trips to notify subscribers. The notification is itself an XDI message. This message is called a push message (or short push). A push message MUST conform to the request message pattern (see ) and in addition MUST meet the following conditions: The push message uses the $push request operation (see ). TODO: describe better how a push message is generated and sent TODO: describe better how the $push operation is used TODO: describe how a push contract's policy must be evaluated by both sender and receiver TODO: describe who in the $push message is the requester and who is responder
Standard Link Contract Templates The link contract templates defined in this section MUST be recognized by XDI processors to be part of the common graph. They can be used for link contract instantiation (see ).
Standard Root Link Contract Template The purpose of the standard root link contract template is to instantiate link contracts with a $all permission on an entire graph ("root access"). The address of this link contract template is $all{$contract}. Its policy authorizes messages only from a single specific requester and requires either a valid signature or a valid secret token. The standard root link contract template is typically instantiated as a $contract entity singleton, since for any given relationship between two peers, having one root link contract is sufficient. The standard root link contract template $all{$contract}: $all{$contract}$do/$all/ ($all{$contract}$do$if$and/$true){{$from}}/$is/{$from} ($all{$contract}$do$if$and$or/$true){{$msg}}<$secret><$token><$valid>/&/true ($all{$contract}$do$if$and$or/$true){{$msg}}<$sig><$valid>/&/true Example instantiated root link contract: (=!:uuid:2222/=!:uuid:1111)$all$contract$do/$all/ (=!:uuid:2222/=!:uuid:1111)($all$contract$do$if$and/$true){$from}/$is/=!:uuid:1111 (=!:uuid:2222/=!:uuid:1111)($all$contract$do$if$and$or/$true){$msg}<$secret><$token><$valid>/&/true (=!:uuid:2222/=!:uuid:1111)($all$contract$do$if$and$or/$true){$msg}<$sig><$valid>/&/true
Standard Operation Link Contract Templates A standard operation link contract template is defined for each one of the XDI operations $get, $set, $add, $mod, $del, $connect, $send, and $push. The addresses of these link contract templates are accordingly $get{$contract}, $set{$contract}, $add{$contract}, $mod{$contract}, $del{$contract}, $connect{$contract}, $send{$contract}, and $push{$contract}. The purpose of a standard operation link contract template is to instantiate link contracts with a single permission on a certain subgraph identified by a variable. The variable corresponds to the operation, e.g. the variable {$get} is used for the $get{$contract} link contract template. Its policy authorizes messages only from a single specific requester and requires a valid signature. A standard operation link contract template is typically instantiated as an instance in a [$contract] entity collection, since for any given relationship between two peers, multiple operation link contracts may exist. All standard operation link contract templates follow the pattern defined in this section, except for $push{$contract}, which is defined in the next section. The standard operation link contract template $get{$contract}: (Note: the same pattern applies for the other standard operation link contract templates except $push{$contract}: $get{$contract}$do/$get/{$get} ($get{$contract}$do$if$and/$true){{$from}}/$is/{$from} ($get{$contract}$do$if$and/$true){{$msg}}<$sig><$valid>/&/true Example instantiated operation link contract: (=!:uuid:2222/=!:uuid:1111)$get[$contract]*!:uuid:lc-1$do/$get/=!:uuid:2222<#email> (=!:uuid:2222/=!:uuid:1111)($get[$contract]*!:uuid:lc-1$do$if$and/$true){$from}/$is/=!:uuid:1111 (=!:uuid:2222/=!:uuid:1111)($get[$contract]*!:uuid:lc-1$do$if$and/$true){$msg}<$sig><$valid>/&/true
Standard Push Link Contract Template The purpose of the standard push link contract template is to instantiate push link contracts with a $push permission on a certain subgraph identified by the {$push} variable. The address of this link contract template is $push{$contract}. Its policy authorizes messages only from a single specific requester and requires a valid signature. The standard push link contract template is typically instantiated as an instance in a [$contract] entity collection, since for any given relationship between two peers, multiple push link contracts may exist. The standard push link contract template $push{$contract}: $push{$contract}$do/$push/{$push} $push{$contract}/$to/{($from)} ($push{$contract}$do$if$and/$true){{$from}}/$is/{$to} ($push{$contract}$do$if$and/$true){{$msg}}<$sig><$valid>/&/true Example instantiated push link contract: (=!:uuid:2222/=!:uuid:1111)$push[$contract]*!:uuid:lc-1$do/$push/=!:uuid:2222<#email> (=!:uuid:2222/=!:uuid:1111)$push[$contract]*!:uuid:lc-1/$to/(=!:uuid:1111) (=!:uuid:2222/=!:uuid:1111)($push[$contract]*!:uuid:lc-1$do$if$and/$true){$from}/$is/=!:uuid:2222 (=!:uuid:2222/=!:uuid:1111)($push[$contract]*!:uuid:lc-1$do$if$and/$true){$msg}<$sig><$valid>/&/true
Standard Deferred Push Link Contract Template The purpose of the standard deferred push link contract template is to instantiate deferred push link contracts with a $push permission on a certain subgraph identified by the {$push} variable. The address of this link contract template is $defer$push{$contract}. Its policy authorizes messages only from a single specific requester and requires a valid signature. In addition, its policy authorizes only message that are a response message to a single specific request message. The standard push link contract template is instantiated automatically every time a request message is deferred (see ). The standard deferred push link contract template is typically instantiated as an instance in a [$contract] entity collection, since for any given relationship between two peers, multiple push link contracts may exist. The standard deferred push link contract template $defer$push{$contract}: $defer$push{$contract}$do/$push/{$push} $defer$push{$contract}/$to/{($from)} ($defer$push{$contract}$do$if$and/$true){{$from}}/$is/{$to} ($defer$push{$contract}$do$if$and/$true){{$msg}}<$sig><$valid>/&/true ($defer$push{$contract}$do$if$and/$true){{$msg}}/$is$msg/{$msg} Example instantiated deferred push link contract: (=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:lc-1$do/$push/=!:uuid:2222<#email> (=!:uuid:2222/=!:uuid:1111)$defer$push[$contract]*!:uuid:lc-1/$to/(=!:uuid:1111) (=!:uuid:2222/=!:uuid:1111)($defer$push[$contract]*!:uuid:lc-1$do$if$and/$true){$from}/$is/=!:uuid:2222 (=!:uuid:2222/=!:uuid:1111)($defer$push[$contract]*!:uuid:lc-1$do$if$and/$true){$msg}<$sig><$valid>/&/true (=!:uuid:2222/=!:uuid:1111)($defer$push[$contract]*!:uuid:lc-1$do$if$and/$true){$msg}/$is$msg/=!:uuid:1111[$msg]*!:uuid:m-1
Standard Message Digest Link Contract Template The purpose of the standard message digest link contract template is to instantiate digest link contracts that only authorize a single specific message. This is achieved through a policy that requires a certain message digest value. Message digest values are described in . The standard message digest link contract template is typically instantiated as an instance in a [$contract] entity collection, since for any given relationship between two peers, multiple message digest link contracts may exist. The standard message digest link contract template $msg$digest{$contract}: $msg$digest{$contract}$do/$all/ ($msg$digest{$contract}$do$if/$true){{$msg}}<$digest>/{&}/{<$digest>} Example instantiated message digest link contract: (=!:uuid:2222/=!:uuid:1111)$msg$digest[$contract]*!:uuid:lc-1/$all/ (=!:uuid:2222/=!:uuid:1111)($msg$digest[$contract]*!:uuid:lc-1$do$if/$true){$msg}<$digest>/&/"... message digest ..."
Common Link Contract Patterns This section describes a number of non-normative link contract patterns that build on this specification. These patterns are designed for various common data sharing and communication use cases.
Root Link Contract A root link contract is a link contract with a $all permission on an entire graph ("root access"). A root link contract is typically set up for the following reasons: By a peer for itself, in order to give an XDI actor root access to its own graph for which it is authoritative. Between peers if they have a highly trusted relationship similar to the legal concepts of custodianship or guardianship (e.g. parent-child). Between XDI agents and XDI endpoints, if they are controlled by the same XDI actor. A root link contract is an instance of the standard root link contract template (see ). A root link contract is based on the generic link contract instance pattern, with the following properties: The requesting authority is set to the XDI authority. The authorizing authority is set to the XDI authority. The template ID is empty. The root link contract MUST use the singleton pattern, i.e. there MUST only be one per XDI authority. The root link contract MUST grant $all permission to the common root node of an XDI graph. The root link contract SHOULD contain a policy that restricts the sender of an XDI message to the XDI authority's subgraph. Authentication SHOULD be required for access to a root link contract. However the XDI authority is the ultimate authority for the policies pertaining to any link contract. Root link contract pattern: (<--AA-->/<--AA-->)$contract$do/$all/ (<--AA-->/<--AA-->)$contract$do$if<--policy-expression--> A root link contract contains a $all permission on an entire graph ("root access"). Example root link contract: (=!:uuid:1111/=!:uuid:1111)$contract$do/$all/ (=!:uuid:1111/=!:uuid:1111)($contract$do$if$and/$true){$from}/$is/=!:uuid:1111 (=!:uuid:1111/=!:uuid:1111)($contract$do$if$and$or/$true){$msg}<$secret><$token><$valid>/&/true (=!:uuid:1111/=!:uuid:1111)($contract$do$if$and$or/$true){$msg}<$sig><$valid>/&/true
Public Link Contract A public link contract contains $get permissions on certain limited subgraphs that are intended to be publicly available. The public link contract is based on the generic link contract instance pattern, with the following constraints: The requesting authority is set to $anon. The authorizing authority is set to the XDI authority. The template ID is set to $public. The public link contract MUST use the singleton pattern, i.e. there MUST only be one per XDI authority. The public link contract SHOULD grant $get permission to the $public subgraph of the XDI authority's subgraph. In addition, the public link contract MAY grant permissions to other parts of the XDI authority's subgraph. The public link contract SHOULD NOT contain a policy. Authentication SHOULD NOT be required for access to a public link contract. However the XDI authority is the ultimate authority for the policies pertaining to any link contract. Public Link Contract Pattern: (<--AA-->/$public)$contract$do/$get/<--AA--><--object-graph--> Note that authorities can further customize the public link contract, e.g. to prevent spam. A public link contract does not contain any policies, i.e. a request message always gets executed. Example public link contract: (=!:uuid:1111/$public)($contract$do/$get)=!:uuid:1111/$is$ref/{} (=!:uuid:1111/$public)($contract$do/$get)/$is$ref/{} (=!:uuid:1111/$public)$contract$do/$get/=!:uuid:1111$public (=!:uuid:1111/$public)$contract$do/$get/=!:uuid:1111$msg$sig$keypair<$public><$key> (=!:uuid:1111/$public)$contract$do/$get/=!:uuid:1111$msg$encrypt$keypair<$public><$key> (=!:uuid:1111/$public)($contract$do/$get)=!:uuid:1111$msg$sig$keypair/$is#/{} (=!:uuid:1111/$public)($contract$do/$get)=!:uuid:1111$msg$encrypt$keypair/$is#/{}
Connect Link Contract A connect link contract contains a $connect permission on an entire graph (see ). A connect link contract contains policies that will defer all request operations. Example connect link contract: (=!:uuid:1111/$connect)$contract$do/$connect/ (=!:uuid:1111/$connect)($contract$defer$push$if$and/$true){$msg}<$sig><$valid>/&/true (=!:uuid:1111/$connect)$contract$do$if//$not TODO: Add some explanation what role this link contract plays for $connect operations and the link contract instantiation process. Note: Previously we had the concept of a "community link contract" and a "requester link contract".
Send Link Contract A send link contract contains a $send permission on an entire graph (see ). A send link contract contains policies that will defer all request operations. Example send link contract: (=!:uuid:1111/$send)$contract$do/$send/ (=!:uuid:1111/$send)($contract$defer$push$if$and/$true){$msg}<$sig><$valid>/&/true (=!:uuid:1111/$send)$contract$do$if//$not
Policy Expression Examples
Usage Policy Examples These examples are written in statement format. Link contract policy that checks if the secret token in a message matches the secret token in the link contract: (<--AA-->/<--RA-->)$contract<$secret><$token>/&/"s3cr3t" (<--AA-->/<--RA-->)($contract$do$if/$true){$msg}<$secret><$token>/$equals/(<--AA-->/<--RA-->)$contract<$secret><$token> Link contract policy that checks if a link contract is not used after a certain time, i.e. is not expired: (<--AA-->/<--RA-->)$contract<#end><$t>/&/"2017-12-31" (<--AA-->/<--RA-->)($contract$do$if/$true){$msg}<$t>/$lesser/(<--AA-->/<--RA-->)$contract<#end><$t> Link contract policy that checks if a link contract is active, and not used before or after a certain time: (<--AA-->/<--RA-->)$contract<#active>/&/true (<--AA-->/<--RA-->)$contract<#start><$t>/&/"2017-01-01" (<--AA-->/<--RA-->)$contract<#end><$t>/&/"2017-12-31" (<--AA-->/<--RA-->)($contract$do$if$and/$true)(<--AA-->/<--RA-->)$contract<#active>/&/true (<--AA-->/<--RA-->)($contract$do$if$and/$true){$msg}<$t>/$greater/(<--AA-->/<--RA-->)$contract<#start><$t> (<--AA-->/<--RA-->)($contract$do$if$and/$true){$msg}<$t>/$lesser/(<--AA-->/<--RA-->)$contract<#end><$t> Link contract policy that checks that the message comes from one of the approved senders: (<--AA-->/<--RA-->)($contract$do$if/$true){$from}/$is/=!:uuid:2222 (<--AA-->/<--RA-->)($contract$do$if/$true){$from}/$is/=!:uuid:3333 (<--AA-->/<--RA-->)($contract$do$if/$true){$from}/$is/=!:uuid:4444 Link contract policy that excludes a certain sender: (<--AA-->/<--RA-->)($contract$do$if/$false){$from}/$is/=!:uuid:1111 Link contract policy that excludes a certain sender (other way of doing it): (<--AA-->/<--RA-->)($contract$do$if$not/$true){$from}/$is/=!:uuid:1111 Link contract to allow Bob access to Alice's phone number: =alice/$ref/=!:uuid:1111 =bob/$ref/=!:uuid:2222 =!:uuid:1111<#tel>/&/"#1-123-567-8900" (=!:uuid:1111/=!:uuid:2222)$contract$do/$get/=!:uuid:1111<#tel> (=!:uuid:1111/=!:uuid:2222)($contract$do$if/$true){$from}/$is/=!:uuid:2222 Link contract policy that checks that the message comes either from myself (=!:uuid:1111) or from one of my friends: =!:uuid:1111/#friend/=!:uuid:2222 (=!:uuid:1111/#friend)($contract$do$if$or/$true)=!:uuid:1111/$is/{$from} (=!:uuid:1111/#friend)($contract$do$if$or/$true)=!:uuid:1111/#friend/{$from} Link contract that allows a $do$signal operation to signal certain "events" on a certain "channel": (<--AA-->/<--RA-->)$contract$do/$do$signal/=!:uuid:1111[#channel]*!23[#event] (<--AA-->/<--RA-->)($contract$do$if$and/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#domain/#cloudos (<--AA-->/<--RA-->)($contract$do$if$and$or/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#type/#notification (<--AA-->/<--RA-->)($contract$do$if$and$or/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#type/#subscription (<--AA-->/<--RA-->)($contract$do$if$and$or/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#type/#deletion Combination of the previous two examples: =!:uuid:1111/#friend/=!:uuid:2222 (<--AA-->/<--RA-->)$contract$do/$do$signal/=!:uuid:1111[#channel]*!23[#event] (<--AA-->/<--RA-->)($contract$do$if$and/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#domain/#cloudos (<--AA-->/<--RA-->)($contract$do$if$and[$or]@~1/$true)=!:uuid:1111/$is/{$from} (<--AA-->/<--RA-->)($contract$do$if$and[$or]@~1/$true)=!:uuid:1111/#friend/{$from} (<--AA-->/<--RA-->)($contract$do$if$and[$or]@~2/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#type/#notification (<--AA-->/<--RA-->)($contract$do$if$and[$or]@~2/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#type/#subscription (<--AA-->/<--RA-->)($contract$do$if$and[$or]@~2/$do$signal)=!:uuid:1111[#channel]*!23[#event]{}/#type/#deletion Link contract policy that allows the message if it is not sent on Friday 13th, and it is not sent by =drummond or =markus. (Note that the weekday and day-of-month definitions still need to be defined in the XDI $ Dictionary.) (<--AA-->/<--RA-->)($contract$do$if$and[$not]@~1$and/$true)<--weekday_is_friday--> (<--AA-->/<--RA-->)($contract$do$if$and[$not]@~1$and/$true)<--day_is_13th--> (<--AA-->/<--RA-->)($contract$do$if$and[$not]@~2$or/$true)=drummond/$is/{$from} (<--AA-->/<--RA-->)($contract$do$if$and[$not]@~2$or/$true)=markus/$is/{$from}
Deletion Policy Examples Link contract that gets deleted after it expires: (<--AA-->/<--RA-->)$contract<#end><$t>/&/"2017-12-31" (<--AA-->/<--RA-->)($contract$del$if/$true){$msg}<$t>/$greater/(<--AA-->/<--RA-->)$contract<#end><$t> Link contract that gets deleted after a single use (the deletion policy always evaluates to true): (<--AA-->/<--RA-->)$contract$del//$if
Trigger Policy and Trigger Message Examples Link contract that gets deleted after it expires: (<--AA-->/<--RA-->)$contract<#end><$t>/&/"2017-12-31" (<--AA-->/<--RA-->)$contract$msg$do/$del/(<--AA-->/<--RA-->)$contract (<--AA-->/<--RA-->)($contract$msg$do$if/$true){$msg}<$t>/$greater/(<--AA-->/<--RA-->)$contract<#end><$t> Link contract that gets deactivated after it receives a message with an invalid signature: (<--AA-->/<--RA-->)$contract<#active>/&/true (<--AA-->/<--RA-->)($contract$msg$do/$set)(<--AA-->/<--RA-->)$contract<#active>/&/false (<--AA-->/<--RA-->)($contract$msg$do$if/$true){$msg}<$sig><$valid>/&/false