Complex permissions: a real use case we struggle to cover with ACLs and the current state of Solid standards



A common use case we struggle to implement with WebACL permissions is the “Follow” or “Like” use case, where a user has the Acl:Add permission on a container to add herself to the list of followers / likers, but not to add other users to the list of followers / likers.

What we are doing at the moment to implement such features is a mixed of Acl:Add permission on the container of followers / likers plus a custom “Agent” triggered on the server side that does the additional checks on the request on that container before letting it pass.

The problem is that the “Agent” part is totally custom, or totally not Solid standard compliant. We declared it nowhere, the front end app doesn’t know it exists, we just have it so that the server does respond accurately to the use case.

Any insight about the right way to implement such a use case? What’s the elegant Solid way for that?

PS : If you want some background, see the initial issue here. Don’t believe what they are saying about SM groups, they are lying.

I want to understand linked data and turtle

Rather than storing all likers in a container and giving everyone permission to add themselves to it, maybe each person needs an account container that only they have permission to access. A notification mechanism could append each like to the thing liked. This way Alice’s like of Bob’s photo lives in Alice’s pod while Bob’s photo and a list of who likes it lives in Bob’s pod.


@jeffz: Thanks for that answer.

If built that way, which makes a lot of sense, how do I display my list of followers, or my counter of likes?

Also, how do I know which one of the “Likes” you stored on your profile is the right one. I allow only one per sextape, but you added 153 on you profile. How do I handle that?

Also, you are saying you are a member of my “Very intimate and closed group”, which is private and impossible to get in. Why should I trust you?


Bob’s photo or his blog or whatever has an ACL that defines who has access. If Alice has access, she can click on a like button which will place her like in her own pod and a notification in Bob’s pod that Alice likes that photo. When Bob’s blog is loaded, the app checks the like-list on Bob’s pod and either automatically verifies by checking with read-only access in Alice’s pod or links to Alice’s pod and lets users verify manually if they care to. If Alice does not have “like” access to Bob’s photo, she can state on her own pod that she likes the photo but that would have no impact on Bob’s pod. There would be a single triple on Alice’s pod of the form “:Alice :likes :BobsPhoto13.” If that triple occurs 153 times, it doesn’t impact thte truthiness of the triple.

P.S. I’m just thinking off the top of my head here,


I like your idea, but there is still something I’m wondering if it is possible:

If I (Alice) send a notification to Bobs pod which looks like this: -> like ->
myLike -> storedAt ->

Can an app verify, that the stored like (.../like.ttl) belongs to Alice? In other words, can an app verify, that the data location ( belongs to the webId? If not one could also pretend to be any other webId this way.


Good question @A_A. I guess Bob’s ACL would specify a webId for Alice when it gives her permission to like Bob’s photo. Alice would need to be using that webId when she performed the like so the like would get deposited in the account associated with the webId and the notification would also point to that account. It may not be the “real” Alice who owns that account, but that’s also true of any permission given to any webId.


Ok, I think now I get what you mean. So for every possible follower a unique file/folder is created where only this user has Write Access to. This limits the use case a bit imo, as it requires white-listing and also unused storage space. I think there should be a way to do it more easily.

Something I thought about (which is definitely not easier, just want to note it), is that RSA could also be used to sign likes on other pods. If Alice wants to like a picture of Bob, she can send a like which is signed with her private key, and Bob (or any other user) can verify the like by getting the public key of Alice’s profile. This would require some standard location (or finding algorithm) of a public key in a pod. The benefit of this would be, that it doesn’t require a white-listing and no storage for folders for all possible followers.

Illustration from wikipedia


Good discussion. I see at least 3 topics in this thread and would like to give my comments for each:

1. About nonrepudiation
@A_A has a good point to utilize asymmetric encryption (eg. RSA) to prove the action is really came from Alice. Meanwhile, the same tactic can also be used for the origin question: It actually doesn’t matter who sends the request to update Bob’s photo POD, as long as the like has a valid signature, it should be added to Bob’s POD. Say Carl also liked Bob’s photo, he can generate a message: m = f("like", <uri_photo>, <carl_private_key>). No matter m is sent by Alice or Carl or anybody else, Bob (or anyone else) can always verify with Carl’s public key to see if Carl really did that like. Therefore, Bob’s Acl:add permission for likers can always be public without complex permission control.
However, this requires an extra PKI system, which is not part of the existing ACL. So @alex.bourlier still needs his agent.

2. About ACL
As far as I read, it looks like ACL only focuses on document/containers. It forces developers to carefully design the hierarchies, decide what triple should be put to which path, introducing complex permission settings.
Solid/SemanticWeb is knowledge-based. I would say a knowledge-oriented access control would be more reasonable. This means no matter where the triple is placed, as long as it matches a certain SPARQL, it has the permission setting like Bala Bala… This would provide a lot of flexibility for developers to design their systems, merge RDF files, and manage accesses.

3. About multi-copy states
Agree with @jeffz. It’s the last thing you want to do to maintain one state in multiple places, especially with various access settings. Think about if the notification failed to sync, or Alice replaced her like with dislike in her own POD, or the system allows multiple likes… a lot of trouble would happen. Depended on system design, the like status can be stored in either Alice or Bob’s POD. Meanwhile, the other POD should only record the event (Alice, interacted, bob_photo) as a reference to the state POD. Whoever wants more details should go to the state POD for checking.


she can click on a like button which will place her like in her own pod and a notification in Bob’s pod that Alice likes that photo

We are facing the same question I was asking here : how is the notification system declared?
I assume you have an “Agent” running on your Pod saying: when A likes B, I notify B she it was liked by A.
But how do you declare such mecanism?
Is it you frontend application which declares it? Is it you Pod?
Is there a standard for this kind of Agents declaration or is it just custom code running like in the old days of 2019?

Can an app verify, that the stored like (…/like.ttl) belongs to Alice? In other words, can an app verify, that the data location ( belongs to the webId? If not one could also pretend to be any other webId this way.

Yes it can:


I’m not sure if this is what I asked about. So, given a webId, I can discover the oicd issuer. But (if I’m not mistaken) this does not verify, that resource xyz belongs to this webId.


I think you asked:

can an app verify, that the data location ( ) belongs to the webId?

And I believe that comes down to saying: is on Alice’s WebID somewhere?
And before that: is the WebID I am presented with a legit one for Alice?
Hence, the piece of spec I shared.

I might very well have missed a part though, but I believe I didn’t.


I still don’t see how we could check this.

Lets say, Alice made her webId with and stores her data on (in our case As Bob I can verify, that Alices webId is authorised by But how can I verify, that resources in her pod (eg belong to her webId? This last step I do not understand yet.


The Document at the WebID could point to to signify that that file is owned and blessed by the WebID’s owner, no?

(Alternatively, commonly a WebID points to a Public Type Index, and the Public Type Index in turn points to a file that contains Likes.)


The problem is, that this could easily be faked. For instance Rob could also point from his webId to I can’t think of a mechanism which could prevents this. It would need to be pointing in both directions, from the storage location (ie to the webId and from the webId to the storage location to verify that it belongs to the webId.


Right, but if Rob were to point from his WebID to, all that would claim is that Rob likes the exact same thing Alice likes, right? (Which I don’t think is a problem?) Additionally, that would give Alice (or whoever has control access over the ability to claim that Rob likes additional things, so there isn’t really incentive for Rob to do that.


Yeah, you’re right. I got the directions wrong in my previous comment.

If we assume, that each pod is only used by one webId, we could check Alice’s profile file for a triple and verify it that way. If we take into account, that a pod could be written to by multiple users, we should use more specific pointers to the storage.


UP :slight_smile:

I still think my question went unanswered :slight_smile:


Sorry, I’m just trying to understand and hopefully you don’t mind my asking. Otto, you say

"So for every possible follower a unique file/folder is created where only this user has Write Access to. "

But I don’t understand why Bob couldn’t just keep all the likes or followers in one file and the app would ask him to add Alice to the whitelist, and then Bob would give Alice append only (but not write, read or control) access to that file. It would be appended if it’s not already there.

Then Bob would use whatever webId and storage pointer Alice gave him. If Alice mistakenly gives a storage pointer to someone else’s pod that she has access to, then that pod owner would have to ban Alice (and/or ban the app).

Ok, I think I see now, maybe how Bob adds Alice to the whitelist is the problem?..Maybe Alice could append to another append only file which is public append only and would be ‘requests to like/follow’, or maybe more accurately, “requests for me to advertise your likes/follows regarding my blog”. Then Bob would have to go in at his convenience, and possibly with a different app, to add Alice to the whitelist on the like/follow file.


Lets say Bob writes a blog post, and Alice, Charlie and Delta are allowed to like it (ie, they are already whitelisted). Alice appends to the like file something like “Alice liked this”. Works fine. But what if Charlie appends “Delta liked this”. Now the problem is, how could we know that Charlie did this and not Delta? How can we prevent this? This is the problem the OP stated (as far as I understood it).

If we have one file per user, Alice could add her like to e.g. likes/alice/likes.ttl. Charlie could add it to likes/charlie/likes.ttl but due to acl restrictions not to likes/delta/likes.ttl. Therefore this should be safe, with the cost of requiring additional space.

@alex.bourlier I think there is no perfect solution as of now, but the scenario as described above works at least in my thoughts. Also the one with the pointers in two directions should work (ie, Alice appends a like to Bobs pod which points to a turtle file on her pod to verify the origin) but is likely more error prone and bandwidth heavy. If you want to get a better solution, maybe bring it up in a panel?


I guess that this would work, but it requires more manual work than most people want to do…? Imagine a FB where everyone could add a like to an image pretending to be their friend. I don’t think anybody would want to check on that all the time. Also it would be interesting how/if this has a solution without whitelisting, allowing everyone to like something.