-
Notifications
You must be signed in to change notification settings - Fork 18
Proposal: use PoP token issuer (and with that, id token audience) to distinguish web apps #12
Comments
Excellent question. (And just as an added detail, I would advocate that the solid oidc clients actually /use/ the client URLs as The main advantage is this: It would extend the "trusted origin" ACL mechanism (and any variations we might come up with), from browser-apps-only, to server side and native apps as well. |
For reference - there's a documented example of doing exactly that here |
Briefly discussed on community call. There's preliminary consensus on the developer's side to implement this. |
(to clarify: this should be normative language in the spec too, not just implemented in certain developers' apps/usecases) |
@gobengo Correct. Given the alternative would be inherently insecure, this will now be normative. |
@dmitrizagidulin I just want to confirm that the following is kosher within oidc specs: Usually, app developers register their app with IDPs. That's where they get their client_id and can set custom redirect urls. But, under Solid, we obviously don't want to require app developers to register with every pod out there, and we certainly don't want apps to be able to redirect just anywhere. So, after some discussion, the solution I came up with was having a hard restriction in the spec that says all redirect routes MUST be on the same domain as the client_id. Does that sound okay? |
Yeah, I do think that's a reasonable requirement. (Redirect uri to be similar domain as the client_id). As far as the Dynamic Registration spec, I do vaguely recall that the spec itself points out that the client should feel free to suggest what client_id it wants (meaning, might as well use its uri), but that the IDP would be free to reject it and give it their own. So yeah, I think it's a decent idea. It's very slightly more restrictive than the current OIDC spec, but in our case, it makes a lot of sense. |
(And I do like your suggestion that having those two domains be the same means that there's less need for required Dynamic registration.) |
I don't see in this spec explicit mention of OpenID Connect Dynamic Client Registration
It doesn't seem that client has any influence on how server creates |
I think we should consider making it possible to deploy different apps on the same origin. Let's say I would like to only use open source apps and always deploy them on my server. If we don't allow multiple apps (clients) on the same origin I would need to have setup where each app gets its own subdomain. |
So I think I was thinking of Section 8.2 - Stateless Registration, in the Dynamic Registration spec. I think that one could be interpreted that the client can specify their own client id (if the server is willing) |
An option to consider that I believe would address this point by @elf-pavlik:
|
There seems to be a confusion between webapps and automomous apps, in the protocol given, where it says "Upon her confirmation here, DecentPhotos will be added as a trusted application in her WebID Profile, identified by its application/agent WebID (https://decentphotos.example/appid#this), and..." The trusted app system in Alice's profile gives blanket authority to a web app at a particular origin. It only makes sense for web apps, where the Same Origin Policy would normally have the browser block the origin because of webapps being normally untrustworthy. The app's webid should surely just get added to the ACLs for the files, like that of a human agent. |
Good catch @timbl - you're correct. The intent for that workflow is to demonstrate autonomous apps, which are authorized through the app's webid in the ACLs. Adding to the user's trusted apps in their profile would be unnecessary. Will adjust that. |
There are two distinct proposals being discussed here:
I would vote we go with the first one. At least for now, we can still consider the second one in a few months from now? |
The second one should be an issue in Solid spec. |
For the original proposal, one problem: isn't the |
Right, so, part of the proposal is to change the mechanism. Currently, each app has no identifier that persists across browser sessions etc - each time, it asks for the IdP to generate a random client_id for it. This works for authentication purposes, but wastes electrons, and is not very helpful for authorization. So part of the proposal is to have the app propose a client_id to the IdP, during registration. (Or to possibly even consider section 8.2, stateless registration). Specifically, each app would propose its url (which should match the redirect_uri in some way), as the client_id. Which would then be able to be used in the ACL mechanisms. |
Yeah, not to mention create a huge list on the server of one-time IDs that need to be kept just in case, but will never be used.
Got it, good. |
Great, I think we all agree then. :) Created issues on two implementations of this spec, to follow this new recommendation. We should also edit the spec text to include it. |
@panva Do you think that this change would be in the spirit of the openid standards? Here's the use case: I would like to generate client_ids based on the Origin header during dynamic registration. I'll then use the client_id to validate if provided redirect URLs are valid (only redirect urls with the same hostname as the client_id will be allowed). I know that "it’s best that it isn’t guessable by third parties" (https://www.oauth.com/oauth2-servers/client-registration/client-id-secret/), but putting the extra restriction on the redirect should negate that weakness. For more information on the reasoning behind this, see this thread (solid/webid-oidc-spec#12 (comment))
sorry to be late to this thread.
that's not what that section means. 8.2 Implementation Notes on Stateless Dynamic Client Registration says that an authorization server can encode information about the client into the client_id it returns. there's no way for the client to suggest to the server what client_id it would like, and the authorization server should definitely not let the client specify its client_id, because that would destroy a huge aspect of OIDC's security model. https://github.com/zenomt/python-webid-oidc/blob/master/oidc.py#L199 is the sort of thing Section 8.2 was talking about. that method results in a client ID that looks something like |
@zenomt - you’re absolutely right, thanks for the catch. I have an alternate proposal, which should accomplish our overall goal, while still being compliant with the spec. (I’ll ask some of the oidc/oauth folks, as well as this community, to review it.) |
one solution that comes to mind is to extend WebID-OIDC to have another claim in the id_token's claim set: the redirect_uri to which the token (or code) was sent. the redirect_uri claim (or its origin) could be used for access control, for example. edit the redirect_uri can be added to the one thing i've never been clear on, for the browser-app implicit workflow case: you don't have anything to put in the Authorization: header for some random (not the IdP) server. an id_token is not an access token. the access_token is only meaningful to the IdP and to someone who has the id_token and can compare the access_token to the at_hash claim. perhaps there's some Solid spec i haven't found yet that defines a way to "log in" with an id_token and access_token and get a cookie set or something? otherwise you need to log in directly to the random server with its normal login page, specify your IdP, and it and your IdP do the OIDC dance. |
i was thinking about my above proposal a lot overnight. while the new proposal: the this still doesn't fully solve the "web app wants to interact with a random server on behalf of the user as their webid" problem though. you want some way to prove to the server that you're acting directly on behalf of the user, and that you're not a MITM that has gotten your hands on an id_token and are presenting it as your own. i have a sketch of a solution to this second problem. there can be a way to "log in" to the server on behalf of your user (perhaps a new WWW-Authenticate method, or an endpoint discovered via a .well-known URL, or something). the method will include, among other things, a challenge nonce from the server. the app/agent combines this nonce, its own nonce, and the URI or origin or something of the resource it's trying to log in to or access, hashes them all together (perhaps with an HMAC-based construction), and uses that as the nonce to the OIDC server. the returned (signed) id_token will include this nonce. the app/agent then presents the id_token, the challenge nonce, the app/agent nonce, and the URI it thinks it's talking about to the server's login endpoint. the server can look up/verify its nonce to correlate the attempted login session, verify the id_token signature, perform the same hash that the app/agent did to verify the nonce in the id_token, confirm the server URI used refers to it or is allowed, and then apply access controls on the webid and the redirect_uri (or its origin, or whatever it wants). if access is allowed, the server can since the app/agent decides the server URI to include in the nonce it sends to the OIDC server, a third party can't trick the app/agent into giving it an id_token (and other stuff) that the third party could then turn around and use on another server. update: here's an example exchange illustrating my sketch a little more concretely. |
over the weekend i baked my idea into a complete protocol and wrote up a spec. it addresses app identification for both WebID-OIDC and WebID-TLS, can work with or without any modification to WebID-OIDC, formalizes handling of self-issued OIDC id_tokens, handles the "app/agent accessing resources on random servers on behalf if its user" problem for WebID-OIDC and WebID-TLS, and addresses some of the issues of using WebID-TLS in real life. i'm happy to submit it in a PR as a proposal, but i'm not sure against which repo or path would be the most appropriate. @dmitrizagidulin any suggestions? edit: move link to github |
Hi @zenomt thanks so much for your contribution! I'd like to clarify a few things with you. Would you be open to hopping on a call, or I'll be in the Fremont / Mountainview area next week so we could meet up in person. |
hi @jaxoncreed . i'm happy to have a call. i made my email address visible in my github profile, so you can email me directly to arrange. |
i hope i can be excused for not having read all closed tickets in all solid source repos. :) i did find a discussion by @dmitrizagidulin at nodeSolidServer/node-solid-server#1061 which describes exactly the main situation i address in my proposal (IdP/OP, app, and RS are all separate), the discussion including references to PoP tokens (thanks @jaxoncreed for pointing me in that direction when we spoke on the phone). i haven't yet found documentation on acquiring and using PoP tokens, except for source code. edit i've read enough of the source that i think i understand how PoP tokens are acquired and would be used in the above 3-party scenario. i have some concerns but they should be made against a spec, not against the source. i would like to suggest that security protocols (especially) be documented before implementation, both so that the protocol can be examined and vetted by as many security experts as possible, and so that implementations can be audited against the specification to make sure the implementations are correct. |
Problem this issue aims to solve: #33 |
In the end we decided that the resource server should look at the issuer of the PoP token. The token validation library will additionally check that is issuer is included in the audience list of the identity token that the PoP token is about. |
at least that's the conclusion @dmitrizagidulin and @jaxoncreed and I just reached :) |
Can there then be an issue proposing that solution in detail please? |
Also, let's please keep this draft solution as-is, and propose different solutions in different issues. And let's not forget to first complete #33, such that we know what requirements the solution should satisfy, and that we can check whether the proposed solution does. |
The detailed explanation of this is in #27. I'm thinking of eliminating the applicationWorkflow.md file in favor of the detailed version |
+1 . however, without a new Issue for this yet, i'd like to say
also +1 i feel that this aspect is orthogonal to the "what exactly is the appid" problem. this addresses "how do you find it, whatever it is". |
This whole issue seems completely misguided and to be based on a complete misunderstanding about web apps. The definition (more or less) of a web app is (more or less, from our point of view) a script which a user runs in a browser in a web page, by virtue of just following a link to the page. The browser warns the server with the "Origin" header, which the web cannot control (nor the user). The Origin header is the only way of identifying a web app. No other identification is appropriate or needed. Propose this issue be closed as it seems to be adding a lot of FUD. |
(Bots, independent services running on the internet, are different. They have a webid of their own. It is good to call them bots instead of apps as apps can be web apps or native apps or bots. The Origin header is never used at all in any way with bots) |
@timbl Do you not think there is a place for web apps that have a backend component that queries pods instead of the web browser? These should still be protected by some kind of trusted app acl, but wouldn't have the origin header because it's not coming from the web browser. Maybe a backend component isn't really the Solid way of doing it? What do you think? |
@jaxoncreed @timbl also please see my comment in #33 (comment) about why i think this is also (and i think primarily) applicable to pure in-browser app scenarios. and also discussion at solid/solid-spec#144 . |
I wasn't sure whether to create this issue on this repo or on the WAC repo, but this is a suggestion that came up during the 'acl:trustedApp' session of the unconference we did in Boston on 22 March, and I still had a todo item that I needed to convert it to a github issue. :)
I think the idea that @dmitrizagidulin coined was that instead of identifying web apps by their Origin, we could assign a client_id to web apps when we give them access. I think if it works the same way in OIDC as in OAuth, then that means the pod would maintain a list of whitelisted apps, tying client_id to origin.
@dmitrizagidulin so one thing I'm not clear on now that I'm writing this down, is how would this be different in result, when comparing it to the current system where the pod has a whitelist of origins, rather than of client_id's?
cc @jaxoncreed
The text was updated successfully, but these errors were encountered: