In other words, is it impossible to define an inheritable default that gives _more_ access to a Container's descendants than to the Container itself?
Or with a code example: is this not a valid ACL Rule? (Syntax errors and prefixes notwithstanding.)
:ControlReadWriteDefault
a acl:Authorization;
acl:agentClass foaf:Agent;
acl:default tes:;
acl:mode acl:Control, acl:Read, acl:Write.
("Valid" meaning: it gives everyone Read, Write and Control access to children of the Container that do not have their own ACL, and there's no need for an acl:accessTo tes:; to do so.)
Emmet and I agree this should not happen. You shoudn't be able to give more access to the descendants but I'm interested in the spec team opinion.
My own understanding is that default and accessTo are fully independent properties.
That means that your above example do not give any access rights on inheritance algorithm.
In order to address ambiguities and tighten the spec, this issue should be taken up when specifying shape of ACL: https://github.com/solid/specification/issues/169 .
I summarise some common knowledge:
An ACL document may have zero or more authorization policies where each policy uniquely is described based on the following dimensions:
acl:agent, acl:agentClass, and/or acl:agentGroupacl:accessTo and/or acl:defaultacl:modeAn authorization policy without a acl:mode entails no access.
An ACL document may have max one authorization policy with max one .acl:default statement.
acl:default's range is a resource of container type, and its value is the container resource that is associated with the ACL document.
acl:default check is done in context of the ACL inheritance algorithm. If no acl:default is found in the effective container's ACL, no access is granted.
A container's ACL may have one authorization policy including both acl:accessTo and acl:default. The authorization policy will be used in different context.
A container's ACL may have two authorization policies where one only includes acl:accessTo, and the other authorization policy only includes acl:default. This effectively allows a container (via acl:accessTo) to have access privileges different than the contained resources (via acl:default) when the ACL inheritance algorithm is triggered.
Simple situations:
Append access to container
Read access to container
Note https://solid.github.io/specification/#delete :
To delete a resource, an acl:agent MUST have acl:Write privilege per the ACL inheritance algorithm on the resource and the containing container.
From another angle: if it is possible to have Write access on a resource without Write on its containing container, then clients will not be able to delete the contained resource. At least for delete operations, it entails that a contained resources can be partly controlled by authorization policies in ACL documented as per ACL inheritance algorithm. The *nix filesystem permissions works the same way.
In *nix filesystem, user is also granted to Read a file in a directory even if they don't have Read on directory.
$ mkdir foo/
$ echo "bar" > foo/bar
$ chmod -r foo/
$ cat foo/bar
bar
$ ls foo/
ls: cannot open directory 'foo/': Permission denied
$ chmod -w foo/
$ rm foo/bar
rm: cannot remove 'foo/bar': Permission denied
$ chmod +w foo/
$ rm foo/bar
So, at least, both behaviours mentioned above are compatible with *nix filesystem permissions - a significant compatibility IMO.
An ACL document may have max one authorization policy with max one
acl:defaultstatement.
Do I read this correctly : acl:default can only be used once in an ACL document.
And the following example is not valid :
<#read>
a acl:authorization;
acl:accessTo <./>;
acl:default <./>;
acl:agentGroup <any group URI>;
acl:mode acl:Read.
<#ReadWriteControl>
a acl:authorization;
acl:accessTo <./>;
acl:default <./>;
acl:agentGroup <an other group URI>;
acl:mode acl:Read, acl:Write, acl:Control.
@bourgeoa That's correct. As far as I'm aware, there is currently no information that would help to determine which of the authorization policies including acl:default would be applicable. It could of course be arbitrarily argued that it should be the first one when listed, at random, a union, or one with least number of access modes or whatever may be considered to be "safe", .. .and so on. Possibly even just halt altogether and deny access.
Simpler to restrict by allowing only max one acl:default per ACL document when an ACL is create or updated. We can indicate error handling.
@bourgeoa That's correct. As far as I'm aware, there is currently no information that would help to determine which of the authorization policies including acl:default would be applicable. It could of course be arbitrarily argued that it should be the first one when listed, at random, a union, or one with least number of access modes or whatever may be considered to be "safe", .. .and so on. Possibly even just halt altogether and deny access.
Simpler to restrict by allowing only max one acl:default per ACL document when an ACL is create or updated. We can indicate error handling.
This isn't how I've understood how acl:default can be used. You can have multiple instances of acl:default for many reasons, most notably for various agents:
<#agentADefaultRead> a acl:authorization;
acl:default <./>;
acl:agent <Agent A WebID>;
acl:mode acl:Read.
<#agentBDefaultAll> a acl:authorization;
acl:default <./>;
acl:agent <Agent B WebID>;
acl:mode acl:Read, acl:Append, acl:Write, acl:Control.
But I think you can also have multiple acl:default for same agent as well; the server would check them all until any of them gives the requested access (or if all fails, deny access).
@megoth True! Thanks for clarifying that. I went along with the example and completely skipped over acl:agent, :agentClass, :agentGroup as a dimension. It still holds true if multiple authorization policies have the same agents listed (along with default). System either needs to prevent their creation/updates - making sure authorization policies are indeed unique, or alternatively, it needs to know what to do if/when it encounters such policies.
Updated https://github.com/solid/specification/issues/193#issuecomment-679012925 to indicate the dimensions that uniquely identifies an authorization policy. We can still edit this to frame it closer to what we like.
(edited : sorry I did not see @megoth above comments)
@csarven I think they could also both be true (the algorithm for default will mimic for accessTo) and when checking for an agent, look for agentGroup, then check for default in same authorization rule.
The above seems to be the actual way NSS does.
And when you create an ACL document with mashlib authorization pane default is added to all authorization rules.
ACL document created by mashlib authorization pane :
@prefix : <#>.
@prefix n0: <http://xmlns.com/foaf/0.1/>.
@prefix n1: <http://www.w3.org/ns/auth/acl#>.
@prefix test1: <./>.
@prefix c1: </profile/card#>.
@prefix c2: <https://bourgeoa.inrupt.net/profile/card#>.
@prefix c3: <https://bourgeoa.solid.community/profile/card#>.
:ControlReadWrite
a n1:Authorization;
n1:accessTo test1:;
n1:agent c2:me, c1:me, c3:me;
n1:default test1:;
n1:mode n1:Control, n1:Read, n1:Write.
:Read
a n1:Authorization;
n1:accessTo test1:;
n1:agentClass n0:Agent;
n1:default test1:;
n1:mode n1:Read.
Most helpful comment
This isn't how I've understood how
acl:defaultcan be used. You can have multiple instances ofacl:defaultfor many reasons, most notably for various agents:But I think you can also have multiple
acl:defaultfor same agent as well; the server would check them all until any of them gives the requested access (or if all fails, deny access).