Assuming that both travel over the latest version of TLS, why should I use client credentials?

The obvious answer is:

  1. The access token will expire at some point
  2. The client id and secret will travel only once over the wire
  3. We can also use a refresh token, further strengthening the security

I argue that we could also make the username/password or preshared secret travel only once and share a session token that will too expire quite easily.

So in this scenario, is the refresh token the only reason to use it?

  • What if you want to share credentials across multiple services? Say let users use FB credentials on your app. Would you expect users to send their FB credentials to your app? – Limit Nov 26 '20 at 12:59
  • Also, client credentials are used when an app wants to act by itself. Not on behalf of users. – Limit Nov 26 '20 at 13:12
  • You got me wrong. I mean a preshared username password for system to system exchanges. Something like System1Username -> System1Password. – Athanasios Kataras Nov 26 '20 at 13:15
  • Better yet, remove username password and add preshared secret. – Athanasios Kataras Nov 26 '20 at 13:16
  • 1
    I think you forget that there is a third option between HTTP Basic Authentication and OAuth: the classic login directly at the server with a HTML form which then results in a session cookie. It looks for me that this option is what you actually want. The use case for OAuth is instead to explicitly have the authentication separated from the application, for example with single sign on. – Steffen Ullrich Nov 26 '20 at 14:16

The purpose of the client credentials grant flow is to enhance the ability of the client to bracket their privileges.

Here's the idea. You have a small piece of glue code which actually talks to the authorization server. It does the usual authorization code grant flow on behalf of other parts of the client and returns access tokens, like a proxy server. The rest of your code is then blissfully unaware of most of the OAuth complexity, and only has tokens for the specific resources that it needs to operate on. This is good, because it provides for privilege bracketing, reducing the amount of damage that can be done if a specific portion of the client is compromised. It also makes audit logging simpler and harder to subvert. You are likely to derive more security benefit from this if the proxy is heavily isolated from the rest of the client, such as by running on a separate machine, and only communicating with the rest of the client through a narrow and simple API. The proxy can also perform any sort of internal authentication which may be appropriate to the client's needs, to ensure that each component can only request tokens scoped to the appropriate permissions or resources.

But then you have a problem: Sometimes, part of the client wants to interact with a resource which does not belong to any end user, but instead belongs to the client as a whole. This might involve provisioning, billing, or any number of other administrative processes which are not specific to one end user. The "easy way out" is to give this piece of the client the same credential you gave to the aforementioned proxy, so that it can prove its identity. But if you do that, then this component will be able to do anything that the client as a whole can do, including requesting unrelated access tokens. This breaks our nice privilege bracketing.

This is the problem which the client credentials grant flow is designed to solve. The component which wants to do (whatever administrative thing) simply asks the OAuth proxy to obtain a client token for the specific resource it needs, and the proxy does so. That token is then scoped to this specific administrative task, and in no way entitles the component to access a user's data or anything else which is "not its job."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.