Solid Application Interoperability

Editor’s Draft,

This version:
https://solid.github.io/data-interoperability-panel/specification/
Issue Tracking:
GitHub
Inline In Spec
Editors:
Justin Bingham
Eric Prud'hommeaux
Josh Collins

Abstract

This specification details how Agents and Applications can safely share and interoperate over data in a Solid Pod.

Status of this document

1. Introduction

Solid affords us the opportunity to create a valuable and powerful ecosystem where people and organizations retain control of their data, but are also able to put it to work and use it to its full potential. The fundamentals of Solid make this possible, but further definition of standard methods and mechanisms must be established to make it practical, intuitive, and secure.

Note: See Problems and Goals for Interoperability in Solid for a detailed explanation of the problem space.

This specification details how Agents in the Solid ecosystem can read, write, and manage data stored in a Solid pod using disparate Applications, either individually or in collaboration with other Agents.

§ 4 Application Registration lets Agents register and track the Applications they’ve decided to use.

§ 5 Data Registration lets Agents register, organize, and lookup their data. Data is stored uniformly, avoiding complex physical hierarchies. Shape trees and shapes provide strong data validation and intuitive data boundaries.

§ 6 Data Authorization provides the means for an Agent to grant other Agents and Applications access to data in their control.

2. Agent

2.1. Overview

Agents represent the primary actors in an interoperable Solid ecosystem.

An Agent is denoted by an identity. Dereferencing that identity leads to the Agent, and a graph of useful information about them. This graph is used by the Agent to look up their own data, as well as data that has been shared with them.

An Agent is designed to be publicly accessible, but many of the things the Agent links to are designed to be private, or accessible only by other Agents or Applications that the Agent has authorized.

Consequently, other Agents and Applications can dereference the identity of an Agent to obtain the information they need to interact with them.

Most of an Agent’s information is stored in Registries. A Registry is a place where an Agent can store and find different types of data, often for particular purposes. Each type of Registry serves a specific purpose or function.

Registry Description
Application Registry Records the Applications that a given Agent uses or has given access to. See Application Registration
Data Registry Stores and organizes data types for interoperable use by different Applications and shared with other Agents See Data Registration
Access Grant Registry Records access granted to other Agents and/or Applications See Access Grants
Access Receipt Registry Tracks access that has been granted by other Agents See Access Receipts
Remote Data Registry Local references to data that has been shared by other Agents See Remote Data Registration

2.2. Data Model

2.2.1. Summary

When an Agent has more than one pod, or is managing data on behalf of another Agent, they will be linked to multiple Registries of the same type. A Registry Set is used to organize Registries of the same type together.

An Agent links to each kind of Registry Set through type-specific subproperties of interop:hasRegistrySet.

This allows one Agent to link to many Registries across the Web, without exposing those Registries in a public document. Different permissions can be assigned to each Registry Set, depending on the sensitivity of the Registries they link to.

Registry Sets link to Registries through the interop:hasRegistry property.

Agent at https://alice.pod.example/profile/id#me
<#me>
  a interop:Agent;
  ######## Registry Sets ########
  interop:hasApplicationRegistrySet <https://alice.pod.example/profile/application#set> ;
  interop:hasDataRegistrySet <https://alice.pod.example/profile/data#set> ;
  interop:hasAccessGrantRegistrySet <https://alice.pod.example/profile/grant#set> ;
  interop:hasAccessReceiptRegistrySet <https://alice.pod.example/profile/receipt#set> ;
  interop:hasRemoteDataRegistrySet <https://alice.pod.example/profile/remote#set> ;
  ######## Inboxes ########
  interop:hasInbox <https://alice.pod.example/inbox/general> ;
  interop:hasAccessInbox <https://alice.pod.example/inbox/access> .

2.2.2. Agent

An Agent is a distinct individual, group, organization, or piece of software with an identity that can be strongly authenticated.

Agent
Property Range Description
hasApplicationRegistrySet ApplicationRegistrySet Application Registry Set for the Agent
hasDataRegistrySet DataRegistrySet Data Registry Set for the Agent
hasAccessGrantRegistrySet AccessGrantRegistrySet Access Grant Registry Set for the Agent
hasAccessReceiptRegistrySet AccessReceiptRegistrySet Access Receipt Registry Set for the Agent
hasRemoteDataRegistrySet RemoteDataRegistrySet Remote Data Registry Set for the Agent
hasInbox ldp:inbox A general inbox for messages sent to the Agent
hasAccessInbox ldp:inbox An inbox for access related messages sent to the Agent

The AgentShape is used to validate an instance of the Agent class.

<#AgentShape> {
  a [ interop:Agent ] ;
  interop:hasApplicationRegistrySet IRI ;
  interop:hasDataRegistrySet IRI ;
  interop:hasAccessGrantRegistrySet IRI ;
  interop:hasAccessReceiptRegistrySet IRI ;
  interop:hasRemoteDataRegistrySet IRI ;
  interop:hasInbox IRI ;
  interop:hasAccessInbox IRI
}

The AgentTree is assigned to a resource to ensure it will validate against the AgentShape.

<#AgentTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#AgentShape> ;
  st:matchesUriTemplate "{id}" .

2.3. Resource Hierarchy

Resource Class Shape Shape Tree
/profile/ - - ProfileTree
-- id#me Agent AgentShape AgentTree
-- application#set ApplicationRegistrySet ApplicationRegistrySetShape ApplicationRegistrySetTree
-- data#set DataRegistrySet DataRegistrySetShape DataRegistrySetTree
-- grant#set AccessGrantRegistrySet AccessGrantRegistrySetShape AccessGrantRegistrySetTree
-- receipt#set AccessReceiptRegistrySet AccessReceiptRegistrySetShape AccessReceiptRegistrySetTree
-- remote#set RemoteDataRegistrySet RemoteDataRegistrySetShape RemoteDataRegistrySetTree
/inbox/access ldp:inbox - AccessInboxTree
/inbox/general ldp:inbox - -

Agent resources MAY use any resource or subject names. The names used herein have been selected for comprehension and readability.

2.4. Permission Model

The permission model for the resources detailed in § 2.3 Resource Hierarchy are illustrated in the table below.

Notable items:

Permission model for Agent resources
Agent Public Trusted Agents Other Agents Granted Access
Resource Access Access Access Subject Access
/profile/ Control - Control - -
-- id Control Read Control - -
-- application Control - Control - -
-- data Control - Control - -
-- access Control - Control - -
-- receipt Control - Control - -
-- remote Control - Control - -

3. Application

3.1. Overview

Applications are pieces of software that Agents use to access, manipulate, and manage the data in their control, and the data they’ve been granted access to.

An Application is denoted by an identity. Dereferencing that identity leads to an Application profile instance, and a graph of useful information about them.

The information in the Application profile is used during § 4 Application Registration and § 6 Data Authorization to help Agents determine whether they want to use the Application, what kind of data it needs access to, and whether they’ll willing to give it that access.

The Application profile is designed to be publicly accessible.

3.2. Data Model

3.2.1. Summary

An Application provides summary detail about itself, and its author, via properties in the Application class.

An Application identifies the types of data it requires access to by linking to Access Need Groups via the interop:hasAccessNeedGroup property.

Application at https://app.example/profile/id#app
<#app>
  a interop:Application ;
  interop:applicationName "Example Application" ;
  interop:applicationDescription "This is a description of the Example Application" ;
  interop:applicationAuthor <https://app.example/org/id#agent> ;
  interop:applicationAuthorName "Example Organization" ;
  interop:applicationThumbnail <https://app.example/profile/thumb.svg> ;
  interop:hasAccessNeedGroup <#exampleAccessNeedGroup> .

3.2.2. Application

An Application is a piece of software that an Agent uses to access, manipulate, and manage the data in their control, as well as the data they’ve been granted access to.

Application
Property Range Description
applicationName xsd:string Name of the Application
applicationDescription xsd:string Description of the Application
applicationAuthor Agent Agent that authored the Application
applicationAuthorName xsd:string Name of the Author
applicationThumbnail binary image Thumbnail for the Application
hasAccessNeedGroup AccessNeedGroup Access Need Group representing types of data the Application needs to operate

The ApplicationShape is used to validate an instance of the Application class.

<#ApplicationShape> {
  a [ interop:Application ] ;
  interop:applicationName xsd:string ;
  interop:applicationDescription xsd:string ;
  interop:applicationAuthor IRI ;
  interop:applicationAuthorName xsd:string ;
  interop:applicationThumbanil IRI? ;
  interop:hasAccessNeedGroup IRI* ;
}

The ApplicationTree is assigned to a resource to ensure it will validate against the ApplicationShape.

<#ApplicationTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#ApplicationShape> ;
  st:matchesUriTemplate "{id}" .

3.3. Resource Hierarchy

Resource Class Shape Shape Tree
/profile/ - - ApplicationProfileTree
-- id#app Application ApplicationShape ApplicationTree
-- thumb.svg - - -

Application resources MAY use any resource or subject names. The names used herein have been selected for comprehension and readability.

3.4. Permission Model

The permission model for the resources detailed in § 2.3 Resource Hierarchy are illustrated in the table below.

Notable items:

Permission model for Application resources
Agent Public Trusted Agents Other Agents Granted Access
Resource Access Access Access Subject Access
/profile/ Control - - - -
-- id Control Read - - -
-- thumb.svg Control Read - - -

4. Application Registration

4.1. Overview

Application Registration lets Agents register and track the Applications they’ve decided to use. It provides a dedicated place to store internal data specific to the function of a given Application.

Giving Applications their own private data space in Solid may seem counterintuitive to Solid’s proposition to decouple data and Applications.

However, some data is extremely specific to the function of a particular Application, and has absolutely no value to any others. Forcing that data into standard types and structures can lead to mixing in with the interoperable data, creating convoluted vocabularies, shape trees, and shapes that inhibit adoption by others.

Giving Applications a private space where they can store internal data is therefore a key factor in broad interoperability, because it protects interoperable data from pollution by narrowly focused elements.

4.2. Data Model

4.2.1. Summary

Data model for application registration

An Agent links to Application Registry Sets via the interop:hasApplicationRegistrySet property.

An Application Registry Set links to any number of Application Registries via the interop:hasRegistry property.

Each Application an Agent registers has an Application Registration. An Application Registry links to any number of Application Registrations via the interop:hasRegistration property.

Agent at https://alice.pod.example/profile/id#me linking to an Application Registry Set
<#me>
  a interop:Agent;
  interop:hasApplicationRegistrySet <https://alice.pod.example/profile/application#set> .
An Application Registry Set at https://alice.pod.example/profile/application#set linking to two different Application Registries
<#set>
  a interop:ApplicationRegistrySet;
  interop:hasRegistry <https://alice.pod.example/applications/#registry> ,
                  <https://alice.otherpod.example/applications/#registry> .
An Application Registry at https://alice.pod.example/applications/#registry linking to several Application Registrations
<#registry>
  a interop:ApplicationRegistry ;
  interop:hasRegistration <705563552198b6fb3efc40717872aa2ec35d669c1095cc5d665f499ec5d7e23a/#registration> ,
                      <ede6aa50cb9e5fc564fdb4f0dc661685825ee3178355214086be27f9830e2a42/#registration> ,
                      <150dca42b3d5661ba10a28e0aff36f212e27b0f7463fe1ef3bf1b5a45b640673/#registration> ,
                      <b3564e72a3877c9cfa9e4bc4d9e47e9b7c536ae9927407c8dd00ec3b0069f536/#registration> .
An Application Registration at https://alice.pod.example/applications/705563552198b6fb3efc40717872aa2ec35d669c1095cc5d665f499ec5d7e23a/#registration
<#registration>
  a interop:ApplicationRegistration ;
  interop:registeredBy <https://alice.pod.example/profile/id#me> ;
  interop:registeredWith <https://trusted.example/id#agent> ;
  interop:registeredAt "2020-04-04T20:15:47.000Z"^^xsd:dateTime ;
  interop:updatedAt "2020-04-04T21:11:33.000Z"^^xsd:dateTime ;
  interop:registeredApplication <https://app.example/profile/id#agent> ;
  interop:hasAccessReceipt <./04ca5ba7-0166-4312-ae96-09b9f3a25ba0#receipt> .

4.2.2. Application Registry Set

An Application Registry Set is a Registry Set specifically made up of Application Registries.

ApplicationRegistrySet a rdfs:subClassOf RegistrySet
Property Range Description
hasRegistry Registry Link to associated Application Registries

The ApplicationRegistrySetShape is used to validate an instance of the ApplicationRegistrySet class.

<#ApplicationRegistrySetShape> {
  a [ interop:ApplicationRegistrySet ] ;
  interop:hasRegistry IRI+
}

The ApplicationRegistrySetTree is assigned to a resource to ensure it will validate against the ApplicationRegistrySetShape.

<#ApplicationRegistrySetTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#ApplicationRegistrySetShape> ;
  st:matchesUriTemplate "application" .

4.2.3. Application Registry

An Application Registry is a collection of Application Registrations stored in a specific location in a pod.

ApplicationRegistry a rdfs:subClassOf Registry
Property Range Description
hasRegistration ApplicationRegistration Link to an associated Application Registration

The ApplicationRegistryShape is used to validate an instance of the ApplicationRegistry class.

<#ApplicationRegistryShape> {
  a [ interop:ApplicationRegistry ] ;
  interop:hasRegistration IRI*
}

The ApplicationRegistryTree is assigned to a container resource to ensure that it will validate against the ApplicationRegistryShape, and contain only conformant instances of the ApplicationRegistrationTree.

<#ApplicationRegistryTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#ApplicationRegistryShape> ;
  st:contains <#ApplicationRegistrationTree> ,
              st:AllowNone .

4.2.4. Application Registration

An Application Registration provides the Agent with a place to maintain metadata, state, preferences, and other application-specific data associated with a given Application they have elected to use.

ApplicationRegistration a rdfs:subClassOf Registration
Property Range Description
registeredBy Agent Agent that registered the Application Registration
registeredWith Application Application used to create the Application Registration
registeredAt xsd:dateTime Date and time the Application Registration was created
updatedAt xsd:dateTime Date and time the Application Registration was updated
registeredApplication Application The Application that was registered
hasAccessReceipt AccessReceipt An Access Receipt that lets the Application know what the Agent has granted them access to

The ApplicationRegistrationShape is used to validate an instance of the ApplicationRegistration class.

<#ApplicationRegistrationShape> {
  a [ interop:ApplicationRegistration ] ;
  interop:registeredBy IRI ;
  interop:registeredWith IRI ;
  interop:registeredAt xsd:dateTime ;
  interop:updatedAt xsd:dateTime ;
  interop:registeredApplication IRI ;
  interop:hasAccessReceipt IRI?
}

The ApplicationRegistrationTree is assigned to a resource via the ApplicationRegistryTree, to ensure that the Application Registration will validate against the ApplicationRegistrationShape. It can include any resources, but ensures that if an Access Receipt is added, it is validated against AccessReceiptTree.

<#ApplicationRegistrationTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#ApplicationRegistrationShape> ;
  st:contains <#AccessReceiptTree> ,
                st:AllowAll ;
  st:matchesUriTemplate "{id}" .

4.3. Resource Hierarchy

Resource Class Shape Shape Tree
/profile/ - - ProfileTree
-- application#set ApplicationRegistrySet ApplicationRegistrySetShape ApplicationRegistrySetTree
/applications/#registry ApplicationRegistry ApplicationRegistryShape ApplicationRegistryTree
-- 70556355...c5d7e23a/#registration ApplicationRegistration ApplicationRegistrationShape ApplicationRegistrationTree
---- 04ca5ba7...f3a25ba0#receipt AccessReceipt AccessReceiptShape AccessReceiptTree
---- ex-cache-1122 - - -
-- ede6aa50...830e2a42/#registration ApplicationRegistration ApplicationRegistrationShape ApplicationRegistrationTree
---- 2af133d6...78e343ba#receipt AccessReceipt AccessReceiptShape AccessReceiptTree
---- ex-internal-idx - - -
-- 150dca42...5b640673/#registration ApplicationRegistration ApplicationRegistrationShape ApplicationRegistrationTree
---- 14f8bfb9...e42f7084#receipt AccessReceipt AccessReceiptShape AccessReceiptTree
-- b3564e72...0069f536/#registration ApplicationRegistration ApplicationRegistrationShape ApplicationRegistrationTree

The Application Registry Set and the Application Registry MAY or MAY NOT be on the same pod.

Application Registry Set and Application Registry resources MAY use any resource or subject names.

The resource name for an Application Registration container MUST be a SHA-256 hash encoding of the identity for the registered Application, which is linked via interop:registeredApplication.

Example Application Identity: https://app.example/profile/id#agent

SHA-256 Hash: 705563552198b6fb3efc40717872aa2ec35d669c1095cc5d665f499ec5d7e23a

Is it necessary to use a one-way hash for application registration resource names. Github issue

Application Registrations use containers so that registered Applications have dedicated space to store internal, non-interoperable data. In the figure above, we can see an application-specific cache resource (ex-cache-1122) and an internal index (ex-internal-idx).

4.4. Permission Model

The permission model for the resources detailed in § 4.3 Resource Hierarchy are illustrated in the table below.

Notable items:

Note: Append+ indicates that Read/Write is granted to the subsequently created resource.

Permission model for Application Registry resources.
Agent Public Trusted Agents Other Agents
Resource Access Access Access Subject Access
/profile/ - Control - Control - -
-- application Application Registry Set Control - Control - -
/applications/ Application Registry Control - Control - -
-- 70556355...c5d7e23a Application Registration Control - Control Registered Application Read/Append+
---- 04ca5ba7...f3a25ba0 Access Receipt Control - Control Registered Application Read
---- ex-cache-1122 - Control - Control Registered Application Read/Write
-- ede6aa50...830e2a42 Application Registration Control - Control Registered Application Read/Append+
---- 2af133d6...78e343ba Access Receipt Control - Control Registered Application Read
---- ex-internal-idx - Control - Control Registered Application Read/Write
-- 150dca42...5b640673 Application Registration Control - Control Registered Application Read/Append+
---- 14f8bfb9...e42f7084 Access Receipt Control - Control Registered Application Read
-- b3564e72...0069f536 Application Registration Control - Control Registered Application Read/Append+

4.5. Operations

4.5.1. Load Application Registration

This operation allows an Application find and load a corresponding Application Registration for a given Agent.

Failure to discover an Application Registration means that the Application is not registered.

Per the § 4.4 Permission Model, a given Application will only have access to its own Application Registration. Since Applications do not have access to the list of Applications in an Agent’s Application Registries, they must perform a direct lookup in the addressable space of each Application Registry in the Application Registry Set to find a corresponding Application Registration.

Note: This specification is designed to support compartmentalization of data between Applications. Server-side support may vary. See § 12.1 Application Authorization.

4.5.1.1. Inputs
4.5.1.2. Outputs
4.5.1.3. Operation Details
  1. AGENT provides their identity to APP

  2. APP dereferences the identity of AGENT get AGENT's identity profile document.

  3. Let ARSET be the Application Registry Set linked via AGENT hasApplicationRegistrySet.

    1. Because ARSET is a non-public document, AGENT and APP will be required to furnish a DPoP proof and access token to the Solid Server, obtained via the Solid-OIDC protocol.

  4. For each Application Registry AREGISTRY in ARSET

    1. Let IDSHA256 be the SHA-256 hash of APP's identity

    2. Let STATUS be the HTTP status code returned from a GET or HEAD of https://AREGISTRY/IDSHA256

    3. Return AREGISTRY if STATUS is 200 OK

  5. Return FALSE

4.5.2. Register Application

This operation creates a new Application Registration, and MUST be called from an § 6.2.1 Application Requests Access workfow.

4.5.2.1. Inputs
4.5.2.2. Outputs
4.5.2.3. Operation Details
  1. Let EXISTING be an Application Registration returned from § 4.5.1 Load Application Registration with inputs: AGENT, APP

  2. Return EXISTING if EXISTING is not empty

  3. Let REG be a newly initialized Application Registration

  4. Let REG registeredBy be AGENT

  5. Let REG registeredWith be the identity of the Application executing the operation

  6. Let REG registeredAt be the current date and time

  7. Let REG updatedAt be the current date and time

  8. Let REG registeredApplication be the identity of APP

  9. Let IDSHA256 be the SHA-256 hash of APP's identity

  10. Add REG to the REGISTRY container, using IDSHA256 as the resource name

  11. Assign permissions for REG per the § 4.4 Permission Model

  12. Link REG to REGISTRY via REGISTRY hasRegistration

  13. Return REG

5. Data Registration

5.1. Overview

Data Registration lets Agents store and manage the data they control. Data of various types is organized and stored in a uniform way to aid validation, authorization, discovery, and more.

Complex hierarchies that hinder interoperability are avoided by storing data in a relatively flat hierarchy. This creates natural data boundaries that make data storage and authorization more intuitive.

5.2. Data Model

5.2.1. Summary

Data model for data registration

An Agent links to a Data Registry Set via the interop:hasDataRegistrySet property.

A Data Registry Set links to any number of Data Registries via the interop:hasRegistry property.

A Data Registry links to any number of Data Registrations via the interop:hasRegistration property.

There is a Data Registration for each unique type of stored data. Each Data Registration contains and links to any number of Data Instances via the ldp:contains property.

Agent at https://alice.pod.example/profile/id#me linking to a Data Registry Set
<#me>
  a interop:Agent;
  interop:hasDataRegistrySet <https://alice.pod.example/profile/data#set> .
A Data Registry Set at https://alice.pod.example/profile/data#set linking to two different Data Registries
<#set>
  a interop:DataRegistrySet;
  interop:hasRegistry <https://alice.pod.example/data/#registry> ,
                  <https://alice.otherpod.example/data/#registry> .
A Data Registry at https://alice.pod.example/data/#registry linking to several Data Registrations
<#registry>
  a interop:DataRegistry ;
  interop:hasRegistration <8501f084-deb9-4775-8a35-2040df435d21/#registration> ,
                      <df4ab227-2f15-455d-8ca2-fad10fb9f9bc/#registration> ,
                      <d0954df2-e7c3-40b4-9eeb-65df92d9167e/#registration> ,
                      <87da9aa5-3f6c-4bc2-a5d4-adb7efcaee5d/#registration> ,
                      <bc3d8522-7f00-4d90-a01b-54ec01591640/#registration> ,
                      <3a3ee852-ff49-46ea-b7a8-65cec55879a4/#registration> .
A Data Registration at https://alice.pod.example/data/8501f084-deb9-4775-8a35-2040df435d21/#registration
<#registration>
  a interop:DataRegistration ;
  interop:registeredBy <https://alice.pod.example/profile/id#me> ;
  interop:registeredWith <https://app.example/id#agent> ;
  interop:registeredAt "2020-04-04T20:15:47.000Z"^^xsd:dateTime ;
  interop:updatedAt "2020-04-04T21:11:33.000Z"^^xsd:dateTime ;
  interop:registeredShapeTree note:notebookTree ;
  interop:registeredType note:notebook .

5.2.2. Data Registry Set

A Data Registry Set is a Registry Set specifically made up of Data Registries.

DataRegistrySet a rdfs:subClassOf RegistrySet
Property Range Description
hasRegistry Registry Link to associated Data Registries

The DataRegistrySetShape is used to validate an instance of the DataRegistrySet class.

<#DataRegistrySetShape> {
  a [ interop:DataRegistrySet ] ;
  interop:hasRegistry IRI+
}

The DataRegistrySetTree is assigned to a resource to ensure it will validate against the DataRegistrySetShape.

<#DataRegistrySetTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#DataRegistrySetShape> ;
  st:matchesUriTemplate "application" .

5.2.3. Data Registry

A Data Registry is a collection of Data Registrations, each representing a unique type of data associated with a given shape tree.

A Data Registry can be used for basic discovery, but it is not designed nor intended to be an efficient means to query or index data. However, it is intended to be used as reliable source data for different query engines or indexing schemes.

DataRegistry a rdfs:subClassOf Registry
Property Range Description
hasRegistration DataRegistration Link to an associated Data Registration

The DataRegistryShape is used to validate an instance of the DataRegistry class.

<#DataRegistryShape> {
  a [ interop:DataRegistry ] ;
  interop:hasRegistration IRI*
}

The DataRegistryTree is assigned to a container resource to ensure that it will validate against the DataRegistryShape, and contain only conformant instances of the DataRegistrationTree.

<#DataRegistryTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#DataRegistryShape> ;
  st:contains <#DataRegistrationTree> ,
              st:AllowNone .

5.2.4. Data Registration

A Data Registration provides the Agent with a place to store Data Instances of a particular type, conforming to a given shape tree, indicated by the interop:registeredShapeTree property.

A Data Instance is a unique, stored instance of a particular type of data, conforming to the shape tree for the instance’s Data Registration.

DataRegistration a rdfs:subClassOf Registration
Property Range Description
registeredBy Agent Agent that registered the Data Registration
registeredWith Application Application used to create the Data Registration
registeredAt xsd:dateTime Date and time the Data Registration was created
updatedAt xsd:dateTime Date and time the Data Registration was updated
registeredShapeTree st:ShapeTree The Shape Tree that was registered
registeredType rdf:type Type of data registered

The DataRegistrationShape is used to validate an instance of the DataRegistration class.

<#DataRegistrationShape> {
  a [ interop:DataRegistration ] ;
  interop:registeredBy IRI ;
  interop:registeredWith IRI ;
  interop:registeredAt xsd:dateTime ;
  interop:updatedAt xsd:dateTime ;
  interop:registeredShapeTree IRI ;
  interop:registeredType IRI*
}

The DataRegistrationTree is assigned to a resource via the DataRegistryTree, to ensure that the Data Registration will validate against the DataRegistrationShape.

<#DataRegistrationTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#DataRegistrationShape> ;
  st:matchesUriTemplate "{id}" .

5.3. Resource Hierarchy

Resource Class Shape Shape Tree
/profile/ - - ProfileTree
-- data#set DataRegistrySet DataRegistrySetShape DataRegistrySetTree
/data/#registry DataRegistry DataRegistryShape DataRegistryTree
-- 8501f084...2040df43/#registration DataRegistration DataRegistrationShape DataRegistrationTree, FooContainingTree
---- 16e1eae9...ca3805c4/#foo FooInstance FooShape FooTree
---- 886785d2...5ac36b7b/#foo FooInstance FooShape FooTree
---- dae5015c...7ca7a198/#foo FooInstance FooShape FooTree
-- df4ab227...fad10fb9/#registration DataRegistration DataRegistrationShape DataRegistrationTree, BarContainingTree
---- 9b60a354...cb9da85c/#bar BarInstance BarShape BarTree
---- 6e545b74...b15cbdce/#bar BarInstance BarShape BarTree
---- d33e01c8...ac9e3cc6/#bar BarInstance BarShape BarTree
---- 927108fa...14985cb9/#bar BarInstance BarShape BarTree
---- 180dda0b...c4f8c4dc/#bar BarInstance BarShape BarTree
-- 3c9c9cff...fc7f916b/#registration DataRegistration DataRegistrationShape DataRegistrationTree, BazContainingTree
---- 4376595a...f8d2547c/#baz BazInstance BazShape BazTree
---- 14c9fc6a...7f6de3ca/#baz BazInstance BazShape BazTree

The Data Registry Set and the Data Registry MAY or MAY NOT be on the same pod.

Data Registry Set and Data Registry resources MAY use any resource or subject names.

Data Registrations and Data Instances MUST use UUIDs for resource names.

A Data Registration container MUST contain conformant instances of the shape tree associated with the Data Registration via interop:registeredShapeTree.

Two complementary shape trees MUST be assigned to the same Data Registration container to ensure that it conforms to general validation requirements, and to ensure that it only contains Data Instances of the registered shape tree identified by interop:registeredShapeTree.

In the figure below, the combination of a DataRegistrationTree and FooContainingTree on the same Data Registration can be observed. Furthermore, an example of a contained Data Instance is provided, which conforms to FooTree per the directive in FooContainingTree.

Intersecting shape trees for a Data Registration and the shape tree registered with it
-- 8501f084-deb9-4775-8a35-2040df435d21/#registration
Contents of the Data Registration
<#registration>
  a interop:DataRegistration ;
  interop:registeredBy <https://alice.pod.example/profile/id#me> ;
  interop:registeredWith <https://app.example/id#agent> ;
  interop:registeredAt "2020-04-04T20:15:47.000Z"^^xsd:dateTime ;
  interop:updatedAt "2020-04-04T21:11:33.000Z"^^xsd:dateTime ;
  interop:registeredShapeTree foo:fooTree ;
  interop:registeredType foo:fooThing .
Ensure the container resource for the Data Registration conforms to interops#DataRegistrationShape.
<#DataRegistrationTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#DataRegistrationShape> ;
  st:matchesUriTemplate "{id}" .

And also ensure the Data Registration only contains resources that conform to <#FooTree>.

<#FooContainingTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:contains <#FooTree> ;
  st:matchesUriTemplate "{id}" .
---- 16e1eae9-20a5-489d-8380-8c07ca3805c4#foo
Contents of the Data Instance
<#foo>
  a foo:fooThing ;
  foo:isExample "of an instance" .
Ensure the resource for the Data Instance conforms to <#FooTree>.
<#FooTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <foo#FooShape> ;
  st:matchesUriTemplate "{id}" .

5.4. Permission Model

Almost all of the collaborative use cases between Agents in the ecosystem are based on data furnished through the Data Registry.

Only the Agent or Trusted Agents have the ability to manage contents and permissions across Data Registries, including the creation and modification of Data Registrations. The table below illustrates this using the resource hierarchy from the previous section. Other Agents are granted varying levels of access by the Agent or their Trusted Agents.

Note: § 6 Data Authorization provides patterns for managing Access Grants and sending Access Receipts to the Agents who were granted access.

Permission model for Data Registry resources.
Agent Public Trusted Agents Other Agents
Resource Access Access Access Subject Access
/profile/ - Control - Control - -
-- data Data Registry Set Control - Control - -
/data/ Data Registry Control - Control - -
-- 8501f084...2040df43 Data Registration Control Varies Control Grantee Varies
---- 16e1eae9...ca3805c4 Data Instance Control Varies Control Grantee Varies
---- 886785d2...5ac36b7b Data Instance Control Varies Control Grantee Varies
---- dae5015c...7ca7a198 Data Instance Control Varies Control Grantee Varies
-- df4ab227...fad10fb9 Data Registration Control Varies Control Grantee Varies
---- 9b60a354...cb9da85c Data Instance Control Varies Control Grantee Varies
---- 6e545b74...b15cbdce Data Instance Control Varies Control Grantee Varies
---- d33e01c8...ac9e3cc6 Data Instance Control Varies Control Grantee Varies
---- 927108fa...14985cb9 Data Instance Control Varies Control Grantee Varies
---- 180dda0b...c4f8c4dc Data Instance Control Varies Control Grantee Varies
-- 3c9c9cff...fc7f916b Data Registration Control Varies Control Grantee Varies
---- 4376595a...f8d2547c Data Instance Control Varies Control Grantee Varies
---- 14c9fc6a...7f6de3ca Data Instance Control Varies Control Grantee Varies

A signficant amount of flexibility is needed in granting other Agents access to data in the registry. It is also important to avoid the creation of permission swamps that are unwieldy for Agents to manage.

Organizing data by shape tree creates natural permission boundaries, making authorization more intuitive and manageable.

Access is granted to a certain type of data by granting access to the entire Data Registration, or to specific Data Instances within it.

Note: [WAC] doesn’t have any mechanism to extend or modify inherited permissions. Access Control Policies (ACP) is recommended for optimal results.

5.4.1. Access to a Data Registration

Access granted at the Data Registration level applies to all Data Instances within it.

The access modes listed in the table below can be combined as needed.

Modes of access for a Data Registration
Mode Resultant Access
Read Can read all existing and yet to be created Data Instances. Includes being able to see the full list of Data Instances in the registration.
Write Can modify the Data Registration, and all existing Data Instances within it. Can create new Data Instances, and can delete them.
Append Can only create new Data Instances within the Data Registration.
Read Permissions Can read permissions on the Data Registration, as well as any Data Instances within it.
Write Permissions Can change permissions on the Data Registration, as well as any Data Instances within it.

5.4.2. Access to Specific Data Instances

Access granted at the Data Instance level apply only to that instance, and the resources within it.

The access modes listed in the table below can be combined as needed.

Modes of access for a Specific Data Instance
Mode Resultant Access
Read Can list and read all resources within the Data Instance.
Write Can modify the Data Instance and any resources within it, including creating and deleting resources.
Append Can create resources within the Data Instance. Can add to a resource in the Data Instance but cannot remove anything from it, or delete it.
Read Permissions Can read permissions on the Data Instance and any resources within it.
Write Permissions Can change permissions on the Data Instance and any resources within it.

5.5. Operations

Registering data in a Data Registry is primarily concerned with the following two operations:

The following operations allow for the lookup, creation, and deletion of Data Registrations and Data Instances in a Data Registry.

Note: Managing Data Registrations and the Data Instances contained within them is inextricably linked to permissioning the data for effective use and secure collaboration. This is covered at length in § 6 Data Authorization.

5.5.1. Load Data Registration

Description
This operation returns a Data Registration the corresponds to a given shape tree in a Data Registry.
Inputs
TREE Shape tree to match against
REGISTRY Data Registry to look for a match within
Outputs
Data Registration Loaded by matching against TREE in REGISTRY
  1. MUST return 404 if TREE or REGISTRY cannot be successfully dereferenced.

  2. For each Data Registration REGISTRATION included in REGISTRY hasRegistration

    1. return REGISTRATION if REGISTRATION registeredShapeTree == TREE

5.5.2. Create Data Registration

Description
This operation creates a new Data Registration in a Data Registry for a specific shape tree.
Inputs
TREE Shape tree to register
TYPE Optional rdf:type to associate with the registration
REGISTRY Data Registry where the registration will be created
Outputs
Data Registration Created for TREE in REGISTRY
  1. MUST return 404 if TREE or REGISTRY cannot be successfully dereferenced.

  2. MUST return 400 if an existing Data Registration is returned from § 5.5.1 Load Data Registration with inputs: TREE, REGISTRY

  3. Let REG be a newly initialized Data Registration

  4. Let REG registeredBy be the current Agent

  5. Let REG registeredWith be the identity of the Application executing the operation

  6. Let REG registeredAt be the current date and time

  7. Let REG updatedAt be the current date and time

  8. Let REG registeredShapeTree be TREE

  9. Let REG registeredType be TYPE if TYPE is not empty

  10. PUT REG into the REGISTRY container

    1. A UUID MUST be assigned as the resource name.

    2. Plant TREE with REG as the Target Container.

  11. Assign permissions for REG per the § 5.4 Permission Model

  12. Link REG to REGISTRY via REGISTRY hasRegistration

  13. Return REG

5.5.3. Create Data Instance

Description
This operation will create a new Data Instance for a given Data Registration. It must be a conformant instance of the shape tree registered with the Data Registration, per the validation structure detailed in § 5.3 Resource Hierarchy.

Assumes that a Data Registration has already been loaded by § 5.5.1 Load Data Registration and provided as input.

Inputs
REGISTRATION Data Registration to associated the new Data Instance with
INSTANCE Instance corresponding with REGISTRATION registeredShapeTree
Outputs
Data Instance Created for REGISTRATION in REGISTRY
  1. PUT INSTANCE into the REGISTRATION container

    1. A UUID MUST be assigned as the resource name.

    2. A target shape tree MUST be assigned via the rel=http://shapetrees.org/#targetShapeTree HTTP Link relation

    3. A focus node for shape tree validation MUST be assigned via the rel=http://shapetrees.org/#FocusNode HTTP Link relation

  2. Return INSTANCE

5.5.4. Delete Data Registration

Description
This operation deletes a Data Registration from a Data Registry.
Inputs
REGISTRATION Data Registration to delete
REGISTRY Data Registry of REGISTRATION
Outputs
HTTP Status Code As returned from server
  1. MUST return 404 if REGISTRATION cannot be successfully dereferenced.

  2. MUST return 400 if REGISTRATION contains one or more Data Instances.

  3. Remove REGISTRATION from the graph of REGISTRY via REGISTRY hasRegistration

  4. DELETE REGISTRATION

Cleanup of related data may need to be specified

5.5.5. Delete Data Instance

Description
This operation deletes a Data Instance from a Data Registration.
Inputs
INSTANCE Data Instance to delete
Outputs
HTTP Status Code As returned from server
  1. MUST return 404 if INSTANCE cannot be successfully dereferenced.

  2. If INSTANCE is a container

    1. Let RESOURCES be a hierarchy of all resources contained by INSTANCE, including any child containers and resources.

    2. DELETE each RESOURCE in RESOURCES, iterating up from the bottom of the RESOURCES hierarchy

  3. DELETE INSTANCE

Cleanup of related data may need to be specified

6. Data Authorization

6.1. Overview

The ability for one Agent to grant others access to data in their control is a fundamental element of a collaborative interoperable ecosystem.

Data Authorization represents several key elements that work together to grant, adjust, and rescind access to data controlled by an ecosystem participant.

6.2. Workflows

The following workflows represent the authorization patterns enabled by this specification.

6.2.1. Application Requests Access

Let CONTROLLER be an Agent that wants to give an Application APP access to data in their control.

Let APP be the Application that CONTROLLER wishes to use, and must grant access to. APP may be an Application that is piloted by the Agent, or it may be an autonomous service that operates independently. The following workflow applies to both cases.

Let AUTHZ be an Application trusted by the Agent for authorization and access control.

Let REGISTERAPP be a boolean value that indicates whether the Application is requesting to be Registered

Let GRANTACCESS be a boolean value that indicates whether the Application wishes to be granted access to data

  1. CONTROLLER decides they’d like to use APP

  2. CONTROLLER provides their identity to APP

  3. APP dereferences the identity to get CONTROLLER's identity profile document.

  4. APP discovers that AUTHZ is the Authorization Agent for CONTROLLER via the § 11.2.1 Load Trusted Agent operation.

  5. APP redirects CONTROLLER to AUTHZ via the § 11.2.2 Redirect to Trusted Agent operation.

    1. If REGISTERAPP is true

      1. Let APPREG be an Application Registration returned by § 4.5.1 Load Application Registration with inputs: CONTROLLER, APP

      2. If APPREG is empty let APPREG be the Application Registration returned by § 4.5.2 Register Application with inputs: AGENT, APP, REGISTRY.

    2. If GRANTACCESS is true

      1. AUTHZ looks in APP's application profile document for Access Need Groups with an interop:accessScenario of interop:PersonalAccess

      2. Any Access Need Groups found are passed to the § 8.4.10 Present Grant operation, which presents them to CONTROLLER.

      3. CONTROLLER decides whether to grant APP the access requested.

      4. CONTROLLER authorizes the requested Access Need Groups and Access Needs:

        1. The § 8.4.5 Record Grant operation is invoked

          1. An Access Grant is stored in CONTROLLER's Access Grant Registry.

          2. § 8.4.9 Apply Permissions is called to apply permissions based on the Access Grant.

          3. § 9.4.1 Provide Access Receipt is called to store the Access Receipt. The Application has set interop:receivesAccessReceipt to ReceiptInRegistration, so the Access Receipt is stored in the Application Registration for APP.

    3. AUTHZ redirects CONTROLLER back to APP via the § 11.2.3 Return from Trusted Agent operation.

6.2.2. Another Agent Requests Access

Let REQUESTER be an Agent requesting data from another Agent CONTROLLER with a known identity.

Let REQAPP be an Application piloted by REQUESTER

Let RAUTHZ be an Application trusted by REQUESTER for authorization and access control.

Let CONTROLLER be an Agent in control of data that REQUESTER would like to access.

Let CAUTHZ be an Application trusted by CONTROLLER for authorization and access control.

  1. REQUESTER would like access to CONTROLLER's data.

  2. REQUESTER provides CONTROLLER's identity to REQAPP.

  3. REQAPP dereferences CONTROLLER's identity to get CONTROLLER's identity profile document.

  4. REQAPP uses Access Need Groups from its application profile document with an interop:accessScenario of interop:SharedAccess to identify Access Need Groups to request from CONTROLLER.

  5. CONTROLLER has an interop:receivesAccessReceipt value of ReceiptInMessage in their identity profile document.

  6. REQAPP puts the Access Need Groups into an Access Request and posts it to the access inbox identified by interop:hasAccessInbox in the CONTROLLER's identity profile document.

  7. CAUTHZ monitors CONTROLLER's access inbox autonomously. It notifies CONTROLLER when a new Access Request is received.

    1. CONTROLLER clicks a link in the notification from CAUTHZ, opening the CAUTHZ user interface and invoking the § 8.4.10 Present Grant operation using the Access Need Groups from the Access Request.

    2. CONTROLLER determines whether they wish to grant the access requested.

    3. Assuming CONTROLLER authorizes a minimum of the required Access Need Groups and Access Needs, the § 8.4.5 Record Grant operation is invoked.

    4. § 8.4.5 Record Grant stores an Access Grant in CONTROLLER's Access Grant Registry.

      1. § 8.4.9 Apply Permissions is called to apply permissions based on the Access Grant.

      2. § 9.4.1 Provide Access Receipt is called to deliver the Access Receipt.

        1. CAUTHZ dereferences REQUESTER's identity to get REQUESTER's identity profile document.

        2. REQUESTER has set interop:receivesAccessReceipt to ReceiptInMessage, so the Access Receipt is posted to the access inbox identified via hasAccessInbox in REQUESTER's 'identity profile document.

  8. RAUTHZ monitors REQUESTER's access inbox autonomously. It notifies REQUESTER when a new Access Receipt is received.

    1. REQUESTER clicks the link in the notification, opening the RAUTHZ user interface and invoking the § 9.4.4 Present Access Receipt operation to approve the Access Receipt.

    2. REQUESTER accepts the Access Receipt, and RAUTHZ invokes the § 9.4.2 Record Access Receipt operation.

      1. § 9.4.2 Record Access Receipt is called to store the Access Receipt in REQUESTER's Access Receipt Registry.

      2. § 10.4.1 Update Remote Data is called to update REQUESTER's Remote Data Registry to reflect what is in the Access Receipt.

6.2.3. Controller Shares Access

Let CONTROLLER be an Agent in control of data that they would like to authorize RECEIVER to access.

Let CAPP be an Application piloted by CONTROLLER

Let CAUTHZ be an Application trusted by CONTROLLER for authorization and access control.

Let RECEIVER be an Agent receiving access to data from another Agent CONTROLLER.

Let RAUTHZ be an Application trusted by RECEIVER for authorization and access control.

  1. CONTROLLER would like to give RECEIVER access to their data.

  2. CONTROLLER provides RECEIVER's identity to CAPP.

  3. CAPP dereferences RECEIVER's identity to get RECEIVER's identity profile document.

  4. CAPP discovers that CAUTHZ is the Authorization Agent for CONTROLLER via the § 11.2.1 Load Trusted Agent operation.

  5. CAPP redirects CONTROLLER to CAUTHZ via the § 11.2.2 Redirect to Trusted Agent operation.

    1. CAUTHZ looks in CAPP's application profile document for Access Need Groups with an interop:accessScenario of interop:SharedAccess

    2. Any Access Need Groups found are passed to the § 8.4.10 Present Grant operation, which presents them to CONTROLLER.

    3. CONTROLLER authorizes the data to share with RECEIVER based on the provided Access Need Groups.

      1. The § 8.4.5 Record Grant operation is invoked

        1. An Access Grant is stored in CONTROLLER's Access Grant Registry.

        2. § 8.4.9 Apply Permissions is called to apply permissions based on the Access Grant.

        3. § 9.4.1 Provide Access Receipt is called to store the Access Receipt. RECEIVER has set interop:receivesAccessReceipt to ReceiptInMessage, so the Access Receipt is posted to the access inbox identified via hasAccessInbox in RECEIVER's 'identity profile document.

    4. CAUTHZ redirects CONTROLLER back to CAPP via the § 11.2.3 Return from Trusted Agent operation.

  6. RAUTHZ monitors RECEIVER's access inbox autonomously. It notifies RECEIVER when a new Access Receipt is received.

    1. RECEIVER clicks the link in the notification, opening the RAUTHZ user interface and invoking the § 9.4.4 Present Access Receipt operation to approve the Access Receipt.

    2. RECEIVER accepts the Access Receipt, and RAUTHZ invokes the § 9.4.2 Record Access Receipt operation.

      1. § 9.4.2 Record Access Receipt is called to store the Access Receipt in RECEIVER's Access Receipt Registry.

      2. § 10.4.1 Update Remote Data is called to update RECEIVER's Remote Data Registry to reflect what is in the Access Receipt.

6.2.4. Controller Shares Access with Invited Agent

Controlling Agent initiates sharing their data with an Agent that doesn’t have an identity or a pod.

Let CONTROLLER be an Agent in control of data that they would like to authorize INVITEE to access.

Let CAPP be an Application piloted by CONTROLLER

Let CAUTHZ be an Application trusted by CONTROLLER for authorization and access control.

Let CISERVICE be an Application trusted by CONTROLLER to validate invitations made to INVITEEs.

Let INVITEE be a person without an identity or pod that CONTROLLER would like to authorize to access their data. CONTROLLER knows their e-mail address and mobile phone number.

LET PROVIDER be a service that hosts identities and pods who provisions the same for INVITEE

Let PAUTHZ be an Application offered by PROVIDER and trusted by INVITEE for authorization and access control.

  1. CONTROLLER would like to give INVITEE access to their data.

  2. CONTROLLER provides INVITEE's e-mail address and mobile number to CAPP.

  3. CAPP discovers that CAUTHZ is the Authorization Agent for CONTROLLER via the § 11.2.1 Load Trusted Agent operation.

  4. CAPP redirects CONTROLLER to CAUTHZ via the § 11.2.2 Redirect to Trusted Agent operation.

    1. CAUTHZ looks in CAPP's application profile document for Access Need Groups with an interop:accessScenario of interop:SharedAccess

    2. Any Access Need Groups found are passed to the § 8.4.10 Present Grant operation, which presents them to CONTROLLER.

    3. CONTROLLER authorizes the data to share with INVITEE based on the provided Access Need Groups.

      1. The § 8.4.6 Record Invitation operation is invoked

        1. An Access Invitation is stored in CONTROLLER's Access Grant Registry.

        2. § 8.4.7 Deliver Invitation is called to create an invitation entry for each Access Invitation Channel in the Access Invitation with CISERVICE

        3. For each Access Invitation Channel in the Access Invitation

          1. CISERVICE sends a notification to INIVITEE using the medium associated with the Access Invitation Channel type

    4. CAUTHZ redirects CONTROLLER back to CAPP via the § 11.2.3 Return from Trusted Agent operation.

  5. INVITEE receives a notification associated with one of the Access Invitation Channels.

    1. INVITEE clicks a link in the notification to register an identity and pod with PROVIDER.

    2. INVITEE clicks a link in the notification bringing them to the CISERVICE user interface to validate the invitation by invoking § 8.4.8 Validate Invitation.

      1. If validation is successful, but there are other Access Invitation Channels left to validate, the INVITEE will be prompted to validate them. Continue until failure or validation of all Access Invitation Channels are succesful.

      2. CISERVICE initializes a new Access Grant via § 8.4.1 Initialize Grant, using the contents of the Access Invitation, and the new registered identity for INVITEE.

      3. CISERVICE calls § 8.4.5 Record Grant using the Access Grant initialized from the Access Invitation

        1. An Access Grant is stored in CONTROLLER's Access Grant Registry.

        2. § 8.4.9 Apply Permissions is called to apply permissions based on the Access Grant.

        3. § 9.4.1 Provide Access Receipt is called to store the Access Receipt. INVITEE has set interop:receivesAccessReceipt to ReceiptInMessage, so the Access Receipt is posted to the access inbox identified via hasAccessInbox in INVITEE's 'identity profile document.

Should we assume that CISERVICE is able to manage grants, or should it need to redirect through the authorization agent? Perhaps the recommendation should be that they are combined? Bad separation of concerns?

This doesn’t take account a sequencing of validation steps from one channel to another.

7. Access Needs

7.1. Overview

Agents or Applications in the ecosystem often require access to data controlled by some other Agent. Consequently, a common way to explain and communicate data needs between participants in the ecosystem is required.

A given Agent or Application expresses their access needs by providing one or more Access Need Groups to the Agent controlling the data they require access to. The channels through which these may be communicated are detailed in § 6.2 Workflows.

The § 7.3.1 Compile Access Need Group operation processes each Access Need Group received by the controlling Agent. A Compiled Access Group is generated for each Access Need Group that was received.

Compiled Access Groups and the Compiled Accesses associated with them are used as input to the § 8.4.10 Present Grant operation, and are stored as part of the Access Grant by the § 8.4.5 Record Grant operation.

7.2. Data Model

7.2.1. Summary

An Access Need Group links to one or more Root Access Needs via the hasAccessNeed property. When the § 7.3.1 Compile Access Need Group operation follows a Root Access Need, it looks for Access Need Overrides linked to the Access Need Group via hasAccessNeedOverride to change the defaults inherited from the Root Access Need, or the most recent Access Need Override.

An Access Need is associated with one shape tree via interop:registeredShapeTree.

A Compiled Access Group is linked to the Access Need Group it was generated from via fromAccessNeedGroup. It links to an Access Need Group Decorator via hasAccessNeedGroupDecorator.

It links to one or more Root Compiled Accesses via hasCompiledAccess. Each Root Compiled Access represents a hierarchy of Compiled Accesses corresponding with the associated shape tree.

Each Compiled Access links to child Compiled Accesses via referencesCompiledAccess or skos:narrower.

An Access Need Group links to an Access Decorator Index of different Access Decorator Series that explain the Access Need Group and Access Needs in different languages. Each Access Decorator Series has one or more Access Decorator Versions pointing to an Access Decorator Resource, which contains the actual language-specific content mappings.

An Access Need Group linking to Access Needs
<#notebook-collaboration-group>
  a interop:AccessNeedGroup ;
  interop:accessNecessity interop:AccessRequired ;
  interop:accessScenario interop:PersonalAccess, interop:SharedAccess ;
  interop:authenticatesAs interop:Pilot ;
  interop:hasAccessNeed <#notebook> ;
  interop:hasAccessNeedOverride <#note> ;
  interop:hasAccessDecoratorIndex <notebook-access-decorator-index.ttl> .

<#notebook>
    a interop:AccessNeed ;
    interop:inAccessNeedGroup <#notebook-collaboration-group> ;
    interop:registeredShapeTree <note:notebook-tree> ;
    interop:recursivelyAuthorize true ;
    interop:accessNecessity interop:AccessRequired ;
    interop:accessMode acl:Read, acl:Write .

<#note> # Override to stop recursion
    a interop:AccessNeed ;
    interop:inAccessNeedGroup <#notebook-collaboration-group> ;
    interop:registeredShapeTree <note:notebook-tree> ;
    interop:recursivelyAuthorize false ;
    interop:accessNecessity interop:AccessRequired ;
    interop:accessMode acl:Read, acl:Write .
A Compiled Access Group linking to Compiled Accesses
<#compiled-notebook-collaboration-group>
  a interop:CompiledAccessGroup ;
  interop:fromAccessNeedGroup <#notebook-collaboration-group> ;
  interop:hasAccessNeedGroupDecorator ex:notebook-collaboration-decorator ;
  interop:authenticatesAs interop:Pilot ;
  interop:accessNecessity interop:AccessRequired ;
  interop:accessScenario interop:PersonalAccess, interop:SharedAccess ;
  interop:hasCompiledAccess <#notebook> .

<#compiled-notebook>
  a interop:CompiledAccess ;
  interop:inCompiledAccessGroup <#compiled-notebook-collaboration-group> ;
  interop:registeredShapeTree note:notebook-tree ;
  interop:hasShapeTreeDecorator note:notebook-decorator> ;
  interop:hasAccessNeedDecorator ex:notebook-need-decorator ;
  interop:accessNecessity interop:AccessRequired ;
  interop:accessMode acl:Read, acl:Write ;
  interop:referencesCompiledAccess <#compiled-note> .

<#compiled-note>
  a interop:CompiledAccess ;
  interop:inCompiledAccessGroup <#compiled-notebook-collaboration-group> ;
  interop:registeredShapeTree <note:note-tree> ;
  interop:hasShapeTreeDecorator note:note-decorator> ;
  interop:hasAccessNeedDecorator ex:note-need-decorator ;
  interop:accessNecessity interop:AccessRequired ;
  interop:accessMode acl:Read, acl:Write .
Access Decorator Index document linked by the #notebook-collaboration-group
@prefix interop: <http://www.w3.org/ns/solid/interop#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<>
  a interop:AccessDecoratorIndex ;
  interop:defaultLanguage "en"^^xsd:language ;
  interop:hasSeries <#series-en> .

<#series-en>
    a interop:AccessDecoratorSeries ;
    interop:usesLanguage "en"^^xsd:language ;
    interop:hasVersion <#en-v10>, <#en-v11> .

<#en-v10>
    a interop:AccessDecoratorVersion ;
    interop:isVersion "1.0.0" ;
    interop:hasSHA256 "98198123981273981273918273912738" ;
    interop:hasAccessDecoratorResource <notebook-decorator-en-1.0> .

<#en-v11>
    a interop:AccessDecoratorVersion ;
    interop:isVersion "1.1.0" ;
    interop:hasSHA256 "12312312371273712731872371273712" ;
    interop:hasAccessDecoratorResource <notebook-decorator-en-1.1> .
An Access Decorator Resource referenced by the Access Need Decorator Index
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix interop: <http://www.w3.org/ns/solid/interop#> .
@prefix note: <http://shapetrees.pub/ns/note#> .

<> a interop:AccessDecoratorResource .

<#notebook-collaboration-decorator>
  a interop:AccessNeedGroupDecorator ;
  interop:hasAccessNeedGroup <#notebook-collaboration-group> ;
  skos:prefLabel "Collaborate on notes"@en .
  skos:definition "Allowing for full reading and writing of notebooks and notes"@en .

<#notebook-decorator>
  a interop:AccessNeedDecorator ;
  interop:hasAccessNeedGroup <#notebook-collaboration-group> ;
  interop:registeredShapeTree <note:notebook-tree> ;
  skos:prefLabel "Notebooks can be presented along with a list of their contents and read / written"@en .

<#note-decorator>
  a interop:AccessNeedDecorator ;
  interop:hasAccessNeedGroup <#notebook-collaboration-group> ;
  interop:registeredShapeTree <note:note-tree> ;
  skos:prefLabel "Notes can be accessed and written"@en .
An Access Request sent from one agent to another
@prefix interop: <http://www.w3.org/ns/solid/interop#> .
@prefix note: <http://shapetrees.pub/ns/note#> .

<> a interop:AccessRequest ;
  interop:fromAgent https://alice.pod.example/profile/id#me ;
  interop:toAgent https://bob.pod.example/profile/id#me ;
  interop:hasAccessNeedGroup <#notebook-collaboration-group> .

<#notebook-collaboration-group>
  a interop:AccessNeedGroup ;
  interop:accessNecessity interop:AccessRequired ;
  interop:accessScenario interop:PersonalAccess, interop:SharedAccess ;
  interop:authenticatesAs interop:Pilot ;
  interop:hasAccessNeed <#notebook> ;
  interop:hasAccessNeedOverride <#note> ;
  interop:hasAccessDecoratorIndex <notebook-access-decorator-index.ttl> .

<#notebook>
    a interop:AccessNeed ;
    interop:inAccessNeedGroup <#notebook-collaboration-group> ;
    interop:registeredShapeTree <note:notebook-tree> ;
    interop:recursivelyAuthorize true ;
    interop:accessNecessity interop:AccessRequired ;
    interop:accessMode acl:Read, acl:Write .

<#note> # Override to stop recursion
    a interop:AccessNeed ;
    interop:inAccessNeedGroup <#notebook-collaboration-group> ;
    interop:registeredShapeTree <note:notebook-tree> ;
    interop:recursivelyAuthorize false ;
    interop:accessNecessity interop:AccessRequired ;
    interop:accessMode acl:Read, acl:Write .

7.2.2. Access Need Group

An Access Need Group is a collection of Access Needs that a given Agent and/or Application uses to communicate a data access request to other Agents.

Each Access Need is associated with a specific shape tree, and shape trees provide both physical and/or virtual hierarchies. The § 7.3.1 Compile Access Need Group operation starts with each Root Access Need linked via hasAccessNeed, and traverses the shape tree hierarchy, creating a Compiled Access at each new shape tree and linking them in a tree via referencesCompiledAccess or skos:narrower. Each Access Need Override that it encounters when traversing the hierarchy applies new inherited defaults, or stops the recursion before it continues through the remainder of the tree.

AccessNeedGroup
Property Range Description
accessNecessity interop:AccessRequired, interop:AccessOptional Necessity of the access to the requesting party
accessScenario interop:PersonalAccess, interop:SharedAccess Context in which the access group should be presented
hasAccessNeed AccessNeed Link to a Root Access Need
hasAccessNeedOverride AccessNeed Link to an Access Need Override
authenticatesAs Agent or interop:Pilot Agent or mode the Application authenticates as
hasAccessNeedDecoratorIndex - Index of Acccess Decorator Resources to describe Access Need Group and Access Needs

The AccessNeedGroupShape is used to validate an instance of the AccessNeedGroup class.

<#AccessNeedGroupShape> {
  a [ interop:AccessNeedGroup ] ;
  interop:accessNecessity [ interop:AccessRequired interop:AccessOptional ] ;
  interop:accessScenario [ interop:PersonalAccess interop:SharedAccess ] ;
  interop:authenticatesAs IRI ;
  interop:hasAccessNeed IRI+ ;
  interop:hasAccessNeedOverride IRI* ;
  interop:hasAccessDecoratorIndex IRI
}

7.2.3. Access Need

An Access Need represents the requirement of one specific type of data represented by a shape tree, as part of an Access Need Group.

Each Access Need represents a request to access, create, or manage all or a subset of Data Instances associated with a single Data Registration for a given shape tree.

Specific Data Instances may be requested by explicitly associating them with the Access Need via hasDataInstance.

Each Access Need has one or more access modes, and a property that indicates the necessity of the Access Need; required or optional. For example, an Access Need for read access to shape tree N can be identified as a required item in the Access Need Group.

Access Needs are described using language-specific Access Need Decorators.

AccessNeed
Property Range Description
inAccessNeedGroup AccessNeedGroup Access Need Group that the Access Need is part of
registeredShapeTree st:ShapeTree The shape tree requested by the Access Need
hasDataInstance - Request specific Data Instances of the registered shape tree
recursivelyAuthorize xsd:boolean
  • true - continue traversing shape tree hierarchy for authorization when true
  • false - stop traversal
accessMode acl:Read, acl:Write, acl:Control, acl:Append Requested modes of access for the Access Need
accessNecessity interop:AccessRequired, interop:AccessOptional Necessity of the access to the requesting party

The AccessNeedShape is used to validate an instance of the AccessNeed class.

<#AccessNeedShape> {
  a [ interop:AccessNeed ] ;
  interop:inAccessNeedGroup IRI+ ;
  interop:registeredShapeTree IRI ;
  interop:hasDataInstance IRI* ;
  interop:recursivelyAuthorize [ true false ] ;
  interop:accessMode [ acl:Read acl:Write acl:Append acl:Control ]+ ;
  interop:accessNecessity [ interop:AccessRequired interop:AccessOptional ] ;
}

7.2.4. Compiled Access Group

A Compiled Access Group is output by the § 7.3.1 Compile Access Need Group operation when given an Access Need Group as input.

Compiling an Access Need Group includes:

A Root Compiled Access is the compiled version of the corresponding Root Access Need in the source Access Need Group.

CompiledAccessGroup
Property Range Description
fromAccessNeedGroup AccessNeedGroup The Access Need Group used to generate the Compiled Access Group
hasAccessNeedGroupDecorator AccessNeedGroupDecorator An Access Need Group Decorator that describes this Compiled Access Group
authenticatesAs Agent or interop:Pilot Agent or mode the Application authenticates as
accessScenario interop:PersonalAccess, interop:SharedAccess Context in which the access group should be presented
accessNecessity interop:AccessRequired, interop:AccessOptional Necessity of the access to the requesting party
hasCompiledAccess CompiledAccess Link to a Root Compiled Access

The CompiledAccessGroupShape is used to validate an instance of the CompiledAccessGroup class.

<#CompiledAccessGroupShape> {
  a [ interop:CompiledAccessGroup ] ;
  interop:fromAccessNeedGroup IRI ;
  interop:hasAccessNeedGroupDecorator IRI ;
  interop:authenticatesAs IRI ;
  interop:accessNecessity [ interop:AccessRequired interop:AccessOptional ] ;
  interop:accessScenario [ interop:PersonalAccess interop:SharedAccess ] ;
  interop:hasCompiledAccess IRI+ ;
}

7.2.5. Compiled Access

A Compiled Access is generated by the § 7.3.1 Compile Access Need Group operation as it processes an input Access Need Group. A Compiled Access is added to the Compiled Access Group for every unique shape tree encountered as the operation traverses the shape tree hierarchy.

CompiledAccess
Property Range Description
inCompiledAccessGroup CompiledAccessGroup Compiled Access Group the Compiled Access belongs to
hasShapeTreeDecorator st:ShapeTreeDecorator Decorator associated with the shape tree that describes the name of the shape-tree and what data it represents in the preferred language of the Agent
hasAccessNeedDecorator AccessNeedDecorator Decorator that explains the reason for the access need in the preferred language of the Agent
hasDataGrant DataGrant Data Grant associated with the Compiled Access, established when the Access Grant is created
hasDataInstance DataInstance Links to any specific Data Instances that were included in the original request
registeredShapeTree st:ShapeTree Shape tree associated with the Compiled Access
accessMode acl:Read, acl:Write, acl:Control, acl:Append Requested modes of access for the Compiled Access
accessNecessity interop:AccessRequired, interop:AccessOptional Necessity of the access to the requesting party
supportedBy CompiledAccess A Compiled Access whose shape tree st:supports the shape tree of this Compiled Access
supports CompiledAccess A Compiled Access that shape tree of this Compiled Access st:supports
referencesCompiledAccess CompiledAccess The next Compiled Access in a virtual hierarchy
skos:narrower CompiledAccess The next Compiled Access in a virtual hierarchy where the regular shape tree hierarchy has been extended to include a skos hierarchy.

The CompiledAccessShape is used to validate an instance of the CompiledAccess class.

<#CompiledAccessShape> {
  a [ interop:CompiledAccess ] ;
  interop:inCompiledAccessGroup IRI+ ;
  interop:hasShapeTreeDecorator IRI ;
  interop:hasAccessNeedDecorator IRI? ;
  interop:hasDataGrant IRI? ;
  interop:hasDataInstance IRI* ;
  interop:registeredShapeTree IRI ;
  interop:accessMode [ acl:Read acl:Write acl:Append acl:Control ]+ ;
  interop:accessNecessity [ interop:AccessRequired interop:AccessOptional ] ;
  interop:supportedBy IRI* ;
  interop:supports IRI
  interop:referencesCompiledAccess IRI* ;
  skos:narrower IRI* ;
}

7.2.6. Access Request

An Access Request is used to send Access Need Groups from one Agent to another.

AccessRequest
Property Range Description
fromAgent Agent The Agent who sent the Access Request
toAgent Agent The Agent the Access Request is meant for
hasAccessNeedGroup AccessNeedGroup One or more Access Need Groups detailing the access requested

The AccessRequestShape is used to validate an instance of the AccessRequest class.

<#AccessRequestShape> {
  a [interop:AccessRequest] ;
  interop:fromAgent IRI ;             # Agent who sent the receipt
  interop:toAgent IRI ;               # Recipient of the receipt
  interop:hasAccessNeedGroup @<#:AccessNeedGroupShape>+
}

7.2.7. Access Decorator Index

An Access Decorator Index is a listing of one or more Access Decorator Series.

AccessDecoratorIndex
Property Range Description
defaultLanguage xsd:language Default language to select if not provided as input
hasSeries AccessDecoratorSeries Link to an Access Decorator Series

The AccessDecoratorIndexShape is used to validate an instance of the AccessDecoratorIndex class.

<#AccessDecoratorIndexShape> {
  a [ interop:AccessDecoratorIndex ] ;
  interop:defaultLanguage xsd:language ;
  interop:hasSeries @AccessDecoratorSeries+ ;
}
7.2.7.1. Access Decorator Series

An Access Decorator Series has one or more Access Decorator Versions in a given language.

AccessDecoratorSeries
Property Range Description
usesLanguage xsd:language Language code associated with the Access Decorator Series
hasVersion AccessDecoratorVersion Links to an Access Decorator Version in the series

The AccessDecoratorSeriesShape is used to validate an instance of the AccessDecoratorSeries class.

<#AccessDecoratorSeriesShape> {
  a [ interop:AccessDecoratorSeries ] ;
  interop:usesLanguage xsd:language ;
  interop:hasVersion @AccessDecoratorVersion+ ;
}
7.2.7.2. Access Decorator Version

An Access Decorator Version is a versioned instance of a given Access Decorator Resource.

CompiledAccessGroup
Property Range Description
isVersion xsd:string Semantic version of the Access Decorator Resource (e.g. "1.1.0")
hasSHA256 xsd:string SHA-256 hash of the linked Access Decorator Resource
hasAccessDecoratorResource AccessDecoratorResource Links to the actual Access Decorator Resource document

The AccessDecoratorVersionShape is used to validate an instance of the AccessDecoratorVersion class.

<#AccessDecoratorVersionShape> {
  a [ interop:AccessDecoratorVersion ] ;
  interop:isVersion xsd:string ;
  interop:hasSHA256 xsd:string ;
  interop:hasAccessDecoratorResource IRI ;
}

7.2.8. Access Decorator Resource

An Access Decorator Resource is a document that contains Access Need Group Decorators and Access Need Decorators in a given language.

AccessDecoratorResource
Property Range Description
No properties - -
7.2.8.1. Access Need Group Decorator

An Access Need Group Decorator provides a subject name and more in depth description that explains why a given Access Need Group is being requested of an Agent.

AccessNeedGroupDecorator
Property Range Description
hasAccessNeedGroup AccessNeedGroup Access Need Group the decorator applies to
skos:preflabel xsd:string Short label (title) for the Access Need Group
skos:definition xsd:string Description of why the Access Need Group requires the access it is requesting.

The AccessNeedGroupDecoratorShape is used to validate an instance of the AccessNeedGroupDecorator class.

<#AccessNeedGroupDecoratorShape> {
  a [ interop:AccessNeedGroupDecorator ] ;
  interop:hasAccessNeedGroup IRI ;
  skos:prefLabel xsd:string ;
  skos:definition xsd:string
}
7.2.8.2. Access Need Decorator

An Access Need Decorator provides a specific explanation of why that data type is being requested.

AccessNeedDecorator
Property Range Description
hasAccessNeedGroup AccessNeedGroup Access Need Group the decorator applies to
registeredShapeTree st:ShapeTree Shape tree associated with the Access Need the decorator should apply to
skos:prefLabel xsd:string Specific explanation of why that data type is being requested

The AccessNeedDecoratorShape is used to validate an instance of the AccessNeedDecorator class.

<#AccessNeedDecoratorShape> {
  a [ interop:AccessNeedDecorator ] ;
  interop:hasAccessNeedGroup IRI ;
  interop:registeredShapeTree IRI ;
  skos:prefLabel xsd:string
}

7.3. Operations

The following operations explain how to process Access Need Groups so they can be presented to an Agent in Access Grant Operations

7.3.1. Compile Access Need Group

Description
This operation takes a given Access Need Group with a number of associated Access Needs and processes them to produce a Compiled Access Group that is ready to present to a given Agent via the § 8.4.10 Present Grant operation.
  1. The shape tree associated with each Root Access Need is traversed to the desired level of recursion, including across references. A Compiled Access is added in a linked hierarchy starting with the Root Access Need, representing every unique shape tree that was traversed.
  2. Decorators are looked up and linked to the Compiled Access Group and where available for every Compiled Access
  3. Any Supporting Access Needs are associated with Compiled Accesses.
Inputs
GROUP An Access Need Group
LANG The Agent’s preferred language
Outputs
CAGROUP A Compiled Access Group generated from the input GROUP, with an associated set of Compiled Accesses
  1. Perform a validation of the RDF graph of GROUP against interop:AccessNeedGroupShape. MUST return a status code of 400 if validation fails.

  2. Let ALLNEEDS be the combined set of Access Needs linked via GROUP hasAccessNeed and GROUP hasAccessNeedOverride

  3. Let OVERRIDES be the Access Needs linked via GROUP hasAccessNeedOverride

  4. Let TREEDECS represent all Shape Tree Decorators associated with ALLNEEDS

  5. Let ALLDECS represent all Access Need Decorators associated with ALLNEEDS

  6. Let CAGROUP be a Compiled Access Group

  7. Let CAGROUP hasAccessNeedDecorator be the Access Need Group Decorator returned from § 7.3.5 Get Access Need Group Decorator with inputs: GROUP, LANG

  8. Let CAGROUP fromAccessNeedGroup be GROUP

  9. Let CAGROUP accessNecessity be GROUP accessNecessity

  10. Let CAGROUP authenticatesAs be GROUP authenticatesAs

  11. For each Root Access Need ROOT linked via GROUP hasAccessNeed

    1. Let CAGROUP hasCompiledAccess be linked to the Root Compiled Access returned by § 7.3.2 Compile Access Need with inputs: ROOT registeredShapeTree, ROOT, ALLNEEDS, OVERRIDES, TREEDECS, ALLDECS, LANG

  12. Let ALLCOMPILED represent all Compiled Accesses linked via CAGROUP hasCompiledAccess, as well as all Compiled Accesses linked to them via referencesCompiledAccess or skos:narrower.

  13. For each Root Compiled Access PROOT linked via CAGROUP hasCompiledAccess

    1. Call § 7.3.3 Link Supported Compiled Accesses with inputs: PROOT, ALLCOMPILED

7.3.2. Compile Access Need

This operation is called recursively to build up a linked hierarchy of Compiled Accesses in concert with the § 7.3.2.4 _walkDecorators operation.

7.3.2.1. Inputs
7.3.2.2. Outputs
7.3.2.3. Operation Details
  1. Let TOPTREEDEC be the Shape Tree Decorator returned from the Get Shape Tree Decorator operation with inputs: TREE, LANG

  2. Let SPECIFICNEED be the Access Need returned from the § 7.3.2.5 _getSpecificAccessNeed operation with inputs: TREE, OVERRIDES, LASTNEED

  3. return the Compiled Access returned by calling § 7.3.2.4 _walkDecorators with inputs: TREE, TOPTREEDEC, SPECIFICNEED, ALLDECS, ALLNEEDS, OVERRIDES, TREEDECS, LANG

7.3.2.4. _walkDecorators

This operation is called recursively to build up a linked hierarchy of Compiled Accesses in concert with the § 7.3.2 Compile Access Need operation.

7.3.2.4.1. Inputs
7.3.2.4.2. Outputs
7.3.2.4.3. Operation Details
  1. Let COMPILED be a new Compiled Access

  2. Let COMPILED registeredShapeTree be TREE

  3. Let COMPILED accessNecessity be set to NEED's accessNecessity

  4. Let COMPILED accessMode be all of NEED's accessModes

  5. Let COMPILED fromAccessNeed be NEED

  6. Let COMPILED hasAccessNeedDecorator be the Access Need Decorator returned from § 7.3.6 Get Access Need Decorator with inputs: NEED, LANG

  7. Let COMPILED hasShapeTreeDecorator be TREEDEC

  8. If TREEDEC skos:narrower

    1. Let NARROWERDEC be TREEDEC skos:narrower

    2. Let NARROWERTREE be NARROWERDEC hasShapeTree

    3. Let NARROWERCA be the Access Need returned from the § 7.3.2.5 _getSpecificAccessNeed operation with inputs: NARROWERTREE, OVERRIDES, NEED

    4. Let COMPILED skos:narrower be the Compiled Access returned from calling § 7.3.2.4 _walkDecorators with inputs: NARROWERTREE, NARROWERDEC, NARROWERCA, ALLDECS, ALLNEEDS, OVERRIDES, TREEDECS, LANG

  9. For each shape tree REFTREE linked via TREE st:references

    1. Call § 7.3.2 Compile Access Need with inputs REFTREE, NEED, ALLNEEDS, OVERRIDES, TREEDECS, ALLDECS, LANG

7.3.2.5. _getSpecificAccessNeed

This operation looks through all of the Access Need Overrides associated with a given Access Need Group to see if there is an Access Need Override for the input shape tree. If there is not, it will effective inherit its defaults from the last Access Need instead.

7.3.2.5.1. Inputs
7.3.2.5.2. Outputs
7.3.2.5.3. Operation Details
  1. For each Access Need NEED in OVERRIDES

    1. return NEED if NEED registeredShapeTree is TREE

  2. return DEFAULTNEED

This is a recursive operation that iterates through all of the Compiled Accesses associated with a Compiled Access Group and links together any that have a support relationship.

A support relationship exists when the shape tree associated with one Compiled Access has an st:supports predicate that links to the shape tree of another Compiled Access. They are linked bi-directionally through the interop:supports and interop:supportedBy properties.

  1. Let TREE be CACCESS registeredShapeTree

  2. If TREE st:supports

    1. Let SUPPORTEDTREE be the shape tree linked by TREE st:supports

    2. For each Compiled Access COMPILED in ALLCOMPILED

      1. Let SUPPORTEDCA be the return of § 7.3.3.4 Iterate for Supported Compiled Accesses with inputs: ALLCOMPILED, TREE

      2. Let CACCESS supports be SUPPORTEDCA

      3. Let SUPPORTEDCA supportedBy be CACCESS

  3. For each Compiled Access REFCA linked by CACCESS referencesCompiledAccess

    1. Call § 7.3.3 Link Supported Compiled Accesses with inputs: REFCA, ALLCOMPILED

  4. For each Compiled Access NARROWERCA linked by CACCESS skos:narrower

    1. Call § 7.3.3 Link Supported Compiled Accesses with inputs: NARROWERCA, ALLCOMPILED

7.3.3.4. Iterate for Supported Compiled Accesses

This is a recursive function that iterates through a linked hierarchy of Compiled Accesses looking for a Compiled Access with a matching shape tree.

7.3.3.4.1. Inputs
7.3.3.4.2. Outputs
7.3.3.4.3. Operation Details
  1. Return CACCESS if CACCESS registeredShapeTree is TREE

  2. For each Compiled Access REFCA linked by CACCESS referencesCompiledAccess

    1. Call § 7.3.3.4 Iterate for Supported Compiled Accesses with inputs: REFCA, TREE

  3. For each Compiled Access NARROWERCA linked by CACCESS skos:narrower

    1. Call § 7.3.3.4 Iterate for Supported Compiled Accesses with inputs: NARROWERCA, TREE

  4. Return NULL

7.3.4. Get Access Decorator Resource

This operation returns the appropriate Access Decorator Resource from an input Access Decorator Index for the provided language. If the provided language is not available, a default language is used instead.

7.3.4.1. Inputs
7.3.4.2. Outputs
7.3.4.3. Operation Details
  1. Let USESERIES be INDEX defaultSeries

  2. Let USEVERSION be an unassigned Access Decorator Version

  3. For each Access Decorator Series SERIES in INDEX

    1. Let USESERIES be SERIES if SERIES usesLanguage == LANG

  4. MUST return a status code of 404 if no Access Decorator Series are found.

  5. For each Access Decorator Version VERSION in USESERIES hasVersion

    1. Let USEVERSION be VERSION if VERSION is a more recent semantic version than USEVERSION or if USEVERSION is unassigned.

  6. MUST return a status code of 404 if no Access Decorator Versions are found.

  7. Let DECR be the Access Decorator Resource linked from USEVERSION hasAccessDecoratorResource

  8. MUST return a status code of 404 if DECR is unassigned.

  9. return DECR

7.3.5. Get Access Need Group Decorator

This operation returns the appropriate Access Need Group Decorator for an input Access Need Group in the provided language. If the provided language is not available, a default language is used instead.

7.3.5.1. Inputs
7.3.5.2. Outputs
7.3.5.3. Operation Details
  1. Let DECR be the Access Decorator Resource returned by § 7.3.5 Get Access Need Group Decorator with inputs: GROUP hasAccessDecoratorIndex, LANG

  2. Let USEGDEC be an unassigned Access Need Group Decorator

  3. Let GDECS be all Acess Need Group Decorators in DECR

  4. For each [=Acces Need Group Decorator] GDEC in GDECS

  5. Let USEGDEC be GDEC if GDEC hasAccessNeedGroup is GROUP

  6. MUST return a status code of 404 if USEGDEC is unassigned

  7. return USEGDEC

7.3.6. Get Access Need Decorator

This operation returns the appropriate Access Need Decorator for an input Access Need in the provided language. If the provided language is not available, a default language is used instead.

7.3.6.1. Inputs
7.3.6.2. Outputs
7.3.6.3. Operation Details
  1. Let GROUP be NEED inAccessNeedGroup

  2. Let DECR be the Access Decorator Resource returned by § 7.3.5 Get Access Need Group Decorator with inputs: GROUP hasAccessDecoratorIndex, LANG

  3. Let USENDEC be an unassigned Access Need Decorator

  4. Let NDECS be all Acess Need Decorators in DECR

  5. For each [=Acces Need Decorator] NDEC in NDECS

  6. Let USENDEC be NDEC if NDEC hasAccessNeedGroup is GROUP and NDEC registeredShapeTree is NEED registeredShapeTree

  7. MUST return a status code of 404 if USENDEC is unassigned

  8. return USENDEC

8. Access Grants

8.1. Overview

Write overview for Access Grants

8.2. Data Model

8.2.1. Summary

Data model for the access registry

An Agent links to Access Grant Registry Sets via the interop:hasAccessGrantRegistrySet property.

An Access Grant Registry Set links to any number of Access Grant Registries via the interop:hasRegistry property.

An Access Grant Registry links to any number of registered Access Grants and Access Invitations via the interop:hasRegistration property.

Agent at https://alice.pod.example/profile/id#me linking to an Access Grant Registry Set
<#me>
  a interop:Agent;
  interop:hasAccessGrantRegistrySet <https://alice.pod.example/profile/grant#set> .
An Access Grant Registry Set at https://alice.pod.example/profile/grant#set linking to two different Access Grant Registries
<#set>
  a interop:AccessGrantRegistrySet;
  interop:hasRegistry <https://alice.pod.example/grants/#registry> ,
                  <https://alice.otherpod.example/grants/#registry> .
An Access Grant Registry at https://alice.pod.example/grants/#registry linking to several registered Access Grants or Access Invitations
<#registry>
  a interop:AccessGrantRegistry ;
  interop:hasRegistration <ab3d0023-3860-4358-ae33-8d3af1097b9d#grant> ,
                      <ad7b935f-ced9-4ce6-835f-5c6abc046228#grant> ,
                      <5ed73c65-ce77-4c8a-8f7e-9715b90307e6#grant> ,
                      <2d575cba-3f6c-4c58-bccd-0e6266ba56cf#invitation> .
An Access Grant at https://alice.pod.example/grants/ab3d0023-3860-4358-ae33-8d3af1097b9d#grant
<#grant>
  a interop:AccessGrant ;
  interop:registeredBy https://alice.pod.example/profile/id#me ;
  interop:registeredWith https://trusted.example/id#agent ;
  interop:registeredAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:updatedAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:hasAccessGrantSubject <#grant-subject> ;
  interop:hasCompiledAccessGroup <#cag-notebook-group> ;
  interop:hasDataGrant <#notebook-grant>, <#note-grant> .

<#grant-subject>
  a interop:AccessGrantSubject ;
  interop:accessByAgent https://alice.pod.example/profile/id#me ;
  interop:accessByApplication https://nevernote.example/id#agent .

<#notebook-grant>
  a interop:DataGrant ;
  interop:hasRegistration data:notebook-tree ;
  interop:registeredShapeTree note:notebook-tree ;
  interop:satisfiesCompiledAccess <#ca-notebook> ;
  interop:accessMode acl:Read, acl:Write ;
  interop:scopeOfDataGrant interop:AllInstances ;

<#note-grant>
  a interop:DataGrant ;
  interop:hasRegistration data:note-tree ;
  interop:registeredShapeTree note:note-tree ;
  interop:satisfiesCompiledAccess <#ca-note> ;
  interop:accessMode acl:Read, acl:Write ;
  interop:scopeOfDataGrant interop:AllInstances ;

<#cag-notebook-group>
  a interop:CompiledAccessGroup ;
  interop:fromAccessNeedGroup ex:accessNotebookGroup ;
  interop:hasAccessNeedGroupDecorator ex:accessNotebookGroupDecorator ;
  interop:accessNecessity interop:AccessRequired ;
  interop:authenticatesAs interop:Pilot ;
  interop:hasCompiledAccess <#ca-notebook> .

<#ca-notebook>
    a interop:CompiledAccess ;
    interop:registeredShapeTree note:notebook-tree ;
    interop:accessMode acl:Read, acl:Write ;
    interop:accessNecessity interop:AccessRequired ;
    interop:hasAccessNeedDecorator ex:notebookAccessDecorator ;
    interop:hasShapeTreeDecorator note:notebookDecorator ;
    interop:referencesCompiledAccess <#ca-notes> ;
    interop:hasDataGrant <#notebook-grant> .

<#ca-note>
    a interop:CompiledAccess ;
    interop:registeredShapeTree note:note-tree ;
    interop:accessMode acl:Read, acl:Write ;
    interop:accessNecessity interop:AccessRequired ;
    interop:hasAccessNeedDecorator ex:noteAccessDecorator ;
    interop:hasShapeTreeDecorator note:noteDecorator ;
    interop:hasDataGrant <#note-grant> .
An Access Invitation at https://alice.pod.example/grants/2d575cba-3f6c-4c58-bccd-0e6266ba56cf/#invitation
<#invitation>
  a interop:AccessInvitation ;
  interop:registeredBy https://alice.pod.example/profile/id#me ;
  interop:registeredWith https://trusted.example/id#agent ;
  interop:registeredAt "2020-09-13T19:32:52Z"^^xsd:dateTime ;
  interop:updatedAt "2020-09-13T19:32:52Z"^^xsd:dateTime ;
  interop:expiresAt "2020-09-20T19:32:52Z"^^xsd:dateTime ;
  interop:hasCompiledAccessGroup <#cag-notebook-group> ;
  interop:hasDataGrant <#notebook-grant>, <#note-grant> ;
  interop:hasAccessInvitationChannel <#phone-channel>, <#email-channel> .

<#phone-channel>
  a interop:PhoneInvitationChannel ;
  interop:channelTarget "(555) 555-1212" ;
  interop:channelCode "654345" ;
  interop:isValidated false ;
  interop:remainingAttempts 3 .

<#email-channel>
  a interop:EmailInvitationChannel ;
  interop:channelTarget "bob@example.com" ;
  interop:channelCode "434567" ;
  interop:isValidated true ;
  interop:remainingAttempts 3 .

<#notebook-grant>
  a interop:DataGrant ;
  interop:hasRegistration data:notebook-tree ;
  interop:registeredShapeTree note:notebook-tree ;
  interop:satisfiesCompiledAccess <#ca-notebook> ;
  interop:accessMode acl:Read, acl:Write ;
  interop:scopeOfDataGrant interop:AllInstances ;

<#note-grant>
  a interop:DataGrant ;
  interop:hasRegistration data:note-tree ;
  interop:registeredShapeTree note:note-tree ;
  interop:satisfiesCompiledAccess <#ca-note> ;
  interop:accessMode acl:Read, acl:Write ;
  interop:scopeOfDataGrant interop:AllInstances ;

<#cag-notebook-group>
  a interop:CompiledAccessGroup ;
  interop:fromAccessNeedGroup ex:accessNotebookGroup ;
  interop:hasAccessNeedGroupDecorator ex:accessNotebookGroupDecorator ;
  interop:accessNecessity interop:AccessRequired ;
  interop:authenticatesAs interop:Pilot ;
  interop:hasCompiledAccess <#ca-notebook> .

<#ca-notebook>
    a interop:CompiledAccess ;
    interop:registeredShapeTree note:notebook-tree ;
    interop:accessMode acl:Read, acl:Write ;
    interop:accessNecessity interop:AccessRequired ;
    interop:hasAccessNeedDecorator ex:notebookAccessDecorator ;
    interop:hasShapeTreeDecorator note:notebookDecorator ;
    interop:referencesCompiledAccess <#ca-notes> ;
    interop:hasDataGrant <#notebook-grant> .

<#ca-note>
    a interop:CompiledAccess ;
    interop:registeredShapeTree note:note-tree ;
    interop:accessMode acl:Read, acl:Write ;
    interop:accessNecessity interop:AccessRequired ;
    interop:hasAccessNeedDecorator ex:noteAccessDecorator ;
    interop:hasShapeTreeDecorator note:noteDecorator ;
    interop:hasDataGrant <#note-grant> .

8.2.2. Access Grant Registry Set

An Access Grant Registry Set is a Registry Set specifically made up of Access Grant Registries.

AccessGrantRegistrySet a rdfs:subClassOf RegistrySet
Property Range Description
hasRegistry Registry Link to associated Access Grant Registries

The AccessGrantRegistrySetShape is used to validate an instance of the AccessGrantRegistrySet class.

<#AccessGrantRegistrySetShape> {
  a [ interop:AccessGrantRegistrySet ] ;
  interop:hasRegistry IRI+
}

The AccessGrantRegistrySetTree is assigned to a resource to ensure it will validate against the AccessGrantRegistrySetShape.

<#AccessGrantRegistrySetTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#AccessGrantRegistrySetShape> ;
  st:matchesUriTemplate "access" .

8.2.3. Access Grant Registry

An Access Grant Registry is a collection of Access Grants stored in a specific location in a pod.

AccessGrantRegistry a rdfs:subClassOf Registry
Property Range Description
hasRegistration Registration Link to associated Access Grants

The AccessGrantRegistryShape is used to validate an instance of the AccessGrantRegistry class.

<#AccessGrantRegistryShape> {
  a [ interop:AccessGrantRegistry ] ;
  interop:hasRegistration IRI*
}

The AccessGrantRegistryTree is assigned to a container resource to ensure that it will validate against the AccessGrantRegistryShape, and contain only conformant instances of the AccessGrantTree and AccessInvitationTree.

<#AccessGrantRegistryTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#AccessGrantRegistryShape> ;
  st:contains <#AccessGrantTree> ,
              <#AccessInvitationTree> ,
              st:AllowNone .

8.2.4. Access Grant

Each Access Grant represents access granted to one recipient; the Access Grant Subject, based on access criteria detailed in one or more Compiled Access Groups. Access is granted to registered data in Data Registries, identified by Data Grants linked to the Access Grant.

AccessGrant a rdfs:subClassOf Registration
Property Range Description
registeredBy Agent Agent that registered the Access Grant
registeredWith Application Application used to create the Access Grant
registeredAt xsd:dateTime Date and time the Access Grant was created
updatedAt xsd:dateTime Date and time the Access Grant was updated
hasAccessGrantSubject AccessGrantSubject Links to one Access Grant Subject who was granted access.
hasCompiledAccessGroup CompiledAccessGroup Links to a Compiled Access Group associated with the Access Grant.
hasDataGrant DataGrant Links to a Data Grant associated with the Access Grant.

The AccessGrantShape is used to validate an instance of the AccessGrant class.

<#AccessGrantShape> {
  a [ interop:AccessGrant ] ;
  interop:registeredBy IRI ;
  interop:registeredWith IRI? ;
  interop:registeredAt xsd:dateTime ;
  interop:accessGrantSubject @AccessGrantSubject ;
  interop:hasCompiledAccessGroup @CompiledAccessGroupShape+ ;
  interop:hasDataGrant @DataGrantShape+
}

The AccessGrantTree is assigned to a resource via the AccessGrantRegistryTree, and ensure that the assigned resource will validate against the AccessGrantShape.

<#AccessGrantTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#AccessGrantShape> ;
  st:matchesUriTemplate "{id}" .

8.2.5. Access Grant Subject

An Access Grant Subject represents a unique combination of who and what is being granted access. For example, it allows a single Agent to be specified, or a given Agent using a given Application.

AccessGrantSubject
Property Range Description
accessByAgent Agent Agent being granted access
accessByApplication Application Application being granted access

The AccessGrantSubjectShape is used to validate an instance of the AccessGrantSubject class.

<#AccessGrantSubjectShape> {
  a [ interop:AccessGrantSubject ] ;
  interop:accessGrantSubjectAgent IRI? ;
  interop:accessGrantSubjectApplication IRI?
}

8.2.6. Data Grant

A Data Grant records a decision made by a given Agent based upon Compiled Accesses presented to them for a given Data Registration.

DataGrant
Property Range Description
hasRegistration DataRegistration Data Registration the Data Grant applies to
registeredShapeTree st:ShapeTree The shape tree registered at the target Data Registration
satisfiesCompiledAccess CompiledAccess Links to a Compiled Access satisfied by the Data Grant
accessMode acl:Read, acl:Write, acl:Control, acl:Append Union of access modes from Compiled Accesses linked by satisfiesCompiledAccess
scopeOfDataGrant interop:AllInstances, interop:InheritInstances, interop:SelectedInstances, interop:NoAccess Identifies the access scope of the Data Grant
  • interop:AllInstances - Scope includes access to all Data Instances of the associated Data Registration
  • interop:InheritInstances - Scope includes access to Data Instances inherited by instances selected in the Data Grant linked via interop:inheritsFrom
  • interop:SelectedInstances - Scope includes access only to those Data Instances specifically selected by the Agent
  • interop:NoAccess - No access is granted
inheritsFrom DataGrant Identifies a Data Grant whose selected Data Instances narrow the scope of instances to be presented by this grant.
hasDataInstance Instance of registeredShapeTree Links to a Data Instance of registeredShapeTree.

The DataGrantShape is used to validate an instance of the DataGrant class.

<#DataGrantShape> {
  a [ interop:DataGrant ] ;
  interop:hasRegistration IRI ;
  interop:registeredShapeTree IRI ;
  interop:satisfiesCompiledAccess @CompiledAccessShape+ ;
  interop:accessMode [ acl:Read acl:Write acl:Append acl:Control ]+ ;
  interop:scopeOfDataGrant [ interop:SelectedInstances interop:AllInstances interop:InheritInstances interop:NoAccess ]+ ;
  interop:inheritsFrom @DataGrantShape*
}

8.2.7. Access Invitation

An Access Invitation is a subclass of Access Grant used when an Agent wishes to grant access to another Agent whose decentralized identity is unknown to them, or may not exist yet, so they must be first invited through another channel (such as phone or email).

Like an Access Grant, an Access Invitation links to access criteria detailed in one or more Compiled Access Groups, with associated Data Grants indicating the intended access to be granted.

However, instead of linking to an Access Grant Subject, an Access Invitation links to one or more Access Invitation Channels.

Each channel represents a mechanism through which the invitation can be delivered and validated. The mechanism is designed so that multiple channels may be validated before an invitation is confirmed and converted to an Access Grant.

AccessInvitation a rdfs:subClassOf AccessGrant
Property Range Description
registeredBy Agent Agent that registered the Access Invitation
registeredWith Application Application used to create the Access Invitation
registeredAt xsd:dateTime Date and time the Access Invitation was created
updatedAt xsd:dateTime Date and time the Access Invitation was updated
expiresAt xsd:dateTime Date and time the Access Invitation expires
hasAccessInvitationChannel AccessInvitationChannel Links to an Access Invitation Channel
hasCompiledAccessGroup CompiledAccessGroup Links to a Compiled Access Group associated with the Access Invitation.
hasDataGrant DataGrant Links to a Data Grant associated with the Access Invitation.

The AccessInvitationShape is used to validate an instance of the AccessInvitation class.

<#AccessInvitationShape> {
  a [ interop:AccessInvitation ] ;
  interop:registeredBy IRI ;
  interop:registeredWith IRI? ;
  interop:registeredAt xsd:dateTime ;
  interop:updatedAt xsd:dateTime ;
  interop:expiresAt xsd:dateTime? ;
  interop:hasCompiledAccessGroup @<#:CompiledAccessGroupShape>+ ;
  interop:hasDataGrant @<#:DataGrantShape>+
  interop:hasAccessInvitationChannel @<#:AccessInvitationChannelShape>+ ;
}

The AccessInvitationTree is assigned to a resource via the AccessGrantRegistryTree, and ensures that the assigned resource will validate against the AccessInvitationShape.

<#AccessInvitationTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#AccessInvitationShape> ;
  st:matchesUriTemplate "{id}" .

8.2.8. Access Invitation Channel

An Access Invitation Channel represents a mechanism through which an Access Invitation can be delivered and validated.

AccessInvitationChannel
Property Range Description
rdf:type interop:PhoneInvitationChannel, interop:EmailInvitationChannel, interop:SMSInvitationChannel, interop:OfflineInvitationChannel, interop:LDNInvitationChannel Each channel is represented by a subClassOf AccessInvitationChannel
channelTarget xsd:string Target used when validating the channel
channelCode xsd:string Code used for channel validation
isValidated xsd:boolean Indicates whether the channel has been validated
remainingAttempts xsd:integer Number of allowed validation attempts remaining

The AccessInvitationChannelShape is used to validate an instance of the AccessInvitationChannel class.

<#AccessInvitationChannelShape> {
   a @<#ChannelTypes> ;
   interop:channelTarget xsd:string ;
   interop:channelCode xsd:string ;
   interop:isValidated xsd:boolean ;
   interop:remainingAttempts xsd:integer
}

<#ChannelTypes> [
  :PhoneInvitationChannel   # Telephone
  :EmailInvitationChannel   # E-mail
  :SMSInvitationChannel     # SMS (Simple Messaging Service)
  :OfflineInvitationChannel # Other communication, e.g. verbal, shared note
  :LDNInvitationChannel     # Linked Data Notification
]

8.3. Resource Hierarchy

Resource Class Shape Shape Tree
/profile/ - - ProfileTree
-- grant#set AccessGrantRegistrySet AccessGrantRegistrySetShape AccessGrantRegistrySetTree
/grants/#registry AccessGrantRegistry AccessGrantRegistryShape AccessGrantRegistryTree
-- c482f931...630e5ab0#grant AccessGrant AccessGrantShape AccessGrantTree
-- e0983a7e...88c387ea#grant AccessGrant AccessGrantShape AccessGrantTree
-- eddf13d6...7f4962c5#grant AccessGrant AccessGrantShape AccessGrantTree
-- a990c1b9...c041eb74#grant AccessGrant AccessGrantShape AccessGrantTree
-- 265ef957...6689aee7#grant AccessGrant AccessGrantShape AccessGrantTree

The Access Grant Registry Set and the Access Grant Registry MAY or MAY NOT be on the same pod.

Access Grant Registry Set and Access Grant Registry resources MAY use any resource or subject names.

Access Grants MUST use UUIDs for resource names.

8.4. Operations

The § 8.4.10 Present Grant operation is non-normative, and meant to instruct a developer in how to load and initialize an Access Grant, present it to an Agent, invoke the appropriate operations to manipulate Data Grants in accordance with the Agent’s decisions, and then record those decisions, which will also apply the permission changes.

8.4.1. Initialize Grant

Initialize an Access Grant or Access Invitation by processing the input Access Need Groups into Compiled Access Groups, then initializing Data Grants with no access (yet) for the corresponding Compiled Accesses in each group.

8.4.1.1. Inputs
8.4.1.2. Outputs
8.4.1.3. Operation Details
  1. MUST return a status code of 400 if both SUBJECT and ICHANNELS are provided

  2. If SUBJECT is provided

    1. Let NEW be a newly initialized Access Grant

    2. Let NEW hasAccessGrantSubject be SUBJECT

  3. If ICHANNELS is provided

    1. Let NEW be a newly initialized Access Invitation

    2. For each Access Invitation Channel ICHANNEL in ICHANNELS

      1. Let ICHANNEL be linked to NEW via NEW hasAccessInvitationChannel

  4. For each Access Need Group GROUP in GROUPS

    1. Let CAGROUP be the Compiled Access Group returned from § 7.3.1 Compile Access Need Group with inputs GROUP, LANG

    2. Link CAGROUP to NEW via NEW hasCompiledAccessGroup

  5. Let CAGROUPS be all Compiled Access Groups linked to NEW via hasCompiledAccessGroup

  6. Let DATAGRANTS be an empty set of Data Grants

  7. For each Compiled Access Group CAGROUP in CAGROUPS

    1. For each Compiled Access CACCESS in CAGROUP

      1. Let MATCHING be a Data Grant in DATAGRANTS where CACCESS registeredShapeTree == MATCHING registeredShapeTree

      2. If MATCHING let CACCESS hasDataGrant be MATCHING

      3. If MATCHING is missing

        1. Let NEWDATAGRANT be a newly initialized Data Grant

        2. Let NEWDATAGRANT registeredShapeTree be CACCESS registeredShapeTree

        3. Let NEWDATAGRANT hasRegistration be a Data Registration DR where DR registeredShapeTree == NEWDATAGRANT registeredShapeTree

        4. Let NEWDATAGRANT scopeOfDataGrant be interop:NoAccess

        5. Let CACCESS hasDataGrant be NEWDATAGRANT

        6. Add CACCESS hasDataGrant to DATAGRANTS

      4. Let DATAGRANT be CACCESS hasDataGrant

      5. Let DATAGRANT satisfiesCompiledAccess include CACCESS

      6. Let DATAGRANT accessmodes include CACCESS accessmodes

  8. Return NEW

8.4.2. Load Grant

This operation will load an Access Grant from a given Access Grant Registry

8.4.2.1. Inputs
8.4.2.2. Outputs
8.4.2.3. Operation Details
  1. For each Access Grant GRANT included in REGISTRY hasRegistration

    1. return GRANT if GRANT hasAccessGrantSubject == SUBJECT

8.4.3. Load Invitation

This operation will load an Access Invitation from a given Access Grant Registry

8.4.3.1. Inputs
8.4.3.2. Outputs
8.4.3.3. Operation Details
  1. Let INVITATIONS be an empty set of Access Invitations

  2. For each Access Invitation INVITATION linked via REGISTRY hasRegistration

    1. For each Access Invitation Channel ICHANNEL linked via INVITATION hasAccessInvitationChannel

      1. Next if ICHANNEL channelTarget != TARGET

      2. Next if CODE is not empty and ICHANNEL channelCode != CODE

      3. Add INVITATION to INVITATIONS

  3. Return INVITATIONS

8.4.4. Validate Grant

This operation is used to validate an Access Grant or Access Invitation before it is stored in an Access Grant Registry

8.4.4.1. Inputs
8.4.4.2. Outputs
8.4.4.3. Operation Details
  1. If GRANT is an Access Invitation

    1. Perform a validation of the RDF graph of GRANT against interop:AccessInvitationShape. MUST return a status code of 400 if validation fails.

  2. If GRANT is an Access Grant

    1. Perform a validation of the RDF graph of GRANT against interop:AccessGrantShape. MUST return a status code of 400 if validation fails.

  3. Let CAGROUPS be the Compiled Access Groups linked to GRANT via GRANT hasCompiledAccessGroup

  4. Let DGRANTS be the Data Grants linked to GRANT via GRANT hasDataGrant

  5. For each Compiled Access Group CAGROUP in CAGROUPS:

    1. For each Compiled Access CACCESS in CAGROUP traversed via CACCESS skos:narrower or CACCESS referencesCompiledAccess:

      1. Let NDGRANT be the Data Grant associated with CACCESS via CACCESS hasDataGrant

        1. Error if NDGRANT is missing

        2. Error if NDGRANT satisfiesCompiledAccess doesn’t link to CACCESS

        3. Error if interop:RegisteredShapeTree is not the same in NDGRANT and CACCESS

  6. For each Data Grant DGRANT in DGRANTS

    1. Let CA be all Compiled Accesses across CAGROUPS

    2. Let DGCA be all Compiled Accesses linked to DGRANT via DGRANT satisfiesCompiledAccess

    3. Error if DGCA is not in CA

    4. Error if DGCA is empty

    5. Error if DGRANT access modes are not an exact union of DGCA accessMode values when DGRANT scopeOfDataGrant is not interop:NoAccess

8.4.5. Record Grant

This operation stores a new or updated Access Grant in an Access Grant Registry, applies permissions accordingly, and calls for an access receipt to be provided.

8.4.5.1. Inputs
8.4.5.2. Outputs
8.4.5.3. Operation Details
  1. Call § 8.4.4 Validate Grant with inputs: GRANT. MUST return a status code of 400 if validation fails.

  2. Add or Update GRANT resource in the REGISTRY container, conforming to the assigned interopt:AccessGrantTree.

  3. Link GRANT to the REGISTRY via REGISTRY hasRegistration if it has not already been added

  4. Call § 8.4.9 Apply Permissions with inputs: GRANT

  5. TODO - CALL TO PROVIDE ACCESS RECEIPT GOES HERE

  6. Return GRANT

Need to properly factor in multi-pod scenarios. Must identify the proper access registry to store things in based on the data registration, which means pods will also need to be registered.

8.4.6. Record Invitation

This operation stores a new or updated Access Invitation in an Access Grant Registry.

8.4.6.1. Inputs
8.4.6.2. Outputs
8.4.6.3. Operation Details
  1. Call § 8.4.4 Validate Grant with inputs: INVITATION. MUST return a status code of 400 if validation fails.

  2. Add or Update INVITATION resource in the REGISTRY container, conforming to the assigned interopt:AccessInvitationTree

  3. Link INVITATION to the REGISTRY via ACCESS hasRegistration if it has not already been added

  4. TODO - CALL TO DELIVER INVITATION VIA CHANNEL GOES HERE

  5. Return INVITATION

8.4.7. Deliver Invitation

Write standard operation for invitation delivery

8.4.8. Validate Invitation

Write standard operation for validating an invitation

8.4.9. Apply Permissions

8.4.9.1. Inputs
8.4.9.2. Outputs
8.4.9.3. Operation Details
  1. Let DGRANTS be the Data Grants linked to GRANT via GRANT hasDataGrant

  2. For each Data Grant DGRANT in GRANTS

    1. Let the Data Registration linked via DGRANT hasRegistration be DREG

    2. If DGRANT scopeOfDataGrant includes interop:NoAccess

      1. Ignore any other scopes linked via DGRANT scopeOfDataGrant

      2. Let ACL be the ACL Resource directly associated with DREG

      3. Let STATEMENTS be any Authorization Statements in ACL directly associated with GRANT accessGrantSubject.

      4. For each STATEMENT in STATEMENTS

        1. Remove Authorization Subject from STATEMENT

        2. Remove STATEMENT if there are no remaining Authorization Subjects

    3. If DGRANT scopeOfDataGrant includes interop:AllInstances

      1. Error if interop:AllInstances is not the only scope associated via DGRANT scopeOfDataGrant

      2. Let ACL be the ACL Resource directly associated with DREG

      3. Let STATEMENTS be any Authorization Statements in ACL directly associated with GRANT accessGrantSubject.

      4. For each STATEMENT in STATEMENTS

        1. Remove Authorization Subject from STATEMENT

        2. Remove STATEMENT from ACL if there are no remaining Authorization Subjects in STATEMENT

      5. Add a new Authorization Statement NEWSTATEMENT to ACL

        1. Set NEWSTATEMENT Authorization Subject to GRANT accessGrantSubject.

        2. Set the access modes for NEWSTATEMENT to the access modes linked via DGRANT accessMode such that all Data Instances in REG inherit those access modes

    4. If DGRANT scopeOfDataGrant includes ONLY interop:InheritInstances

      1. Let IDGRANT be the inherited Data Grant

      2. Error if DGRANT inheritsFrom is missing

      3. Error if IDGRANT interop:RegisteredShapeTree does not have a reference to DGRANT interop:registeredShapeTree via st:references

      4. Let ACL be the ACL Resource directly associated with DREG

      5. Let STATEMENTS be any Authorization Statements in ACL directly associated with GRANT accessGrantSubject.

      6. For each STATEMENT in STATEMENTS

        1. Remove Authorization Subject from STATEMENT

        2. Remove STATEMENT from ACL if there are no remaining Authorization Subjects in STATEMENT

      7. Add a new Authorization Statement NEWSTATEMENT to ACL

        1. Set NEWSTATEMENT Authorization Subject to GRANT accessGrantSubject.

        2. Set the access modes for NEWSTATEMENT to the access modes linked via DGRANT accessMode such that all Data Instances in REG inherit those access modes, with the following condition:

          1. Access will only be granted to Data Instances when a link exists between IDGRANT interop:registeredShapeTree and DGRANT interop:registeredShapeTree.

          2. The predicate of the link must be the same as the property detailed in st:traverseViaShapePath, in the st:references from IDGRANT interop:registeredShapeTree

    5. If DGRANT scopeOfDataGrant includes interop:InheritInstances AND interop:SelectedInstances

      1. Error if any other scopes are associated via DGRANT scopeOfDataGrant

      2. Error if DGRANT inheritsFrom is missing

      3. Error if IDGRANT interop:RegisteredShapeTree does not have a reference to DGRANT interop:registeredShapeTree via st:references

      4. Use instructions for interop:SelectInstances

    6. If DGRANT scopeOfDataGrant includes interop:SelectedInstances

      1. Let INSTANCES be the Data Instances linked via DGRANT interop:hasDataInstance

      2. Error if there are no INSTANCES

      3. For each INSTANCE in INSTANCES

      4. Error if INSTANCE is missing

      5. Let ACL be the ACL Resource directly associated with INSTANCE

      6. Let STATEMENTS be any Authorization Statements in ACL directly associated with GRANT accessGrantSubject

      7. For each STATEMENT in STATEMENTS

        1. Remove Authorization Subject from STATEMENT

        2. Remove STATEMENT from ACL if there are no remaining Authorization Subjects in STATEMENT

      8. Add a new Authorization Statement NEWSTATEMENT to ACL

        1. Set NEWSTATEMENT Authorization Subject to GRANT accessGrantSubject.

        2. Set the access modes for NEWSTATEMENT to the access modes linked via DGRANT accessMode

        3. If INSTANCE is a container, ensure all resources in the container are set to inherit those access modes

Deal with cases when the data registration doesn’t exist yet

Append mode for AllInstances needs to be specially handled, and may require an additional attribute specified in the requested Access Needs

8.4.10. Present Grant

This operation is non-normative, and meant to instruct a developer in how to load and initialize an Access Grant or Access Invitation, present it to an Agent, invoke the appropriate operations to manipulate Data Grants in accordance with the Agent’s decisions, and then record and act upon those decisions.

8.4.10.1. Inputs
8.4.10.2. Operation Details
  1. MUST return a status code of 400 if both SUBJECT and TARGET are provided

  2. If SUBJECT is provided

    1. Let GRANT be an Access Grant returned by § 8.4.2 Load Grant with inputs: SUBJECT, REGISTRY

      1. If GRANT is missing, let GRANT be an Access Grant returned by § 8.4.1 Initialize Grant with inputs: SUBJECT, REGISTRY, GROUPS, LANG.

    2. Present the Access Grant Subject

  3. If TARGET is provided

    1. Let GRANT be an Access Invitation returned by § 8.4.3 Load Invitation with inputs: TARGET, REGISTRY

      1. If GRANT is missing, let GRANT be an Access Invitation returned by § 8.4.1 Initialize Grant with inputs: ICHANNELS, REGISTRY, GROUPS, LANG

  4. If available, present the Agent who granted access via registeredBy

  5. If available, present the Application used by the Agent to grant access via registeredWith

  6. If available, present the timestamp of creation via registeredAt, and update via updatedAt

  7. For each Compiled Access Group CAGROUP linked via GRANT hasCompiledAccessGroup

    1. Let GDEC be the Access Need Group Decorator linked via CAGROUP hasAccessNeedGroupDecorator

    2. Present the group name via GDEC skos:prefLabel

    3. Present the group description via GDEC skos:definition

    4. Identify the Agent that will be granted access via authenticatesAs. interop:Pilot indicates a piloted application.

    5. If CAGROUP accessNecessity is AccessOptional and CAGROUP isEnabled is true, allow the group to be disabled by invoking the § 8.4.11 Deny Compiled Access Group operation with inputs: GRANT, CAGROUP

    6. If CAGROUP accessNecessity is AccessOptional and CAGROUP isEnabled is false, allow the group to be enabled by setting CAGROUP isEnabled to true.

    7. If (CAGROUP accessNecessity is AccessOptional and CAGROUP isEnabled), or if CAGROUP accessNecessity is AccessRequired

      1. For each Root Compiled Access ROOT linked via CAGROUP hasCompiledAccess

        1. For each Compiled Access CACCESS starting with ROOT and traversed via CACCESS skos:narrower or CACCESS referencesCompiledAccess:

          1. Let DATAGRANT be CACCESS hasDataGrant

          2. Let NDEC be CACCESS hasAccessNeedDecorator

          3. Let STDEC be CACCESS hasShapeTreeDecorator

          4. If CACCESS accessNecessity is AccessOptional, and DATAGRANT scopeOfDataGrant is interop:NoAccess

            1. Allow access selection to be enabled and managed as detailed in the remainder of this operation.

          5. Present the name of the shape tree via STDEC skos:prefLabel

          6. Present the reason access to this data is needed via NDEC skos:prefLabel

          7. Present the access modes requested via CACCESS accessModes

          8. For each Supporting Access Need SUPPORTING linked via CACCESS supportedBy

            1. Present the name of the shape tree via the associated Shape Tree Decorator

            2. Present the reason access to this data is needed via the associated Access Need Decorator

            3. Present the access modes requested via SUPPORTING accessModes

          9. If DATAGRANT scopeOfDataGrant is interop:NoAccess

            1. Allow interop:AllInstances to be selected, which invokes the § 8.4.13 Select All Instances for Access operation with inputs: GRANT, CAGROUP, CACCESS

            2. Allow a subset of Data Instances be selected, and let INSTANCES be that subset, invoking the § 8.4.12 Select Specific Instances for Access operation with inputs: INSTANCES, GRANT, CAGROUP, CACCESS

          10. If DATAGRANT scopeOfDataGrant is interop:AllInstances, then present the user with summary details, and the ability to see specific instances.

            1. Let INSTANCES be a selected set of Data Instances

            2. If the user chooses to select specific instances from this list, invoke the § 8.4.12 Select Specific Instances for Access operation with inputs: INSTANCES, GRANT, CAGROUP, CACCESS.

          11. If DATAGRANT scopeOfDataGrant is interop:SelectedInstances, then present the user with the specific instances they have selected, and:

            1. Let INSTANCES be a selected set of Data Instances

            2. Allow the selected Data Instances to be adjusted, and invoke the § 8.4.12 Select Specific Instances for Access operation with inputs: INSTANCES, DATAGRANT, CAGROUP, CACCESS.

            3. Allow all Data Instances to be selected, invoking the § 8.4.13 Select All Instances for Access operation with inputs: GRANT, CAGROUP, CACCESS.

          12. If DATAGRANT scopeOfDataGrant is interop:InheritInstances, present the inherited Data Instances and:

            1. Let INSTANCES be a selected set of Data Instances

            2. Allow a subset to be selected, invoking the § 8.4.12 Select Specific Instances for Access operation with inputs: INSTANCES, GRANT, CAGROUP, CACCESS

            3. Identify the Compiled Access / Data Grant and selected Data Instances that were inherited from.

          13. If DATAGRANT scopeOfDataGrant includes interop:SelectedInstances and interop:InheritInstances

            1. Let INSTANCES be a selected set of Data Instances

            2. Give the ability to adjust the selected instances, invoking the § 8.4.12 Select Specific Instances for Access operation with inputs: INSTANCES, GRANT, CAGROUP, CACCESS.

            3. Give the ability to revert to all inherited instances, invoking the § 8.4.13 Select All Instances for Access operation with inputs: GRANT, CAGROUP, CACCESS

    8. Call § 8.4.5 Record Grant if GRANT is an Access Grant to save.

    9. Call § 8.4.6 Record Invitation if GRANT is an Access Invitation to save.

Consider when an existing Access Need Group is expanded or contracted

Consider when there are new Groups being requested from a given Agent

8.4.11. Deny Compiled Access Group

This operation is used when a given Compiled Access Group with optional necessity has been denied.

8.4.11.1. Inputs
8.4.11.2. Operation Details
  1. Let CAGROUP isEnabled be false if CAGROUP accessNecessity is interop:AccessOptional

  2. For each Compiled Access CACCESS in CAGROUP

    1. Let DATAGRANT be CACCESS hasDataGrant

    2. Let DATAGRANT scopeOfDataGrant be interop:NoAccess

8.4.12. Select Specific Instances for Access

Used to select specific Data Instances for a given Data Grant, which has a recursive application down the hierachy, with subordinate Data Grants reducing their associated scope of Data Instances to only those related to the instances above them.

Write operation for selecting specific Data Instances for a given Data Registration within an Access Grant

8.4.13. Select All Instances for Access

Used to select all Data Instances for a given Data Grant. In the event where this is moving from a subset of inherited instances, this will expand to only include all inherited instances.

Write operation for selecting all Data Instances for a given Data Registration within an Access Grant

9. Access Receipts

9.1. Overview

Write overview for Access Receipts

9.2. Data Model

9.2.1. Summary

Data model for the Access Receipt Registry

An Agent links to Access Receipt Registry Sets via the interop:hasAccessReceiptRegistrySet property.

An Access Receipt Registry Set links to any number of Access Receipt Registries via the interop:hasRegistry property.

An Access Receipt Registry links to any number of registered Access Receipts via the interop:hasRegistration property.

Agent at https://alice.pod.example/profile/id#me linking to an Access Receipt Registry Set
<#me>
  a interop:Agent;
  interop:hasAccessReceiptRegistrySet <https://alice.pod.example/profile/receipt#set> .
An Access Receipt Registry Set at https://bob.pod.example/profile/receipt#set linking to two different Access Receipt Registries
<#set>
  a interop:AccessReceiptRegistrySet;
  interop:hasRegistry <https://bob.pod.example/receipts/#registry> ,
                  <https://bob.otherpod.example/receipts/#registry> .
An Access Receipt Registry at https://bob.pod.example/receipts/#registry linking to several registered Access Receipts
<#registry>
  a interop:AccessReceiptRegistry ;
  interop:hasRegistration <fa6d6553-0308-4abd-bce6-888df653695a#receipt> ,
                      <d49eae8c-e138-4153-86ed-63832deadc6b#receipt> ,
                      <506a0cee-1dc9-4720-a768-294aa0284502#receipt> .
An Access Receipt at https://bob.pod.example/receipts/fa6d6553-0308-4abd-bce6-888df653695a#receipt
<#receipt>
  a interop:AccessReceipt ;
  interop:registeredBy https://bob.pod.example/profile/id#me ;
  interop:registeredWith https://trusted.example/id#agent ;
  interop:registeredAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:updatedAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:providedAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:fromAgent https://alice.pod.example/profile/id#me ;
  interop:toAgent https://bob.pod.example/profile/id#me ;
  interop:hasDataReceipt <#notebook-receipt>, <#note-receipt> .

<#notebook-receipt>
  a interop:DataReceipt ;
  interop:hasRegistration https://alice.pod.example/data/notebook/#registration ;
  interop:registeredShapeTree note:notebook-tree ;
  interop:accessMode acl:Read, acl:Write ;
  interop:scopeOfDataGrant interop:SelectedInstances ;
  interop:hasDataInstance https://alice.pod.example/data/notebook/notebook-1/#notebook ,
                                https://alice.pod.example/data/notebook/notebook-2/#notebook .

<#note-receipt>
  a interop:DataReceipt ;
  interop:hasRegistration https://alice.pod.example/data/note/#registration ;
  interop:registeredShapeTree note:note-tree ;
  interop:accessMode acl:Read, acl:Write ;
  interop:scopeOfDataGrant interop:inheritInstances ;
  interop:inheritsFrom <#notebook-receipt> ;
  interop:hasDataInstance https://alice.pod.example/data/note/note-1/#note ,
                                https://alice.pod.example/data/note/note-2/#note ,
                                https://alice.pod.example/data/note/note-3/#note ,
                                https://alice.pod.example/data/note/note-4/#note ,
                                https://alice.pod.example/data/note/note-5/#note .

9.2.2. Access Receipt Registry Set

An Access Receipt Registry Set is a Registry Set specifically made up of Access Receipt Registries.

AccessReceiptRegistrySet a rdfs:subClassOf RegistrySet
Property Range Description
hasRegistry Registry Link to associated Access Receipt Registries

The AccessReceiptRegistrySetShape is used to validate an instance of the AccessReceiptRegistrySet class.

<#AccessReceiptRegistrySetShape> {
  a [ interop:AccessReceiptRegistrySet ] ;
  interop:hasRegistry IRI+
}

The AccessReceiptRegistrySetTree is assigned to a resource to ensure it will validate against the AccessReceiptRegistrySetShape.

<#AccessReceiptRegistrySetTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#AccessReceiptRegistrySetShape> ;
  st:matchesUriTemplate "receipt" .

9.2.3. Access Receipt Registry

An Access Receipt Registry is a collection of Access Receipts stored in a specific location in a pod.

AccessReceiptRegistry a rdfs:subClassOf Registry
Property Range Description
hasRegistration Registration Link to associated Access Receipts

The AccessReceiptRegistryShape is used to validate an instance of the AccessReceiptRegistry class.

<#AccessReceiptRegistryShape> {
  a [ interop:AccessReceiptRegistry ] ;
  interop:hasRegistration IRI*
}

The AccessReceiptRegistryTree is assigned to a container resource to ensure that it will validate against the AccessReceiptRegistryShape, and contain only conformant instances of the AccessReceiptTree.

<#AccessReceiptRegistryTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#AccessReceiptRegistryShape> ;
  st:contains <#AccessReceiptTree> ,
              st:AllowNone .

9.2.4. Access Receipt

Each Access Receipt ...

Write definition for Access Receipt class

AccessReceipt a rdfs:subClassOf Registration
Property Range Description
registeredBy Agent Agent that registered the Access Receipt
registeredWith Application Application used to create the Access Receipt
registeredAt xsd:dateTime Date and time the Access Receipt was created
updatedAt xsd:dateTime Date and time the Access Receipt was updated
providedAt xsd:dateTime Date and time the Access Receipt was shared
fromAgent Agent Agent that granted access and sent the Access Receipt
toAgent Agent Agent who was granted access and received the Access Receipt
hasDataReceipt DataReceipt Data Receipt for a shared Data Registration and any shared Data Instances

The AccessReceiptShape is used to validate an instance of the AccessReceipt class.

<#AccessReceiptShape> {
  a [interop:AccessReceipt] ;
  interop:fromAgent IRI ;             # Agent who sent the receipt
  interop:toAgent IRI ;               # Recipient of the receipt
  interop:registeredBy IRI ;
  interop:registeredWith IRI? ;
  interop:registeredAt xsd:dateTime ;
  interop:updatedAt xsd:dateTime ;
  interop:providedAt xsd:dateTime ;
  interop:hasDataReceipt @<#:DataReceiptShape> ;
}

The AccessReceiptTree is assigned to a resource via the AccessGrantRegistryTree, and ensures that the assigned resource will validate against the AccessReceiptShape.

<#AccessReceiptTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#AccessReceiptShape> ;
  st:matchesUriTemplate "{id}" .

9.2.5. Data Receipt

A Data Receipt ...

Write definition for Data Receipt class

DataReceipt
Property Range Description
hasRegistration DataRegistration Remote Data Registration the Data Receipt applies to
registeredShapeTree st:ShapeTree The shape tree registered at the target Data Registration
accessMode acl:Read, acl:Write, acl:Control, acl:Append Access modes granted
scopeOfDataGrant interop:AllInstances, interop:InheritInstances, interop:SelectedInstances, interop:NoAccess Identifies the access scope of the Data Grant
  • interop:AllInstances - Scope includes access to all Data Instances of the associated Data Registration
  • interop:InheritInstances - Scope includes access to Data Instances inherited by instances selected in the Data Receipt linked via interop:inheritsFrom
  • interop:SelectedInstances - Scope includes access only to those Data Instances specifically selected by the Agent
  • interop:NoAccess - No access is granted
inheritsFrom DataReceipt Identifies a Data Receipt whose selected Data Instances narrow the scope of instances to be presented by this receipt.
hasDataInstance Instance of registeredShapeTree Links to a Data Instance of registeredShapeTree.
replacedBy DataReceipt Another Data Receipt that replaces this one

The DataReceiptShape is used to validate an instance of the DataReceipt class.

<#DataReceiptShape> {
  a [interop:DataReceipt] ;
  interop:hasRegistration IRI ;       # Remote data registration
  interop:registeredShapeTree IRI ;   # Associated shape tree
  interop:accessMode [ acl:Read acl:Write acl:Append acl:Control ]+ ;
  interop:scopeOfDataGrant [ interop:SelectedInstances interop:AllInstances interop:InheritInstances interop:NoAccess ]+ ;
  interop:hasDataInstance IRI* ;     # if specific instances are selected or inherited
  interop:inheritsFrom @<#:DataReceiptShape>* ;
  interop:replacedBy IRI?
}

9.3. Resource Hierarchy

Resource Class Shape Shape Tree
/profile/ - - ProfileTree
-- receipt#set AccessReceiptRegistrySet AccessReceiptRegistrySetShape AccessReceiptRegistrySetTree
/receipts/#registry AccessReceiptRegistry AccessReceiptRegistryShape AccessReceiptRegistryTree
-- fa6d6553...5a#receipt AccessReceipt AccessReceiptShape AccessReceiptTree
-- d49eae8c...6b#receipt AccessReceipt AccessReceiptShape AccessReceiptTree
-- 506a0cee...02#receipt AccessReceipt AccessReceiptShape AccessReceiptTree

The Access Receipt Registry Set and the Access Receipt Registry MAY or MAY NOT be on the same pod.

Access Receipt Registry Set and Access Receipt Registry resources MAY use any resource or subject names.

Access Receipts MUST use UUIDs for resource names.

9.4. Operations

9.4.1. Provide Access Receipt

9.4.1.1. Inputs
9.4.1.2. Outputs
9.4.1.3. Operation Details
  1. Let REC-SUBJECT be the Access Grant Subject linked via GRANT hasAccessGrantSubject

  2. Let REC-AGENT be REC-SUBJECT accessByAgent

  3. Let REC-APP be REC-SUBJECT accessByApplication

  4. Let RECEIPT be an empty Access Receipt

  5. If REC-APP is not empty

    1. If REC-APP interop:receivesAccessReceipt is ReceiptInRegistration

      1. Let RECEIPT be result of § 9.4.1.4 Provide Receipt in Application Registration with inputs: GRANT

    2. If REC-APP interop:receivesAccessReceipt is ReceiptInMessage

      1. Let RECEIPT be result of § 9.4.1.6 Provide Receipt in Message with inputs: GRANT

  6. If REC-APP is empty and REC-AGENT is not empty

    1. Return error if REC-AGENT interop:receivesAccessReceipt is not ReceiptInMessage

    2. Let RECEIPT be result of § 9.4.1.6 Provide Receipt in Message with inputs: GRANT

  7. Return RECEIPT

9.4.1.4. Provide Receipt in Application Registration
9.4.1.4.1. Inputs
9.4.1.4.2. Outputs
9.4.1.4.3. Operation Details
  1. Let REC-SUBJECT be the Access Grant Subject linked via GRANT hasAccessGrantSubject

  2. Let REC-APP be REC-SUBJECT accessByApplication

    1. Let RECEIPT be an empty Access Receipt

  3. Let RECEIPT fromAgent be CONTROLLER

  4. Let RECEIPT toAgent be REC-APP

  5. Let RECEIPT providedAt be the current time

  6. For each Data Grant DATAGRANT linked via GRANT hasDataGrant

    1. Let RECEIPT hasDataReceipt be linked to the result of § 9.4.1.5 Provide Data Receipt with inputs: DATAGRANT

  7. Let APPREG be result of § 4.5.1 Load Application Registration with inputs: CONTROLLER, REC-APP

    1. Call § 4.5.2 Register Application if APPREG is empty

  8. Post RECEIPT to APPREG container

  9. Let CURRENT be APPREG hasAccessReceipt

  10. Remove CURRENT if it exists

  11. Let APPREG hasAccessReceipt be CURRENT

  12. Return RECEIPT

9.4.1.5. Provide Data Receipt
9.4.1.5.1. Inputs
9.4.1.5.2. Outputs
9.4.1.5.3. Operation Details
  1. Let DATARECEIPT be an empty Data Receipt

  2. Let DATARECEIPT hasRegistration be DATAGRANT hasRegistration

  3. Let DATARECEIPT registeredShapeTree be DATAGRANT registeredShapeTree

  4. Let DATARECEIPT accessModes be the same as DATAGRANT accessModes

  5. Let DATARECEIPT scopeOfDataGrants be the same as DATAGRANT scopeOfDataGrants

  6. Let DATARECEIPT hasDataInstances be the same as DATAGRANT hasDataInstances

  7. Let DATARECEIPT inheritsFroms be the same as DATAGRANT inheritsFroms

  8. Return DATARECEIPT

9.4.1.6. Provide Receipt in Message
9.4.1.6.1. Inputs
9.4.1.6.2. Outputs
9.4.1.6.3. Operation Details
  1. Let REC-SUBJECT be the Access Grant Subject linked via GRANT hasAccessGrantSubject

  2. Let REC-AGENT be REC-SUBJECT accessByAgent

  3. Let RECEIPT be an empty Access Receipt

  4. Let RECEIPT fromAgent be CONTROLLER

  5. Let RECEIPT toAgent be REC-AGENT

  6. Let RECEIPT providedAt be the current time

  7. For each Data Grant DATAGRANT linked via GRANT hasDataGrant

    1. Let RECEIPT hasDataReceipt be linked to the result of § 9.4.1.5 Provide Data Receipt with inputs: DATAGRANT

  8. Post RECEIPT to REC-AGENT hasAccessInbox

  9. Return RECEIPT

9.4.2. Record Access Receipt

This operation stores a new Access Receipt in an Access Grant Registry, which in turn will update Remote Data Registries to reflect the access granted in the Access Receipt.

9.4.2.1. Inputs
9.4.2.2. Outputs
9.4.2.3. Operation Details
  1. Let CURRENT be an Access Receipt returned by § 9.4.3 Load Access Receipt with inputs: FROMAGENT, REGISTRY

  2. If CURRENT is empty

    1. Add RECEIPT to REGISTRY

    2. Link RECEIPT to REGISTRY via REGISTRY hasRegistration

  3. If CURRENT is not empty

    1. Update CURRENT with RECEIPT

  4. Call § 10.4.1 Update Remote Data with inputs: RECEIPT

  5. Return RECEIPT

9.4.3. Load Access Receipt

9.4.3.1. Inputs
9.4.3.2. Outputs
9.4.3.3. Operation Details
  1. For each Access Receipt RECEIPT included in REGISTRY hasRegistration

    1. return RECEIPT if RECEIPT fromAgent == AGENT

9.4.4. Present Access Receipt

This operation shows an Agent an Access Receipt that was delivered to them from another Agent who granted them access to the data reflected in the receipt.

It presents them the access that has been granted in the receipt, and prompts them to accept it. Acceptance will record the receipt in their Access Receipt Registry, and update their Remote Data Registry to reflect it.

9.4.4.1. Inputs
9.4.4.2. Operation Details
  1. Present RECEIPT fromAgent as the Agent granting access

  2. Present RECEIPT toAgent as the Agent receiving access

  3. Let CURRENT be an Access Receipt returned by § 9.4.3 Load Access Receipt with inputs: RECEIPT fromAgent, REGISTRY

  4. If CURRENT is not empty

    1. Present the Agent that accepted it via RECEIPT registeredBy

    2. Present the Application is was accepted with via RECEIPT registeredWith

    3. Present when it was registered via RECEIPT registeredAt

    4. Present when it was last updated via RECEIPT updatedAt

  5. For each Data Receipt DATARECEIPT linked via RECEIPT hasDataReceipt

    1. Let STDEC be the Shape Tree Decorator returned from the Get Shape Tree Decorator operation with inputs: RECEIPT registeredShapeTree, LANG

    2. Present the name of the shape tree via STDEC skos:prefLabel

    3. Present RECEIPT accessModes

    4. Present RECEIPT scopeOfDataGrant

      1. If RECEIPT scopeOfDataGrant is interop:NoAccess

        1. Present the user any access that is being rescinded if they have an existing Data Receipt from RECEIPT fromAgent for RECEIPT registeredShapeTree

      2. If RECEIPT scopeOfDataGrant is interop:AllInstances

        1. Present the Agent with summary details, and the ability to view the Data Instances

      3. If RECEIPT scopeOfDataGrant includes interop:SelectedInstances

        1. Present the Agent with summary details, and the ability to view the Data Instances

      4. If RECEIPT scopeOfDataGrant includes interop:InheritInstances

        1. Present the Agent with summary details, and the ability to view the Data Instances, along with pointers to the Data Receipt they inherit from.

        2. Order this Data Receipt after the Data Receipt they inherit from.

  6. Discard Access Receipt if Agent does not accept

  7. Call § 9.4.2 Record Access Receipt with inputs: RECEIPT, REGISTRY if Agent accepts the Access Receipt

10. Remote Data Registration

10.1. Overview

Write overview for Remote Data Registration

10.2. Data Model

10.2.1. Summary

Data model for the Remote Data Registry

An Agent links to Remote Data Registry Sets via the interop:hasRemoteDataRegistrySet property.

A Remote Data Registry Set links to any number of Remote Data Registries via the interop:hasRegistry property.

A Remote Data Registry links to any number of registered Remote Data Registrations via the interop:hasRegistration property.

A Remote Data Registration may link to one or more Remote Data Instances via the interop:hasRemoteDataInstance property.

Agent at https://alice.pod.example/profile/id#me linking to an Remote Data Registry Set
<#me>
  a interop:Agent;
  interop:hasRemoteDataRegistrySet <https://alice.pod.example/profile/remote#set> .
A Remote Data Registry Set at https://bob.pod.example/profile/remote#set linking to two different Remote Data Registries
<#set>
  a interop:RemoteDataRegistrySet;
  interop:hasRegistry <https://bob.pod.example/remote/#registry> ,
                  <https://bob.otherpod.example/remote/#registry> .
An Remote Data Registry at https://bob.pod.example/remote/#registry linking to several registered Remote Data Registrations
<#registry>
  a interop:RemoteDataRegistry ;
  interop:hasRegistration <f0ebbd29-3a5a-4770-af29-cdb7693066b4/#registration> ,
                      <265dff0c-b199-42d8-95b3-d1eaae91c412/#registration> ,
                      <f68e95eb-a61f-408c-8d83-c4f21dae6115/#registration> .
An Remote Data Registration at https://bob.pod.example/remote/f0ebbd29-3a5a-4770-af29-cdb7693066b4/#registration
<#registration>
  a interop:RemoteDataRegistration ;
  interop:registeredBy <https://bob.pod.example/profile/id#me> ;
  interop:registeredWith <https://trusted.example/id#agent> ;
  interop:registeredAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:updatedAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:providedAt "2020-09-05T06:16:01Z"^^xsd:dateTime ;
  interop:hasDataReceipt <https://bob.pod.example/receipts/fa6d6553-0308-4abd-bce6-888df653695a#notebook-receipt> ;
  interop:hasRegistration <https://alice.pod.example/data/notebook-tree/#registration> ;
  interop:registeredShapeTree note:notebook-tree ;
  interop:scopeOfDataGrant interop:SelectedInstances ;
  interop:accessMode acl:Read, acl:Write ;
  interop:hasRemoteDataInstance <https://bob.pod.example/remote/f0ebbd29-3a5a-4770-af29-cdb7693066b4/cd04e76b-d64d-4cea-aacf-fb248a295002#instance> ,
                            <https://bob.pod.example/remote/f0ebbd29-3a5a-4770-af29-cdb7693066b4/9506b58f-3c36-4c0c-a698-712baf478deb#instance> .
An Remote Data Instance at https://bob.pod.example/remote/f0ebbd29-3a5a-4770-af29-cdb7693066b4/cd04e76b-d64d-4cea-aacf-fb248a295002
<#registration>
  a interop:RemoteDataInstance ;
  interop:registeredAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:updatedAt "2020-09-05T06:15:01Z"^^xsd:dateTime ;
  interop:providedAt "2020-09-05T06:16:01Z"^^xsd:dateTime ;
  interop:hasDataReceipt <https://bob.pod.example/receipts/fa6d6553-0308-4abd-bce6-888df653695a#notebook-receipt> ;
  interop:registeredShapeTree note:notebook-tree ;
  interop:accessMode acl:Read, acl:Write ;
  interop:hasDataInstance <https://alice.pod.example/data/notebook/notebook-1/#notebook> .

10.2.2. Remote Data Registry Set

A Remote Data Registry Set is a Registry Set specifically made up of Remote Data Registries.

RemoteDataRegistrySet a rdfs:subClassOf RegistrySet
Property Range Description
hasRegistry Registry Link to associated Remote Data Registries

The RemoteDataRegistrySetShape is used to validate an instance of the RemoteDataRegistrySet class.

<#RemoteDataRegistrySetShape> {
  a [ interop:RemoteDataRegistrySet ] ;
  interop:hasRegistry IRI+
}

The RemoteDataRegistrySetTree is assigned to a resource to ensure it will validate against the RemoteDataRegistrySetShape.

<#RemoteDataRegistrySetTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#RemoteDataRegistrySetShape> ;
  st:matchesUriTemplate "receipt" .

10.2.3. Remote Data Registry

A Remote Data Registry is a collection of Remote Data Registrations stored in a specific location in a pod.

RemoteDataRegistry a rdfs:subClassOf Registry
Property Range Description
hasRegistration Registration Link to associated Remote Data Registrations

The RemoteDataRegistryShape is used to validate an instance of the RemoteDataRegistry class.

<#RemoteDataRegistryShape> {
  a [ interop:RemoteDataRegistry ] ;
  interop:hasRegistration IRI*
}

The RemoteDataRegistryTree is assigned to a container resource to ensure that it will validate against the RemoteDataRegistryShape, and contain only conformant instances of the RemoteDataRegistrationTree.

<#RemoteDataRegistryTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#RemoteDataRegistryShape> ;
  st:contains <#RemoteDataRegistrationTree> ,
              st:AllowNone .

10.2.4. Remote Data Registration

An Agent maintains a Remote Data Registration to represent a Data Registration that another Agent has shared with them. It may represent access to the entire Data Registration, or only to a select group of Remote Data Instances within.

A Remote Data Registration is created when an Agent receives an Access Receipt from another Agent that includes access to a given Data Registration.

RemoteDataRegistration a rdfs:subClassOf Registration
Property Range Description
registeredBy Agent Agent that registered the Remote Data Registration
registeredWith Application Application used to create the Remote Data Registration
registeredAt xsd:dateTime Date and time the Remote Data Registration was created
updatedAt xsd:dateTime Date and time the Remote Data Registration was updated
providedAt xsd:dateTime When the Remote Data Instance was shared by remote Agent
hasRegistration DataRegistration Link to the Data Registration that was shared
registeredShapeTree st:ShapeTree Shape tree associated with the shared Data Registration
scopeOfDataGrant interop:AllInstances, interop:InheritInstances, interop:SelectedInstances, interop:NoAccess Identifies the scope of access that was granted
  • interop:AllInstances - Scope includes access to all Data Instances of the shared Data Registration
  • interop:InheritInstances - Scope includes access to Data Instances inherited by instances selected in the Data Receipt linked via interop:inheritsFrom
  • interop:SelectedInstances - Scope includes access only to those Data Instances specifically selected by the Agent
  • interop:NoAccess - No access is granted
accessMode acl:Read, acl:Write, acl:Control, acl:Append Access modes granted on the shared Data Registration
hasRemoteDataInstance RemoteDataInstance Link to Remote Data Instance associated with the Remote Data Registration
hasDataReceipt DataReceipt Link to Data Receipt that granted this shared access

The RemoteDataRegistrationShape is used to validate an instance of the RemoteDataRegistration class.

<#RemoteDataRegistration> {
  a [interop:RemoteDataRegistration] ;
  interop:registeredBy IRI ;
  interop:registeredWith IRI ;
  interop:registeredAt xsd:dateTime ;
  interop:providedAt xsd:dataTime ;
  interop:updatedAt xsd:dateTime ;
  interop:hasRegistration IRI ;           # Remote data registration
  interop:registeredShapeTree IRI ;       # Associated shape tree
  interop:scopeOfDataGrant [ interop:SelectedInstances
                         interop:AllInstances
                         interop:InheritInstances
                         interop:NoAccess ]+ ;
  interop:accessMode [ acl:Read acl:Write acl:Append acl:Control ]+ ;
  interop:hasRemoteDataInstance IRI* ;    # if specific instances are selected or inherited
  interop:hasDataReceipt IRI+ ;         # Associated data receipts
}

The RemoteDataRegistrationTree is assigned to a resource via the RemoteDataRegistryTree, and ensures that the assigned resource will validate against the RemoteDataRegistrationShape.

<#RemoteDataRegistrationTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeContainer ;
  st:validatedBy <interops#RemoteDataRegistrationShape> ;
  st:matchesUriTemplate "{id}" ;
  st:contains <#RemoteDataInstanceTree> ,
              st:AllowNone .

10.2.5. Remote Data Instance

An Agent maintains a Remote Data Instance to represent a Data Instance that another Agent has shared with them.

A Remote Data Instance is created when an Agent receives an Access Receipt from another Agent that includes access to a specific Data Instance.

RemoteDataInstance
Property Range Description
registeredAt xsd:dateTime When the Remote Data Instance was created
updatedAt xsd:dateTime When the Remote Data Instance was last updated
providedAt xsd:dateTime When the Remote Data Instance was shared by remote Agent
hasDataInstance Data Instance Link to Data Instance associated with the Remote Data Instance
registeredShapeTree st:ShapeTree Shape tree associated with the shared Data Instance
accessMode acl:Read, acl:Write, acl:Control, acl:Append Access modes granted on the shared Data Instance
hasDataReceipt DataReceipt Link to Data Receipt that granted this shared access

The RemoteDataInstanceShape is used to validate an instance of the RemoteDataInstance class.

<#RemoteDataInstance> {
  a [interop:RemoteDataInstance] ;
  interop:hasDataInstance IRI ; # Remote Data Instance
  interop:registeredAt xsd:dateTime ;
  interop:providedAt xsd:dataTime ;
  interop:registeredShapeTree IRI ;       # Associated shape tree
  interop:accessMode [ acl:Read acl:Write acl:Append acl:Control ]+ ;
  interop:hasDataReceipt IRI+ ;         # Associated data receipts
}

The RemoteDataInstanceTree is assigned to a resource via the RemoteDataInstanceTree, and ensures that the assigned resource will validate against the RemoteDataInstanceShape.

<#RemoteDataInstanceTree>
  a st:ShapeTree;
  st:expectsType st:ShapeTreeResource ;
  st:validatedBy <interops#RemoteDataInstanceShape> ;
  st:matchesUriTemplate "{id}" .

10.3. Resource Hierarchy

Resource Class Shape Shape Tree
/profile/ - - ProfileTree
-- remote#set RemoteDataRegistrySet RemoteDataRegistrySetShape RemoteDataRegistrySetTree
/remote/#registry RemoteDataRegistry RemoteDataRegistryShape RemoteDataRegistryTree
-- f0ebbd29...b4/#registration RemoteData RemoteDataRegistrationShape RemoteDataRegistrationTree
---- cd04e76b...02#instance RemoteDataInstance RemoteDataInstanceShape RemoteDataInstanceTree
---- 9506b58f...eb#instance RemoteDataInstance RemoteDataInstanceShape RemoteDataInstanceTree

The Remote Data Registry Set and the Remote Data Registry MAY or MAY NOT be on the same pod.

Remote Data Registry Set and Remote Data Registry resources MAY use any resource or subject names.

Remote Data Registrations and Remote Data Instances MUST use UUIDs for resource names.

10.4. Operations

10.4.1. Update Remote Data

10.4.1.1. Inputs
10.4.1.2. Outputs
10.4.1.3. Operation Details
  1. For each Data Receipt DRECEIPT linked via RECEIPT hasDataReceipt

    1. Let REMOTEDR be a Remote Data Registration returned from § 10.4.5 Load Remote Data Registration with inputs: DRECEIPT hasRegistration, REGISTRY

      1. If REMOTEDR is not empty

        1. Call § 10.4.4 Update Remote Data Registration with inputs: REMOTEDR, DRECEIPT, RECEIPT

      2. If REMOTEDR is empty

        1. Next if DRECEIPT scopeOfDataGrant is interop:NoAccess

        2. Call § 10.4.2 Create Remote Data Registration with inputs: RECEIPT, DRECEIPT, REGISTRY

10.4.2. Create Remote Data Registration

10.4.2.1. Inputs
10.4.2.2. Outputs
10.4.2.3. Operation Details
  1. MUST return error if DRECEIPT scopeOfDataGrant includes interop:SelectedInstances or interop:inheritInstances and DRECEIPT hasDataInstance is empty

  2. Let REMOTEDR be an empty Remote Data Registration

  3. Let REMOTEDR registeredBy be the current Agent

  4. Let REMOTEDR registeredWith be the current Application

  5. Let REMOTEDR registeredAt be the current timestamp

  6. Let REMOTEDR updatedAt be the current timestamp

  7. Let REMOTEDR providedAt be RECEIPT providedAt

  8. Let REMOTEDR hasDataReceipt be DRECEIPT

  9. Let REMOTEDR hasRegistration be DRECEIPT hasRegistration

  10. Let REMOTEDR registeredShapeTree be DRECEIPT registeredShape

  11. Let REMOTEDR scopeOfDataGrants be DRECEIPT scopeOfDataGrants

  12. Let REMOTEDR accessModes be DRECEIPT accessModes

  13. If DRECEIPT scopeOfDataGrant is interop:AllInstances

    1. Let REMOTEDR scopeOfDataGrant be interop:AllInstances

  14. If DRECEIPT scopeOfDataGrant is interop:SelectedInstances AND/OR interop:InheritInstances

    1. For each Data Instance RDI linked via DRECEIPT hasDataInstance

      1. Let REMOTEDR hasRemoteDataInstance be linked with the Remote Data Instance returned from § 10.4.3 Create Remote Data Instance with inputs: REMOTEDR, RDI, DRECEIPT, RECEIPT

10.4.3. Create Remote Data Instance

10.4.3.1. Inputs
10.4.3.2. Outputs
10.4.3.3. Operation Details
  1. Let REMOTEDI be an empty Remote Data Instance

  2. Let REMOTEDI registeredAt be the current timestamp

  3. Let REMOTEDI updatedAt be the current timestamp

  4. Let REMOTEDI providedAt be RECEIPT providedAt

  5. Let REMOTEDI registeredShapeTree be DRECEIPT registeredShapeTree

  6. Let REMOTEDI accessModes be DRECEIPT accessModes

  7. Let REMOTEDR hasDataReceipt be DRECEIPT

  8. Let REMOTEDR hasDataInstance be DRECEIPT hasDataInstance

10.4.4. Update Remote Data Registration

10.4.4.1. Inputs
10.4.4.2. Outputs
10.4.4.3. Operation Details
  1. MUST return error if REMOTEDR providedAt is later than RECEIPT providedAt

  2. If REMOTEDR hasDataReceipt is not DRECEIPT

    1. Let OLDDRECEIPT be REMOTEDR hasDataReceipt

    2. Let REMOTEDR hasDataReceipt be DRECEIPT

    3. Let OLDRECEIPT replacedBy be DRECEIPT

    4. Let OLDRECEIPT updatedAt be the current timestamp

  3. Let REMOTEDR accessModes be DRECEIPT accessModes

  4. If DRECEIPT scopeOfDataGrant is interop:NoAccess

    1. Let REMOTEDR scopeOfDataGrant be interop:NoAccess

    2. Let REMOTEDR accessMode be empty

    3. For each Remote Data Instance REMOTEDI linked via REMOTEDR hasRemoteDataInstance

      1. Delete REMOTEDI

      2. Remove REMOTEDR hasRemoteDataInstance link to REMOTEDI

  5. If DRECEIPT scopeOfDataGrant is interop:AllInstances

    1. For each Remote Data Instance REMOTEDI linked via REMOTEDR hasRemoteDataInstance

      1. Delete REMOTEDI

      2. Remove REMOTEDR hasRemoteDataInstance link to REMOTEDI

  6. If DRECEIPT scopeOfDataGrant is interop:SelectedInstances or interop:InheritInstances

    1. For each Remote Data Instance REMOTEDI linked via REMOTEDR hasRemoteDataInstance

      1. Delete REMOTEDI

      2. Remove REMOTEDR hasRemoteDataInstance link to REMOTEDI

    2. For each Data Instance RDI linked via DRECEIPT hasDataInstance

      1. Let REMOTEDR hasRemoteDataInstance be linked with the Remote Data Instance returned from § 10.4.3 Create Remote Data Instance with inputs: REMOTEDR, RDI, DRECEIPT, RECEIPT

  7. Let REMOTEDR updatedAt be the current timestamp

  8. Return REMOTEDR

It might be more elegant to not wipe out the remote data instances and recreate them with changes.

Someone should be able to grant a given Agent different modes of access for different selected instances in a given registration.

10.4.5. Load Remote Data Registration

10.4.5.1. Inputs
10.4.5.2. Outputs
10.4.5.3. Operation Details
  1. For each Remote Data Registration REMOTEDR in REGISTRY

    1. return REMOTEDR if REMOTEDR hasRegistration == DATAREG

11. Trusted Agents

11.1. Overview

A trusted Agent is an application that a Agent trusts to perform actions for them with elevated privilege. They can be trusted to help a Agent to make smart decisions related to their data.

There’s no limit to what a trusted agent can assist with, but registering applications and authorizing access to data are two critical operations covered in this proposal.

A trusted application registration agent helps the Agent make smart decisions about the applications they choose to utilize, and ensure they get provisioned appropriately.

A trusted agent for data authorization is needed in cases where the resource controller wishes to grant limited access to data in her Pod to another authenticated agent or user-piloted application, but needs assistance to determine what access is needed, and help to provision that access.

There are three typical patterns to interact with a trusted agent; Embedded, Synchronous, and Asynchronous.

The Embedded pattern is employed when the application in question has full control privileges, and the trusted agent capabilities can be executed directly. An example of an application that could fall into this category would be a Pod management application installed by default by the user’s Pod provider.

The Synchronous pattern utilizes a web-based redirect flow much like an OAuth2 grant flow. The user is redirected to the trusted agent URL, with a callback parameter provided as part of the request. When the trusted agent is finished, it sends the user back to the provided callback URL. This is an excellent pattern for application registration and data authorization.

The Asynchronous pattern utilizes an event based model, where a message is sent to the Trusted Agent through some mechanism (direct, pubsub, etc). This flow is most typical for server-side/bot applications or any piloted clients that can make use of asynchronous notification processing.

A given trusted agent may employ one or more of these patterns.

11.2. Operations

11.2.1. Load Trusted Agent

Write operation for Load Trusted Agent

11.2.2. Redirect to Trusted Agent

Write operation for Redirect to Trusted Agent

11.2.3. Return from Trusted Agent

Write operation for Return from Trusted Agent

12. Security

12.1. Application Authorization

For authorization purposes, client Applications in use today fall into two buckets:

Strongly identifiable applications can be identified by third parties independently from the user or Agent controlling them. Only server-side applications are strongly identifiable. As confidential clients, they can keep secrets and can present attestations and third-party credentials via DNS / domain certificates.

In the case of a strongly identifiable application, the identity of Agent and the Application are one and the same. The Application has its own identity. A given Agent can authorize a given Application to access data based solely on the identity of that Application.

Weakly identifiable applications include in-browser Javascript Applications and native desktop or mobile Applications. They are considered weakly identifiable because they are not able to keep secrets on an instance level. They are often referred to as public clients. Native apps should be strongly-identifiable in theory (since they are able to keep secrets on an instance level), but not in practice because the OS manufacturers do not make their trust infrastructure available. Weakly identifiable clients are only strongly identifiable to the user or Agent controlling them.

In the case of Weakly identifiable applications, the ability for a Solid pod to limit access to data by the Application in use is only as strong as the trustworthiness of the Agent piloting that Application, along with their ability to avoid using malicious Applications. The identity of the Application can be manipulated by the Agent in control. This means that Alice can strongly control the Applications that she uses to access her own data, but has limited ability to control the Applications that Bob uses to access the data she shares with him.

13. Definitions

All definitions as stated below should be considered in the context of an interoperable ecosystem for Solid, whether explicitly stated or not.

Solid is a protocol made up of a number of open web standards aimed at decentralizing data on the web.

A Solid pod is a place for storing and accessing data via the Solid protocol, with mechanisms for controlling who or what can access that data.

An interoperable ecosystem is a collection of Solid compatible applications developed by one or more entities, used by a community of users, that can safely access and manipulate the same kinds of data in pods.

A server-side application runs on a dedicated server. They may also act as autonomous authenticated agents.

A user-piloted application runs on a user’s device, with the user as the authenticated agent. They include in-browser javascript applications, native desktop applications, and mobile applications.

An authenticated agent is an agent that has strongly authenticated their identity by proving control of the identity profile document via an authentication protocol such as [WEBID-OIDC].

An identity is a unique URI that can be dereferenced to return an identity profile document. Compatible identity systems include WebID and DID.

An identity profile document is a linked data document obtained by dereferencing the URI for a given identity. It provides information that can be used to prove that a given Agent controls the document.

A WebID is a web resource at an HTTP URI which refers to an agent. An identity profile document can be accessed by dereferencing the WebID. [WEBID]

A DID is a URI that associates a DID subject (e.g. an agent, thing, data model, abstract entity, etc.) with a DID document, equivalent to an identity profile document, to allow trustable interactions with that subject. [DID]

An ApplicationID is a web resource at an HTTP URI uniquely associated with a given application. For server-side applications, it may also serve as an identity. An application profile document can be accessed by dereferencing the ApplicationID.

An application profile document is a linked data document obtained by dereferencing the URI for a given ApplicationID. It contains useful information about an application that can be employed in various workflows including application registration and data authorization.

An acl resource as defined by [WAC] may be directly associated with a resource or indirectly associated with a resource through inheritance. It determines which authorization subjects can access a resource, and the modes of access they have for it.

An access mode denotes operations (e.g. read, write) that a given authorization subject can perform on a resource.

An authorization subject is the target of a given authorization statement in an acl resource. It is either an Agent (individual, group, server-side application), a User-Piloted Application in use by any Agent, or a combination of a specific Agent using a specific User-Piloted Application.

An authorization statement is ...

A trusted agent is any application that a Agent trusts to perform actions for them. These actions typically require some leve

An application registration agent is a type of trusted agent that an Agent uses to register and manage applications that interface with their pod.

A data authorization agent is a type of trusted agent that assists a Agent with the managing the data in their Data Registries, and authorizing access to it from other authorization subjects.

A shape provides a schema that RDF data graphs must meet in order to be considered conformant. A shape associated with a given resource in a pod ensures that any data stored in that resource must conform to the associated shape. Shape languages include [SHEX] and [SHACL].

A shape tree defines a prospective tree of related resources which can be read and written by applications. The shape tree associates each of these resources with a shape. This allows one to treat a set of related resources as a single grouping, and apply that to a range of operations including access control, data organization, data validation, and data migration. [SHAPETREES]

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[CSP3]
Mike West. Content Security Policy Level 3. 15 October 2018. WD. URL: https://www.w3.org/TR/CSP3/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[WAC]
Web Access Control. URL: https://solid.github.io/specification/wac/

Informative References

[DID]
Drummond Reed; et al. Decentralized Identifiers (DIDs) v1.0. URL: https://www.w3.org/TR/did-core/
[PROBLEMS-AND-GOALS]
Justin Bingham; et al. Problems and Goals for Interoperability, Collaboration, and Security in a Solid Pod. URL: https://github.com/solid/data-interoperability-panel/blob/master/problems-and-goals.md
[SHACL]
Holger Knublauch; Dimitris Kontokostas. Shapes Constraint Language (SHACL). URL: https://www.w3.org/TR/shacl/
[SHAPETREES]
Justin Bingham; et al. Shape Trees. URL: https://shapetrees.github.io/specification/primer
[SHEX]
Eric Prud'hommeaux; et al. Shape Expressions Language 2.1. URL: http://shex.io/shex-semantics/index.html
[WEBID]
Tim Berners-Lee; Henry Story; Andrei Sambra. WebID 1.0. URL: https://www.w3.org/2005/Incubator/webid/spec/identity/
[WEBID-OIDC]
Dmitri Zagidulin. WebID-OIDC Authentication Specification. URL: https://github.com/solid/webid-oidc-spec

Issues Index

Is it necessary to use a one-way hash for application registration resource names. Github issue
Cleanup of related data may need to be specified
Cleanup of related data may need to be specified
Should we assume that CISERVICE is able to manage grants, or should it need to redirect through the authorization agent? Perhaps the recommendation should be that they are combined? Bad separation of concerns?
This doesn’t take account a sequencing of validation steps from one channel to another.
Write overview for Access Grants
Need to properly factor in multi-pod scenarios. Must identify the proper access registry to store things in based on the data registration, which means pods will also need to be registered.
Write standard operation for invitation delivery
Write standard operation for validating an invitation
Deal with cases when the data registration doesn’t exist yet
Append mode for AllInstances needs to be specially handled, and may require an additional attribute specified in the requested Access Needs
Consider when an existing Access Need Group is expanded or contracted
Consider when there are new Groups being requested from a given Agent
Write operation for selecting specific Data Instances for a given Data Registration within an Access Grant
Write operation for selecting all Data Instances for a given Data Registration within an Access Grant
Write overview for Access Receipts
Write definition for Access Receipt class
Write definition for Data Receipt class
Write overview for Remote Data Registration
It might be more elegant to not wipe out the remote data instances and recreate them with changes.
Someone should be able to grant a given Agent different modes of access for different selected instances in a given registration.
Write operation for Load Trusted Agent
Write operation for Redirect to Trusted Agent
Write operation for Return from Trusted Agent