specification: Decision: Access Rule with `acl:default` does not imply `acl:accessTo`

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.)

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 27 (24 by maintainers)

Commits related to this issue

Most upvoted comments

@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).

It also might need pointing out that the access function does not care if there is a bunch or Authentication nodes or one so long as there is the logical statement made which authorizes each mode needed. I was asked to put in some pseudocode for the function, hough it is a bit off topic.

Suppose the Resource R in question is in container C. To do the operation requires a set of modes. Then the operation is allowed iff

For EVERY mode M needed,

  • there is SOME node N for which all of:
    • N mode M
    • N type Authentication
    • N (accessTo R) OR (N default C)
    • N applies to the agent directly OR through Group membership, OR through Class membership

To be more explicit, you could say:
For EVERY mode M needed,

  • there is some node N (no matter what other nodes there are) for which all of:
    • N mode M (no matter what other modes it may have)
    • N type Authentication (no matter what types it may have)
    • N (accessTo R) OR (N default C) (no matter what other resources and containers are also mentioned)
    • N applies to the agent directly OR through Group membership, OR through Class membership (no matter what other agents may also be directly or indirectly also mentioned)

Do NOT assume the modes will be on the same node N. Different modes may be supplied by quite different forms – say one through default and one through accessTo, one via the agent, one via a group and another by a class.

@michielbdejong Just a heads-up: the title does now more accurately reflect the description I wrote in the original comment, but now the “yes” and “no” in your comment (referring to “the question in the title of this issue”) are in reverse 😃

Changed the title to reflect what @Vinnl actually meant by the text, I think.

@michielbdejong – I’m pretty sure you meant for one of the “Option ‘yes’” headers above to be “Option ‘no’” (I think the second?)…

Let’s see if we can find a way out of this impasse: Should the question in the title of this issue be answered with ‘yes’ or with ‘no’?

The facts:

  • NSS, PSS, CSS answer it with ‘yes’.
  • ESS answers it with ‘no’.
  • The spec text in https://github.com/solid/web-access-control-spec#default-inherited-authorizations can be read with both ‘yes’ and ‘no’ in mind.
  • We need to choose, we can’t have a situation where some servers behave differently from others.
  • If we say ‘yes’, we make WAC more powerful. This could be a good thing, or a bad thing.
  • Sarven does not take a ‘yes’ or ‘no’ stance, but does point out that there are use cases that are possible with ‘yes’ but not with ‘no’. So I think we agree that ‘yes’ is more powerful - it gives the pod owner (or the Solid app developer, depending how you look at it) more options, and these could be useful in some situations. He also mentions some situations where both systems would work equally well.
  • I do (hereby) take a stance and propose we answer with ‘yes’. I think Sarven’s example about the inbox is compelling, but I can also think of more use cases. You could also for instance create a container that is not itself publicly readable, but its contents are. This serves UC 2.9.3 of the authorization panel, for instance.
  • We have worked with “yes” historically (specifically in NSS and in Solid OS, which still do, but also Trellis, historically), and I think this has a weight, although of course not in itself compelling enough to base a decision on if we currently disagree with it, as Aaron rightly commented.
  • Emmet and Nicolas answer it with ‘no’, IIUC this is because they feel the extra options could be a “footgun”.

Option ‘yes’

Then we:

  • make this clear in the spec.
  • We unskip the tests for this and keep them as testing the ‘yes’ behaviour.
  • We ask the ESS team to change the behaviour of their server. In the process, existing ACL docs that only have acl:default should be updated to add acl:accessTo so their behaviour stays as intended.
  • We add warnings to app developers saying “careful, you are about to give more access to the descendants, are you sure?”,
  • In end-user facing GUIs we could just hide this “footgun” possibility altogether, or hide it behind some “Advanced options!” warning.

Option ‘no’

Then we:

  • make this clear in the spec.
  • We unskip the tests for this and invert them so they test the ‘no’ behaviour.
  • We ask the NSS, PSS, and CSS teams to change the behaviour of their server. Wherever a container had less access than its descendants, the safe option is to reduce access for the descendants, to match what the container itself has.
  • Apps and user expectations will break if they currently gave more access to descendants, since we are removing that feature from Solid and it will no longer be available. We explain why we chose to do this, and hope everybody will understand.

Please vote. Also, if there are more arguments to vote ‘no’ other than the “it’s a footgun” argument which I hope I’m attributing correctly to the proponents of ‘no’, then please detail these - if they are compelling, the ‘yes’ voters might be convinced to switch!

From my understanding, I think the behaviour that’s currently implemented in NSS, PSS and CSS and tested by the Solid test suite, is the correct one (i.e. acl:default and acl:accessTo are orthogonal), and that we should ask Inrupt if they can align the behaviour of https://pod-compat.inrupt.com with that.

Simple evidence of this is for instance https://github.com/solid/node-solid-server/blob/v5.6.4/default-templates/new-account/.acl#L20-L23: it’s basically the way it’s always been, and it probably doesn’t help the eco-system if newer implementations of Solid fork away from that?

@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.

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.