npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-entra-token

v0.1.0

Published

Microsoft Entra ID client-credentials for n8n, with the token cached and refreshed before it expires instead of after it fails

Downloads

156

Readme

n8n-nodes-entra-token

A Microsoft Entra ID client-credentials credential for n8n that caches the token and refreshes it before it expires, instead of after a request fails.

Drop-in for the HTTP Request node: pick it under Predefined Credential Type.

Why

n8n's built-in OAuth2 credential refreshes reactively. It sends whatever token it has stored, waits for the rejection, then fetches a new one. It also does not coordinate: seven items in one node produce seven separate token requests.

Measured on n8n 2.35.7, same workflow, same identity provider, six cycles of seven items each:

| | Token requests | Successful calls | Rejections | |---|---|---|---| | n8n's built-in path | 41 | 42 | 35 | | With this credential | 6 | 42 | 0 |

Same useful work. 85% fewer requests to the identity provider, and every 401 disappears because the token is renewed before it is needed.

Against a provider that rate-limits, those 41 requests are what earns a 429, and a burst of them arrives precisely when tokens expire together.

Install

Self-hosted n8n, as a community node:

npm install n8n-nodes-entra-token

Or Settings → Community nodes → Install and enter n8n-nodes-entra-token.

Configure

Create a credential of type Microsoft Entra ID (cached token).

| Field | Notes | |---|---| | Authority | Leave as is unless you are on a sovereign cloud, for example https://login.microsoftonline.us | | Directory (Tenant) ID | The tenant GUID from your app registration overview | | Application (Client) ID | | | Client Secret | Stored encrypted by n8n like any other credential | | Scope | Must end in /.default. Client credentials on the v2.0 endpoint reject delegated scopes with invalid_scope | | Refresh Margin (Seconds) | Default 30. How early to renew |

Then in an HTTP Request node: AuthenticationPredefined Credential TypeMicrosoft Entra ID (cached token).

How it works

The token lives in this package, not in n8n's credential store.

authenticate is used in its function form, which n8n runs once per outgoing request. That is the only hook that sees a request before it is sent, and therefore the only place a refresh can happen ahead of expiry. The alternative hook, preAuthentication, only runs when the stored token is empty or after a rejection has already happened, which is too late by construction.

Three things the cache does:

Refresh early. Expiry is tracked from the expires_in Entra returns, on a monotonic clock, and a token is treated as stale one margin before it expires. A token with two seconds left is useless for a call that takes three, and the margin also absorbs drift between your clock and Entra's.

Single-flight. When several requests find the token stale at the same moment, the first one fetches and the rest wait for that result. Seven callers, one token request. A waiter re-checks the cache after the lock frees, because a waiter that fetches immediately turns one stampede into seven sequential exchanges, which is worse than no coordination at all.

Key on the whole configuration. Authority, tenant, client, scope, and a hash of the secret. Rotating the secret takes effect on the next call rather than serving a token minted with the old one.

What it does not do

  • It is per-process. Two n8n workers mean two caches and two token requests rather than one. A shared cache would fix that and would add a network hop, a serialization format, and a failure mode of its own.
  • It does not recover from early revocation. If a token is revoked inside its stated lifetime, requests fail until it expires on the clock. Reacting to that needs a hook that sees responses, which the function form of authenticate does not get.
  • The token request does not use n8n's HTTP helper. The function form is not given the helper, and a verified community node may not add a runtime dependency, so the exchange uses Node's global fetch. Behind a corporate proxy that fetch is not proxy-aware, so the token request may fail where other n8n requests succeed.
  • It ships one credential, no nodes. Use it from the HTTP Request node.

Reproducing the numbers

Everything above was measured, not estimated. The harness is in spike/:

cd spike
python run_test.py --items 7 --cycles 6 --pause 25 --ttl 20

It starts an instrumented fake identity provider, brings up n8n in Docker, creates the credential and a workflow over the REST API, fires the workflow, and reports how many token requests actually reached the provider. Point the compose file at ./custom instead of ./custom-real to measure n8n's built-in path for comparison.

Development

npm install
npm test     # 9 checks on the cache logic, no framework, no network
npm run build

Licence

MIT