How a SOLID app can have persistent access to all the pods of the users who registered to the app?

I have a server application, where a user can register and create a list of favorite places.
This user can invite friends to see his favorite places. Let’s call it PlaceBook.

First time a user connects to the app, he logs though his solid POD WebId, and authorizes PlaceBook to read and write his pod.

For all subsequent connections to PlaceBook, the user is no more asked if he authorizes PlaceBook to access his pod, because authorization is already given, and stored in the user POD.

First question : how does the SOLID Pod know that the request is from an authorized app ? just by checking the url referrer ? is this safe (meaning : can’t the url referrer tampered with ?) ?

So any time the user creates a new places, through PlaceBook, PlaceBook creates this place in the user pod, which it is authorized to.

With one user, all is still pretty clear. Now with several users :

I am user B. Through PlaceBook, user A has invited me as one of his friends. This means, inside PlaceBook, that user B can see the places visited by user A.

When user B connects through PlaceBook, it authorizes PlaceBook to access his pod. But also : user B wants to see the list of his friends (ok) and also the list of places visited by his friends. The list of places visited by user B ‘s friends are stored in the friends PODs, which is ok because PlaceBook has access to them (as they are part of PlaceBook and gave authorization).

Therefore : I am connected as user B, and PlaceBook with access files in user A’s POD. How this work ? Just because PlaceBook will emit an http request to user A’s pod and this request is coming from a authorized url ? or is there any certificate / token to be used as well ? and if so : is this certificate / token unique for PlaceBook as an App Token, or there will be one certificate / token for every actual user of the app ? which means that the first time a user connects to PlaceBook and authorizes access, PlaceBook should store this user token to its own database in order to use it anytime it needs to access the POD ?

Thank you for help !

The server knows the app from its origin - an unspoofable part of the header sent by the browser. When the app connects, the server checks the origin header against the list of trustedApps in the pod owner’s profile. If there is a match, rights are granted as specified. No token is exchanged. Nothing about the transaction is stored anywhere.

That explains the app access. In addition to app access, all users must have have the appropriate rights. Those rights are dependent on a logged-in webId whose status is sent as tokens which are managed by Solid-Auth-Client or Solid-Auth-Cli. That token is also exchanged between the server and the browser and there is no need for a third party to know or store it, AFAIK.

Thank you Jeff !

Ok so if I understand well : once the user has given access right to his pod to an app, it means that it gave access to an app on a server, idenfified in an unspoofable way by domain name and potentially other things ? (like ? what ? IP adress, other stuff ?)

And most importantly for my need : once a user has given access to an app, server side the app can make requests to the pod, with nothing else than just making the request (no token), and it will be authorized ?

Thank you for your light !

No other stuff is needed to authorize the app. AFAIK. Only what the user puts in the trustedApp specification. And yes, unless the user revokes the access or the app is served from a different place, the app has access just by making a request without any token. But again, that authorizes the app, not the user. The user authorization is through a different mechanism and one needs both app and user permissions to get access to all but completely public resources.

Hi Walter,

@jeffz knows more about this than me, but I just wanted to add…

There are two processes involved, authentication and authorization.

Authentication is done by a relying party and the relying party assure’s your friends pods that you have the WebId that you say you have. That’s explained here https://github.com/solid/solid-spec/blob/master/README.md#authentication

Authorization is per file or resource. Your friend’s pods authorize each request based on Access Control List files on their pods which contain your WebId, or a group which includes your WebId, as explained here https://github.com/solid/solid-spec/blob/master/README.md#authorization-and-access-control

App authorization is done per origin as @jeffz describes.

1 Like

All good points, @anon36056958 . Thanks.

1 Like

Thank you Jeff, Ok it is clear. I now have all I need so far to build my prototype. Thank you !

Thank you @anon36056958 , ok I think I have all I need. So far !

I still have a concern regarding accessing POD from the app. I haven’t tested it yet, but here is my concern :

When the query to the pod is done from the browser, the origin will be set by the browser and the call authorized this way.

However, if I make the http request to the pod server side, from the application code that is running in my application server (in my case IIS), will the origin of my request be set properly and my call authorized ? do you have any idea about this @jeffz ?

Thank your for help
Walter

If it is sent through a browser, you’ll need to authorize localhost or whatever the server is. If it is sent from a command line or script on the server using solid-auth-cli, it will send an orgin:null which the Solid server will accept without further questions. Since this only gives you app authorization, not user operation, it is not a risk.

Then there must be something I did not fully understand…

I understood that an Application can be granted access to a user pod data, as being part of the list of trusted apps on the user pod. And by checking the origin, the pod knows if it can or not authorize the call. And for me, in this case : no prior authentication would be necessary : the app is kind of authenticated by its origin. Or do we still need to be authenticated for this call for a given WebId ? in which case with which webId ? the app does not have one … or does it mean that what app authorization does is to allow the app to perform action on behalf of the user, but still requires the given user to be authenticated ?

To access anything except fully public resources, you need BOTH an app authorization and a webId authorization. Which webId? Any one you have rights to. Solid-auth-cli will accept your login parameters and authenticate you with whatever webid you tell it to. You can then read and write to any resource that webId is authorized for.

“what app authorization does is to allow the app to perform action on behalf of the user, but still requires the given user to be authenticated”

Yes, that is correct for resources that require authentication. For writing to places like the inbox which allow anyone to append resources, you only need the app authorization.

Thank you Jeff,

I think I get it. However I am a bit confused on how a fully fledge application can be designed and implemented on top of SOLID. Let’s say we want to do a facebook like application, on top of solid, and let’s say all data (post, comments etc.) are private. How this would work ? at some point server side we would need to build the feed, collect comments on post from multiple users (and therefore several PODs), and serve this to the browser. So I don’t see how to do this with data stored on many user pods and still requiring authentication to all the pods. Or does it mean that the only way private comments from other users can be seen are by the request made by a user being friend (at SOLID level) of the user who commented, and that the application has no way to aggregate all comments for a post from different PODs ? And therefore all requests have to be done client side, directly on the browser, nothing be done server side ? (which can be very limited as far as the level of functionalities we want to achieve).

I guess it requires a complete new way of designing apps. Is there any guidance at this subject somewhere to read ?

Thank again for your willingness to answer me !

“at some point server side we would need to build the feed, collect comments on post from multiple users”

Nope. That is how the web works, not Solid. In Solid each user stores their own data and a client-side app collects and displays it. The client-side app does not need to be housed on a server. There are some use cases for server-to-server communication and for user-file-system to server communication which is where solid-auth-cli can come in. Even there, the app is acting as a client to a Solid server, not necessarily acting as a server on its own. Switching things to client-side from server-side is at the heart of Solid’s ability to avoid centralization. Yes it requires heavy lifting on the part of client apps, but Javascript is quite robust these days.

Ok @jeffz, I get it :blush: Now I have the piece that was missing for me to fully get the whole SOLID philosophy, it is suddenly all clear :grinning:

So there is no server anymore, only client apps, I did get it for the data, but somehow I was in an old frame of mind where I was still imagining keeping a server for doing the work.

Ok this is great, will just give me quite more work to make my low code platform generate apps this way, but this is feasible !

Ok, let’s go work a bit on this :grin:

Thank you so much @jeffz for helping me get this clarity !!

Maybe there is something that can be said in this direction on the SOLID presentation : clearly insist on the fact that data is decentralized but also that there are no more server involved, it is a full decentralization. If it was not crystal clear for me, it will probably not be for others also…

I just want to add on this because it might not be fully clear yet.

When making a request these steps happen for authorization:

  1. The client (app) sends a request to the server to read the file parent/foo.ttl. This includes the origin (~url) of the app and the webId (verification token) if the user is logged in.
  2. The Pod checks if the user has the permissions to read foo.ttl. It does this by looking at the Access Control List (the acl file) of the foo.ttl file. On NSS¹ this would be the foo.ttl.acl file which specifies which users have which permissions. If foo.ttl has no acl file, it would be inherited from its parent (or grandparent, or …). Permissions look roughly like webId has [READ, WRITE] access to this file. Also note that you could say everyone has [READ] access to this file for public resources.
  3. The Pod checks if the app is trusted by the user. The user has a list of trusted apps in their profile, where they can say I trust origin to [READ, WRITE] on my behalf. If the user is logged in on an app which is not trusted by him/her, the Pod will reject the request.

I’m not sure if everything of this is 100% correct, but I hope it’s helpful for understanding the concept.

Possible permissions are: READ, WRITE, APPEND and CONTROL (latter means that you can modify permissions)
Possible agents are: webIds, groups (of webIds), public, logged in

¹NSS (Node Solid Server) is the Pod Server used by solid.community and inrupt.net. There are also Pod Servers based on a different code base, but it seems like this is the most commonly one used.

1 Like

Thank you for the details

Hi I was read your answer and I want to be sure if i got it right.
According to 2,3 steps the following scenario is possible: a user A authenticates himself with his WebID and his provider in an application, and then the app makes a request to get data from the pod of a user B, whose WebID is known to the app. If the user B has set in his pod that the application is trusted and that the WebID of A has permission to read data from B’s pod then the data will be returned to the app and so displayed at A. Is it correct?

1 Like

Yes @Athina for me this is correct. The important point is that it is not enough that user B authorized the application to read data, It is also mandatory that user A has also rights to read B data. Both are necessary, which is what make it safe.

Knowing that there is a way for an application (I think, this is my experimentation … ) to get around apps permissions, but this is a back door / bug I guess : An application can easily get around apps permissions

I’m honestly not sure who needs to specify if the app is trusted: The one who uses it, or the owner of the file. I’d actually think that it should be the one who uses the app, but you can just try it out.

Apart from that it sounds good.

1 Like