solid / data-interoperability-panel

Repository for the Solid Data Interoperability Panel
MIT License
51 stars 19 forks source link

Access token needed to access registry sets? #139

Open woutermont opened 3 years ago

woutermont commented 3 years ago

As I understand the current draft, an application would need an Agent's Access Token to retrieve the Agent's Application Registry set. This seems to defeat the purpose of limiting access of Applications to specific Resources as descibed by the draft, since the Application could simply use the Token to access all resources as if it were the Agent itself.

Do I miss something here?

elf-pavlik commented 3 years ago

I think this situation is still not perfectly clear in general solid ecosystem. Even with current state of Solid-OIDC, access token includes webid claim denoting the User and client_id claim denoting the application.

Application could simply use the Token to access all resources as if it were the Agent itself.

Authorization guard enforcing access control policies will need to take both webid and client_id claims into account so what you said can not happen!


It is still unclear how to handle this use case 2.5.2. Limiting application access while not acting as resource controller. IMO Solid-OIDC shouldn't be issuing access tokens but only draw the line to issuing id token. In that case we could use combination of OAuth 2.0 Token Exchange and something inspired from User-Managed Access (UMA) 2.0 - Claims Gathering. This would allow application to exchange id token and provide additional claims. One of those additional claims could be data grant relevant to the resource server it requests data from. Above may require to separate Data Access Consent, representing user's consent decision and Data Grants which would need to be more granular with specific audience (RS hosting particular data registration).

woutermont commented 3 years ago

Authorization guard enforcing access control policies will need to take both webid and client_id claims into account so what you said can not happen!

Aren't we then unnecessarily duplicating access control policies? If an end-user autherizes a client app using OIDC, why would the resource server need to perform additional checks on the client id?

Since interaction between end-users and different client apps happens on-the-fly, authorizing the client seems i.m.o. something that should be done by the end-user at the OIDC provider. Have we looked into resource indicators as a possible solution?

elf-pavlik commented 3 years ago

Since interaction between end-users and different client apps happens on-the-fly, authorizing the client seems i.m.o. something that should be done by the end-user at the OIDC provider.

Currently Solid Application Interoperability - 6. Data Authorization describes consent screen and issuing Data Grants to applications. It still does needs some work but we are pretty confident that this responsibility will lay with user associated trusted agent. Actually you could take a look at some early sequence diagrams in Solid Application Interoperability Primer - 2.15. Sequence diagrams, currently I have them for case where IdP and Authorization Agent are combined together, while we want it to be possible we also want to support separate IdP and Authorization Agent with some extra redirects happening.

Have we looked into resource indicators as a possible solution?

Could you clarify where would you see them used and how it would work with current form of 7. Access Needs

justinwb commented 3 years ago

Aren't we then unnecessarily duplicating access control policies? If an end-user autherizes a client app using OIDC, why would the resource server need to perform additional checks on the client id?

Because the application I use to manage my financial information shouldn't automatically get access to my medical data, and vice versa. The value of Client Identifiers is realized when you provide a scheme to compartmentalize information based on them. They are not perfect, but as applied in this specification for someone managing data in their control, they're pretty effective.

elf-pavlik commented 3 years ago

Since interaction between end-users and different client apps happens on-the-fly, authorizing the client seems i.m.o. something that should be done by the end-user at the OIDC provider.

I started a Draft PR in Solid-OIDC https://github.com/solid/solid-oidc/pull/18 which aims at removing notion of OIDC provider acting as Authorization Server. It proposes RS associated AS which should not be conflated with Requesting Party's (user of the client) Authorization Agent. We still should clarify distinction between Resource Owner (so also RS) associated Authorization Server and Requesting Party associated Authorization Agent.

@woutermont do you think this issue requires further discussion or we can close it?

woutermont commented 3 years ago

If that is the way the panel wants to go, then you can close this issue. Just seems like a waste of good functionality if we extend OIDC and then don't use the underlying authorization capabilities.

elf-pavlik commented 3 years ago

@woutermont now we also have this issue https://github.com/solid/authentication-panel/issues/186

I think we also need to keep something in mind, in many cases the End-user (aka. Requesting Party) will be different from Resource Owner. In that case End-user uses their Authorization Agent (similar as they use their Idp). At the same time after changes we are discussing Access Token gets issued by Authorization Server associated with Resource Server so also Resource Owner. So we have distinct Authorization Agent (associated with End-user) and Authorization Server (associated with Resource Owner). Part of the Authorization we focus on in this panel pretty much focuses on the Authorization Agent and Applications (Client instances). IMO Authorization Server should be defined in AuthZ panel once we correct Solid-OIDC to only be responsible for AuthN, so pretty much only ID Token.

I also should add that I do find it tricky that AuthN and AuthZ work is happening in 3 different panels and we should be syncing it up much better than we currently do.

justinwb commented 3 years ago

I also should add that I do find it tricky that AuthN and AuthZ work is happening in 3 different panels and we should be syncing it up much better than we currently do.

+1 - @woutermont would be great to get your use cases included (or make sure we have them reflected somewhere already) as we try to consolidate the attentions around authz

woutermont commented 3 years ago

@justinwb, there's no specific use case underlying this issue; rather a worry about the user's access token still being needed in the application's flow, and thus still not closing all the doors for malicious token replay.

elf-pavlik commented 3 years ago

rather a worry about the user's access token still being needed in the application's flow and thus still not closing all the doors for malicious token replay.

Do you refer to Access Token as currently specified by Solid-OIDC? Does it still apply once Solid-OIDC moves away from issuing global access tokens?

I think we should focus on documenting the scenario where we have potential vulnerability.

woutermont commented 3 years ago

@elf-pavlik, I'm not sure, since I do not entirely comprehend which way the authentication panel wants to go without global access tokens. This issue dates from before that intention was known to me, and it is unclear to me if it would still exist in that regard.

In any case, the interoperability specification, or more specifically the API document, seems to indicate that the application will need to access non-public resources, e.g. the application registry set. As it currently stands, this would be done by using the user's access token, which means the application must be able to add this token to requests, and thus can also access other resources. Moving away from global access tokens will only prevent such misuse if the alternative does not consist in a similar flow where the application has such a capability.

But again, as to what the details of such an alternative would be, I'm not yet up to speed.

elf-pavlik commented 3 years ago

As it currently stands, this would be done by using the user's access token, which means the application must be able to add this token to requests, and thus can also access other resources.

I don't understand where does the assumption that application would be able to access anything else beyond what user authorized it to access. Application can access:

Besides above application can't access anything else.

Current Solid-OIDC oversteps into authorization in a way that doesn't leave space to put those Data Grants into the flow, but even here we could look into defining out of band mechanism to deliver them to where access is being guarded. In solid/solid-oidc#18 I'm proposing how to change the flow that Data Grants issued for application would need to be included in the flow, based on them access restrictions which user puts on application would be enforced.

woutermont commented 3 years ago

Unless I'm missing something, the application must be able to send some form of credential to access the application registry. For example, in this access request diagram the ACME project gets an access token from Alice's IdP. As it currently stands, using that token grants global access to everything Alice can access.

How would a restriction of Solid-OIDC to mere authentication with an id token change this? Even in the diagram from solid/solid-oidc#18, the resource client first gets an id token from the IdP, and then exchanges it for a (local) access token at the RS-bound AS. What prevents the client from using the id token to get a local access token at another RS/AS, or using the (local) access token to access other resources than the application registry?

Edit: note that in this scenario, the application is not yet known to the RS/AS, and possibly not to the user either; the only way to identify the application and/or its rights is by way of the tokens, which are those of the user, and thus indistinguishable from an immediate (i.e. not application mediated) request by the user.

elf-pavlik commented 3 years ago

As it currently stands, using that token grants global access to everything Alice can access.

IMO this is only due to lagging work on AuthZ panel. Data Grants from this panel provide big part of possible solution, it's still matter of integrating it with AuthN and rest of AuthZ.

What prevents the client from using the id token to get a local access token at another RS/AS, or using the (local) access token to access other resources than the application registry?

By default any application should have no access, an opposite to what currently seems to be the case. We currently look in two directions of addressing it:

  1. Authorization Agent updates access policies for all the resources 'out of band' adding client restrictions. Here Authorization Agent has special designation in user's WebID Document which gives it rights equal to the user, so it shouldn't be considered a regular application.

I don't like this approach personally since it may lead to racing conditions, this UC would also not be supported by current WAC and I find it unclear if ACP would address it.

  1. Authorization Agent issues Data Grants as tokens which can be pushed as claims when obtaining access tokens

solid/solid-oidc#18 includes pushing optional tokens but doesn't show getting one from Authorization agent Last week I started a thread on GNAP mailing list where I would try to get suggestions how GNAP would handle issuing and exchanging such 'client permissions tokens'.

I'm also looking at Authorization Capabilities for Linked Data if we could align Data Grants with them and use as 'client permissions tokens'.

woutermont commented 3 years ago

If the issue indeed stems from a discrepancy between the panels, my bad (although it can be good to leave the issue open untill that discrepancy is solved). While quite complex, I do think the general direction in which this panel is going is a good one.

However, even when I just look at the latest specification's API and diagrams, I see the user's id token pass through the client. One question I'm therefore left with is: how to distinguish between a client request bearing the user's token, and a non-mediated request made by the user him/her-self? Am I missing something in that regard?

elf-pavlik commented 3 years ago

One question I'm therefore left with is: how to distinguish between a client request bearing the user's token, and a non-mediated request made by the user him/her-self? Am I missing something in that regard?

Currently I only can think of one case where that is happening, when user navigates web browser directly to protected resource, I have bit stale issue for it https://github.com/solid/authorization-panel/issues/80

Do you see any other cases where there would be no client acting on End-user's behalf?

woutermont commented 3 years ago

Do you see any other cases where there would be no client acting on End-user's behalf?

Of course: when I send an HTTP/LDP command via the terminal, or even any other application capable of sending such requests.

Having the resource server act as client in such cases seems to open the vulnerablility rather than close it. Assuming that I want to be able to access my data via a terminal or directly in the browser, I would have to give explicit access to my data to the resource server, upon which any malicious client through which my tokens flow can also use these to send such 'client-less' requests to access the same data.

elf-pavlik commented 3 years ago

any other application capable of sending such requests

IMO This application should act as client, and you should authorize it first

I send an HTTP/LDP command via the terminal

I think we should look for approach where even such generic http clients (eg. curl) can act as oauth client which requires prior authorization

I would have to give explicit access to my data to the resource server

I think that would be the only exception where resource server has implicit access to data, since it already hosts that data and enforces access control policies. End-to-end encryption have been mentioned by currently we tend to assume that resource server can access data it serves.

acoburn commented 3 years ago

I send an HTTP/LDP command via the terminal

I think we should look for approach where even such generic http clients (eg. curl) can act as oauth client which requires prior authorization

The client_credentials flow would be one approach. Another approach is the use of refresh tokens with authorization_code flow. Another option is to use SAML assertions and exchange that via OAuth2 (e.g. UMA 2.0) for an access token. Another is the use of DID Auth. Another is to use GNAP. There are others.

All of these involve fetching and/or negotiating an access token and using that token when interacting with a Pod. It doesn't much matter whether the HTTP request is performed with cURL or directly with a browser or via a script or an IoT device: they all involve some sort of access token. How the client fetches that access token is up to the client. Solid does not mandate a particular mechanism. Solid-OIDC is one mechanism that is currently defined, but it is not exclusive.

I use client_credentials flow all the time to work with Pods via Python scripts.

woutermont commented 3 years ago

@acoburn, I'm not contending there are different ways to get an access token, but rather how that access token will limit access to a limited set of resources.

If I'm understanding our conversation correctly, @elf-pavlik states that every access token should be client-bound. If that would be the case, even global access tokens seem sufficient to limit access per user+client combination (not sure I see the need for local AS then). However:

How will an IdP/AS/RS distinguish between the two scenario's?

Indeed, if we enforce all access to happen via some client, this issue seems to be solved. But doesn't this pose a heavy restriction on how we can access the RS? Up till now, Solid has been built using very widespread standards with minimal extra requirements. Any application able to send OIDC authenticated HTTP/LDP requests could in principle be used within the Solid ecosystem. We should take care that additional requirements, like being identifiable as a client, do not change that.

acoburn commented 3 years ago

some resources need to be accessable regardless of the client, i.e. before the client is given access

That is fine. Then set the authorization rules such that any client can read and/or write those resources.

some resources need i.m.o. to be accessible without a client (e.g. terminal access).

That's your opinion. Terminal access does not imply no client, but you may choose to have no client identifier in that case. Either way, you can simply define the access rules such that any client can access a resource.

woutermont commented 3 years ago

you may choose to have no client identifier in that case [...] you can simply define the access rules such that any client can access a resource.

But there is a difference: if 'any (new) client' can access the application registry set, and 'I myself via no client' want to access everything, how do we detect the difference? Because I do not want 'any client' to be able to access everything.

acoburn commented 3 years ago

@wouteraj this conversation is going in circles.

If you want your application registry set to be accessible to any client including one that does not declare its identity, then set the access controls appropriately. If you want to restrict these resources to particular clients, then set the the access controls appropriately.

how do we detect the difference?

You detect the difference by having your client app declare its identity in a way that is verifiable; otherwise it is an anonymous client.

elf-pavlik commented 3 years ago

some resources need to be accessable regardless of the client, i.e. before the client is given access (e.g. application registration set); and

We removed that, authorization agent will now point client to its registration, which no other client can access. If registration doesn't exist client can only initiate authz flow which will result in creating registration.

some resources need i.m.o. to be accessible without a client (e.g. terminal access).

I think making exception could lead to a security hole where client tries to act as 'no client'. At the same time we could have easy way to create special client on authorization agent. This way credentials would be created to use it as a client from command line. We should create issue to track this option.

woutermont commented 3 years ago

Thanks, @elf-pavlik!

I think making exception could lead to a security hole where client tries to act as 'no client'.

This was exactly what I was trying to point out.

We removed that, authorization agent will now point client to its registration, which no other client can access. If registration doesn't exist client can only initiate authz flow which will result in creating registration.

I did not know that this had changed since I started this issue; hard to keep up with all specs/panels as a full-time developer. Since this was the main thing I was trying to make clear, we can close this issue (and indeed start a new one for supporting terminals and other 'legacy' clients).

Edit: Just to clarify, @acoburn, if the conversation was indeed going in circles, it was only so because I was unable to understandably explain the above conclusion and/or you were unable to understand my explanation. When I started the issue, the part which @elf-pavlik clarified as having been removed from the spec posed a real security vulnerability if combined with the idea of also enabling access with no client identifier (as in the example of a terminal). The fact that the progress of the specs/panels is hard to follow is exactly what I address in this comment about engaging with the community. (Also: I'll interpret the fact that you tagged my boss in that complaint instead of me as an unhappy mistake of names 😉 I hope it wasn't meant another way.)

elf-pavlik commented 3 years ago

Since this was the main thing I was trying to make clear, we can close this issue (and indeed start a new one for supporting terminals and other 'legacy' clients).

I've created #178

Also: I'll interpret the fact that you tagged my boss in that complaint instead of me as an unhappy mistake of names 😉 I hope it wasn't meant another way.

I'm not intending to respond as @acoburn but when I start typing @w WJ comes up before WT, mostly likely his fingers were to quick to autocomplete.

acoburn commented 3 years ago

Also: I'll interpret the fact that you tagged my boss in that complaint instead of me as an unhappy mistake of names wink I hope it wasn't meant another way.

Ahh, that was an auto-complete mistake. My apologies.

bblfish commented 3 years ago

@woutermont this issue was brought up in last week's authorization panel for which I have just put up the meeting notes PR.

I pointed out during the meeting, that in the case of HTTPSig the Wallet agent signs potentially every request a client is making to a server. So it can sign the Date header for example, to reduce the ability to replay a request.

Since requests can be signed individually, it is then possible to use the WAC ontology to specify rules to Authorise the Wallet agent signing the requests to do so for particular apps. Please join the discussion on this: Use WAC ontology for authorising authentication.