Open kjetilk opened 2 years ago
https://github.com/solid/specification/issues/235 https://github.com/solid/web-access-control-spec/issues/85
The WAC ED spec in fact already approaches this from the point of operations.
Great work putting this together @kjetilk - this is a really good, thoughtful breakdown. Also very glad that @csarven pointed out https://github.com/solid/web-access-control-spec/issues/85. We're also having similar discussions in the interoperability panel. Lets pick one place to work through this topic (I'm happy to continue it here).
A modify operation MUST NOT change the state of any other resource than the target resource, except when a new resource is created, then the server will change the parent container by adding or removing containment.
I don't believe there's an advantage to having modify encompass create
From the principle of least privilege, it seems, at least intuitively, to be attractive that a modify operation should not include the create operation
+1
Since the delete operation results in a change of state of the parent container, the agent is also required to be authorized to perform the resulting operation on that container, in this case, it needs a Write or Modify access mode on the parent container.
What would be the use of a delete mode if you need another mode to complete a deletion?
Generally I believe that we should try to make any new modes as simple and intuitive as possible, or we run the risk of misinterpretation, which could then end up in rules being created incorrectly, and data being exposed as a consequence. In the simplest terms for me, that would be:
acl:create
on the parentacl:delete
on it, or acl:delete
inherited from the parent (and not overridden on the resource)acl:modify
acl:extend
permission (note: see point below on why this isn't acl:append
related to backwards compatibility)I do appreciate the path to backwards compatibility with existing modes, which to me would be:
acl:write
but deprecate its use, and for a container resource make that equivalent to acl:create
, acl:modify
, and acl:delete
. for a non-container resource make that equivalent to acl:modify
and acl:delete
.acl:append
but deprecate its use. while i think append is the most fitting mode name for this operation, we'd need to determine how we want to reconcile append modes on a container moving forward, since it has also been used for creating child resources. With that context, let acl:append
on a container be equivalent to acl:create
and acl:extend
, and acl:append
on a non-container resource be equivalent to acl:extend
. Note that I wouldn't be totally against changing the behavior of acl:append
to line up with what i'm proposing for acl:extend
- but that would be a non-backwards compatible breaking change - and it would probably be easier on everyone to avoid that.A control operation includes read, create, modify or delete the resource containing a representation of authorizations.
I think we should reconsider need for Control
and any further spin-offs. Besides solid/specification#303 I would also like to point out new use case 2.6.1. Delegating subset of received access to another agent which mentions fact that anyone already effectively can 'share' their access (or restricted subset) if they use any of pretty straight forward approaches based on impersonation. Given that it might be worth to properly support alternative approach based on delegation.
In that case only owner of the storage would have initial implicit right to grant access, any other agent who was granted access by the owner uses delegation chain (preferably with a trail) to further propagate their access.
It seems to me that "Access Control Resource" should be a generic term for any such resource, including WAC's ACL resources and ACP's ACRs. Thus, the latter will have to give that up for the greater good. :-)
Following train of thought is still in it's early stage but I might already bring it up. I think ACR might be an artifact of specific authorization system, like WAC or ACP and different system might manage policies differently.
It might be useful to only focus on common access modes that apply to data in general. If specific authorization system uses ACRs, it could define additional modes specific to that system. Later when resource server (storage) needs to allow/disallow operation on ACR, authorization system would provide it with common access mode that should be applied to that ACR, only using any additional access mode internally to the authorization system itself.
I like the diagram with top level concepts and subconcepts below them. It helps a lot.
First it identifies two main interaction types: Read
and Write
. I think we have definitively very very strong mathematical underpinnings for those interactions as being fundamental. The mathematics of dynamical systems are based on two types of functions on a state S.
get: S -> A
put: S -> A -> S
which from a state and a value returns a new state.This was found in the 1990ies as part of the work on Caolgebras, such as Bart Jacobs' Objects and Classes Coalgebraically. Later Functional Programming rediscovered this as Lenses which are Monadic versions of the above. And recent mathematical work shows that these fall into a general conception of lenses which can model dynamical systems. For many more resources see this twitter thread. Note that these polynomials are essentially also essentially composed of getters and setters.
So Read
and Write
is I am pretty sure set in stone.
Control
is something completely different, which should not be there along side those two other modes. For one it is not needed, which gives a pretty big clue :-)
Secondly control in the space of access control was introduced by Abadi, Burrows and Needham around 1990 with A Calculus for Access Control in Distributed Systems where A controls p
is a short for if A says p then p
. That is why I think it is actually better modelled as being the Link: <doc.acl>; rel="acl"
header. Arguable that should be "controlledBy" .
I am writing up the mathematical ideas on this on the web-cats issue 28.
Thank for the thoughtful responses!
I will need to write a more lengthy discussion later, but let me just briefly touch on the topic of permissions on the container for deleting a resource, that stems from a general principle that I think is important:
If a resource changes state, that is an operation that should always be subject to authorization. No state changes without authorization. I think that principle makes it clearer for server implementors, but I realize there is a cost. Moreover, with the introduction of a audit log, for example, the idea got into trouble, because the client would certainly not have append permission on the audit log.
After I posted this, I started to think that perhaps the authorization doesn't need to be on the client, as the state change on the container is done by the server. Perhaps we instead should ensure that the server is an agent, and that that agent needs to have Modify permission on the container to delete a resource. But that creates another cost; to delete, the server will first need to check the authorization of the client on the resource, and then the authorization of the server on the container, and fail the client request unless both are in place.
It may seem contrived, but it isn't given that the server has authority to change a resource. If we introduce end-to-end crypto, the server will only see the state changes, it will not see a representation, and so to change the representation, it would need to have authorization to access the keys to do so.
In the trivial cases, however, this would reduce to a more familiar situation, the server will carry default access rules that gives it Modify on all server-managed resources, and the client will only need Delete on the resource to actually delete it.
If we introduce end-to-end crypto, the server will only see the state changes, it will not see a representation, and so to change the representation, it would need to have authorization to access the keys to do so.
I think in this case containment triples would need to be separated from the description of the container. I actually like this approach for more reasons than just end-to-end crypto. Resource with containment statements would be considered Server Managed. It might be better to discuss it in separate issue, for the sake of this issue I just don't think we have to box ourselves in by making assumption that containment triples couldn't be managed in a separate (SM) resource.
@elf-pavlik :
It might be better to discuss it in separate issue, for the sake of this issue I just don't think we have to box ourselves in by making assumption that containment triples couldn't be managed in a separate (SM) resource.
I have to disagree with that. This issue is for what we can have in the Protocol in the short term, it is not for a complete green-field design. For now, containment triples are where they are, in the representation of the container. There is a difficult balance between what we think in the long term, and what can be achieved in the short term to make truly useful stuff for people right now. I'm trying to be conscious about not cutting off future directions and enabling creativity and to allow possible upgrade paths. We may find an upgrade path from containment triples represented in the container to something else, but for the purpose of formulating operations in the Protocol, I strongly suspect moving the containment triples elsewhere isn't position that is viable in the time frame this has.
The panel is of course free to pursue a broader vision.
And now for the longer discussion :-) I am as indicated rather reluctant to spend much time on issues that are not compatible with "current Solid", but I also feel it is important to have this discussion in this panel to make the ideas and the text that will be written around it more mature, with the objective to open an issue on the specification board that is something that the Solid Editors are likely to accept for inclusion in the Protocol spec RSN.
What we could do is flesh out the opportunity space a bit and then quickly narrow it down to what is likely to be formulated in the Protocol.
It seems to me that WAC originally found a pretty good balance between complexity and the principle of least privilege, especially with the Append access mode, which made it possible to have very limited access to write. An Update access mode without Append would have been much worse in that respect.
It is also worth noting that PUT
is a method that can be used in create, modify and append operations. It makes an awful lot of sense from an implementation perspective when you base something on HTTP to lump these together with a Write access mode, and then put DELETE
into the same group to keep the authorization system simple. Now, a create operation can be distinguished from a modify operation using If-None-Match: *
, we have that in the spec now, but it still shines some appropriate light on that we are designing this from the starting point of a Web technology, not from access control systems.
Also, I don't see the need to deprecate Write, to the contrary, it seems to be very nice to have for a lot of people who just want to do a simple thing and where trust between agents are established through meatspace relationships, but I also think it is worthwhile examining the subsets.
Now, I understand that there are real-world cases where this simplicity is not sufficient, so we need to talk about extensions. We could in principle have something like:
Here, Update and Extend is similar to Modify and Append but cannot be used to create new resources.
That would retain the semantics of WAC and so backwards compatibility, but also add the stuff that's desired. I'm not saying that this is what should come out of this discussion, I believe something has to be cut from this diagram. The question is what.
The issue of Control is very interesting, and but I believe we should treat it as a separate issue, through 303.
I think it might be easier to discuss access modes in one issue. Since we seem to converge on spec defining mapping between access modes returned from authorization system (WAC, ACP, etc.) to server operations we could just transfer this issue to specification repository already and focus conversation there.
PUT /C/R Create?, Update acl:Write [2][3] Resource
In this case End-user (via Client) doesn't really update the container. They just create new contained resource and the server updates a server managed contained triples. I think Create on the container should be enough here.
I would see it a different case where End-user (via Client) would want to change client managed triple. For example add/change rdfs:label
providing human readable name for the container. This would require Update on the container
since here server isn't the one being in control of making the update.
BTW is there consensus in the spec for PUT that
If-None-Match: *
If-Match: xyz
? (As explained in MDN: Conditional requests )
Myself I would be 👍 for making those together with Etags a requirement.
It may be worth converting this to a Discussions
, as I can see it being quite a branching topic, and then gather the consensus that arises there to form them into some issues that can be voted on.
If I can consider just one topic|: Should DELETE on a resource require rights on the container? I think I can see merit to @justinwb's argument that that may be overly complicated.
Let me try to see how one could have come to that conclusion. Creation of a resource requires rights to the container, either when using POST or when using PUT. That seems to clearly make sense: there can be no other place for a Creation right to be placed, and creating a resource does change the state of the container.
Deleting a resource also changes its container, but that could be considered a server managed effect, along with creating ACRs, logging, etc...
Deleting a resource also changes its container, but that could be considered a server managed effect, along with creating ACRs, logging, etc...
I suggested that Creating a resource changes a container but it's what you called 'server managed effect' as much as when Deleting a resource. Do you see difference in 'server managed effect' of removing containment triple and adding containment triple?
I agree that Create needs to be associated with an existing container, of course it can't mean creating that already existing container itself. At the same time just like Delete I wouldn't see Create requiring Update operation on the container.
In this case End-user (via Client) doesn't really update the container. They just create new contained resource and the server updates a server managed contained triples. I think Create on the container should be enough here.
RFC 7231 describes creating and replacing resource state with PUT. That's analogous to "Create" and "Update" in the table. Create precedes Update.
A PUT request applied to the target resource can have side effects on other resources. For example, an article might have a URI for identifying "the current version" (a resource) that is separate from the URIs identifying each particular version (different resources that at one point shared the same state as the current version resource). A successful PUT request on "the current version" URI might therefore create a new version resource in addition to changing the state of the target resource, and might also cause links to be added between the related resources.
I think this is similar to Creating new resource with PUT
. Adding server managed containment triple on other resource, the container, shouldn't require Update permission on the container. Client doesn't directly do the update and if containment triples have to be added (or removed on Delete
) by the server, giving client permission to Create on a container or Delete on contained resource should already take into account that server will take care of those side effects.
We're now in The Battle of the Bugs! :-) Over here in authz panel, @kjetilk stands firm, over in the other corner, ready to duke it out on the WAC repo, stands @csarven ! ;-D
Anyway, we're drifting from where I was hoping to take us. I feel strongly that we should first talk about the operations that we need to do. Operations are really what clients will perform, and operations are what servers implement. I shall not comply with @csarven 's assertion that it is nitpicking to cry foul over a choice of CRUD, it is not nitpicking, it is the very crux of the matter :-) What operations we have has potentially tremendous implications on people's ability to control access to their data the way they want, especially in light of the principle of least privilege. I think it is well illustrated by the Update operation vs the Append operation, with CRUD, you do not have a way to to have a resource that people can write to, but not to change. This is exactly why it is so important to first understand the implications of operations.
With that, we can add access modes to operations, and then define how operations are implemented. Obviously, it is not a waterfall here, since the protocol can possibly make different operations practically indistinguishable from each other.
BTW, @elf-pavlik : Conditional request are in the spec, so there has been consensus around that, even though ETag
s aren't mandatory in the the RFC.
@bblfish consensus was reached on the delete requires write on container was reached in https://github.com/solid/specification/issues/197 I think to change that, we should see if we can derive it from some greater principle. As I tried to say above, we could introduce the server as an agent in its own right, and so the server could be the agent having Modify on the container, so the client wouldn't need to have their own Modify access mode. That would have the same effect, but still retain the principle that every state change must be authorized.
For example, an article might have a URI for
Cool that you've brought that up because I've actually implemented what's described in that example in dokieli (introduced in 2017) where updating mem:OriginalResource creates a mem:Memento with a rel:latest-version and rel:predecessor-version links..
Adding server managed containment triple on other resource, the container, shouldn't require Update permission on the container.
And? 1) I was talking about operations not permissions. 2) Again, update was about replacing the resource state. I'll quote from that comment:
[2] Requires Append (or Write) on /C/ and Write on /C/R to Create. [3] Requires Write on /C/R to Update.
I think you've also missed my point about create and replace of resource state. For example, creating resource /C/R entails that server could generate a representation for it when requested. A subsequent request to update the resource state with a particular representation replaces what exists.
Now, when /C/R is created, server can give an updated description of /C/ when requested i.e., including /C/R. This is an effect that is described by Solid Protocol - partly borrowed from LDP.
You could continue to "think Create on the container should be enough" but then you're out of luck to update /C/R. Need an Update "permission" in addition so that PUT works. The way you're using that Create permission is equivalent to acl:Append on /C/ which would only work with POST.
@kjetilk Wow, okay. If you actually read the very next sentence:
Happy to switch to use a different variation, RFC terms, or introduce 50 very specific terms.
So, I'm not sure why you feel the need to corner me on this.. as if I'm saying CRUD terms is the only way or if it even maps perfectly to HTTP or WAC's access modes. I'm well aware of what the actual operations are... The Solid Protocol's operations are informed by WAC's access modes in context of HTTP operations. We've authored that together, as you well know.
And the whole https://github.com/solid/web-access-control-spec/issues/85#issuecomment-867556738 -- which predates this issue here -- is an attempt to collect and understand access modes that are under consideration based on common operations.
What I'm actually sensing in this thread is that people are:
If people want super specific operations or access modes or whatever, consider going through the RFCs for the terms and see also the semantics that the Solid Protocol puts on certain types of resources. That's being grounded on an actual range. In parallel, develop and share an actual application that experiments with the proposed/hypothetical. It can look great on paper but why go through that whole exercise if the UI is going to be bloatware or incomprehensible. Not everything is green-field for very good reasons.
I just don't think we have to box ourselves in by making assumption that containment triples couldn't be managed in a separate (SM) resource.
Cool. Will the server you will develop take on that behaviour?
By the way - this is a tangent - here is some "out of the box" thinking: https://github.com/solid/specification/issues/230#issuecomment-774791386 .. note that it mentions:
what introducing pagination does is moves the server-managed triples (like containment statements, whether it is ldp:contains or as:items is besides the point right now) into its own resource eg. /foo/?p=1.
See also implementation in mayktso server and deployment:
curl -iH'Accept: text/turtle' https://linkedresearch.org/inbox/linkedresearch.org/cloud/
curl -iH'Accept: text/turtle' https://linkedresearch.org/inbox/linkedresearch.org/cloud/?p=1
curl -iH'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"' https://linkedresearch.org/inbox/linkedresearch.org/cloud/
curl -iH'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"' https://linkedresearch.org/inbox/linkedresearch.org/cloud/?p=1
it is not for a complete green-field design.
Why not? We are not thinking out of the box enough.. we should perhaps get rid of the whole containers thing which would actually solve a lot of problems..
@kjetilk Wow, okay. If you actually read the very next sentence:
Happy to switch to use a different variation, RFC terms, or introduce 50 very specific terms.
So, I'm not sure why you feel the need to corner me on this..
I tried to frame it in humorous language in an attempt to not make it confrontational. The point that I was trying to make is that I felt that in spite of that disclaimer, it seemed to discount what I thought we agreed on the need to look into the operations as the basis. I'm sorry if it felt like an attack, it was not intended. I guess we are feeling the effects of not having met in person for two years, we are suffering from insufficient emotional bandwidth.
I was thinking about documenting "Remove (to subtract information from resource state)" operation in https://github.com/solid/web-access-control-spec/issues/85#issuecomment-867556738 (recently updated) as complement to the Append operation - more like entertaining the idea what that might entail. It is intended to be content-level. It is certainly possible with for example HTTP PATCH
and SPARQL Update's DELETE
in payload. (Aside: currently we need read to remove information via PATCH but that's beside the point.) The Remove operation is generally covered by the Update operation (add or remove information). I'm not sure if there are compelling use cases where remove-only is needed.
Thinking further, another way to look at this is whether operations are or should be exclusively resource- or content-level operations, or can they be both depending on the request's characteristics. So perhaps that's something we can explore further. I definitely do think we need to tell them apart whether they are used or not. For instance, the Delete operation, depending on what the request entails could be to delete resource - this is the common thinking - or to delete information in resource state (which may be equivalent to the Remove operation above).
@bblfish consensus was reached on the delete requires write on container was reached in solid/specification#197 I think to change that, we should see if we can derive it from some greater principle.
Yesterday I spent a day to implement DELETE
for the lens based server and wrote up the details of it on gitlab issue 28. Essentially I get all of CRUD to work with Lenses (i.e. setters and getters).
The result is that yes, one is changing the container on DELETE
, but one is also changing the state of the whole web server in a way too... So I don't think this is yet helping make a decision about whether DELETE needs rights to the parent container. I think that may become clearer by thinking of the role of the guard.
Still the fact that we can get all of CRUD (and Append by adding monoid actions I think) shows that this is the right mathematical space.
@csarven :
Thinking further, another way to look at this is whether operations are or should be exclusively resource- or content-level operations, or can they be both depending on the request's characteristics.
Indeed, that could be done. I think that the reason why you see these things conflated is that this distinction hasn't been done thus far. I suppose to keep the number of access modes down, which is good for simplicity, but not for avoiding overpermissioning.
I think the most critical tradeoff we have to make is between those two, actually (simplicity and principle of least privilege). Whether we should make the distinction between resource and content-level operations depends on that trade-off, I think.
Just one question: Why does each comment need to be individual resources in the story
container? That seems to be a requirement that isn't motivated from the use case.
The following is a use case that @elf-pavlik and I put together as a basis for this discussion. It is a slight variation of the read-create-delete use case. The main adjustment is illustrates a case where the graph of a given container would have specific access requirements.
Alice has a short story that she's recently authored and shared with her colleagues, whom she has asked to leave comments about what they did and didn't like about the story.
The content of the short story is stored in a story
collection resource, and each comment that her colleagues submit are stored as an individual resource inside the story
collection.
Any member of her colleagues
group must have the ability to:
story
and list of commentsstory
collectionAny member of her colleagues
group must not have the ability to:
@kjetilk only the creator of the comment can update and delete their own comment.
@kjetilk only the creator of the comment can update and delete their own comment.
Of course. But I don't understand why there is a requirement that the comments are all in the same container. That seems artificial.
To add further understanding, this is a use cases that has been discussed for very many years, and there has been broad agreement that users should write to their own pod, and then notify the story pod. Before Inrupt, I was doing a startup that didn't get off the ground, but we put this up two news-papers that saw their comment sections descending into flamewars, it would be much better if they didn't publish the comments, but received notifications and then automatically or through editorial decision decided which comments to display and thus promote.
In many cases, you don't have that problem, but still, it would usually simplify access control if you put a user's comments into a container of their own. It is important to not overcomplicate things here by needless requirements.
FYI, re "creator", there's been existing work, e.g., https://github.com/solid/solid/issues/111 , 2016 A.D. (if not earlier), and afterwards. There are loads of existing issues on creator, owner... and reminders of it:
https://github.com/solid/specification/issues/197#issuecomment-699942808
and even existing http://www.w3.org/ns/auth/acl#owner for years:
owner a rdf:Property;
rdfs:label "owner"@en;
rdfs:range foaf:Agent;
rdfs:comment """The person or other agent which owns this.
For example, the owner of a file in a filesystem.
There is a sense of right to control. Typically defaults to the agent who craeted
something but can be changed.""".
(the current solid:owner
was informed by acl:owner
)
and perhaps most recent discussion on the possibility of distinguishing the "owner" (=creator) of a resource from the owner of a storage:
https://github.com/solid/specification/issues/265#issuecomment-874704696
Creator, owner stuff should remain in Protocol level -- think audit logs, provenance records, data privacy,... for broad use, not just authorization.
Related:
https://solid.github.io/web-access-control-spec/#consider-acl-resource-activities
Implementations are encouraged to use mechanisms to record activities about ACL resources for the purpose of accountability and integrity, e.g., by having audit trails, notification of changes, reasons for change, preserving provenance information.
https://solid.github.io/web-access-control-spec/#consider-provenance-accountability
Implementations that want to allow a class of write or control operations on resources are encouraged to require agents to be authenticated, e.g., for purposes of provenance or accountability.
and yes,.. there existing standards to meet these..
But we'll probably find a way to reinvent /s
In many cases, you don't have that problem, but still, it would usually simplify access control if you put a user's comments into a container of their own. It is important to not overcomplicate things here by needless requirements.
I'm not sure that understand it, do you suggest that we shouldn't use a container to store any client-managed statement and be able to access control them independently from access controlling creating and/or deleting contained resources?
In many cases, you don't have that problem, but still, it would usually simplify access control if you put a user's comments into a container of their own. It is important to not overcomplicate things here by needless requirements.
I'm not sure that understand it, do you suggest that we shouldn't use a container to store any client-managed statement and be able to access control them independently from access controlling creating and/or deleting contained resources?
Not at all. I essentially only suggest that there is no requirement for the comments in your scenario to be stored in the container of the story. If you drop that requirement, all is good.
This scenario just illustrates something. If we would just have an rdf:label
on the container and would just want to allow colleagues to create new comments, update and/or delete a comment if they created it but not change the rdf:label
on the container, can we support that?
This scenario just illustrates something. If we would just have an
rdf:label
on the container and would just want to allow colleagues to create new comments, update and/or delete a comment if they created it but not change therdf:label
on the container, can we support that?
Yup. You would simply create a container per user, and let them store their comments in there. That'll be a general pattern to follow, I suppose. It is important not to introduce arbitrary requirements that just complicates things.
I think we should really have moved this topic to github discussions as that supports threading. Discussions here become impossible to follow quite quickly, or very tedious to do so.
@kjetilk
Yup. You would simply create a container per user, and let them store their comments in there.
I think there is a good use case for comments on blog posts, where one wants one container for all comments. The space of agents that can comment could be very large and having a container per user, where each user would only have perhaps one entry, seems very much overkill.
Users could either POST their content to the comments container directly, or POST a link to content on their own pod, blockchain or whatever.
The use case that the a person may later want to delete that statement makes sense, and so does it make sense that a user should only be allowed to delete their own content but not anyone else's; be that content a chunk of html or a link to content elsewhere.
Yup. You would simply create a container per user, and let them store their comments in there.
Who exactly would create that? If Alice - in this scenario not only does she need to manage access control rules, but now she needs to manage a hierarchy and give special rights to each container. If the individual colleague, then we have the same problem in the original case (the ability to create or delete resources you create, and only read others). This also wouldn't work if the "group" of users is represented by a general credential (e.g. colleague), and so you don't have advanced knowledge of their individual identity.
It is important not to introduce arbitrary requirements that just complicates things.
Creating a container in advance per colleague for their comments seems like an arbitrary requirement that complicates things 🙂 😉
and there has been broad agreement that users should write to their own pod, and then notify the story pod
That is one pattern, but not the only one (as @bblfish points out). Our job is to provide something flexible so the appropriate pattern can be used for the appropriate scenario. Just because one might be legitimate does not render the others illegitimate.
I really would like to understand what problems do you see with defining Create
and Delete
for contained elements in a way that it doesn't include access to Update
client-managed triples of the container. Does it relate to the side effect, where the server manages adding/removing containment triples?
github discussions as that supports threading
Not really. One level of thread depth is insufficient for even basic "discussions". GitHub could have bolted on NNTP, phpBB, LiveJournal, or any of many other possibilities, to better results.
As they stand, GitHub Discussions are worse than Issues, because you can't get a straight time-series view of posts (for those of us who just want to see all the comments made since the last time we looked at that Discussion); and comments are either "primary" on the initial post or "secondary" on one of those "primary" comments — there's no third-level for subsequent branching.
Yay, Microsoft UX... bleah
Trying to refocus on the initial post:
Delete operation
A delete operation removes the representation of the target resource.
State changes in existing resources
A delete operation changes the state of the target resource and the parent container.
Implementation
As defined.
Access Mode
To execute a delete operation, an agent is required to be authorized with a Delete or Write access mode on the target resource. Since the delete operation results in a change of state of the parent container, the agent is also required to be authorized to perform the resulting operation on that container, in this case, it needs a Write or Modify access mode on the parent container. Delete is an access mode that is a subset of Write. It is mutually exclusive with Modify.
I would like to focus specifically on:
Since the delete operation results in a change of state of the parent container, the agent is also required to be authorized to perform the resulting operation on that container, in this case, it needs a Write or Modify access mode on the parent container.
In the case of Delete, the client doesn't change client-managed triples in the parent container. The server updates server-managed triples in the parent container. I would like to propose that if an agent has Delete right on the resource, they DO NOT need any rights on parent container.
If we manage to resolve that it should be easier to dive into nuances of Create.
In the case of Delete, the client doesn't change client-managed triples in the parent container. The server updates server-managed triples in the parent container. I would like to propose that if an agent has Delete right on the resource, they DO NOT need any rights on parent container.
As @csarven noted, this has recently been decided with the opposite conclusion, and I think we should not just re-open issues all the time.
However, there is a possible compromise: If we see the server as an Agent, then we might say that it is sufficient for the server to have a Modify access mode on the container.
That would have the effect that the client doesn't need to have it (but it could) and so have the same practical effect, and still be consistent with the principle that no state change should be unauthorized.
As @csarven noted, this has recently been decided with the opposite conclusion, and I think we should not just re-open issues all the time.
That issue was specific to WAC. That decision should be input to these discussions, but we shouldn't assume it is settled when the purpose of the panel is to learn from and improve upon shortcomings in WAC and Solid access control in general.
However, there is a possible compromise: If we see the server as an Agent, then we might say that it is sufficient for the server to have a Modify access mode on the container.
If that was an implicit understanding (meaning access control statements don't have to be created to specify this) then I suppose it would be OK to document this as the rationale. Otherwise I'd worry that we run the risk of confusing people when they're managing their access control statements.
However, there is a possible compromise: If we see the server as an Agent, then we might say that it is sufficient for the server to have a Modify access mode on the container.
If that was an implicit understanding (meaning access control statements don't have to be created to specify this) then I suppose it would be OK to document this as the rationale.
I also think this should be implied for the server, otherwise, it simply wouldn't be able to do its job. I would also note that the server is enforcing access policies. Allowing to delete contained resources but not allowing the server to take care of the side effect (removing server-managed containment triple) sounds to me like a self-contradicting policy.
github discussions as that supports threading
Not really. One level of thread depth is insufficient for even basic "discussions". GitHub could have bolted on NNTP, phpBB, LiveJournal, or any of many other possibilities, to better results.
As they stand, GitHub Discussions are worse than Issues, because you can't get a straight time-series view of posts (for those of us who just want to see all the comments made since the last time we looked at that Discussion); and comments are either "primary" on the initial post or "secondary" on one of those "primary" comments — there's no third-level for subsequent branching.
Yay, Microsoft UX... bleah
Just one layer of threading makes it better than the 0 level of discussions we have here. So let the perfect not be the enemy of a little improvement.
Btw. Github discussions went out of beta yesterday, so perhaps we should at least try to see what's new https://twitter.com/github/status/1440723610553884672
I opened a discussions on giving rights to the creator of a resource to see how one would need to deal with that part of the use case brought up above. (waiting to see what the new discussions may look like when someone enables it)
As @csarven noted, this has recently been decided with the opposite conclusion, and I think we should not just re-open issues all the time.
That issue was specific to WAC. That decision should be input to these discussions, but we shouldn't assume it is settled when the purpose of the panel is to learn from and improve upon shortcomings in WAC and Solid access control in general.
There was very little in that discussion that was specific to WAC. Essentially, the comment that turned the discussion was @timbl 's argument that "if I remove Write access to something it won't change." and that is not a WAC-specific argument, it is a general argument about the understanding of the role of access control in Solid.
However, there is a possible compromise: If we see the server as an Agent, then we might say that it is sufficient for the server to have a Modify access mode on the container.
If that was an implicit understanding (meaning access control statements don't have to be created to specify this) then I suppose it would be OK to document this as the rationale. Otherwise I'd worry that we run the risk of confusing people when they're managing their access control statements.
I think the statements would have to be explicit, because if we are to have a system that satisfies @timbl 's argument above, then you need to know whether something can perform a write operation on a resource. However, giving the server modify on all resources could be something done as a matter of configuration, and it could be left open how it is changed.
I think we should have a more principled approach to this. I think @timbl 's statement is also embodied in the principle that "no state change can happen without authorization". Can we agree on such a principle?
We need think ahead too, say that we introduce end-to-end encryption that makes it impossible for the server to modify a resource without authorization. We need to have robust principles that take such scenarios into account, even though they may be more more remote than the use cases we discuss on a daily basis.
I think the statements would have to be explicit, because if we are to have a system that satisfies @timbl 's argument above, then you need to know whether something can perform a write operation on a resource. However, giving the server modify on all resources could be something done as a matter of configuration, and it could be left open how it is changed.
Since that would allow the conforming server not to be authorized to change containment triples, it would not be able to conform to LDP Container requirements. Wouldn't we need to make those requirements conditional?
4.2 Resource Containment
[...] The representation and behaviour of containers in Solid corresponds to LDP Basic Container and MUST be supported.
I seems that server not authorized to update containment statements would stop to be conformant.
5.2 Container
[...]
5.2.3 HTTP POST
[...] 5.2.3.2 When a successful HTTP POST request to a LDPC results in the creation of a LDPR, a containment triple MUST be added to the state of the LDPC whose subject is the LDPC URI, whose predicate is ldp:contains and whose object is the URI for the newly created document (LDPR). [...]
Since that would allow the conforming server not to be authorized to change containment triples, it would not be able to conform to LDP Container requirements. Wouldn't we need to make those requirements conditional?
5.2 Container
[...]
5.2.3 HTTP POST
[...] 5.2.3.2 When a successful HTTP POST request to a LDPC results in the creation of a LDPR, a containment triple MUST be added to the state of the LDPC whose subject is the LDPC URI, whose predicate is ldp:contains and whose object is the URI for the newly created document (LDPR). [...]
My emphasis. The request would not be successful, it would have been denied with a 403
, so it would still be compliant with LDP.
In order to help the process along I have opened a discussion giving rights to the creator of a resource to find out how one could create a rule that would satisfy @justinwb and @elf-pavlik's use cases above.
I offered the following way to encode it in WAC+n3
{ ?i a foaf:Agent } => {
[] a :Authorization;
:accessToClass [
a owl:Restriction;
owl:onProperty iana:author
owl:hasValue ?i ];
:mode :Write;
:agent ?i
}
Given this we can look at Delete
and Create
modes, whilst keeping the use cases proposed.
My emphasis. The request would not be successful, it would have been denied with a
403
, so it would still be compliant with LDP.
I find it problematic that the access mode on a given resource doesn't have an unambiguous mapping to operations that can be performed on that resource. So to know if resource R contained in container C can be deleted one needs to take into account access mode to container C.
As I mentioned during the last meeting, in the interop panel we need to communicate to an agent who receives access, what they can access, and what operations they can perform (or modes that map to operations). If we think of an access matrix below WAC / ACP collapses it on resources why Data Grants collapse the same access matrix on the Agent (user)
We actually quite heavily rely on granting user access to create/update/delete resources in the container but not updating the client-managed triples in the container itself. Of course, the server can still manage the containment triples.
I'd like to see if we can define unambiguous operations on a single resource and see how authorization systems can construct policies using those granular operations. At the same time authorization system would need to ensure that policy is consistent. So if we follow the example we discussed, if resource R in container C has Delete operation allowed to any agent, the container C itself must have Remove containment triple operation allowed to the server itself. Otherwise, the policy would be inconsistent and the authorization system doesn't do its job.
I think having those very granular operations should be enough on the protocol level for authorizations systems to build some higher-level ways to express policies, which can include more abstract access modes. Once again, the authorization system would stay responsible that applied policies stay consistent.
It is welcome that the authorization-panel wants to propose that the protocol needs to define the access modes in a universal way. It has been on my agenda for a while to propose it, as it is important to ease the tensions between the authorization systems.
I have read Authorization UCR and I note that its access modes definitions are incompatible with WAC, and so with Solid as currently defined. I take it as a requirement that the Protocol must be compatible with WAC as defined, and I believe my this thinking does that, as well as satisfies the panel's requirements. I propose a structure where certain access modes grant rights that are a strict subset of others.
However, for the purpose of the Protocol spec, I suggest that we define in terms of operations rather than access modes, and then attach access modes to operations. It is understood that the requirements in the following are on the server, in case I don't include that in every sentence. Thus, there isn't a one-to-one correspondence between the work of this panel and my suggestion, mine is more constrained by Solid as currently defined.
So, here are some ideas for discussion:
Read operation
The server MUST return a representation of the target resource as a response to a read operation.
State changes in existing resources
The server MUST NOT change the state of any resource as a result of a read operation.
Implementation
A request MUST use
GET
,HEAD
orOPTIONS
for read operations, as defined.Access Mode
To execute a read operation, an agent is required to be authorized with a Read access mode. Read is a top level access mode, mutually exclusive with Write and Control.
List operation
State changes in existing resources
A list operation MUST NOT change the state of any resource.
Implementation
To confirm the existence of a resource, the server MUST respond with a
204
.A server implementing this access mode MUST also implement the Prefer Request Header of LDP. A client requests a list operation by using the
include
parameter with a value ofhttp://www.w3.org/ns/ldp#PreferContainment
. A server MUST respond with403
if the header is not present and the requesting agent has List permission.Issue: The
Expect
header is possibly closer to what we want here, and it could be defined analogous to thePrefer
header.Access Mode
List (aka File Scan) is an access mode that is a subset of Read that allows only list operations to be executed.
Write operation
A Write operation MAY make any change to the target resource. The server MAY perform validation and filtering steps on the request. As a result of a write operation, the server will change the parent container by adding or removing containment.
State changes in existing resources
A write operation may change the state of the target resource or its parent container.
Implementation
PUT
,PATCH
,POST
as defined.Access Mode
To execute a write operation, an agent is required to be authorized with a Write access mode on the target resource. If the write operation results in a change of state of the parent container, the agent is also required to be authorized to perform the resulting operation on that container. Write is a top level access mode, mutually exclusive with Read and Control.
Modify operation
State changes in existing resources
A modify operation MUST NOT change the state of any other resource than the target resource, except when a new resource is created, then the server will change the parent container by adding or removing containment.
Implementation
Mostly as defined.
Access Mode
To execute a modify operation, an agent is required to be authorized with a Modify or Write access mode on the target resource. If the modify operation results in a change of state of the parent container, the agent is also required to be authorized to perform the resulting operation on that container. Modify is an access mode that is a subset of Write. It is mutually exclusive with Delete.
Append operation
State changes in existing resources
An append operation MUST NOT change the state of any other resource than the target resource, except when a new resource is created, then the server will change the parent container adding containment.
Implementation
The special characteristics of append operations aren't well defined currently, it would need to be improved in a separate effort.
Access Mode
To execute an append operation, an agent is required to be authorized with a Append, Modify or Write access mode on the target resource. If the modify operation results in a change of state of the parent container, the agent is also required to be authorized to perform the resulting operation on that container. Append is an access mode that is a subset of Modify.
Create operation
State changes in existing resources
Changes the state of the parent container.
Implementation
As defined
It is an error to attempt a create operation on an existing non-container resource (in practice, this would currently not happen, since the server can't in such cases distinguish a create operation from a modify operation).
Access Mode
To execute a create operation, an agent is required to be authorized with a Create, Append, Modify or Write access mode on target resource if it is an existing container, or on the parent container if it does not. Append is an access mode that is a subset of Modify.
Delete operation
A delete operation removes the representation of the target resource.
State changes in existing resources
A delete operation changes the state of the target resource and the parent container.
Implementation
As defined.
Access Mode
To execute a delete operation, an agent is required to be authorized with a Delete or Write access mode on the target resource. Since the delete operation results in a change of state of the parent container, the agent is also required to be authorized to perform the resulting operation on that container, in this case, it needs a Write or Modify access mode on the parent container. Delete is an access mode that is a subset of Write. It is mutually exclusive with Modify.
Control operation
A control operation includes read, create, modify or delete the resource containing a representation of authorizations.
State changes in existing resources
A control operation only changes the state of the target resource.
Implementation
As defined.
Access Mode
To execute a control operation, an agent is required to be authorized with a Control access mode on the target resource. Control is a top level access mode, mutually exclusive with Write and Read.
Read Permissions operation
A read permissions operation can read the resource containing a representation of authorizations.
State changes in existing resources
A read permissions operation MUST NOT change the state of any resource.
Implementation
GET
on a access control resource.Access Mode
To execute a read permissions operation, an agent is required to be authorized with a ReadPermissions access mode. ReadPermissions is an access mode that is a subset of Control.
Some considerations
Minimal requirement on a Solid Server
We need to determine which access modes MUST be supported by a Solid server. WAC's set of Read, Write, Append and Control seems like a good starting point, with the rest defined to be MAY.
Break compatibility by disallowing append to create resources?
From the principle of least privilege, it seems, at least intuitively, to be attractive that a modify operation should not include the create operation, and so more a hierarchy like this:
It is however clear that the append operation is a subset of the modify operation and so that would break the current definition of the Append access mode. Moreover, if we keep WACs current access modes as the minimum, it would mean that you'd need Write to create a resource, which is also not good seen from the principle of least privilege.
Linking and propagation of access control
Control may need to change the state of many other resources depending on the outcome of current work regarding propagation and/or linking of resources to their access controls. This is a breaking change relative to current Solid. In general, I'm a bit divided on what we should do about the impact of state changes done as a side effect by the server.
Definition of terms
It seems to me that "Access Control Resource" should be a generic term for any such resource, including WAC's ACL resources and ACP's ACRs. Thus, the latter will have to give that up for the greater good. :-)
Audit logs, etc
At some point, I'd like to see an auxiliary resource that is an audit log, in which case all operations may append to the audit log, and so all methods would be changing the state of that resource as a side effect. This would then need to be added.
No corresponding WritePermission
Offhand, I couldn't see a use case for a corresponding WritePermission or AppendPermission. It seems that you would always need to read the authorizations to be able to change them meaningfully, and therefore, I didn't put in an analog. I also acknowledge the interesting idea in https://github.com/solid/specification/issues/303 .
Operations discussions
There have been similar discussions in the protocol, notably a series of issues https://github.com/solid/specification/issues/126 , https://github.com/solid/specification/issues/149 , https://github.com/solid/specification/issues/165 and https://github.com/solid/specification/issues/118
I have also felt that the protocol needs an editorial overhaul that should make it easier for others to reference it. My thinking is that an emphasis on various operations should do that.