Why is OAuth Client Credentials safer than OAuth Username-Password

connected-appsoauth2rest-apiSecurity

According to Salesforce, here

"You can use the username-password flow to authorize a client via a connected app that already has the user’s credentials. However, we recommend avoiding this flow because it passes credentials back and forth."

and here

"The OAuth 2.0 user-agent and username-password flows are considered insecure and aren’t recommended.

… In place of the username-password flow, we recommend using OpenID Connect dynamic client registration or the OAuth 2.0 client credentials flow."

and here

"The username-password flow presents security risks. We recommend using the OAuth 2.0 client credentials flow instead."

The OAuth 2.0 Client Credentials Flow documentation then goes on to say:

Sometimes you want to directly share information between two applications without a user getting in the way. For these scenarios, you can use the OAuth 2.0 client credentials flow. In this flow, the client app exchanges its client credentials defined in the connected app—its consumer key and consumer secret—for an access token. This flow eliminates the need for explicit user interaction, though it does require you to specify an integration user to run the integration. You can use this flow as a more secure alternative to the OAuth 2.0 username-password flow.

So, what exactly makes Client Credentials more secure than username-password? Is it just the fact that you can't use the client id/client secret for UI login and that the requesting server doesn't need to securely store login credentials?

If Client Id/Secret are intercepted or otherwise leaked, it feels like it would be just as risky as if username-password for an API-Only user (no UI Access) was intercepted or leaked.

Are there other security benefits to Client Credentials that I'm missing?

Best Answer

Well, any security mechanism isn't going to be of much use if compromised. The difference here is in the extent of the damage you can suffer in such an event.

One benefit I can think of is that the client credentials serves as a centralized point for administration.

While "centralized administration" is broadly true for using a connected app in general (you can revoke/expire tokens/sessions), you can also regularly rotate the client key and secret. That certainly sounds like a better approach than trying to find out which specific users were compromised and having everyone reset their passwords (just in case).

The main benefit appears to be in selecting a particular integration user that you can tightly control permissions for (and grant a minimal set of permissions). More specifically, that integration user is the only possible user that will execute an action given the token returned by the connected app. It doesn't matter if an attacker has obtained the user credentials for a sysadmin in the org, any compromise of the client credentials is limited to the permissions of the assigned integration user.

The client secret is also almost certainly going to have much higher entropy than any user password.

Another benefit from an administration point of view is that an integration user isn't really going to "leave" your organization. There's no need for "wait, were we using Jan from Accounting's password anywhere else?".