Protect APIs using OAuth 2 client credentials grant

Hi

I’m new to Auth0.

I’m implementing APIs in Next.js 14 to be called by multiple external systems.

How can I protect the APIs using OAuth 2.0 client credentials grant? For example, the external system will obtain the access token using client id and client secret, and then call the API using the access token.

Can Auth0 support this use case?

Appreciate if you can point me to the examples, documents and discussions.

Thank you!

:wave: @tjhoo

Having replied to your other recent post here I thought I’d follow up on this one too :smiley:

I’m implementing APIs in Next.js 14 to be called by multiple external systems.

Cool :sunglasses: I’d recommend you take a look at our How to Authenticate with Next.js and Auth0: A Guide for Every Deployment Model Blog article if you haven’t already; I’m not a Next.js expert, but you shouldn’t need any security sensitive information stored in the API in order to validate an Auth0 Access Token.

How can I protect the APIs using OAuth 2.0 client credentials grant? For example, the external system will obtain the access token using client id and client secret, and then call the API using the access token.

As illustrated in the aforementioned Blog article, a Client Credentials wouldn’t typically be used in order to obtain an Access Token token for calling an API. In a Next.js context, where the application is typically a SPA - i.e. a non-confidential Single Page Application client - Authorization Code Grant with PKCE would be used instead. And this doesn’t require that you store any Client Secret for use by the application :sunglasses:

Hope this helps :smiley:

Welcome to the Auth0 Community, by the way :sunglasses: :tada:

1 Like

Thanks for your pointers, but my Next.js application is not serving any page but only the API endpoints (we can think of it like a Express.js serving the API endpoints).

I have created a GitHub repository at GitHub - tjhoo/kinde-client-credentials for Kinde support. Hopefully the README.md describes my use case appropriately …

:thinking: From the looks of your repo, the libraries you’re using are attempting to establish a user-authenticated context. For a stateless API, an authenticated user context - in fact, any authenticated context - shouldn’t be necessary. Your API should simply be validating the Access Token sent to it to determine if the call is authorized.

Thanks for your pointers, but my Next.js application is not serving any page but only the API endpoints (we can think of it like a Express.js serving the API endpoints).

Perhaps take a look at the Auth0 Node (Express) API SDK Quickstarts: Authorization quickstart which illustrates just that - i.e. validating the Access Token passed to the API. Of particular interest to you will be the section here I believe :sunglasses:

FYI, Auth0 supports the use of the RS256 asymmetric encryption algorithm by default for JWT signature creation/validation; Access Tokens generated by Auth0 are in JWT format. So, via the use of public-private key cryptography, it’s possible for the API to validate an Access Token without the need for any secret information held (at the API).

Thanks, @peter.fernandez

I tried the example in Express.js API authorization and it is exactly what I am looking for.

So from here, I should add machine-to-machine application for each of the external applications who wants to call my API?

I tried the example in Express.js API authorization and it is exactly what I am looking for.

Cool; glad to hear it worked for you @tjhoo :sunglasses:

So from here, I should add machine-to-machine application for each of the external applications who wants to call my API?

I’m going to start by referring to my reply to your other post: i.e. M2M tokens and active users calculation? - #2 by peter.fernandez. If you can share a little more about what services your API provides, it may be helpful in determining the particular authentication workflow you require in order to obtain an Access Token.

If you are indeed looking for machine-to-machine level authentication, then yes, you should create a machine-to-machine application for each of the external applications in Auth0 and then they will use their respective Client ID and Client Secret in order to get an Access Token for use when calling your API.

Hope this helps :sunglasses:

My APIs are used to collect audit data from one or more accounting systems (the external application). The accounting system will post the audit data to my APIs.

When my API endpoints received the data, I also need to figure out which “client” is the data from (how?).

It looks like we can get the client id from the req.auth.payload object like this,

router.post('/', (req, res) => {
  // every M2M application has a unique client id like "<client-id>@clients"
  const client = auth.payload.sub;
  res.json({ ... })
})