Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Which permissions are required for deleting a resource? #197

Closed
RubenVerborgh opened this issue Jun 23, 2019 · 46 comments
Closed

Which permissions are required for deleting a resource? #197

RubenVerborgh opened this issue Jun 23, 2019 · 46 comments

Comments

@RubenVerborgh
Copy link
Member

When deleting a resource R in a container C, do we require:

  • Write permissions on R?
  • Write permissions on C?
  • Both?
  • Something else?
@RubenVerborgh
Copy link
Member Author

History in solid/web-access-control-spec#48.

Summary:

We need to decide whether we want Linux compatibility or not.

@csarven
Copy link
Member

csarven commented Nov 28, 2019

If LDP's behaviour is applied to R and C: Write permissions on R as well as C is required in order to remove the containment triple from C. This requirement can be derived from LDP's DELETE: https://www.w3.org/TR/ldp/#ldpc-del-contremovesconttriple

@kjetilk
Copy link
Contributor

kjetilk commented Nov 29, 2019

What if we end up with rm -r (#190)? Then, it would need to be write on all resources down to and including the container?

@csarven
Copy link
Member

csarven commented Nov 29, 2019

I'd like to clarify https://github.com/solid/solid-spec/issues/195#issuecomment-559619352 because of a subtle point related to this issue. With the given that containment triples are server-managed, while Write is required on R, Write is not explicitly required on C for the purpose of removing the containment triple. There is an implicit write operation on C based on LDP's interaction model (when R is removed from containment triples) but that burden is not placed on the requesting agent, hence their access to C can be seen as out of scope. However, as LDPR's lifecycle is dependent and controlled by the LDPC in which it has a binding relationship with, it can be expected that any changes to that binding should require permission to alter C.

What's argued is more of a design decision based on connecting some basic assumptions. AFAICT, requiring Write on C and R in order to delete R is compatible with *nix behaviour.

@csarven
Copy link
Member

csarven commented Nov 29, 2019

What if we end up with rm -r (#190)? Then, it would need to be write on all resources down to and including the container?

If rm -r is analogous, then it'd be reasonable to consider whether -f is applied by default as well ie. no prompt.

[Aside:

  • I'm not sure whether --one-file-system applies to our design. Revisit. Already discussed elsewhere.
  • --preserve-root is taken as given in that ACL document R of root C can't be deleted.
  • -d is used provided that a C is considered to be "empty" if its auxillary resources like acl and possibly meta doesn't count towards it.

]

Having -f as the default would be the simplest design - not to imply ideal - as opposed to for example having a workflow which prompts the user per child resource that's encountered along the way. -I may be useful in that there is some sort of a signal given back to the client (eg. can't delete C or need to delete contained C because it contains R).

In any case, rm -r should be treated as atomic. On *nix, user is only prompted if need to ie. all other removes will succeed.

@kjetilk
Copy link
Contributor

kjetilk commented Nov 30, 2019

Yeah, I think the attractiveness of rm -r is atomicity, which is hard to achieve for multiple HTTP requests.

As for -f, just a wild thought, it is not so much the prompt that I think characterizes -f but that you can delete a file if you would have permission to do so if you changed the permissions on the file and you have permission to do so... Which wasn't particularly clear, I suppose, but the wild thought I had was, perhaps acl:Control has a role to play...?

@csarven
Copy link
Member

csarven commented Sep 10, 2020

Edit: As of this writing, the text in spec says ( as per PR #188 ) based on #197 (comment) (which was one possible approach) :

To delete a resource, an acl:agent MUST have acl:Write privilege per the ACL inheritance algorithm on the resource and the containing container.

The counter argument below indicates why it'd be preferable to not require Write on the container of the contained resource. It would prevent over permissioning and easier policy management.


By not requiring Write on container to delete a contained resource, agents are not granted more access than what they need. Granting an agent with Write on container allows them to modify the container description, potentially modify or delete all contained resources, as well as delete the container.

Use case being that a user needs to create resources in a container where they can then work on the created resource ie. read, update, delete. They don't need to have knowledge or access to anything else in that container, including the container itself.

To put it generally, it is possible for a container and contained resources to have different authorization policies. Example code snippets:

### container's ACL:

<#container-policy>
  acl:accessTo <./> ;
  acl:agentClass foaf:Agent ;
  acl:mode acl:Append ;

<#contained-resources-by-default-read-policy>
  acl:default <./> ;
  acl:agent <http://example.org/the-oracle#i> ;
  acl:mode acl:Read .

<#contained-resources-by-default-control-policy>
  acl:default <./> ;
  acl:agentGroup <http://example.org/the-architect-and-friends#i> ;
  acl:mode acl:Control .
### a contained resource's ACL:

<#contained-resource-policy>
  acl:accessTo <./contained-resource> ;
  acl:agent <http://example.org/agent-smith#i> ;
  acl:mode acl:Read, acl:Write .

Then, Agent Smith should only need Write to delete a contained resource.

@csarven csarven transferred this issue from solid/solid-spec Sep 11, 2020
@csarven csarven added this to the ~First Public Working Draft milestone Sep 11, 2020
@csarven csarven added this to Under discussion in Specification Sep 11, 2020
@RubenVerborgh
Copy link
Member Author

+1 from me

@michielbdejong
Copy link
Contributor

michielbdejong commented Sep 11, 2020

Yeah, I guess both options make sense, but your argument for changing this are convincing. If you have write on R then you can already set it to zero bytes anyway, which is almost the same as deleting it. It's a bit weird that you end up affecting the container's contents without having explicit permission to change it, but that's probably unavoidable.

Since it reduces the required permissions, it will not break many clients. But this is a semver-major change, so I'll change the behaviour in NSS 6.

I hadn't added any tests for this in https://github.com/solid/web-access-control-tests yet, so I'll immediately create the tests to test the new behaviour.

@acoburn
Copy link
Member

acoburn commented Sep 11, 2020

+1 on not requiring acl:Write on the container in order to allow deletion of a contained resource (assuming the agent has acl:Write permission on the contained resource).

@justinwb
Copy link
Member

Also a very strong +1 to not requiring acl:Write on the container to delete a contained resource R when the agent has acl:Write on R.

By not requiring Write on container to delete a contained resource, agents are not granted more access than what they need. Granting an agent with Write on container allows them to alter the container description as well as potentially modify or delete other (but not necessarily all) resources in the container.

Agree with @csarven and echo these points 1000% 👆

@d-a-v-i--
Copy link

+1. because write would not be needed on anything else in the container, restricting write only to the resource meant to be deleted makes sense to me.

@csarven
Copy link
Member

csarven commented Sep 12, 2020

Great! Updated based on most recent consensus: 4fd701f

@csarven csarven moved this from Under discussion to Done in Specification Sep 12, 2020
@csarven csarven closed this as completed Sep 12, 2020
@timbl
Copy link
Contributor

timbl commented Sep 14, 2020

Here is a counter argument to keep the need for Write access to the container also. We have at the moment an invariant property of the system is that if I remove Write access to something it won't change.

I like that. It's logical. For example, if I am reading a file which has no write (or append) access then I can cache it on a much more serious basis. If I don't give anyone write access to a folder, I can assume, like for a file, that it won't change. If you then delete one of its contents, then that breaks - I thought I had a valid copy of the list, and I don't.

One of the directions we have talked about was getting into immutable resources. An immutable resource is one where is is not only unwritable now but will never be writable in the future. That's a fairly short step. With immutable resources, we can refer to them by their hash. They can be Merkle trees, you can stick them in IPFS and do lots of other things. You can send them to the Internet Archive as a final version of this resource.

Lots of things get optimizable when something can't change. You don't need to lock access to it at all.

Being able to tie these good things to the ACL only having Read access is something we would lose.

@timbl
Copy link
Contributor

timbl commented Sep 14, 2020

I see I am too late with this comment

@timbl
Copy link
Contributor

timbl commented Sep 14, 2020

So if I want to keep my say /usr/local/ folder to always just have the fixed three /usr/local/ lib /usr/local/src and /usr/local/bin then I have to bock write access to it and each of the container folders ? The suggested change means that I can't preserve my folder structure without both remove Write access for /usr/local/ AND ALSO /usr/local/ * which defeats the point as you can't use the child folders.

@timbl
Copy link
Contributor

timbl commented Sep 14, 2020

"""Granting an agent with Write on container allows them to modify the container description, potentially modify or delete all contained resources, as well as delete the container.""" -- Not "as well as delete the container" as for that they need W on its parent to.

@timbl
Copy link
Contributor

timbl commented Sep 14, 2020

If you allow files to be deleted from a folder without write access to that folder then surely you have to allow them to be added too?

@csarven csarven reopened this Sep 14, 2020
Specification automation moved this from Done to Under discussion Sep 14, 2020
@csarven
Copy link
Member

csarven commented Sep 14, 2020

if I remove Write access to something it won't change

While agents with Control can make that assumption, agents with Read-only should not. Essentially only storage controller/"owner" can rightfully assume some resources to be immutable in context of immutable authorization policies.

Wouldn't the promise of immutable resources by URI owners be better advertised declaratively with eg. HTTP Link rel=type http://www.w3.org/2006/gen/ont#FixedResource , or negotiated using the Memento protocol ( http://mementoweb.org/ns#Memento ) ?

if I am reading a file which has no write (or append) access then I can cache it on a much more serious basis. If I don't give anyone write access to a folder, I can assume, like for a file, that it won't change. If you then delete one of its contents, then that breaks - I thought I had a valid copy of the list, and I don't.

Controller shouldn't assume a container to be immutable if at the same it is possible to give Write access to a contained resource. Information about the container can change as a side-effect of changing its member, and so we should be careful about how this is interpreted. For example, while the the containment listing may not change after modifying a contained resource, container's description may be updated to indicate last modified date/time of a contained resource or even the container itself. [*nix filesystem does it]


The suggested change means that I can't preserve my folder structure without both remove Write access for /usr/local/ AND ALSO /usr/local/ * which defeats the point as you can't use the child folders.

Yes, must remove Write in this case. Consider the case where a contained resource has its own ACL and you have Write on that resource. The algorithm doesn't need to check your permissions on the container in order for you to modify the resource. So then requiring Write on container in order to delete a resource is something different. If the delete operation is significantly different than the modify operation, then having Write on a resource doesn't necessarily mean you are allowed to delete. Something like acl:Delete would be required to make the distinction.


Not "as well as delete the container" as for that they need W on its parent to.

True. [I've mistakenly introduced that when I edited the comment.]


If you allow files to be deleted from a folder without write access to that folder then surely you have to allow them to be added too?

No. Append or Write is required on container to create a new resource in that container to begin with.


The issue is about changing the frame of how delete operations work in context of ACL and inheritance. From that perspective, I don't object to requiring both Write on container and contained resource in order to delete the contained resource.

To be clear, Write on a resource only entails access privilege to modify it. Only by also having Write on the container of a resource can delete work.


Limiting delete by requiring more privilege is a double edged sword. Great to set higher privileges for destructive operations but it is not particularly a simple design or intuitive - especially when one should only be able to delete a particular contained resource.

@csarven
Copy link
Member

csarven commented Sep 26, 2020

Having hierarchical containment loosely coupled with WAC entails that a contained resource is under the authority/control/URI space (so to speak) of its container. Hence, a request to unlink is triggered via the resource that's targeted, and then processed based on the permissions set on itself and its container.

Requiring delete on the container of a contained resource is also consistent with the way a request to delete a root container are handled ( https://solidproject.org/TR/protocol#deleting-resources ):

When a DELETE request targets storage’s root container or its associated ACL resource, the server MUST respond with the 405 status code.

The underlying rule to delete consists of determining target resource's container. If the resource is contained, privileges on its container are determined. If resource is not contained - as in the case of root container - the request is rejected. The base case.

@timbl
Copy link
Contributor

timbl commented Sep 26, 2020

I believe this user story is satisfied by giving Bob acl:append access to /usr/local/lib, /usr/local/src, and /usr/local/bin (unless i'm misinterpreting).

You are misinterpreting. She wants to allow to them to do whatever they want creating and deleting things inside /usr/local/lib, but not delete /usr/local/lib

@timbl
Copy link
Contributor

timbl commented Sep 26, 2020

There is an incongruence in having the ability to only add new resources into a container via acl:append (which is very useful), and a subsequent inability to delete those specific resources I added if I need to.

I disagree. It's not a bug, it's a feature. With append-only access we are creating not a read-write space but we are allowing the semantics of sending messages. Sending a message is a an event which is at core is not retractable. (You can have all kinds of variety of system which allow actually allow different forms of complete or limited retraction, but basically sending a message adds it to the ever-growing log of things sent, and is not revocable.) In message-based systems, you can send a new message revoking the effect of the first message, but you can't un-send a message. This is valuable.

@timbl
Copy link
Contributor

timbl commented Sep 26, 2020

When I give something only read access, I expect it not to change.
If I give read and append access, I expect it only to grow. Whether it is a list of contained resources or a set of triples in a RDF document.

@timbl
Copy link
Contributor

timbl commented Sep 26, 2020

Core invariants of the system like that make it simpler. They make it better foundation to build other systems on top of. Developers will get used to using them, and hopefully will find the systems easier to learn and easier to remember.

@justinwb
Copy link
Member

You are misinterpreting. She wants to allow to them to do whatever they want creating and deleting things inside /usr/local/lib, but not delete /usr/local/lib

To be fair, that is not what your use case says. The only mention of delete is that she not be allowed to delete those three containers (/usr/local/lib, /usr/local/src, /usr/local/bin). With the added clarification that she should be able to delete things, it changes the approach. The follow-up question being - which things?. Only things that she creates, or anything in those three containers?

@justinwb
Copy link
Member

justinwb commented Sep 26, 2020

When I give something only read access, I expect it not to change.
If I give read and append access, I expect it only to grow. Whether it is a list of contained resources or a set of triples in a RDF document.

I agree that when you have append on a document - you should have confidence that it can only grow. When giving an agent append access to a container, there is also value in scenarios where agents can only add new resources to the container, but have the ability to manage the resources they added (example case - https://solid.github.io/authorization-panel/authorization-ucr/#collection-readappendwrite)

Note that I absolutely agree it is valuable to append to a container so it can only grow per your example @timbl - I'm just pointing out there's a case where it is useful to configure permissions so it can grow, but allow for subsequent management (including deletion) of added resources by their creators

@justinwb
Copy link
Member

Giving Write access to a container [..] would not [alone] allow them to delete contained resources. Write access on each contained resource is still required.

Sorry @csarven I missed that point in the thread earlier. This does add another dimension to it, but if there was not a specific acl set on the resource, I imagine that inherited write permissions from the container would apply and satisfy that requirement?

@csarven
Copy link
Member

csarven commented Sep 28, 2020

if there was not a specific acl set on the resource, I imagine that inherited write permissions from the container would apply and satisfy that requirement?

Only the policies including acl:default from the effective ACL are applied. In the absence of acl:default, permission is denied.

@csarven
Copy link
Member

csarven commented Sep 28, 2020

From hierarchical containment and access controls, I believe it follows that agents with acl:Control access on a container have full permission of the resources under its path. The purpose of this is to prevent agents from losing control of a path. The root container (pim:Storage) MUST have an ACL document - required by the inheritance algorithm - and it MUST include a policy with acl:Control access privilege.

I suggest to clarify this in the spec.

@csarven
Copy link
Member

csarven commented Sep 28, 2020

There are use cases to allow creators of resources to have some sense of right to control the lifecycle of their own creations.

In the case with multiple agents having acl:Write access to a container as per acl:default, it allows any agent to modify or delete (especially if acl:Write access is given to the container) others' resources. There is a need to distinguish agents if only the creators of resources should control (alternatively only read-write) them.

I'd like to connect this with #66 , #153 (and issues therein). The commonality is that agents that assign a URI to a resource also control it - who controls can change over time. This also includes the storage - root container (like pim:Storage).

Hence, reconfirming the need to record the creator/owner with respect to access controls. Related: http://www.w3.org/ns/auth/acl#owner.

@michielbdejong
Copy link
Contributor

+1 to revert, i.e. going back to requiring Write on both C and R.

@michielbdejong
Copy link
Contributor

For the record,

agents with acl:Control access on a container have full permission of the resources under its path

That would be a spec change because that's not how Solid work currently.

record the creator/owner with respect to access controls

Also not currently the case, but of course it's something we could introduce in a future spec change.

@bblfish
Copy link
Member

bblfish commented Oct 21, 2020

I summarize this discussion as the result of the following questions:
What does it mean to give write access to a container? Does that not mean the ability to delete the container? If so how would one give someone the ability to edit only certain resources inside the container? (e.g. the ones they created?) without also giving them rights to dele the container? If one gives write access to only a subset of resources in a container, what is to stop someone removing all content from one of them, which is nearly equivalent to a delete? It seems there is a tension between use cases here, that may be resolved in any number of ways.

  1. We may want to add a history of resources so that deleting a resource does not mean removing the history of it (perhaps only making it invisible to certain groups). That could solve Tim's use case: the container owner would continue seeing the ldp:contains relation to the resource (history), and be able from there to see each state of the resource by following links.
  2. The owner of the container could in an ACL make it (somehow) impossible for anyone who does not have write access to the container to get write access to any other resource in it. If this is recognizable then we can also get Tim's requirements, while allowing other containers that permit edits to contained resources too.

In any case we can add use cases such as Tim's above to the WAC use case document. (note: The link in the use case does not work for me)

@csarven
Copy link
Member

csarven commented Oct 22, 2020

So then moving forward with the change: to delete a contained resource, Write required on both the container and the contained resource. Consistent with the rest of the design.


Related changes to be moved separately (with no dependency on what's discussed in this issue):

agents with acl:Control access on a container have full permission of the resources under its path

That would be a spec change because that's not how Solid work currently.

Right that the proposed change would prescribe behaviour that wasn't previously but it will eliminate implementation variation. At the moment, one implementation may allow loss of control of a subpath while another wouldn't. Are there any implementations with the intention where an agent controlling a path would be prevented from ever controlling a subpath because the subpath is being controlled by another agent? Losing control seems counter intuitive and problematic to me.

record the creator/owner with respect to access controls

Also not currently the case, but of course it's something we could introduce in a future spec change.

There are also use cases where servers may not want to record the creator and clients may not want their identity associated (or tracked) with the created resource. For the latter, the client needs to make that request explicit and the server may accept.

@csarven
Copy link
Member

csarven commented Oct 22, 2020

what is to stop someone removing all content from one of them, which is nearly equivalent to a delete?

It may appear to be equivalent in some situations however they are significantly different:

  • Content modification (even if wiped) does not affect the lifecycle of the resource or associated resources (like ACL).
  • When a resource gets deleted, server also deletes associated resources (like ACL).
  • Deleting a resource is normally a concern of URI persistence and associated policies.
  • Reinstating a previously deleted resource with the originally assigned URI may not be possible.

Having Write on a resource is not destructive without also having Write on its container.

@csarven
Copy link
Member

csarven commented Oct 23, 2020

As long as the controllers/owners (acl:owner) of a storage (pim:Storage / root container) can be distinguished from other agents with Control access on the storage (or any part) and owners can maintain their Control access on the whole storage, then it can be possible to allow non-owners to give someone else Control access to a resource. While the Control access giver (other than owners) may lose their Control of a resource and path under, it doesn't interfere with owners maintaining their Control on storage.

As Control access on a resource would only allow read/write access to its ACL, even agents having Control access on /foo/bar will need to have Write access on /foo/ in order to delete /foo/bar. It follows that path structure can be preserved.

@csarven
Copy link
Member

csarven commented Jul 1, 2021

Thanks for this issue and discussion. Closing this issue as consensus is deemed to be captured in WAC Editor's Draft: https://solid.github.io/web-access-control-spec/ . See #authorization-evaluation , #reading-writing-resources , #loss-of-control-mitigation , #access-mode-extensions . Please use https://github.com/solid/web-access-control-spec for future discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Specification
  
Done
Development

No branches or pull requests

9 participants