# Data Authorization Hackathon
One week of straight up authorization goodness
Deliverables / Output:
JC - How an application expresses it's access requirements
- Application Profile Document
- Access Need Definitions
- What is required vs. optional?
- What other context needs to be provided in the definition?
JC - How those access needs are translated to access control rules
- Data Registry
- ACL definitions - Adding, Updating, Removing
- Testing these live
- Iterating on them so they're maintainable
- Translating the user choices on authorization to registry access
- E.g. I'm going to give you read, write, control access to certain sets of things or individual instances of things.
- Sharing resources with other people in the care constallation
- How much do we need to detail the remote access registry pieces this week? Work for next week?
- What is the user experience for the Grantee?
- How do they navigate to the data they've received access to?
JC - Validating that the flow we've detailed is compatible with the shape tree libraries we're working with. Don't need to step back and expose additional pieces of the API. More concerned with how to present the access request in a human-readable way, then translate that response back to the updated ACLs.
## Application Profile Document
```turtle
@prefix solid: <http://www.w3.org/ns/solid/terms#>.
@prefix eco: <http://www.w3.org/ns/solid/ecosystem#>.
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix schema: <http://www.schema.org>.
@prefix tree: <http://www.w3.org/ns/shapetree#>.
<#agent>
a eco:Application ;
eco:authorizationCallback <https://nevernote.example/callback> ;
eco:applicationAccessSkosIndex <nhs-app-skos-index.ttl> ;
eco:requestsAccess <#bag1>, <#bag2>, <#notifier>.
<#bag1>
eco:requestsAccess <#access-medicalrecord>.
<#bag2>
eco:requestsAccess <#access-medicalrecord-with-benefits>.
<#notifier> # tell your friends your most embarassing medical secrets
eco:requestsAccess <#access-medicalrecord>, <#contacts>.
<#access-medicalrecord>
a eco:AccessNeed ; # declaration of an expected access to a step in a ShapeTree
eco:authenticatesAsAgent <#agent> ; # acl:Pilot means grant access to pilot
eco:requestedAccessLevel eco:Required ; # or eco:Optional
tree:hasShapeTree <http://www.nhs.gov.uk/shapetrees#medicalRecord> ;
eco:recursivelyAuthorize true ;
eco:requestedAccess acl:Read acl:Write.
<#access-diagnosticTest>
a eco:AccessNeed ; # declaration of an expected access to a step in a ShapeTree
eco:authenticatesAsAgent <#agent> ; # acl:Pilot means grant access to pilot
eco:requestedAccessLevel eco:Optional ; # or eco:Optional
tree:hasShapeTree <http://www.nhs.gov.uk/shapetrees#allergies> ;
eco:recursivelyAuthorize true ;
eco:requestedAccess acl:Read acl:Write .
<#access-diagsCondition>
a eco:AccessNeed ; # declaration of an expected access to a step in a ShapeTree
eco:authenticatesAsAgent <#agent> ; # acl:Pilot means grant access to pilot
eco:requestedAccessLevel eco:Optional ; # or eco:Optional
tree:hasShapeTree <http://www.nhs.gov.uk/shapetrees#condition> ;
eco:recursivelyAuthorize true ;
eco:requestedAccess acl:Read .
```
Assumptions:
* ```eco:recursivelyAuthorize``` applies to both ```tree:contains ``` and ```tree:references```. If at any point finer-grained control is required, additional ```eco:AccessNeed``` subjects would be added to stop or modify the top-level access request.
## UI-Building Pseudo-code:
* For each eco:requestsAccess (each bag)
* For each eco:requestsAccess (each rule)
* Determine the ShapeTree referenced by the rule (via tree:hasShapeTree)
* Traverse the ShapeTree to collect all other ShapeTrees that are tree:references or tree:contains
* This yields a superset of ShapeTrees are referenced by all eco:requestsAccess in a given bag
* Draw a 'row' for each ShapeTree
* Label row with ShapeTree SKOS label
* Populate label's tooltip from ShapeTree SKOS description
* Set access controls:
* Disable/enable based on eco:requestedAccessLevel
* Populate additional levels if optional requests exist (_need to talk about this more_)
* Populate request context from Application SKOS
Open items:
* Abstraction / grouping via SKOS? Where can that happen? SHOULD it happen?
## UI-Building Pseudo-code - ericP:
Container-oriented for now; should re-visit instance-level controls after groking this and before chiseling it in stone.
* Given a set of ShapeTree SKOS graphs **`stskosz`**.
* Given a set of __AccessNeeds__ in the agent graph
* **`done`** is an empty List<__tree:ShapeTree__>
* For each __eco:requestsAccess__ **`req`** (probably an ordered set in case multiple rules CHACL the same resources)
* `setAclsFromRule`(`req`, `done`)
* function **`setAclsFromRule`** (**`req`**:__tree:AccessNeed__, **`done`**:List<__tree:ShapeTree__>):
* **`stskos`** is *one* subject in `stskosz` which __tree:hasShapeTree__ `st` # need a merge semantics for multiple applicable stskos nodes
* **`st`** is `req`.hasShapeTree
* if `st` in `done` skip
* `done`.add(`st`)
* Draw a 'row' with
* label: `stskos`.prefLabel
* tooltip: `stskos`.definition
* access: `req`.requestedAccess
* reason: application SKOS node with __tree:hasShapeTree__ the earliest ancestor of `st`
* action: `setAclsFromShapeTree`(`st`, `req`.requestedAccess, `done`)
* Recursively, for each `narrower` in `stskos`.narrower
* if `narrower`.hasShapeTree is in done, return
* `done`.add(`narrower`)
* if there's an AccessNeed with hasShapeTree == `narrower`.hasShapeTree, use it for `req`
* if `req` has no requestedAccess, skip
* Draw a nested `row` (meaning it is revealed if the parent row is "expanded") with
* action: `setAclsFromShapeTree`(`narrower`.hasShapeTree, `req`.requestedAccess, `done`)
* function **`setAclsFromShapeTree`** (`st`:__tree:ShapeTree__, `acl`, `done`)
* recursively, for each ShapeTree `ref` in `st`.references and `st`.contains:
* if `ref` in done, skip
* for each instance container `c` where `c`.hasShapeTree `st`
* `setAcls`(`c`, `req`.requestedAccess)
**Issue**: because `setAclsFromShapeTree` is exhaustive, it creates ACLs which are redundent against the hierarchical default ACLs. We still need to traverse the children to find the references out, but we can keep track of the visited in order to CHACL the minimum number of resources.
## ShapeTree
```turtle
@base <http://www.nhs.gov.uk/shapetrees> .
@prefix tree: <http://www.w3.org/ns/shapetree#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<#medicalRecords>
tree:contents <#medicalRecord> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#medicalRecord>
tree:shape <nhs-schema#medicalRecord> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource>,
tree:references [
tree:treeStep <#patients> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:patient"
],
[
tree:treeStep <#appointments> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:appointment"
],
[
tree:treeStep <#conditions> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:condition"
],
[
tree:treeStep <#prescriptions> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:prescription"
],
[
tree:treeStep <#allergies> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:allergy"
],
[
tree:treeStep <#diagnosticTests> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:diagnosticTest"
],
[
tree:treeStep <#vitalsActivities> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:activity"
],
[
tree:treeStep <#practicioners> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:practicioner"
],
[
tree:treeStep <#documents> ;
tree:shapePath "nhs-schema#medicalRecord/nhs:document"
] .
<#patients>
rdfs:label "patients" ;
tree:contents <#patient> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#patient>
tree:shape <nhs-schema#patientShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#appointments>
rdfs:label "appointments" ;
tree:contents <#appointment> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#appointment>
tree:shape <nhs-schema#appointmentShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#conditions>
rdfs:label "conditions" ;
tree:contents <#condition> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#condition>
tree:shape <nhs-schema#conditionShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#prescriptions>
rdfs:label "prescriptions" ;
tree:contents <#prescription> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#prescription>
tree:shape <nhs-schema#prescriptionShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#allergies>
rdfs:label "allergies" ;
tree:contents <#allergy> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#allergy>
tree:shape <nhs-schema#allergyShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#diagnosticTests>
rdfs:label "diagnosticTests" ;
tree:contents <#diagnosticTest> ;
tree:contents <#condition> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#diagnosticTest>
tree:shape <nhs-schema#diagnosticTestShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#vitalsActivities>
rdfs:label "vitalsActivities" ;
tree:contents <#vitalActivity> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#vitalActivity>
tree:shape <nhs-schema#vitalActivityShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#practicioners>
rdfs:label "practicioners" ;
tree:contents <#practicioner> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#practicioner>
tree:shape <nhs-schema#practicionerShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
<#documents>
rdfs:label "documents" ;
tree:contents <#document> ;
tree:expectedType <http://www.w3.org/ns/ldp#Container> .
<#document>
tree:shape <nhs-schema#documentShape> ;
tree:uriTemplate "{id}" ;
tree:expectedType <http://www.w3.org/ns/ldp#Resource> .
```
## SKOS Defintion - NHS MedicalRecord ShapeTree SKOS
```turtle
@prefix nhs: <http://www.nhs.gov.uk/shapetrees> .
@prefix tree: <http://www.w3.org/ns/shapetree#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
<#patients>
a tree:NavigationStep ;
tree:step nhs:patients ;
skosxl:prefLabel [ skosxl:literalForm "Patient Info"@en ] .
skosxl:definition [ skosxl:literalForm "Some description of patient info"@en ] .
<#appointments>
a tree:NavigationStep ;
tree:step nhs:appointments ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view upcoming and historical medical appointments."@en ] .
<#conditions>
a tree:NavigationStep ;
tree:step nhs:conditions ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view currently active and historical medical conditions."@en ] .
<#prescriptions>
a tree:NavigationStep ;
tree:step nhs:prescriptions ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view currently active and historical prescribed medications."@en ] .
<#allergyIntolerances>
a tree:NavigationStep ;
tree:step nhs:allergyIntolerances ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view information about active allergies."@en ] .
<#diagnosticTests>
a tree:NavigationStep ;
tree:step nhs:diagnosticTests ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view diagnostic test data."@en ] .
<#vitalsActivities>
a tree:NavigationStep ;
tree:step nhs:vitalsActivities ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view historical vital and activity data."@en ] .
<#practicioners>
a tree:NavigationStep ;
tree:step nhs:practicioners ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view current and historical practicioner data."@en ] .
<#documents>
a tree:NavigationStep ;
tree:step nhs:documents ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view additional health documents."@en ] .
```
## SKOS Defintion - NHS-APP-SKOS
```turtle
@prefix nhs: <http://www.nhs.gov.uk/shapetrees> .
@prefix tree: <http://www.w3.org/ns/shapetree#> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
<#patients>
a tree:NavigationStep ;
tree:step nhs:patients ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view patient information such as name, date of birth, address, etc."@en ] .
<#appointments>
a tree:NavigationStep ;
tree:step nhs:appointments ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view upcoming and historical medical appointments."@en ] .
<#conditions>
a tree:NavigationStep ;
tree:step nhs:conditions ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view currently active and historical medical conditions."@en ] .
<#prescriptions>
a tree:NavigationStep ;
tree:step nhs:prescriptions ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view currently active and historical prescribed medications."@en ] .
<#allergyIntolerances>
a tree:NavigationStep ;
tree:step nhs:allergyIntolerances ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view information about active allergies."@en ] .
<#diagnosticTests>
a tree:NavigationStep ;
tree:step nhs:diagnosticTests ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view diagnostic test data."@en ] .
<#vitalsActivities>
a tree:NavigationStep ;
tree:step nhs:vitalsActivities ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view historical vital and activity data."@en ] .
<#practicioners>
a tree:NavigationStep ;
tree:step nhs:practicioners ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view current and historical practicioner data."@en ] .
<#documents>
a tree:NavigationStep ;
tree:step nhs:documents ;
skosxl:prefLabel [ skosxl:literalForm "Allow access to view additional health documents."@en ] .
```
### User has prescriptions and a datatype to index them
- User has instances of prescription shape trees in their data registry
- User has a utility datatype to index prescriptions in their data regsistry
- User wants to use another app, that legitimately needs access to prescriptions, and wants to also use the index data for prescriptions (it needs to know this datatype and know how to work with it if its going to ask - it must ask for it)
- The application is going to explicitly include it its access needs, prescriptions, as well as the prescription utility datatype (for indexing)
- The user is presented with an authorization screen for prescriptions, with a less prominent dependency on prescription index utility datatype (possibly hidden in a show more)
- User accepts, and the application is granted access to both prescriptions and prescription index utility datatype.
Risk: Asking for data that's outside of context and getting the user to authorize access to it, burying the ask in a hidden dependency.
If the data doesn't exist yet - where's the risk?
- Creating a honeypot that other applications could be fooled into putting important data into?