solid / authorization-panel

Github repository for the Solid Authorization Panel
MIT License
19 stars 20 forks source link

add :imports relation #210

Open bblfish opened 3 years ago

bblfish commented 3 years ago

On proposal

This can work for WAC, WAC+ and with some thought needed for ACP. The namespace for this relation is thus to be decided later.

Details

When creating any ldp:Resource, the corresponding Access Control Resource (ACR) need only include the following triple, assuming here that the parent container's ACR is in </.acx>

<> :imports </.acx> .

For a newly created ldp:Container (as used in Solid) the parent ACR would look more like this:

<> :imports <../.acx> .

This brings in all the access control statements into the current ACR, where they act as if they had been placed there. The :imports relation can be transitive, or another transitive relation can be found that would include the ACR's included in the included ACR) As a result anyone with creation rights to the created resource gets rights to the newly created resource, but this link can be broken by removing that link from the newly created ACR, and adding links to individual Rules/Policies

Behavior for verification:

Addendum

This work if rules have specified :accessToClass relations so that rules written higher up can express that they apply to all children.

<#r1> acl:agent  [ cert:key </keys#k>; ]
    acl:mode acl:read;
    acl:accessToClass [ allLdpContainsOf <.> ] . ## see below for a precise definition

An implementation of this used Regexes as written up in the ESW WAC Wiki, but that would not work for the Tor use case. Nevertheless, the same effect and many others can be had by building up concepts from OWL. We can build up a simple relation for the transitive closure of the inverse of ldp:contains:

@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix ldp: <http://www.w3.org/ns/ldp#> .

ldp:isContainedIn owl:inverseOf ldp:contains ;
   rdfs:comment "related an ldp:Resource to its container" .

ldp:isPartOf a owl:TransitiveProperty;
     rdfs:comment """the transitive closure of the ldp:isContainedIn relation. Ie, it relates a resource to all
                 the containers it is in."""; 
     rdfs:subPropertyOf ldp:isContainedIn .

And then we can define precisely what we gave a sketch of above as

@prefix acl: <http://www.w3.org/ns/auth/acl> .

<#r1> acl:agent  [ cert:key </keys#k> ];
    acl:mode acl:Control;
    acl:accessToClass [ a owl:Restriction;
       owl:onProperty ldp:isPartOf;
       owl:hasValue <.> ] .

Now this states precisely that there is a Right for the agent with the given key to be the controller of all child resources. But such a Right is only in effect if it is linked to from a Link: ... rel="acl" header from a given resource, and its imports.

Problems solved

Acceptance criteria

What actions are needed to resolve this issue? (checklist)

bblfish commented 3 years ago

It may be that a better name for :include would be :import. (now updated) Indeed the idea came from owl:imports. Could one re-use owl:imports for this?

ericprud commented 3 years ago

I feel like it might be a cousin of owl:imports, i.e. that there could some generic import directive that then gets type-specific overloads. The OWL spec doesn't really talk about an import directive so much as it talks about imports and directlyImports "assocations". (It turns out that the RDF predicate owl:imports corresponds to directlyImports.)

So basically, these talk about a relationships between ontologies rather than protocol stuff like primacy and error resolution. The other challenge is that imports describes onotologies, not HTTP resources with some RDF media type, implying that whatever you're importing, it damn well better be an ontology. If you import X and X dereferences to a OWL/XML, it MUST have exactly one ontology declaration of X, e.g. <owl:Ontology rdf:about=""> or <owl:Ontology rdf:about="X">. Likewise turtle MUST have <> rdf:type owl:Ontology or <X> rdf:type owl:Ontology.

If you want to special-purpose owl:imports (or anything else) for ACLs, you'll probably want to define an ACL "document" or some similar mechanism upon which to hang the expectations of what will be accepted in an imported ACL doc.

I think Timothy Redmond managed this stuff for the Protege folks but I have no idea if he's still at Stanford.

bblfish commented 3 years ago

I have drawn up a possible layout of access control rules to illustrate how this would work.

  1. We have a root ldp:BasicContainer in which there is a root /.acl resource. This states that all resources contained (transitively) in <https://w3.org/> have associated Rights (Permissions?) to be a. controlled by a </.acl#Admin> agent, b. be readable by any agent

  2. The contained </People> "folder" adds an </People/HR#> controller for all contents of People

  3. The contained </People/Berners-Lee/> folder (a.k.a an ldp:Container) imports the rules from the </.acl> but not the intermediate one from </People/> and adds Tim to the controllers.

  4. Finally </People/Berners-Lee/card> has an associated acl </People/Berners-Lee/card.acl> which was automatically generated and just contains the one statement <> :imports <.acl>

W3CImports

Note that the containedIn relation is an attempt to shortcut a bunch of OWL as explained in this mail to the semweb mailing list. But I am not sure if it is legal.

So what would a GET on </People/Berners-Lee/card.acl> return? It could just return

<> :imports <.acl>

But that would then require a client, and even the server guard to fetch the imported acls... Here it is clear that the server could do a bit of work for the client and return the named graphs in say TriG format

{ <> :imports </People/Berners-Lee/.acl> }

</People/Berners-Lee/.acl> {
   </People/Berners-Lee/.acl#TimRl> acl:agent <card#i>;
          acl:mode acl:Control;
          acl:accessToClass [ :containedIn </People/Berners-Lee/> ];
  </People/Berners-Lee/.acl> :imports </.acl> .
}

</.acl> {
    </.acl#Public> acl:mode acl:Read;
             acl:accessToClass [ :containedIn </> ];
             acl:agentClass foaf:Agent .
    </.acl#Admin> acl:mode acl:Control;
             acl:accessToClass [ :containedIn </> ];
             acl:agentClass <admins#> .
}

Here the interpretation of the named graphs is simple. If we follow from the acl for the resource <card>, the guard on the client or the server are meant to think of all those rules as one big graph, ie. all subgraphs are true, so that we could also just see it as the Turtle file:

  <> :imports </People/Berners-Lee/.acl> 

   </People/Berners-Lee/.acl#TimRl> acl:agent <card#i>;
          acl:mode acl:Control;
          acl:accessToClass [ :containedIn </People/Berners-Lee/> ];
  </People/Berners-Lee/.acl> :imports </.acl> .

    </.acl#Public> acl:mode acl:Read;
             acl:accessToClass [ :containedIn </> ];
             acl:agentClass foaf:Agent .
    </.acl#Admin> acl:mode acl:Control;
             acl:accessToClass [ :containedIn </> ];
             acl:agentClass <admins#> .

This I believe is the "§3.1 Partitioning of triples semantics" described in Towards supporting multiple semantics of named graphs using N3 rules. All the graphs are assumed to be true and mergeable, but are kept distinct to facilitate editing.

The advantage of the Trig format, is that it allows

Given the flattened version of the TriG, the normal WAC algorithm can be applied.

  1. The server Guard knows (a) some identifying information about the client and (b) to which resource access is requested. From (a) and (b) it can filter out the rules in the graph that apply.
  2. The client could look at those rules and find which rules apply to the given resource, and from there decide which credential may need to be presented to gain the required access.
bblfish commented 3 years ago

One open question is how far one can make this work with the ideas from Re-using Policies, where an ACR has an <> authorizes <rule#> relation to each of the rules that apply.

Where does that :authorizes come in useful?

In the scenario described here a client can break the import of a whole acl file by deleting the :imports triple from an ACL . In the example above we must assume that someone deleted the triple

</People/Berners-Lee/.acl> :imports </People/.acl> .

The :authorizes relation seems to give the ability to add rules selectively back in, which could be useful.

On the other hand we would need to re-think the inference rules, because

  1. how would one add the <> authorizes <...> relations to each ACL? Via inference? Using an N3 rule?
  2. there seems to be a value in having the accessToClass as a way of restricting applications of rules, as we saw above.
bblfish commented 3 years ago

We came up with a rule above that applies to all contents recursively of a container. What else can one do?

A rule that applies only to the ACRs of all contents of a container?

:contains٭ owl:TransitiveProperty;
     rdfs:subPropertyOf ldp:contains .

<#r1> acl:agent  [ cert:key </keys#k> ];
    acl:mode acl:Control;
    acl:accessToClass [ a owl:Restriction;
          owl:onProperty [ owl:inverseOf [ owl:propertyChain ( :contains٭ :accessControl ) ] ] ;
          owl:hasValue <.> ] .