W3C home > Mailing lists > Public > public-rww@w3.org > October 2011

ACL files

From: Henry Story <henry.story@bblfish.net>
Date: Tue, 18 Oct 2011 10:27:29 +0200
Cc: WebID Incubator Group WG <public-xg-webid@w3.org>
To: Read-Write-Web <public-rww@w3.org>
Message-Id: <F0DD3161-ECB1-4B5B-82AA-035AD6A29F08@bblfish.net>
Hi,

   I am working on the read write web project [1], which is a very light weight server to PUT, POST, DELETE rdf to a server. I like the way it is very minimalistic and clean. It saves files to the hard drive and so makes things very easy to understand. It is easy to get a full overview of the code which is written in Scala. I'll just first present very roughly how the code works, then go on with a more detailed protocol question.

1. The ReadWrite Web scala project
------------------------------------------------

  The code discussed here is very much in transition, but I thought it is worth to show how it works, as it will also justify why I am taking an interest in the discussion going on here.

  I am developing in the "webid" branch, which now has a WebID implementation of course and a very basic implementation of the ACL ontology to protect a resource. The latest version code for that is here:

   https://dvcs.w3.org/hg/read-write-web/file/8a84fe5eec71/src/main/scala/auth

   - X509Claim is where the verification of the X509Claim is made. It contains a Google Cache to keep sessions for 30 minutes.
   - WebIDClaim are object returned by the X509Claim. One for each WebID. The object can verify the claim
   - Authz contains the basic ACL code. 

It is worth speaking about Authz a bit because it shows many things about why Scala is so nice for this, and a few clever tricks.
the AuthZ class has a protect method, that takes a function from an http request to a response, and returns a function that returns a function from a request to a response. Essentially it just takes the request function and wraps it with the code below:


 def protect(in: Req=>Res): Req=>Res =  {
    96       case req @ HttpMethod(method) & Path(path) if guard(method, path).allow(() => subject(req)) => in(req)
    97       case _ => Unauthorised
    98     }

This says simply: the function to return is one from a request to whatever is the result of the following: extract the HTTP method from the request (GET, PUT, POST,...) and the path of the request. If the guard created from that method allows the subject, then apply the request to the input method - giving us a new function, else return the unauthorised response. The clever thing about this is that the method passed to allow()  does NOT give it a subject - i.e. an identity - but a function to a subject. This means that if there is no restriction on the action 'method' on 'path', then there is no need to evaluate the function - i.e. to find the subject, which might mean fetching the WebID profile. So don't authenticate if you don't need to authorise!

This is very different from the Java access control frameworks I studied superficially recently. There they reason in terms of roles. You authenticate a subject, which is then associated with a role, and roles have rights. It is then a question if the rights objects allow access to the resource. But in our world we want to turn things upside down and be much more flexible. We don't start with a fixed set of roles, but with resources each of which can defined access to it. Essentially a resource gives access to a set of agents, and there can be an infinite set of such agents. Some of those sets can be considered roles in effect.

So currently here is what the files look like this (in the repo)

$ ls test_www/
foaf.n3            foaf.n3.protect.n3 

$ cat test_www/foaf.n3.protect.n3 
@prefix acl: <http://www.w3.org/ns/auth/acl#> .
@prefix : <#> .

:a1 a acl:Authorization;
   acl:accessTo <foaf.n3>;
   acl:mode acl:Read;
   acl:agent <http://bblfish.net/people/henry/card#me> .

before fetching the foaf.n3 file the AuthZ implementation first looks at the foaf.n3.protected.n3 file and tries to deduce from it what access is allowed.  That is only implemented at present in a very basic way: so it does not know about acl:agentClass or accessToClass. 

Finally the code that deals with the PUT/POST etc is here 
    https://dvcs.w3.org/hg/read-write-web/file/8a84fe5eec71/src/main/scala/plan.scala

This code is by Alex Bertails and he has told me it would be under a public licence, but has not yet decided which one. Anyway I suppose that given the it is work at the W3C it has to be a good one.

2. Next steps
------------------

  So there are a million ways one can develop and improve the code. But before going on and building a huge factory, I thought it would be good working out a good use case where we can interact together, so that we can work as a group. So it has to be simple and do something useful - and hopefully viral - in a distributed way. I think if we start with the address book done by Leipzig which I discussed earlier [2], the I want to know what do I need to do for this to work well?

  I suppose the basic thing is that the address book should be able to publish information and only allow access to that information to friends of the person. Presumably then we want to give the address book access to a directory, so that it can write there, and so that it can write access control rules too. Then we want to give the friends access to certain resources. We could also use Bergi's ideas to add filters to the authorisation, which would allow access via filters to resources: so I could say everybody can see my profile, but friends can see everything returned by filter X, and other people whatever filter Y allows. -- I think the code does that as it allows SPARQL queries to be put on the disk. I have not yet looked at how that works.

   Anyway, I know people here have a lot of experience in this space already. Perhaps someone has suggestions about what should be done next to get the simple address book example to work?

	Henry


[1] https://dvcs.w3.org/hg/read-write-web/
[2] http://vimeo.com/30014844

Social Web Architect
http://bblfish.net/
Received on Tuesday, 18 October 2011 08:28:15 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Monday, 30 April 2012 12:56:01 GMT