authorization-panel
authorization-panel copied to clipboard
How should an app change access?
Reading https://github.com/solid/web-access-control-spec, I'm not quite sure what I should do as an app developer in the following situation.
What I want to do: give vincentt
default Read and Append access to ./container
, given the following existing ACL Rule:
<#some-rule>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>, <https://not-vincentt.inrupt.net/profile/card#me>;
acl:accessTo <./container/>, <./other-container/>;
acl:default <./container/>, <.other-container/>;
<#arbitrary-other-predicate> <#arbitrary-value>;
acl:mode
acl:Read.
What I'm currently doing is splitting this up into three separate Rules:
<#some-rule1>
a acl:Authorization;
acl:agent
<https://not-vincentt.inrupt.net/profile/card#me>;
acl:accessTo <./container/>, <./other-container/>;
acl:default <./container/>, <./other-container/>;
<#arbitrary-other-predicate> <#arbitrary-value>;
acl:mode
acl:Read.
<#some-rule2>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>;
acl:accessTo <./container/>, <./other-container/>;
acl:default <./other-container/>;
acl:mode
acl:Read.
<#some-rule3>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>;
acl:default <./container/>;
acl:mode
acl:Read, acl:Append.
So we have:
-
#some-rule1
, which is equal to#some-rule
but with the agentvincentt
removed. -
#some-rule2
, which is equal to#some-rule
but hasvincentt
as the only agent, has removed./container
as default, and does not include non-ACL Triples. -
#some-rule3
, which gives Read and Append access to./container
tovincentt
.
This looks like a reasonable solution, but it has the following problem. What if this was the original Rule:
<#some-other-rule>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>;
acl:default <./container/>;
acl:mode
acl:Read.
Applying the same algorithm, that would result in the following three Rules:
<#some-other-rule1>
a acl:Authorization;
acl:mode
acl:Read.
<#some-other-rule2>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>;
acl:mode
acl:Read.
<#some-other-rule3>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>;
acl:default <./container/>;
acl:mode
acl:Read, acl:Append.
That means we now have #some-other-rule1
and #some-other-rule2
that do not actually do anything. This will quickly become unwieldy!
One thing we could do is to remove Rules that are empty (i.e. contain no non-ACL Triples, and no acl:mode
, or no acl:accessTo
or acl:default
, or acl:agent
, acl:agentGroup
or acl:agentClass
Predicates). However, that leads us to another problem. What if, in the situation above, we didn't want to give Append access, but instead remove the existing Read access? In other words, that would mean that #some-other-rule3
would be empty as well. Then, if we were to remove all empty Rules, no Rule would remain.
And that, in turn, is problematic because, given the ACL inheritance algorithm, there would be no more acl:default
Predicates, leading to the parent's rules suddenly applying.
So the question is: what should an app do to alter existing Access Modes?
There are a few different things going on here.
First, there are some invalid formulations:
<#some-rule3>
, <#some-other-rule>
, <#some-other-rule1>
, <#some-other-rule2>
and <#some-other-rule3>
are invalid and would be ignored: none has an acl:accessTo
predicate. (At least, the server implementation I wrote would ignore these).
Second, the multiple acl:accessTo
and acl:default
values is strange. In the context of the implementation that I've written, an ACL resource can only be attached to a single regular resource. Inheritance via containment may apply, but I would never expect an ACL resource to have multiple values for those predicates -- the irrelevant one(s) would be ignored. For example, if the ACL resource is applied to <./container/>
then the acl:accessTo
and acl:default
would also be <./container/>
. An object value with <./other-container/>
is irrelevant.
There are several approaches to handling the use case you point out. One approach might be to keep the original ACL:
<#some-rule>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>, <https://not-vincentt.inrupt.net/profile/card#me>;
acl:accessTo <./container/>, <./other-container/>;
acl:default <./container/>, <.other-container/>;
<#arbitrary-other-predicate> <#arbitrary-value>;
acl:mode
acl:Read.
And then add a special "addendum" for the vincentt
user:
<#some-rule-for-vincentt>
a acl:Authorization;
acl:agent
<https://vincentt.inrupt.net/profile/card#me>;
acl:accessTo <./container/>, <./other-container/>;
acl:default <./container/>, <.other-container/>;
<#arbitrary-other-predicate> <#arbitrary-value>;
acl:mode
acl:Append
The vincentt
user already has Read
access via <#some-rule>
, so the new rule just adds append access. Note, however, that the multiple values for acl:accessTo
and acl:default
would just be ignored, as would <#arbitrary-other-predicate>
.
Thanks @acoburn.
<#some-rule3>, <#some-other-rule>, <#some-other-rule1>, <#some-other-rule2> and <#some-other-rule3> are invalid and would be ignored: none has an acl:accessTo predicate. (At least, the server implementation I wrote would ignore these).
Would your server also ignore rules that do not specify an agent, agent group or agent class (but do have an acl:accessTo
or acl:default
Predicate), especially when it comes to considering whether an ACL higher up in the tree should apply? Because if so, then I think we can just remove any rules that do not specify either, and then the algorithm described above wouldn't add empty rules.
If not, then we'll assume that no ACL Rule will apply to multiple Resources as well, which means that we'll simply not create <#some-rule2>
and <#some-other-rule2>
, and then we won't have to clean it up after.
The vincentt user already has Read access via <#some-rule>, so the new rule just adds append access.
Right, but I want to be able to deal with the situation in which the user removed Read access as well, so simply adding another addendum wouldn't allow me to deal with that case.
Ah, I just saw your reference to this comment in another issue: https://github.com/solid/specification/issues/55#issuecomment-536092174
So that would mean that removing empty rules would not lead to ACLs higher up in the tree getting applied, so we should be safe here with either approach described in my previous comment. Thanks!
When a contained resource is deleted, the server MUST also delete the associated ACL.
Multiple accessTos would mean that an ACL's lifecycle can depend on multiple resources - especially in the case of directly associated ACLs ie. if one resource gets deleted, the other resources will lose their ACL.
That may not be an immediate issue when an inherited ACL is applied (and doesn't get deleted), but would still have a reference to the deleted resource from an accessTo, unless the server is instructed to cleanup for inherited ACLs.
I think it'd be simpler to create and update policies if only one resource is attached to an accessTo.