e.dan
e.dan

Reputation: 7507

API authentication, using home-grown "API Key" vs. OAuth2 client credentials flow

Our application exposes REST APIs which are currently used by our UI only. The UI currently authenticates users using the OIDC Authorization Code flow, which requires user interaction with the authorization server, in this case, AWS Cognito.

We need to provide customers with a way to authenticate with our application and call our APIs with their own integrated client applications, other than our UI, in a "M2M"-friendly manner. Meaning, we want them to be able to call our APIs from a python script they've developed, for example, or POST data to our API from their application.

The solution proposed by Engineering:

  1. Provide a way to configure "API Keys" in the application, which consist of an ID and a secret.
  2. Store a hashed and salted version of the secret in the application.
  3. The customer client application can authenticate with our APIs by sending the API key ID and secret, which is hashed in the application and compared to the stored version.

We are told that using API keys like this is insecure, and, instead, we should implement the OAuth2 Client Credential flow (using the Private Key JWT method).

My questions:

  1. Why would the OAuth2 Client Credential flow be more secure? In either case (our API keys solution and the OAuth2 solution), the customer client application needs to store a secret: either the private key, or the API key. In both cases, the secret is not stored in the application: either the public key, or a hashed secret is stored.
  2. My understanding is that OAuth2 is not intended to be used for authentication, rather for authorization, and OIDC is built on top of OAuth2 for authentication. Is my understanding correct? So are we supposed to use OIDC for this instead, or is it okay/correct to use OAuth2 for authentication in this case?
  3. If it is better to use the Client Credentials flow, is it possible to use AWS Cognito for this somehow? Or must we use some other authorization server that supports the Client Credentials flow with the Private Key JWT method? We already have some experience with Keycloak - is this a good choice? Or would one implement the OAuth2 in the application itself (a NodeJS Express app) using something like @node-oauth/oauth2-server or oidc-provider?

Upvotes: 0

Views: 123

Answers (1)

Gary Archer
Gary Archer

Reputation: 29291

The customer should route requests to your APIs via their own APIs. It is a little unclear from your question whether your data has a relationship with the customer's users. Eg do you store resources mapped to particular users?

OAUTH FLOWS

The benefits of using an OAuth flow like client credentials include these:

  • You use access tokens as time restricted credentials in API requests, to limit the impact of intercepted tokens / requests
  • API credentials can be locked down, eg using a tenant_id claim and scopes, to reduce privileges and the impact of stolen tokens
  • You can use stronger key based client credentials than API keys, where the client authenticates without disclosing their secret - there are also built-in key renewal patterns
  • You get a consistent authorization coding model in APIs that your developers use, based on scopes and claims

In your API keys solution, an attacker might be able to replay a stolen credential for a long time, regardless of whether it is hashed and salted. Also, a server breach might reveal the API keys of all customers, since an attacker could hash and salt stolen values and resend them.

USER AUTHENTICATION

When a user is present, you run a code flow and always authenticate the user. How this works is left to the implementation of the authorization server (and how you configure it) in the OAuth and OIDC standards. If you clarify the relationship of customer users to your APIs I will expand on this. It might be that the code flow is the correct flow rather than the client credentials flow.

PROVIDERS

You should spend some time to identify the standardised flows and security behaviours that OAuth enables for your use case. The solution you choose might also depend on data sensitivity, threat mitigations and your time to market.

If you choose OAuth then clarify your requirements and do a proof of concept before committing to a provider. An OAuth solution should keep your your code simple, while you use security vetted by many experts.

Upvotes: 1

Related Questions