Skip to content

[BREAKING] feat!: remove Authentication layer - #1390

Open
tusharpandey13 wants to merge 20 commits into
masterfrom
feat/auth-separation-v6
Open

[BREAKING] feat!: remove Authentication layer#1390
tusharpandey13 wants to merge 20 commits into
masterfrom
feat/auth-separation-v6

Conversation

@tusharpandey13

@tusharpandey13 tusharpandey13 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

What this does

Removes the Authentication layer from node-auth0, making it a Management-API-only SDK. ManagementClient continues to work — internal token acquisition is handled directly via the client credentials grant.

Changes

Area Change
Removed src/auth/ (9 files), src/userinfo/AuthenticationClient + UserInfoClient gone from main entrypoint
TokenProvider Inlined client credentials grant (raw fetch + jose). Preserves 10s leeway refresh, in-flight de-dup, client-secret + client-assertion modes. mTLS token endpoint uses mtls.{domain} automatically. Timeout (10s) throws ManagementError(408). Non-2xx throws ManagementError with parsed OAuth error body.
Dead code Removed src/lib/runtime.ts, auth-only src/utils.ts helpers (mtlsPrefix, resolveValueToPromise). Kept generateClientInfo for telemetry
Dependencies Removed uuid
Docs README updated; migration guide rebuilt with corrected v6→v7 method-mapping table, error handling section, mTLS breaking changes

Breaking changes

  • AuthenticationClient and UserInfoClient removed from auth0 main entrypoint. The auth0/legacy entrypoint (auth0-legacy v4) still ships them.
  • getUserInfo: UserInfoClient is removed. Use authClient.getUserInfo({ accessToken }) from @auth0/auth0-auth-js (shipped in #228). For ID token claims, use TokenResponse.claims directly.
  • mTLS: Management clients with useMTLS: true must supply an explicit fetch option. Throws at construction if absent — prevents silent 401s at request time. Token endpoint uses mtls.{domain} automatically.
  • mTLS + client-assertion: mutually exclusive — throws at construction if both are provided (incompatible token endpoint auth methods). useMTLS removed from ManagementClientOptionsWithClientAssertion type.
  • Domain validation: domain must be a bare hostname. Slashes or query strings throw at construction.
  • Error type: token acquisition failures throw ManagementError (not Error). Carries statusCode and parsed body.

Implementation notes

  • TokenProvider POSTs to https://{domain}/oauth/token (or https://mtls.{domain}/oauth/token when useMTLS) with application/x-www-form-urlencoded. expires_in (seconds) → Date.now() + expires_in * 1000 for cache expiry.
  • Client-assertion path uses jose (importPKCS8 + SignJWT), already a project dependency.
  • User-supplied header keys normalized to lowercase before SDK headers override — prevents duplicate Content-Type/content-type causing 400s.
  • Internal token request advertises node-auth0 identity in the Auth0-Client header.
  • Telemetry env field (runtime fingerprint) intentionally absent — documented in code.

Tests

  • token-provider.test.ts: TC-2.1–2.16. Covers credential modes, cache hit, leeway refresh, in-flight de-dup, error propagation, error-not-cached retry, expiry, mTLS customFetch forwarding, mTLS throw-on-no-fetch, domain validation, mTLS+assertion guard, header normalization, typed error body, timeout error.
  • export-surface.test.ts: asserts AuthenticationClient/UserInfoClient absent from main entrypoint.
  • Deleted tests/auth/**, tests/userinfo/**, tests/lib/runtime.test.ts.

Validation

  • Build (CJS + ESM)
  • Lint
  • Unit tests — 555/555

Known issues

yarn.lock contains 3 entries (jose, oauth4webapi, openid-client) that resolve to the internal Artifactory registry (a0us.jfrog.io). These predate this PR and will cause 401s for external contributors running yarn install. The 3 will be cleaned up in a separate lockfile-regen PR.

🤖 Generated with Claude Code

Related PRs

tusharpandey13 and others added 4 commits August 17, 2026 13:12
…uth-js

BREAKING CHANGE: removes AuthenticationClient and UserInfoClient from the
auth0 package. Management API token acquisition now delegates to
@auth0/auth0-auth-js AuthClient.getTokenByClientCredentials. mTLS now
requires an explicit fetch option.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…p any cast

Match published TelemetryConfig ({enabled:false} | {enabled?:true,name,version});
drop unsupported env field; type options as AuthClientOptions.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ent token tests

- Delete obsolete tests/auth/**, tests/userinfo/**, tests/lib/runtime.test.ts
- Rewrite token-provider test to mock @auth0/auth0-auth-js AuthClient (8 cases:
  both credential modes, cache hit, leeway refresh with expiresAt*1000 boundary,
  in-flight dedup, error propagation, error-not-cached, expiry)
- Add export-surface test asserting AuthenticationClient/UserInfoClient removed
- jest: map @auth0/auth0-auth-js to CJS stub for unit/wire (avoids ESM
  openid-client under Jest CJS runtime); allow openid-client/oauth4webapi
  transform in root-tests ESM project

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- README: replace AuthenticationClient/UserInfoClient sections with pointers
  to @auth0/auth0-auth-js; add 'Migrating from v6 to v7' with method-mapping
  table and mTLS note; preserve auth0/legacy docs
- CHANGELOG: v7.0.0 breaking-change entry
- token-provider: doc comment on @auth0/auth0-auth-js delegation + expiresAt
  seconds-to-ms conversion

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tusharpandey13 tusharpandey13 changed the title feat!: remove Authentication layer (v7.0.0), delegate Management token to @auth0/auth0-auth-js [DO NOT MERGE] feat!: remove Authentication layer (v7.0.0), delegate Management token to @auth0/auth0-auth-js Aug 17, 2026
tusharpandey13 and others added 2 commits August 24, 2026 21:10
…dd TC-2.9/2.10

Throw at construction when useMTLS=true and no fetch is provided, preventing
silent 401s at request time. Replace (options as any).fetch with a typed
intersection narrowing. Add comments documenting the telemetry env-field delta
and node-auth0 identity intent. Add TC-2.9 and TC-2.10 covering both paths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tusharpandey13 tusharpandey13 changed the title [DO NOT MERGE] feat!: remove Authentication layer (v7.0.0), delegate Management token to @auth0/auth0-auth-js [DO NOT MERGE] feat!: remove Authentication layer , delegate Management token to @auth0/auth0-auth-js Aug 25, 2026
@tusharpandey13 tusharpandey13 changed the title [DO NOT MERGE] feat!: remove Authentication layer , delegate Management token to @auth0/auth0-auth-js [DO NOT MERGE] feat!: remove Authentication layer Aug 25, 2026
tusharpandey13 and others added 2 commits August 25, 2026 10:44
…t credentials grant

Replace the auth0-auth-js AuthClient delegation with a self-contained raw
fetch + jose implementation. The dep added openid-client and oauth4webapi as
transitive dependencies for what amounts to a single POST to /oauth/token.

Key changes:
- Inline fetchToken(): URLSearchParams body, Content-Type header, response parsing
- Client-assertion path: importPKCS8 + SignJWT via jose (already a dep)
- mTLS: forward caller-supplied fetch; guard against useMTLS + clientAssertion
  combination (mutually exclusive auth methods)
- Domain validation: reject domains containing slashes or query strings
- Telemetry header: use jose base64url.encode instead of Buffer (portability)
- expiresAt computed as Date.now() + expires_in * 1000 (relative, same as pre-v7)
- Add TC-2.11 (domain validation) and TC-2.12 (mTLS+assertion guard); 13/13 pass

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Delete tests/lib/utils.test.ts — tests resolveValueToPromise which was
  removed from src/utils.ts as auth-only dead code
- Add fetch mock to mTLS test in management-client-custom-domain.test.ts —
  TokenProvider now throws at construction when useMTLS=true and no fetch
  is provided (fail-fast guard added in previous commit)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tusharpandey13
tusharpandey13 marked this pull request as ready for review August 25, 2026 05:28
@tusharpandey13
tusharpandey13 requested a review from a team as a code owner August 25, 2026 05:28
@tusharpandey13 tusharpandey13 changed the title [DO NOT MERGE] feat!: remove Authentication layer [BREAKING] feat!: remove Authentication layer Aug 25, 2026
@codecov

codecov Bot commented Aug 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.31250% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.40%. Comparing base (f9d6413) to head (8ddcee5).

Files with missing lines Patch % Lines
src/management/wrapper/token-provider.ts 95.31% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1390      +/-   ##
==========================================
- Coverage   89.73%   89.40%   -0.33%     
==========================================
  Files         441      429      -12     
  Lines       20799    20380     -419     
  Branches    10146     9723     -423     
==========================================
- Hits        18663    18221     -442     
- Misses       2136     2159      +23     
Flag Coverage Δ
alltests 89.40% <95.31%> (-0.33%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/index.ts 100.00% <ø> (ø)
src/lib/middleware/auth0-client-telemetry.ts 57.14% <ø> (-35.72%) ⬇️
src/management/wrapper/ManagementClient.ts 100.00% <ø> (ø)
src/utils.ts 100.00% <ø> (ø)
src/management/wrapper/token-provider.ts 95.77% <95.31%> (-4.23%) ⬇️

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…erated

mTLS token acquisition reads options.fetch which is defined on
BaseClientOptions in the Fern-generated BaseClient.ts. Add a comment
at the usage site so the dependency survives future regenerations.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/management/tests/__mocks__/auth0-auth-js.cjs Outdated
Comment thread src/management/wrapper/token-provider.ts Outdated
…th-js mock artifacts

- Forward plain-string options.headers to POST /oauth/token, matching the
  behavior fixed in v6 via PR #1392. Supplier-function headers are skipped
  (require async resolution, not supported on the token endpoint path).
  SDK-controlled headers (Content-Type, Auth0-Client) always take precedence.
- Delete src/management/tests/__mocks__/auth0-auth-js.cjs — leftover CJS stub
  from when TokenProvider delegated to @auth0/auth0-auth-js; no longer needed.
- Remove three moduleNameMapper entries for @auth0/auth0-auth-js from jest.config.mjs.
- Add TC-2.13 covering plain-string forwarding, supplier filtering, and override precedence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/management/wrapper/token-provider.ts Outdated
Comment thread src/management/wrapper/token-provider.ts Outdated
) {
this.authenticationClient = new AuthenticationClient({ ...options, headers: undefined });
// Validate domain: must be a bare hostname, no slashes or query strings.
if (/[/?#]/.test(options.domain)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check only runs on the client credentials path, since TokenProvider is only constructed from createTokenSupplier. With a static token, new ManagementClient({ domain: "tenant.auth0.com/x", token }) still builds https://tenant.auth0.com/x/api/v2 and nobody complains. An empty string also passes the regex.

Since the PR lists domain validation as a breaking change, it would be better to do this in the ManagementClient constructor (or in buildManagementBaseUrl) so it covers both auth modes, and to reject empty or whitespace only domains too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acknowledged. The guard in TokenProvider only fires on the client-credentials path, so new ManagementClient({ domain: "tenant.auth0.com/x", token }) slips through. Moving it to the ManagementClient constructor would close the gap for all auth modes. Deferring to a follow-up to keep this PR scoped to auth-separation. Noted as a known gap.

Comment thread src/management/wrapper/token-provider.ts
Comment thread src/management/wrapper/token-provider.ts Outdated
Comment thread README.md
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread .gitignore Outdated
Comment thread yarn.lock Outdated
tusharpandey13 and others added 7 commits August 26, 2026 17:07
… error

- Token endpoint uses `mtls.{domain}` when useMTLS is set
- Normalize all user-supplied header keys to lowercase before SDK headers override
- Wrap fetch in AbortSignal.timeout(10_000); timeout throws ManagementError(408)
- Non-2xx response parses JSON body first, falls back to text, throws ManagementError

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
useMTLS + clientAssertionSigningKey throws at construction — they are
mutually exclusive auth methods. Removing useMTLS from WithClientAssertion
prevents the type from advertising an impossible configuration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- makeErrorResponse upgraded to 3-param with JSON body (errorCode, description)
- TC-2.6, TC-2.7: assert ManagementError instance + statusCode instead of regex
- TC-2.9: assert mTLS-prefixed token URL (mtls.{domain})
- TC-2.13: update header key assertions to lowercase (matches normalization)
- TC-2.14: header case normalization — user lowercase key overridden by SDK
- TC-2.15: ManagementError carries statusCode and parsed OAuth error body
- TC-2.16: AbortSignal timeout throws ManagementError(408)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two entries were accidentally merged into one line `*.lcov.forge/` which
matched neither pattern correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix 4 broken links: auth0/node-auth0/tree/.../auth0-auth-js -> auth0/auth0-auth-js/tree/...
- Fix method mapping table: database.signUp/changePassword use nested namespace
- Fix passwordless login* methods: split into challenge + getTokenByPasswordlessDbConnection
- Fix sendSMS -> sendSms (correct camelCase)
- Remove non-existent getUserInfo: no such method in auth0-auth-js; document workarounds
- Add AuthApiError -> ManagementError migration section with before/after examples
- Add mTLS breaking changes block: explicit fetch required, mtls.{domain} automatic, mutually
  exclusive with clientAssertionSigningKey
- Update User Profile Information section to reflect actual available APIs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This package was removed from package.json in 53d0879 but its yarn.lock
entry remained. Removing the unreferenced entry.

Three other packages (jose, oauth4webapi, openid-client) still resolve to
the internal Artifactory registry — these will be cleaned up in a
separate PR once yarn can reach the public registry in CI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
getUserInfo shipped in auth0-auth-js db2435c. Update the User Profile
Information section and migration table to point at
authClient.getUserInfo({ accessToken }) with correct MRRT audience guidance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread src/management/wrapper/token-provider.ts Outdated
Comment thread src/management/wrapper/token-provider.ts
Comment thread src/management/wrapper/token-provider.ts
Comment thread src/management/wrapper/token-provider.ts Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
The auth-separation commit introduced yarn.lock entries resolving to the
internal a0us.jfrog.io Artifactory, which returns 401 for external
contributors on this public repo. jose@^6, oauth4webapi, and openid-client
were transitive dependencies of @auth0/auth0-auth-js, which was reverted
out of package.json. Remove the three now-unreferenced blocks so no entry
points at a host external contributors cannot reach.

The runtime jose dependency resolves via jose@^5 from the public registry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tusharpandey13

Copy link
Copy Markdown
Contributor Author

TokenProvider error handling:
- Read the error response body exactly once. Calling response.json()
  then response.text() throws 'Body has already been read', which
  swallowed non-JSON error payloads (e.g. proxy/WAF 502s). Read text
  first, then attempt to parse it as JSON.
- Map AbortError to a 408 in addition to TimeoutError. Built-in fetch
  aborts with TimeoutError, but node-fetch (used on the mTLS path via a
  custom fetch) aborts with AbortError; without this the mTLS timeout
  surfaced a raw abort error instead of a 408.
- Attach a 'token request failed' message so a 401 from the token
  endpoint is distinguishable from a Management API 401.

README:
- Import from 'auth0' (the published package name), not
  '@auth0/node-auth0', in the error-handling examples.
- Map passwordless loginWithEmail/loginWithSMS one-to-one to
  getTokenByPasswordlessEmail/getTokenByPasswordlessSms, matching the
  migration guide and auth0-auth-js.

Tests: add AbortError timeout case and a non-JSON error-body case.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Combining useMTLS with clientAssertionSigningKey previously threw at
construction. That was an undeclared breaking change: v6 added the mtls.
endpoint alias from useMTLS alone, with no check on the auth method, so
private_key_jwt with a TLS client certificate worked and yielded a
certificate-bound token.

mTLS (RFC 8705) is a transport-layer concern that is independent of the
client authentication method. The TLS client certificate produces a
certificate-bound access token regardless of whether the client
authenticates with client_secret or client_assertion. Rejecting the
stronger credential (private_key_jwt) while allowing the weaker one
(client_secret) was also inconsistent.

- Add useMTLS to ManagementClientOptionsWithClientAssertion so it is on
  both members of the credentials union.
- Remove the mutual-exclusivity throw and read useMTLS off the union
  directly instead of casting to the client-secret type.
- TC-2.12 now asserts the combination is allowed and hits the mtls alias
  with a client_assertion body.
- README: document that useMTLS works with both auth methods.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants