4

We have been tasked with implementing a dashboard containing multiple widgets. The dashboard itself and all widgets need to access various secured APIs. Our authorisation protocol is OpenID.

Currently, the dashboard requests an access_token with all scopes required by all widgets. Widgets use this shared access_token to make requests to secure APIs.

The problem is, because this shared access_token has so many scopes, it is too "powerful". We are concerned that by using this shared token, widgets and APIs may have more rights than they are entitled to. Ideally we'd like that every widget has a separate access_token with its own scope.

I'm not sure how to achieve this. If every widget requests its own access_token, then the user will be redirected to authorisation endpoint multiple times. This is unacceptable for UX reasons.

We have considered wrapping widgets in iframes. So each widget can redirect inside of its own frame without affecting the dashboard. However, because they all run on the same domain, they can always access access_tokens of other widgets (because they are stored in LocalStorage), so I'm not sure this is better from a security perspective.

How can we architecture the authorisation system in a dashboard so that all widgets have their own access_tokens?

Oleg
  • 184
  • 6
  • I think i saw your other question. I'm confused by your interpretation of these 'widgets' as entities with authorisation in their own right. are they owned by different companies or something? – Ewan Oct 30 '17 at 11:37
  • @Ewan My other question is unrelated. The "widgets" are small web apps (ideally webcomponents) written by various teams inside our large company. An example of a widget would be a chart that displays some data private to the user. – Oleg Oct 30 '17 at 12:18
  • and in creating the widget your org has decided to show that info to users right? theres no question of the widget having too much access. You can give it full rights to the data. you only care whether the user should be allowed to use widget – Ewan Oct 30 '17 at 17:45
  • How are you handling authorization? The `access_token` represents authentication OK, but is too opaque to be used for authorization purposes. JWT (the `id_token`) can include the roles or any application specific values which can be further used by each widget. I agree, multiple authentications are less than ideal, but can be handled without user interaction. That's similar to how Atlassian JIRA's dashboard works. Unless you have full PKI that requires you to enter a pin, it's invisible to the user. – Berin Loritsch Oct 30 '17 at 17:55
  • @BerinLoritsch I'm pretty sure that `access_token` means authorization, not authentication due to OAuth2 being an authorization framework. What do you mean by "*can be handled without user interaction*"? I'm under impression that users need to give their consent explicitly. – Oleg Oct 30 '17 at 20:02
  • @Oleg, that's a one-time set up between sites. Once that token has been properly registered, the user doesn't need to do it again. The big question you'll have to answer is what level (if any) integration your apps are going to share. This is more a policy question rather than a technical one. Particularly since all the sites are owned by the same company if I read your question correctly. – Berin Loritsch Oct 30 '17 at 20:45
  • @BerinLoritsch I'm not sure I understand. Are you suggesting that we keep the system as it is where all widgets share the same `access_token` containing all `scope`s? – Oleg Oct 30 '17 at 22:14
  • @Oleg, I'm struggling with what the end goal is. the `access_token` authorizes a connection, but doesn't do anything more granular than when that token was granted. You might have to perform 2 layer authorization (i.e. within the application). That works with a single token or multiple tokens. However, it's also not unheard of to use JWT internally which has the grants for that token. There are options. – Berin Loritsch Oct 31 '17 at 12:50
  • @BerinLoritsch The end goal is to have a token per widget (if that is even possible). – Oleg Oct 31 '17 at 15:26

1 Answers1

2

From a threat modeling perspective, it is not clear really what security benefit will you achieve by having each widget have its own token.

So unless it can be demonstrated that there is a clear security advantage (even if defense in depth), my suggestion would be to avoid adding complexity in your application, and keep it simple. Many security issues are caused by complexity.

For the case you present, let's look at the possibilities.

  1. If the client is compromised, (that is, client in OAuth 2.0 parlance as per RFC 6749) it does not matter whether each widget has a different token or not, all of them will be compromised. Likewise, if authorization server or resource server is compromised, again having a different token per widget doesn't help.

  2. If I were to really have a separate token for each widget, then the right model would be to have them as different clients with each having its own approved scopes that they can request from the authorization server. This will at least ensure that one widget cannot request a token with scopes that it is not approved for in requests to the resource server.

    However, based on your explanation, that does not seem to be the primary concern. (The only concern you have is that a single access token with too many scopes is shared by all widgets.) Even if it were, you would want to weigh it against usability because bad usability causes users to take shortcuts that you would want to avoid.

So based on these points, I would say that it does not seem to be a major security concern (unless I am missing something). If I were in your place, I might as well be happy getting one access token for the entire dashboard and using it as needed.

FYI, you may want to consult RFC 6819: OAuth 2.0 Threat Modeling and Security Considerations. I do not think that has anything related to this either.

Omer Iqbal
  • 3,224
  • 15
  • 22
  • 1
    "*if [...] resource server is compromised, again having a different token per widget doesn't help*" Why not? We have multiple resource servers. A compromised resource server might legitimately call another server using a token with all scopes. – Oleg Nov 07 '17 at 10:53
  • If you have multiple resource servers, and you're concerned one of them could be compromised then you can have one token per resource server so access token that grants access on one resource server is not seen by the other server. – Omer Iqbal Nov 07 '17 at 18:05
  • But then I'm back to the original problem of multiple `access_token`s which means a redirect per token. Also, it's more complicated than a token per widget. – Oleg Nov 07 '17 at 20:40
  • IMHO, this is a different problem. The client can get a refresh token from the authorization server with scopes needed across all resources. Then, as per RFC 6749 section 1.5, it can use the refresh token "to obtain additional access tokens with identical or narrower scope (access tokens may have a shorter lifetime and fewer permissions than authorized by the resource owner)." Essentially, the client can use the refresh token to get one access token per resource server with scopes that give it access only to that resource server. One server cannot then use a client's token to access another. – Omer Iqbal Nov 08 '17 at 07:57
  • In Implicit Flow there's no refresh token. – Oleg Nov 08 '17 at 09:59
  • Then, one solution is to fetch access tokens from the web app and send down with the dashboard code. – Omer Iqbal Nov 23 '17 at 13:06