3

First, let me assure you that I have read a number of posts on the topic before asking this question, but I am still confused and would appreciate more insights.

So, here's the premise:

  • There is a client application that authenticates the user via OpenID Connect;
  • This application talks to an external API ("resource server") that needs to perform a fine-grained authorization based on the user identity;
  • The external API receives an access token (JWT bearer) from the client application. The access token is issued by the authorization server in scope of an OpenID Connect flow;
  • The access token has the audience claim set to the resource server's ID (and the resource server does validate the audience claim);
  • The access token has a UPN / email claim describing the identity of the user.

Now here's where I get confused:

On one hand, I am using OIDC and not plain OAuth 2.0, so I should be in good standing regarding security vulnerabilities (of course provided I have measures in place for mitigating CSRF attacks and for rejecting any "forged" tokens).

On the other hand, though, I am passing information about the user in an access token which is believed to be a big no-no in the world of OIDC & OAuth.

Am I misunderstanding something? Is it possibly safe to have identity information in an access token provided the access token was obtained in scope of an OIDC flow?

Just in case, I realize that there is a notion of scopes, but they do not look like an appropriate tool for defining and managing fine-grained permissions.

5
  • UPN/Email is a default claim in OIDC, so that's expected in most deployments. Is there some other claim you're worried about? What other info are you interested in? Also, in many cases the resource server will use the user id (often based off email) to look up local-to-server permissions/roles. Commented May 17, 2018 at 14:28
  • @Clockwork-Muse only UPN/email, and exactly as you are describing, the resource server will use the email in lieu of the user id.
    – DmytroL
    Commented May 18, 2018 at 20:07
  • ... where are you finding "passing user info in a token is a no-no"? You primarily want to keep info out to prevent somebody from using it if the token is stolen (ie, no SSN), but email isn't (normally) considered that secure/confidential. If the access token is stolen, though, normally you worry more about it being used than being read. Putting some id information in is primarily a convenience for the service, so they don't have to ping the auth server for the information. Commented May 18, 2018 at 20:52
  • @Clockwork-Muse I am not sure if I have read exactly this wording somewhere, and it could as well be I am just misinterpreting the "OAuth is not an authentication protocol" mantra. What I do remember reading for sure is that access tokens cannot represent a specific user since no authentication happens when an access token is being issued. Meaning, that a resource server should not make any assumptions about the user based on an access token since the access token is nothing more than a "valet key". But could it be that "valet key" tokens are only a case with "plain" OAuth but not OIDC?
    – DmytroL
    Commented May 20, 2018 at 7:53
  • "What I do remember reading for sure is that access tokens cannot represent a specific user since no authentication happens when an access token is being issued." - Authentication != Authorization. An access token is a list of things you're authorized to access, which is going to include the user unique id (subject, which won't change if/when email does). In order to get an access token, you've already authenticated yourself (user to auth server), now you just need to webserver to get the list of viable claims (authorized actions), without it worrying about checking who you are. Commented May 20, 2018 at 19:16

1 Answer 1

0

Yes it's an abuse. In OIDC, claims about the user can be obtained by the client in two ways:

  • The ID token (which is a JWT).
  • The userinfo JSON endpoint (by exchanging the OAuth access token).

The access token isn't necessarily a JWT. You can't rely on it containing any information that the client can use. It could just be a random string. The intended audience for the access token is other components of the remote systems, not the client.

That said, since both the ID token and Access token are supplied together (in the same response, typically through a secure connection with the trusted identity provider) then in practice, if the provider does use a JWT access token, the client can probably trust its claims as much as it trusts anything else.

If you're implementing the backend, then you should probably ensure your access token isn't leaking personal information beyond what you already deliberately expose in the ID token or userinfo response. So if the resource server does need finer grained information, maybe use an opaque random bearer token rather than a JWT, and have the resource server use a secure backchannel microservice to map the token to the claims (so that the private claims are not exposed to the client). Or at minimum, use an encrypted JWT for the access token, and don't expose the decryption key externally.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .