-1

Someone pointed out to me this phrase on the OAuth website:

ID tokens should never be sent to an API.

(source)

We have 2 in-house applications, an ASP.NET back-end (the API), and a JavaScript front-end. They are separately deployed, but this is just the nature of modern front-end development I think. 10 years ago it would have been a single ASP.NET MVC application.

We need to secure it using single sing-on: only employees with a specific role should be allowed to use it.

So I think the front-end app should initiate authentication using OIDC, so with scope set to openid and using the code grant type (PKCE). When the front-end acquired the ID token, it can send it to the API and the API’s middleware will verify the signature and extract the role claims.

Back to the quote, and my question: if I should 'never' send an ID token to an API, then what am I supposed to do here?

To be clear, this question is about OIDC. There is no delegated authorization involving a 3rd-party, so I did not tag this question with the OAuth tag, because employees are not asked to consent to the front-end accessing 'their' resources on the back-end. The users simply must authenticate and have been assigned a role to be allowed to use the application.

Michiel van Oosterhout
  • 22,839
  • 15
  • 90
  • 132
  • 1
    Does this answer your question? [Should I send identity token to my api resources?](https://stackoverflow.com/questions/54204170/should-i-send-identity-token-to-my-api-resources) – Ouroborus Aug 29 '23 at 07:08
  • From what I understand there are basically two types of tokens: Authentication and authorization. Authentication is about proving who you are. Authorization is about what you can do. An ID token comes from authentication (SSO in your case) and would be converted into an authorization token. The authorization token is what would be sent to the API. (The authorization token may contain some kind of identifier for the user, but not the ID token itself, usually for purpose of tracking.) – Ouroborus Aug 29 '23 at 07:16
  • My understanding is that the access token would be strictly an OAuth 2 access token, so it would indicate that the user has given consent to allow a 3rd-party access to the user’s resources. It seems this will not achieve security since the user is allowed to just consent? In our scenario, authorization will be based on claims, not scopes, and only administrators would be in control of the claims, i.e. by making an employee member of a user group. So OIDC to let the user authenticate using single sign-on, and then check claims in the ID token to verify the employee is allowed to use the app. – Michiel van Oosterhout Aug 29 '23 at 07:21
  • I have since learned that our OAuth server (Azure AD) can 'enrich' an access token with claims about the user, including roles. This makes the access token sufficient for the role-based access control we plan to perform in the back-end API. – Michiel van Oosterhout Sep 01 '23 at 14:52

1 Answers1

1

The ID token represents proof of the authentication event and is designed to be read by clients to inform them of how and when authentication occurred. It is pretty normal to ignore this token though.

The access token is designed to be sent to APIs. It is often not readable by clients. It has a short lifetime such as 15 minutes, after which it is refreshed using a refresh token.

The access token has scopes, eg finance, which ensure that requests are immediately rejected if sent to obviously invalid APIs or endpoints. It also has claims, eg a role or tenant_id, which have different values for each user. Scopes and claims together ensure that clients can be issued locked down access tokens, with least privilege to APIs.

If your API security ever undergoes third party reviews, eg PEN tests, then use of access tokens as API credentials would be the expected behaviour.

The most common option these days is to use OIDC and OAuth 2.0 together. Also, OAuth is very widely used in first-party use cases, due to the rich API message credential and the ability to authenticate in many ways. In such cases the consent step is omitted. This does not change the roles of the tokens though.

Gary Archer
  • 22,534
  • 2
  • 12
  • 24
  • Thanks. "`role` ... lock down the permissions the client is granted", do you mean the client application or the end-user? It seems from OAuth 2 spec that scopes indicate are what the end-users allows the client to do (on the end-user's behalf), whereas roles are not part of the OAuth spec (I think). Reading up on our OAuth 2 auth server (Azure AD), I have since learned that it allows us to set it up in such a way that after the end-user consents to the scopes, role claims for the user can be added to the access token. For us, this 'closes' the loop, we can send the access token to the API. – Michiel van Oosterhout Sep 01 '23 at 14:49
  • 1
    Yep - claims are the user level privileges so I improved the wording. Claims are the main authorization mechanism, eg that APIs use to enforce business rules. – Gary Archer Sep 01 '23 at 16:33