Expired Management API Token with node-auth0

Hi,

I’m having issues with the access token expiring when using the ManagementClient from the node-auth0 library. Looking at the code on GitHub, it seems like the ManagementClient should automatically get an access token through the TokenProviderMiddleware, including when the current access token expires.

export class ManagementClient extends ManagementClientBase {
  constructor(options: ManagementClientOptionsWithToken);
  constructor(options: ManagementClientOptionsWithClientCredentials);
  constructor(
    options: ManagementClientOptionsWithToken | ManagementClientOptionsWithClientCredentials
  ) {
    super({
      ...options,
      baseUrl: `https://${options.domain}/api/v2`,
      middleware: [
        new TokenProviderMiddleware(options),
        ...(options.telemetry !== false ? [new TelemetryMiddleware(options)] : []),
      ],
      parseError,
    });
  }
}

In TokenProvider

  public async getAccessToken() {
    if (!this.accessToken || Date.now() > this.expiresAt - LEEWAY) {
      this.pending =
        this.pending ||
        this.authenticationClient.oauth.clientCredentialsGrant({
          audience: this.options.audience,
        });
      const {
        data: { access_token: accessToken, expires_in: expiresIn },
      } = await this.pending.finally(() => {
        delete this.pending;
      });
      this.expiresAt = Date.now() + expiresIn * 1000;
      this.accessToken = accessToken;
    }
    return this.accessToken;
  }

In my app, I initialize a new ManagementClient every time I want to hit a Management API:

export const getAuth0Client = () =>
  new ManagementClient({
      domain: process.env.X,
      clientId: process.env.Y,
      clientSecret: process.env.Z,
  })

I expect that each client instance should have a fresh access token. Strangely, I only hit the ManagementApiError: Expired token received for JSON Web Token validation error when trying to access users or roles but not invites.

Can you please help me understand what the issue might be?

Thanks!

Hi @alan.h,

Welcome to the Auth0 Community!

The error you experience happens when the access token being used has expired. I suggest referring to this related community post that addresses this issue.

Essentially, you will want to verify the exp claim of your Management API access token is still valid:

  1. Copy the generated Management API token from your code,
  2. Paste the token on https://jwt.io/ and copy exp value in the payload
  3. Go to https://www.epochconverter.com/ and verify if the exp value is expired.

Let me also mention that you might hit the capacity for your monthly M2M authentication calls if you issue a new access token for every request. In general, you should cache the access token and renew it only once it has expired.

Thanks,
Rueben

Hi @rueben.tiow,

I ended up making a manual access token request using an AuthenticationClient and the clientCredentialsGrant method.

    const client = new AuthenticationClient(config)

    const audience = `https://${config.domain}/api/v2/`
    const {
      data: { access_token: newToken },
    } = await client.oauth.clientCredentialsGrant({ audience }, { initOverrides: IGNORE_CACHE })

export const IGNORE_CACHE: InitOverride = ({ init }) =>
  Promise.resolve({
    cache: "no-store",
    headers: { ...init.headers, "Cache-Control": "no-store" },
  })

I then pass this token into the ManagementClient instead of relying on it internally fetching an access token, which looks to have fixed my issue. The IGNORE_CACHE headers are probably relevant; I had similar issues previously where my Management API request responses were getting cached.

I’m also now checking the expiration to ensure I’m not requesting a new token before the current one has expired, thanks for the callout!

My previous confusion was due to the fact that the expired token error was only being hit when I was trying to fetch users / roles, but not invites. I’d assume that if the access token is expired, it should appear expired to all endpoints (and likewise for valid access tokens).

Regardless, my issue is now resolved, thanks again!

1 Like

Hi @alan.h,

Thanks for reply and sharing your approach with the rest of the Community!

Please reach out to us again if you have any additional questions.

Cheers,
Rueben