Archive for December, 2008

Quantifying cwm Variables…

Thursday, December 18th, 2008

Mostly for my benefit, but here are a few examples of how cwm’s N3Rules translate into formal logic:

  • Global universal quantification:
    @prefix : <#> .
    @forAll :x  .
    
    { :x  :a :b . } => { :x  :c :d . } .
    
    :someValue :a :b .

    ∀x (a(x, b) → c(x, d))

    Therefore the above entails the additional statement :someValue :c :d . as :x is bound to :someValue on the RHS.

  • Global existential quantification:
    @prefix : <#> .
    @forSome :x  .
    
    { :x  :a :b . } => { :x  :c :d . } .
    
    :someValue :a :b .

    ∃x (a(x, b) → c(x, d))

    Therefore the above entails no additional statements.

  • LHS universal quantification:
    @prefix : <#> .
    
    { @forAll :x  . :x  :a :b . } => { :x  :c :d . } .
    
    :someValue :a :b .

    (∀x a(x, b)) → c(x, d)

    Therefore the above entails no additional statements.

  • LHS existential quantification:
    @prefix : <#> .
    
    { @forSome :x  . :x  :a :b . } => { :x  :c :d . } .
    
    :someValue :a :b .

    (∃x a(x, b)) → c(x, d)

    Therefore the above entails the additional statement :x :c :d . as :x is unbound on the RHS.

  • RHS universal quantification:
    @prefix : <#> .
    
    { :someValue :a :b . } => { @forAll :x  . :x  :c :d . } .
    
    :someValue :a :b .

    a(someValue, b) → (∀x c(x, d))

    Therefore the above entails (generally) @forAll :z . :z :c :d .

  • RHS existential quantification:
    @prefix : <#> .
    
    { :someValue :a :b . } => { @forSome :x  . :x  :c :d . } .
    
    :someValue :a :b .

    a(someValue, b) → (∃x c(x, d))

    Therefore the above entails the additional statement [ :c :d ] .

Finally, two trickier specific examples: “If there exists a foaf:Person that all (known) foaf:Persons foaf:know, then there exists a :P opularPerson” and, “any foaf:Person that is foaf:knows of all (known) foaf:Persons in a :P opularPerson” can’t be done properly without completely closing the world. cwm cannot do this without artificially closing the world through built-ins.

TAAC in Action

Friday, December 12th, 2008

TAAC Examples

I’ve posted three examples that utilize TAAC in some manner.

You can test any of these yourself if you present the proper client certificate linked to your FOAF file (otherwise, without a client certificate, you won’t be able to authenticate with FOAF+SSL.) If you don’t have a properly configured certificate or FOAF file, Henry Story has a short description of how you can set this up in Firefox 3 with some utilities in the sommer repository. In addition, this server requires you to explicitly provide a certificate (as client certificates are optional).

So How Does TAAC Work?

As mentioned previously, Henry Story has some excellent descriptions of how the FOAF+SSL protocol works in general. TAAC is merely an implementation of this, but goes further to implement an authorization framework. How does this work though? The following diagram goes a ways toward explaining TAAC’s design (especially with regard to authorization) in general.

(A diagram of TAAC)

TAAC acts as a proxy for any URI access within the directory it’s set up in (thanks to mod_python). On every access, it will check the requested URI against the list of URIs having an rein:access-policy (as populated from the file specified in the POLICY_FILE variable). If no access policy exists, TAAC gladly permits normal access without any needed authentication.

If an access policy exists, however, TAAC will immediately attempt to properly reach a successful completion of the FOAF+SSL authentication protocol. I won’t go into significant details here, as Henry Story gives an excellent overview of the protocol (in a somewhat earlier state, though the same principles still apply) on his blog.

Following this, TAAC takes the successfully authenticated URI-token and logs the attempted access to a log file (specified by LOG_FILE). Taking this generated resource describing the access, and the AIR policy attached with the rein:access-policy triple, TAAC then proceeds to run an AIR reasoner over the policy with the given log resource. If the resource describing the access is concluded to be air:compliant-with the associated access-policy, the fact that access was granted according to the policy is logged, and access is granted. Otherwise, the fact that access was denied is logged, and access is denied with a 403 response.

Authentication and Authorization on the Open Social Web with TAAC

Thursday, December 11th, 2008

Update 3: The subversion repository for tmswap has been superseded by the Mercurial repository for air-reasoner

Update 2: The subversion repository should now have public checkouts enabled with the username and password ‘dig’.

Update: The subversion repository is currently not set up for external access. I probably won’t be able to get this resolved until Monday at the earliest. For the time being, you can extract this tarball into the directory you wish to protect, and skip the first two steps.

Recent discussions on the foaf-protocols mailing list have been pushing the FOAF+SSL protocol (discussed earlier on both Henry Story’s and my blogs) towards a more finalized state, pending some clarification of issues with generating the self-signed certificates that serve as the key to the protocol. As has been mentioned on the list and the blog several times, I have been maintaining an independent Python implementation of the FOAF+SSL implementation, and I now feel that the implementation is at a stable enough state to officially offer up instructions for installing TAAC.

Before I give instructions on how to do so, however, let me digress onto an important subtopic, that being the subtle difference of authentication and authorization, as the dichotomy is critical to understanding how TAAC works. FOAF+SSL is fundamentally an authentication mechanism. It provides a method to confirm that the individual presenting the SSL certificate is, in fact, the persons who is also in control of the FOAF resource specified in the certificate. It does not, however, specify any criteria for how access should actually be granted. It only establishes an identity.

TAAC implements FOAF+SSL as one of several authentication mechanisms tested, including a sample implementation of the RDFAuth mechanism, as well as an OpenID-based mechanism. TAAC, however, only implements these authentication mechanisms as a means to the goal of achieving a flexible Semantic-Web-friendly authorization framework. While the language and reasoning is still very much in flux, the idea of TAAC is to permit the creation of distributed access control lists and complex access control policies on top of semantic web data. Indeed, the current implementation (slowly) permits such authorization rules as “Only friends of people I specify as friends or the friends I specify can access this page” or “MIT students who are sophomores or juniors currently taking 6.805 can access this page” without having to maintain cumbersome access control lists, instead deferring to collections of data compiled by others. In effect, we can rely on MIT to maintain the list of current students, and accurately state their class year and the classes they are taking, such that we can merely reason over that data without having to compile an access control list from it.

Installing TAAC

Before You Install: Make sure you have installed the python-openid and pyCrypto >= 2.0.1 frameworks and are running mod_python on your server. While python-openid is not absolutely necessary for FOAF+SSL, TAAC is implemented with an additional vestigial OpenID mechanism that may or may not be integrated as an alternative mechanism to FOAF+SSL for FOAF-based authentication schemes, and hence requires the library

  1. Get the TAAC source code and copy the files and directories enclosed in the directory in which you want to protect some files. The source code is available in an SVN repository at https://svn.csail.mit.edu/dig/TAMI/2008/taac/proxy.
  2. Get the tmswap directory needed for TAAC to properly operate and copy it into the directory containing the TAAC code. The source code is available in an SVN repository at https://svn.csail.mit.edu/dig/TAMI/2007/cwmrete/tmswap.. The tmswap SVN repository has been superseded by the air-reasoner Mercurial repository at http://dig.csail.mit.edu/hg/air-reasoner/. Clone the repository and either:
    • Copy the tmswap directory (if it exists in the current revision)
    • Switch to the refactor branch and copy the contents of the root directory of the repository into a new tmswap directory
  3. Configure TAAC. The primary configuration for TAAC is in taac/config.py. You most probably don’t need to change any of the settings, but you should be aware of their setting, as it impacts the remainder of this installation process. POLICY_FILE is the relative path from proxy.py to the file that links your protected files to the corresponding policy files governing access. POLICY_TYPE is the MIME type of POLICY_FILE (‘text/rdf+n3′ or ‘application/rdf+xml’ most likely). LOG_FILE is the relative path from proxy.py to the file to log access information to. The other settings are not terribly relevant to FOAF+SSL and can be left alone.
  4. Setup your policy file. Your policy file (at the path specified by POLICY_FILE, defaulting to ‘./policies.n3′) is the key to protecting your URIs with FOAF+SSL. The policy file is an RDF file that links resources representing the protected URIs to their corresponding policy files. This is most easily done with the rein:access-policy (http://dig.csail.mit.edu/2005/09/rein/network#access-policy) property (subject to change in future TAAC releases). Here’s a very simple policies.n3 that protects my_file.html:
    @prefix rein: <http://dig.csail.mit.edu/2005/09/rein/network#> .
    
    <./my_file.html> rein:access-policy <./my_file.policy.n3> .
    
  5. Create a policy The policy is the access-policy attached by policies.n3. This policy is written in the AIR language, may be somewhat daunting for someone trying to write their first policy. A couple of sample policies include http://www.pipian.com/rdf/tami/juliette.policy.n3#JulietteLocationDissemPolicy, which permits any valid authentication via FOAF+SSL, and http://www.pipian.com/rdf/tami/juliette.policy.n3#JulietteFOAFDissemPolicy, which allows only friends and friends of friends of Juliette access.
  6. Create your log file with mode 0666. This is usually ‘log.n3′.
  7. Edit your .htaccess file. In order to actually enable the protection, you need to create a .htaccess file that actually adds proxy.py as a mod_python proxy and explicitly enables SSL client certificates to be passed to proxy.py. http://www.pipian.com/rdf/tami/htaccess is a good example for Apache 1.3 SSL servers. Apache 2.0′s mod_ssl requires somewhat different flags to enable passing SSL client certificates (melvin carvalho says that SSLOptions should be set to +StdEnvVars and +ExportCertData).
  8. TAAC should now be set up and running

The above instructions should work, but I have not officially tested them on a clean server.

It is worth noting that TAAC is still very much in flux and is alpha-quality software, and tends to follow the discussions on the foaf-protocols list rather closely, so the above instructions and configuration options may change without warning. Furthermore, there are some caveats with TAAC. In particular, it only currently allows for static policies and static protected URIs. It’s my hope to extend TAAC such that it will have hooks to allow for custom policies dependent on script arguments in the URL, no longer requiring static lists of all possible URIs (so protecting scripts is currently not likely to work well, especially if they take free-form arguments like session variables).

So that hopefully wraps it up a bit, and will get you started on getting a FOAF+SSL implementation set up of your own. TAAC may be clunky now, but the hope is to streamline it such that it’s easily integrated into any Python web application.