-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal for keyed Access Tokens in a Distributed Network #21
Comments
@jricher regarding Dynamic Registration: today, dynamic registration is used only between a client (such as a single-page browser app (SPA)) and the user's OpenID Provider. since the user is likely to be the same from use-to-use of the same SPA in the same browser on the same device, the SPA can (and many do) remember the client ID & secret (and other aspects of the openid-configuration) from run-to-run in that browser on that device. and as we discussed on the call this morning, my proposal doesn't require a dynamic registration with the Resource Server's Authorization Server either. regarding DPoP: i believe the DPoP construction specifically is intended to solve a different problem. DPoP as of draft -02 is vulnerable to a downgrade attack, though for Solid it could be mandatory. i think the attack model DPoP is trying to address isn't an issue in Solid (or even in my proposal, as the RS and its AS are already in cahoots, and any auth token presented to an RS would only be good in the same protection spaces controlled by its AS anyway). any proof of possession of a private key that comprises a signature over information required to establish whatever identity/authorization/whatever claims would be sufficient and semantically equivalent (like today's POP tokens, DPoP, HTTP signatures, my proposed POP tokens, etc). regarding OIDC id_tokens vs a new JWT-based construction: my gut feeling without seeing more specific information is that any new construction would be semantically equivalent to an ID token issued by the user's/webid's trusted identity provider/issuer (for example, an id_token issued by the user's OpenID Connect Provider), but would also require recreating all the rest of the OpenID Connect infrastructure to let the user log in in the first place. i look forward to additional information that might help me understand better what you're proposing. |
I think for User associated Authorization Server we don't need Dynamic Registration and actually could use static registration step to let the User set app specific permissions. Having JWT access token to include those app specific authorizations (even just by reference) seems to address use cases where User doesn't want to define it for each Resource Server and does not to have them discoverable except for Resource Servers hosting resources app needs to access. |
@zenomt: DynReg is needed in WebID-OIDC because the keying material used by the client is associated with the client's registration, and not with the access token itself. This doesn't make sense for ephemeral keys and in-browser clients. This is in fact where DPoP comes into play: the keys used by DPoP do not need to be pre-registered with the client, removing the need to have each instance of the client dynamically register itself with the target AS. And again my point on ID Tokens: they are never meant to be sent outside of the client, they are a message TO the client. The name "ID Token" is a bad one as it seems to be put on par with, or parallel to, the access token, which is not the case. Access tokens are made to be sent to the RS, which is what we're doing here. What I'm proposing is a method of being able to recognize an access token with a key proof in a distributed fashion, and for that you need at least some means to communicate the token's origins and validity bounds, which is where the JWT comes in. I don't understand what you mean about "recreating all of the connect infrastructure", because to have the user log in and get the access token, you just need OAuth. Remember, in OIDC, the user isn't logging in to the RS, they're logging in to the client. For the proposal above to work for accessing APIs, you don't need OIDC at all, just OAuth (and the extensions listed). If you want the user's identity information to also be available to the client in a standard fashion, you can also use OIDC on top of OAuth to do that, just as it's designed to do. And regarding the downgrade attack and token formats: in my view, these would all be required as part of a Solid profile combining all of these technologies. We would not be inventing new endpoints or protocol flows, but we would be combining them in a consistent fashion that we would then standardize. |
@jricher i think we may be talking past each other. i have a strong feeling that i'm not understanding the access model you're describing and how that fits in with Solid.
i'm not sure what you mean by "target AS". in the current Solid POPToken scheme and in my proposal, dynamic registration is only done between the client app and the user's trusted OpenID Provider.
i understand what you're saying. however, it's not against the rules for a client to show an id_token in its possession to anyone else, particularly if that's what the user wants. while the id_token is audience-bound to the client to which it was sent, having a
without OIDC, i'm not sure how the user logs in with just OAuth. this and the other things you've described above suggest to me that you're talking about an identity and authorization model very different than WebID-OIDC and Web Access Control, and in particular you're envisioning authorization servers somewhere that issue access tokens that themselves grant access to resources, rather than just conveying the identity of the presenter (and her client app, according to her) where an access control system in the resource server makes a just-in-time access determination based on identity-centric access control rules (for example, WAC). if that's not what you're talking about, then i am very definitely misunderstanding you, for which i apologize (as i don't mean to mischaracterize your proposal). either way, additional detail to illustrate what all the pieces are and how they fit together would be greatly appreciated. |
Before weighing in, one thing I wanted to clarify: Currently, the WebID-OIDC protocol does not use the Dynamic Registration to register a client app's keys. So, currently, we're only using DynReg for a (throwaway) |
In DPoP Proof JWTs: Syntax I see:
and later in DPoP Proof JWTs: Checking DPoP Proofs
Does it mean that if application acting as client and using HTTP/2 wants to fetch contents of LDP Container - let's say containing 1000 LDP Resources - it has to create DPoP Proof JWT for each of those 1000 resources? I think in current WebID-OIDC application acting as client needs to create just one PoP token per Resource Server. RS would only accept PoP tokens that application created for that RS (@dmitrizagidulin please correct me if I confuse something)
@jricher Could you please expand on this point. In common example also discussed in solid/authorization-panel#30 (comment) We would have Progressive Web App acting as Public Client served from https://demo.saywhat.example Given that Alice registers this PWA with Authorization Server associated with her and Bob registers the same PWA with Authorization Server associated with him. And that WebID acts as globally unique identifier (IRI). Would both Authorization Servers (Alice's and Bob's) use the same WebID to identify that PWA served from https://demo.saywhat.example or each Authorization Server would create during static registration WebID specific to that AS? Also would any Authorization Server verify identity of the Application acting as client only based on its
In case where Public Client (eg. PWA) would use the same WebID with any number of user associated Authorization Servers, what would that static registration result creating? |
To clarify, the client does not create a token. The client :presents: a token with proof of a key associated with that token. So if the client is presenting that token, with its associated proof, to 1000 different RS's, and those RS's are distinct enough from each other that they'd know they were distinct, then yes it would create 1000 different proofs. It does this as part of the process of making the HTTP request. This proof is going to need to be very short-lived in the time scale anyway, and prevent replay attacks with some randomness in the request, so you actually :want: the client to create a new proof each time and not re-use it. If the client reusing a token at multiple RS's over time without additional effort were the goal, we could get by with bearer tokens. But keep in mind if all those resources are in one logical "group", then the client could potentially get away with replaying the same token proof to them, if it did so quickly enough. But then you'd have to weigh the benefits of letting a client do that, sometimes, with the downside of giving an attacker a place in which to easily hide their replay attack. As for the client_id, it depends on the nature of the app. A web server with shared users wouldn't need to be a public app, for one. An ephemeral SPA style client would be a new instance of the same public client software on every load, even from the same server, and so would therefore need to be either a public client or a dynamically registered client. Same with multiple copies of an installed native application. The static registration would create the client_id, which could in turn be (or be referenced to) a WebID. When talking to multiple AS's, you'd need a way to either register with each of them, or create an identifier that could be referenced by each AS in a distributed fashion. This is one of the downsides of OAuth's model, which assumes a client talks to one AS in the usual mode of operation. |
Thank you @jricher for quick answer! In my previous comment I talked about fetching 1000 resources from the same LDP Container so we talk about single Resource Server. If DPoP Proof has REQUIRED in DPoP Proof JWTs: Checking DPoP Proofs
Do you know of any benchmarks of creating DPoP Proofs on average low end mobile device?
I would also like to clarify what goes in DPoP-bound Access Token and what goes into DPoP Proof.
I think case of SPA/PWA style client comes as very common scenario in Solid ecosystem. If we would require them to have public (global) WebID which includes valid
In other words any AS could use that WebID (an IRI) as @zenomt I recall you mentioning some reason for AS specific |
@elf-pavlik when doing dynamic registration, newly issued client_ids must be unique. on the monday phone call, i mentioned that my OP implementation makes new unique client_ids by encoding information about the registered response types and redirect_uris (and a random salt) directly in the client_id, so no per-client state needs to be stored in the OP. see https://github.com/zenomt/python-webid-oidc/blob/master/oidc.py#L202 which results in a client_id that looks something like
these client_ids also come with client_secrets, also with no per-client state in the OP: https://github.com/zenomt/python-webid-oidc/blob/master/oidc.py#L219 . the above is one way to do Stateless Dynamic Client Registration. |
@zenomt do you see any possible problem with all Authorization Servers using globally unique WebID of the application as its I think that matches this part of the initial proposal
For next Monday I'll try to make Sequence diagrams similar to one in https://github.com/solid/webid-oidc-spec/blob/master/application-user-workflow.md based on my understanding of this proposal. |
@elf-pavlik that matches my thinking on the proposal as well. I'm not enough of an expert on WebID, but as long as the AS can recognize the |
i don't see a security problem with this (although since the mapping from webid to redirect_uri is only one-way, the webid of the app isn't strongly authenticated to the user by following the redirect_uri, which might be a problem, and the webid need not have the same origin as the redirect_uri, which might also be a problem; more reflection is needed). however, i do have some other problems with this approach: currently, WebID-OIDC has a very modest incremental add to an ordinary OpenID Provider:
to support "app's webid is the
i'd prefer to take a step back and ask what problems we're really trying to solve with this:
given the kinds of changes to an OP that would be needed, and the implementation and operational costs associated with them, i'm not in favor of skipping dynamic client registration and using the webid as the i think there is tremendous value in keeping the required changes to an ordinary OIDC Provider implementation as small and uncontroversial as possible to encourage the adoption and use of WebID-OIDC. all three of today's required additions are backward-compatible and trivial to implement. |
after writing that giant message above, i thought of a simple example that doesn't work for "app has a webid that the OP dereferences". imagine i'm in my corporate (or home) intranet, using an app hosted on an inside-only server TL;DR: asymmetric connectivity → no joy. edit: also consider the "inside-only" server |
Just like with mobile app on the device, |
@jricher with the benefit of some clarifications in this thread and time for additional reflection, i think i mostly understand what you proposed in the initial posting. i'll address your boldface points here:
as i mentioned above, i don't believe Dynamic Client Registration is actually a problem that needs to be solved here. i think using a webid (or any other link that must be loaded by the user's identity provider) as an implicit client_id won't work because of asymmetric connectivity. Dynamic Client Registration is not where confirmation keys are registered in the current solution (as @dmitrizagidulin clarified above, that happens at token request time with the
the premise here was mistaken: in the current POPToken scheme, ephemeral confirmation keys are associated with the id_token at the
an OIDC id_token containing a
the user's Identity Provider has no authority to grant an access token for an unassociated (third-party, non-coupled) Resource Server -- all it should have the power to do is to help establish the identity of the presenter. the WAC model places access control decisions in the Resource Server, based on the identity of the client/requestor. scopes of various sorts being added to an identity assertion from an IdP i suppose could be used to reduce the access rights of a presenter to less than those that the RS would otherwise allow, but in all cases access control is ultimately up to the RS. any statements of scope in any kind of credential/token obtained from the user's identity provider should not improperly leak potentially private information about the user to other parties (for example, if i'm using app Cool Photos, which accesses Alice's photos and Bob's photos, it's not any of Alice's business that i also look at Bob's photos, and it's not any of Bob's business that i look at Alice's photos, and it's neither Alice's nor Bob's business that i use Cool Photos to edit my own photos but only use it to view their photos). |
I think this might apply in current OIDC based approach, I've been looking recently at User-Managed Access (UMA) 2.0 Grant for OAuth 2.0 Authorization and Federated Authorization for User-Managed Access (UMA) 2.0 (both co-authored by @jricher) which provide a lot of flexibility for user to associate resources with authorization servers, quote:
I haven't dived to deep into UMA and I can't tell yet how its use cases compare to solid use cases. For example in Solid w often can have a resource where multiple users have different access modes and they want to use their authorization servers to grant clients of their choice subset of their access. I think for now we should not assume Resource Server associated Authorization Server and consider User associated Authorization Servers. Possibly based on broad use cases we may need to support both approaches and WAC could provide way for specifying policy for which Authorization Server gets selected for the resource when accessed by a user. In more liberal domains user would use Authorization Server associated with them to delegate access to clients. In more conservative domains, user would have to use Resource Server associated Authorization Server, possibly even using OIDC to authenticate with the AS mandated in that conservative domain.
I do think we may have some issues here with From https://github.com/solid/webid-oidc-spec#pod
And https://github.com/solid/webid-oidc-spec#presenter
I think in usual OIDC the client (app) would act as Relying Party. In current PoP Tokens approach we have pretty much Resource Server (Solid POD) also acting as Relying Party which doesn't get id_token from IdP but gets it from Presenter wrapped in PoP Token. From https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
https://openid.net/specs/openid-connect-core-1_0.html#Terminology
Based on above I don't know if we really can consider Solid POD hosting a resource as OIDC RP. PROPOSAL: Let's create granular github issues for different aspects we discussed here. Once we clarify the issue we could see how this proposal addresses the specific issue. Currently I think we would have
|
I think latest draft submitted by @EndlessTrax follows most aspects of the suggested approach. Structured Scopes / Rich Authorization Requests still need to be evaluated as part of addressing where authorization comes in. |
Public Clients. Instead of dynamic registration as in the current prototype, we should be using static registration or its equivalent to introduce a client to the AS. With the current prototype setup, registration is required to set up a client_id and associate it with the application keys. The downside is that for ephemeral applications, and even native applications that can get deactivated/uninstalled/abandoned, this leaves a lot of dangling registrations at an AS that will never be seen again. The client ID in OAuth2 allows an instance of software to be identified across multiple authorization requests, but it’s rare that a single application instance would ever ask for a second token. I believe that we can use technologies like PKCE and DPoP to fill in the functionality currently provided by DynReg. Coupled with this, we can use a WebID for the client ID, or use it to fetch/validate a client ID, and tie that to a set of display and key information for a client. Client IDs are public information, and any attacker could claim any client ID, but we can use WebID mechanisms to lock down the behavior of a given client ID such that any attacker would need to also have control over the appropriate URLs for an app.
DPoP with ephemeral keys. Instead of the keys being registered in one-time-use client entries, DPoP allows a client to present an ephemeral key at token request time. These keys don’t have to be strongly associated to a client’s identity, but they tie a token request to subsequent token presentations. This prevents a token from being replayed by another party, such as a downstream RS. This key binding lasts as long as the token.
JWT Profile. In addition to the key presentation mechanism of DPoP, we need a way for the RS to figure out who the token’s for and what software is presenting it. We can define JWT claims for the user and client software, and define in the Solid profile that these are WebID’s and how these are to be dereferenced. This would allow the RS to validate the token’s presentation mechanism, which binds to the client, and the token’s own signature, which binds to the AS, and the WebID’s for the user and client, which validate those parties and allow authorization decisions. This JWT access token would replace the use of the ID Token in the current process (and therefore no longer depend on OIDC either), and would need to comply with the various BCP’s for JWTs that are floating around. 1 2 3
Structured Scopes. Proposed work by Torsten Lodderstedt. This allows us to define the kinds of information being requested and authorized by the protocol, and as Dmitry pointed out, the current thinking in the OAuth world aligns with the WAC concepts in Solid.
Alignment with existing infrastructure would take the form of an identity broker (for users on their way in) or an application gateway (for APIs on the way out) to bridge between the Solid ecosystem and traditional OAuth/OIDC/SAML systems.
And finally, much of this approach aligns with ongoing work in the XYZ Project, which is seeking to patch a lot of the problems in the OAuth protocol and its extensions.
The text was updated successfully, but these errors were encountered: