This page will be used to design a WebAccessControl Authorization Delegate.
Use Cases
Phase 1
- As a user from the Registrar office creates an Asset with a loan agreement document, the user assigns a property to the asset indicating that the asset is restricted to the Registrar staff, the user (a member of the Registrar group) should not be locked out of viewing/editing the resource.
- A user wishes to create multiple resources that all share access restrictions. The user is able to create a single access control list that is used by that group of resources. In addition, they do not have to explicitly link to the ACL from every resource; the appropriate ACL is inferred from the collection a resource is a member of (collection defined as a resource that ldp:contains the target resource) or the class(es) it is an instance of.
- There is a collection that is by default restricted access. However, there are a selection of resources within that collection that are publicly available. These public resources are not necessarily grouped together in a single hierarchy within the collection.
- An unauthenticated user requests a protected resource. The system presents them with an authentication challenge. The user successfully authenticates, and it is determined that they have read access to the requested resource. The system retrieves and presents the resource to the user.
- Some means of simulating this scenario will have to be devised for testing purposes, since presumably the test Vagrant will not be connected to an authentication service.
- An authorized user must be able to change which ACL applies to a given resource or group of resources without moving those resources.
- An authorized user must be able to edit an ACL in place in order to update the policy that applies to all resources governed by that ACL.
- An ACL should be its own ACL; thus, a user who has read (or write) access to a given ACL should be able to read (or write) to that ACL. A user who has no access according to a given ACL should not be able to view the ACL.
- A collection of books has an ACL that allows anonymous read access. One book within that collection (book A) has more restrictive access rules (i.e. only certain authorized users can read it), and these rules are defined in a different ACL that book A points to. Another book in the same collection (book B) points to no ACL directly, but should be governed by the ACL of the parent collection. When an anonymous user attempts to access book A, access should be denied (due to the ACL that book A points to), but when the same user tries to access book B, access is allowed by virtue of the ACL that the parent collection points to.
- The opposite scenario to #8 above – i.e. where the collection has more restrictive rules and the child book has more permissive rules – should also be possible by simply reversing the two ACLs.
Phase 2 - proposed
- A resource can be related to tags. Each tag is contained in a tag category: Conservation, Imaging, Licensing, etc. For tags related to a certain resource:
- Imaging users can read, create and delete tags in Imaging category
- Imaging users can read tags in Conservation category
- Conservation users can read, create and delete tags in Conservation and Imaging categories
- Note: F4 does not have "tags" per se. Are you envisioning a "tag" as a resource? or a property?
- See comment below
- Enforce ACLs on binary resources
- Add support for external ACL resources (resources that point to an ACL that is outside the Fedora domain)
- Add support for external agentClass graphs
- Enforce ACLs on ACL resources with a filesystem-based backstop (at present, only the admin user can add/edit ACLs)
- Verify header-based (delegated) authentication use cases
- Add ACL URIs to response headers as
Link: <acl-uri>; rel=meta
- Implement
acl:Control
andacl:Append
modes - Add support for inclusion of other acls via
acl:include
Removed/Amended Use Cases
Amended
- Phase 1, #2 - A user wishes to create multiple resources that all share access restrictions. The user is able to create a single access control list that is used by that group of resources. In addition, they do not have to explicitly link to the ACL from every resource; the appropriate ACL is inferred from the collection a resource is a member of, the class(es) is is an instance of, or other metadata associated with the resource.
- Amended to remove the underlined context above and to define "is a member of" as a resource which ldp:contains the target.
Removed
- An unauthenticated user requests a publicly readable resource. The system retrieves and presents the resource to the user without any authentication challenge.
- It should be possible to create an ACL that changes over time without user intervention (e.g. an embargo policy).
- This type of operations should make use of the proposed API extension architecture and a front-end web service to handle expiration of policies and leave Fedora to only apply the policies at the time of the request.
Questions arising from use cases
- Given these multiple ways of inferring which ACLs apply to a given resource (via collection, class, or other metadata), there must be clear rules for determining the precedence of policies and for resolving conflicts between policies.
- See Finding the effective policy set below.
- In the interest of security, the absence of an applicable ACL should result in denial of Create, Update, and Delete requests (and possibly also Read requests?) to non-admin users, but should allow all CRUD operations to admin users.
- the absence of an applicable ACL will result in denial of all requests.
Proposed Requirements (Phase 1)
- Completed
- Not yet completed
Sprint 1 (Phase I) Requirements
- F4 MUST allow assertions about authorization to be modeled in RDF in accordance with the WebAccessControl specification.
- Access assertions to be implemented are
- READ -> GET a resource
- WRITE -> PUT/POST/PATCH/DELETE a resource
- APPEND -> PATCH a resource, restricted to Insert statements only.
- as well as extending for:
- DELETE -> DELETE a resource
- UPDATE -> PUT/POST a resource
- The implementation assumes an ACL is it's own ACL, therefore CONTROL will not be implemented at this time.
- Optional extensions (ie. regex matching) will not be implemented in Phase 1.
- Access assertions to be implemented are
- F4 MUST be able to enforce authorization based on WebAC when a resource is requested via the REST-API
- F4 MUST allow authorization policies to apply to a group of resources which consists of:
- Resources sharing a rdf:type attribute matching an acl:accessToClass rule in an ACL in the preconfigured location.
- Note: sprint-1 implementation does not confine ACLs to reside in a "preconfigured location", but they can instead exist anywhere within the repository.
- Resources (without their own specific policy) share the policy of their container (defined as the resource which ldp:contains the target).
- Resources sharing a rdf:type attribute matching an acl:accessToClass rule in an ACL in the preconfigured location.
- F4 MUST honor the most permissive authorization policy when multiple policies apply to a request.
- See the section Finding the effective policy set, for more clarity.
- F4 MUST provide a way for external services such as Solr to enforce the authorization rules defined in the repository.
- Would one method of achieving this be to create separate solr cores for public users vs. admin users and publish only the public resources to the former and everything to the latter, or does the use case dictate more granular distinctions?
- Each request for a Web Resource returns an HTTP document containing a Link header (Link: <>; rel=acl) to an ACL resource which describes access to the given resource and potentially others.
- Servers are required to recognize the class foaf:Agent as the class of all agents (i.e. foaf:Agent is synonymous with "everyone")
Sprint 2 (Phase I) Requirements
Must have
- Enforce ACLs on ACL resources with filesystem-based backstop:
- Implement acl:Control, acl:Append, acl:Update and acl:Delete modes:
- F4 MUST provide a way for external services such as Solr to enforce the authorization rules defined in the repository:
- and
- Enforce ACLs on binary files:
- More documentation:
- Add support for agentClass graphs defined within F4:
- Verify header-based (delegated) authentication is supported (where headers are used to define the effective agent, independent of any container-based AuthN):
- Fix bug with versioned resources:
- Make webac and audit default configuration in fcrepo-webapp-plus:
- Bug fixes
Nice to have
- Add ACL uris to response headers as "Link: <acl-uri>; rel=acl":
- Support external ACLs (ACLs not managed by fedora)
- Add support for agentClass graphs defined external to F4
- Minor code cleanup:
Likely not
- Support for inclusion of other ACLs via acl:include
Removed requirements
- F4 resources that are open for public read should not challenge the client to authenticate
- What if a resource has no ACL? Should there be a default behavior? (for example allow all to admin user; deny all to non-admin?)
- This requirement specifies public *read*. Do we also want to allow a public write? While use cases for the latter are admittedly going to be rare, it would seem better not to be opinionated here if public write is what an implementer wants.
See this comment below for more information on this removal.
Finding the effective policy set
Finding the effective ACL
Use ACL that directly references target resource, if exists, else
if multiple ACLs apply to a given target resource, the most permissive is used.
Use ACL from configured location that has policy for target resource class, if exists, else
if multiple ACLs apply to a given class, the most permissive is used.
accessToClass statements in ACLs not in the configured location are ignored.
Recursively follow steps 1 and 2 for parent resource that ldp:contains target resource, if exists, else
Deny access
Resolving the effective policy from an ACL
Use policy that specifies requesting userId, if exists, else
Use policy that specifies requesting groupId, if exists, else
Note, if multiple requesting groupIds have policies, use the one that grants the most access.
Deny access
Authentication Considerations
[NOTE: This section has been stricken because it is not germane to the specific effort to develop a WebACL authorization delegate; the authentication considerations described below need to be part of the larger configuration of the ways Fedora and the web server interact, but that is a separate issue.]
Open Questions
- Is there anything currently implemented within the Hydra WebAC implementation that strays from direct compatibility with the WebAC standard? In other words, are there currently barriers to the goal of cross-application compatibility?
Role Commitments
Development
Stakeholder
Related Documents
- https://www.w3.org/wiki/WebAccessControl (note that this is still a wiki, not yet a draft let alone a standard)
- http://www.w3.org/TR/2014/NOTE-ldp-acr-20140916/ (a note only)
- https://github.com/duraspace/pcdm/wiki#webacl
- Authorization Delegates
- http://www.w3.org/ns/auth/acl
- Hydra implementation of WebAC
- https://github.com/projecthydra/hydra-head/blob/master/hydra-access-controls/app/models/hydra/access_controls/permission.rb
- https://github.com/projecthydra/hydra-head/blob/master/hydra-access-controls/app/models/hydra/access_controls/access_control_list.rb
- https://github.com/projecthydra/hydra-head/wiki/Access-Controls-with-Hydra
38 Comments
Andrew Woods
re (2): Since authentication is assumed to have happened prior to the request coming into F4, it will be the responsibility of the application over F4 or the webserver to determine if an authentication challenge is required.
Andrew Woods
For the initial implementation, I would advocate for simplicity and narrower scope.
Stefano Cossu
Agree; but also a higher degree of flexibility will be needed at some point to allow users move out of XACML.
As for regex matching, wouldn't it be more useful to have SPARQL query matching?
Andrew Woods
This is probably not so much an F4 consideration as it is the application over F4's or the webserver's since authentication challenges will be coming from these upper levels.
Peter Eichman
I have struck out requirement 3 above, since it looks like there are several ways to delay the authentication challenge until needed. The main requirement to do this is to distinguish at the container or webserver proxy level between an unauthenticated request that Fedora rejects with a 403 (should trigger an authentication challenge) and a 403 that was rejected even though it had credentials in the request (in this case, the 403 response should be passed on the client as-is, since this is a true unauthorized response).
Andrew Woods
The questions under this point should definitely be clarified. The WebAC "specification" scopes the resources to be protected as references to:
Peter Eichman
I agree. In addition, I have some questions regarding the WebAC spec itself, especially with regards to the acl:agentClass and acl:accessToClass predicates. The spec states that the object of the acl:agentClass must be a resolvable resource that contains triples of the form <> foaf:member <agent>. It then goes on to say that acl:accessToClass should be treated similarly, but I don't see how foaf:member could be used to do this, as it relates a foaf:Group to a foaf:Agent.
I also was highly confused by the use of the rdfs:Class as the range of the acl:*Class properties, since the spec indicates that the members of an agent class or an access class must be enumerated, and it is not as simple as just adding the stated class as an additional rdf:type to the resource in question. In other words, this graph would not be sufficient to grant <x> write access to <r>:
Nor would this:
(I think part of my problem is a terminological issues, of using "class" to refer to what appears to be an enumerated list of resources rather than a type.)
Andrew Woods
My assumption (which should be discussed) is that if no ACL is found on a resource, the first ACL found by traversing up the JCR hierarchy would be used. In that case, I believe the only scenario of having conflicting ACLs would occur in the case that you mention: "two conflicting ACLs attached to a particular resource".
Peter Eichman
By traversing up the JCR hierarchy, does that mean looking for a resource that is an ACL, or looking for the first resource that has an ACL? I assume it would be the latter, but it would be good to make it explicit.
Andrew Woods
Yes, I was meaning the latter.
A. Soroka
"Do these groupings of resources relate at all to the underlying JCR tree?"
I hope not. This suggestion above exposes implementation details at much too high a level. Andrew Woods, I think using the JCR hierarchy here is a bad idea. It should be LDP containment that provides this kind of zipping or traversal. That is ultimately more flexible and more in line with our intentions to sacrifice code on the altar of specification.
Andrew Woods
A. Soroka
Stefano Cossu
Stefano Cossu
This is probably simpler and faster but would I am concerned if it may limit modeling capabilities.
For example, I set a general access rule at the top repository level:
users in the 'web' group can read resources of type 'webPublished'
Then I have a container with a more specific policy attached:
Users in the 'imaging' group can create, update and delete resources of type 'image' [in this container].
According to the current proposal, I would have to re-link the web user policy to the lower-level container in order to have it honored, because Fedora will stop at the first policy it finds - correct?
And if policy linkage in the top level resource changes, would I have to go back to all the specific policies and apply those changes too?
Andrew Woods
This certainly deserves discussion. The counter-example to the one you provide is if an "admin" user requests a resource that is "writable" by "admins" but only "readable" for "public". I would expect the "admin" to be able to write the resource.
Stefano Cossu
This needs discussion indeed. Allowing more permissive policies trump restrictive ones may open to serious security leaks.
The most flexible approach, which is not contemplated in the current WebAC draft, would be to explicitly define how each policy interacts with other policies, setting the most conservative options by default.
This also assumes that Fedora would traverse the whole containment hierarchy up to the root level and combine all the policies found along the way according to these directives.
Jared Whiklo
I think in your counter-example you meant to say:
If so, then I would agree and I think this also fits with Stefano Cossu's points (both above and below) about accumulating permissions.
Andrew Woods
Jared Whiklo, no, I think my counter-example captures my intention as stated.
Jared Whiklo
Ok, Andrew Woods, it took me a little to understand that. But I think I got it, I am going to try and re-state it to make sure.
So, the public can read a resource and an admin can write to a resource. Then by your example the most permissive policy is public can read and therefore the admin loses their ability to write.
This seems to tie the size of a group to the "permissiveness". I would say being able to write is more permissive than being able to read. But because the general public can read we are giving that the more permissive "title".
Julie Allinson
A few York use cases here: https://docs.google.com/document/d/1P849TIMzOTseTNJLgENfHQdjbAo1bv4oC8ShOuvJ9sg/edit
Stefano Cossu
Use case #1: "As a user from the Registrar office creates an Asset with a loan agreement document, the user assigns a property to the asset indicating that the asset is restricted to the Registrar staff, the user (a member of the Registrar group) should not be locked out of viewing/editing the resource"
This seems more like an application-level concern, i.e. having Sufia (in our case) check that the user applying the restriction belongs to the group that has access to the resource before applying the policy, to prevent them to be locked out. Fedora should not be concerned directly with that IMO.
Or are you thinking about a different scenario?
Stefano Cossu
Use case #2: "...other metadata associated with the resource"
This does not seem attainable within the current WebAC draft but is high up in my wish list.
Julie Allinson
Yes, this is what I was trying to outline in my notes, to be able to assign access control via a custom predicate rather than via a grouping (Class) of resources.
I'm not keen on having to create hierarchies to apply access control, it's a major limitation in F3.
I noticed in the draft that apart from a regex example, there was very little on accessToClass.
A. Soroka
If policy mapping is mediated through LDP containment (and not the JCR hierarchy) you can do that via an Indirect container. A predicate with a value is an intensional definition of a class.
Stefano Cossu
Can you provide an example scenario using an indirect container to apply a policy to a resource based on a certain property value? This sounds interesting but I cannot quite get it straight...
A. Soroka
I cannot supply you with an example of anything until there is something with which to build one. What's on this page are just requirements.
The real point is that in an LDP Indirect container, containment is decided by your choice of predicate.
Stefano Cossu
My requirement / use case is having e.g.
users in "Curatorial" group can read resources with a property myns:createdByDepartment set to myns:Imaging
Can that be resolved via LDP containment?
A. Soroka
Possibly. It depends on (amongst other things) what myns:Imaging is. This is all very premature. We are talking about possible implementations when the requirements are not close to finished.
Stefano Cossu
I see these as potential decision-driving use cases rather than implementation specs and that is why I exposed them in plain English. Maybe I can make this case more plain English and put it in the use cases above?
A. Soroka
We are not talking about use cases now. We are talking about implementation. We went wrong after "This does not seem attainable within the current WebAC draft but is high up in my wish list."
What is or is not attainable is not a matter for use cases. That is a question to be answered after the use cases are clear. We can then turn back to them and sift and sort them. But blocking something out because you suspect that it cannot be done is not a good pattern. That was why I commented.
Julie Allinson
My use case here would be:
I want to be able to provide public read access to <my_resource> based on the following.
<my_resource> ecm:rights <http://creativecommons.org/publicdomain/>
Stefano Cossu
Andrew Woods: "
Tags are resources created by repo managers and attached to certain resources via a predicate such as myns:hasTag.
The point I am trying to make here is that some access policies may have to follow a more complex path: tagged resource > tag > tag category
Let me know if this needs to be reformulated or is out of scope altogether.
Andrew Woods
The modeling of this scenario in the WebAC context would likely be to use an rdf:Class instead in the place of a "tag" such that an acl:accessToClass policy can be employed.
Stefano Cossu
In theory I could turn tag categories or even tag links in a resource into classes, but then those "classes" would have to actually be available as Fedora resources so I can give them a label or other metadata, or to query them when a client pulls a list of available tags ordered (and access-controlled) by category. I am not sure if that is bad practice or not.
Joshua Westgard
Regarding testing the Phase 2 development features, in my reading of the tickets above there are 7 or 8 individual points to test. In general they seem straightforward, but I do have a few questions:
Peter Eichman
I can answer (2) pretty easily (and I believe Unknown User (acoburn) is working on a how-to guide for this as well). Yes, you would use
--header
(or the short form,-H
) incurl
to pass the delegated user. The header isOn-Behalf-Of
:Andrew Woods
As for #1, a missing piece is the write-up of how to potentially configure Solr to use the
Link
header now provided by F4. Jared Whiklo? Unknown User (acoburn)? is that documentation something that could be done for Joshua Westgard in the short-term? If not, we will need to help with that testing at a later date.As for #3, testing with and without a backstop ACL sounds right.
Joshua Westgard
Thanks, Andrew. I can certainly wait and look at the documentation, and Peter Eichman has offered to help with the Vagrant and/or a .war file for the new version if need be. And we can always defer testing on elements that require a fuller setup until those pieces are in place.