Skip to content

Add organization support to test token command for M2M Applications#1475

Merged
ramya18101 merged 8 commits intoauth0:mainfrom
ttstarck:feat/m2m-organization
Apr 9, 2026
Merged

Add organization support to test token command for M2M Applications#1475
ramya18101 merged 8 commits intoauth0:mainfrom
ttstarck:feat/m2m-organization

Conversation

@ttstarck
Copy link
Copy Markdown
Contributor

@ttstarck ttstarck commented Mar 27, 2026

Summary

The auth0 test token command allows developers to fetch tokens for their applications directly from the CLI. For Machine-to-Machine (M2M) apps, this uses the OAuth client credentials flow. However, when an API requires tokens to be scoped to a specific Auth0 organization, there was no way to pass that organization through the CLI — the command simply didn't support it.

This PR adds that missing --organization flag to auth0 test token for M2M apps, so developers can fetch organization-scoped tokens without leaving the terminal. It also adds a guardrail: if the client grant is configured to require an organization but none is provided, the CLI now surfaces a clear error pointing the user to the --organization flag, rather than silently failing.

🔧 Changes

  • internal/cli/utils_shared.go:
    • Moved checkClientIsAuthorizedForAPI here (was in test.go);
    • added organization param to BuildOauthTokenParams and runClientCredentialsFlow;
    • added validation for grants that require an organization
  • internal/cli/test.go: wired organization through to runClientCredentialsFlow
  • internal/cli/utils_shared_test.go: Added test coverage for BuildOauthTokenParams with organization, and a full table-driven test suite for checkClientIsAuthorizedForAPI covering all grant/org scenarios

🔬 Testing

auth0 test token fetches a token with the organization claim

./out/auth0 test token $CLIENT_ID --audience $AUDIENCE -o $ORG_ID --json-compact | jq keys
 ▸    Domain    : <domain>
 ▸    Client ID : <client-id>
 ▸    Type      : Machine to Machine

 ▸    ✅   Access Token copied to clipboard!

[
  "access_token",
  "expires_in",
  "token_type"
]

auth0 test token without --organization fails with a clear error when the client grant requires an organization

./out/auth0 test token $CLIENT_ID --audience $AUDIENCE --json-compact
 ▸    Domain    : <domain>
 ▸    Client ID : <client-id>
 ▸    Type      : Machine to Machine

 ▸    Failed to log in with client credentials for client with ID "<client-id>": the client grant for <audience> requires an organization.

Use the --organization flag to specify one..

auth0 test token without --organization succeeds when the grant does not require an organization

./out/auth0 test token $CLIENT_ID --audience $AUDIENCE --json-compact | jq keys
 ▸    Domain    : <domain>
 ▸    Client ID : <client-id>
 ▸    Type      : Machine to Machine

 ▸    ✅   Access Token copied to clipboard!

[
  "access_token",
  "expires_in",
  "token_type"
]

Unit Tests: go test ./internal/cli/...

I did not add an integration test as we cannot pass an organization parameter to the Auth0 Management API, and all the existing integration tests use the Management API.

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@ttstarck ttstarck requested a review from a team as a code owner March 27, 2026 19:42
@ttstarck ttstarck changed the title Add organization support for M2M client credentials flow Add organization support to test token command for M2M Applications Mar 27, 2026
@ramya18101
Copy link
Copy Markdown
Contributor

@ttstarck ,Thanks for raising the PR.
We will review and get back to you soon!

@ttstarck ttstarck force-pushed the feat/m2m-organization branch from eba1beb to d8191f7 Compare March 31, 2026 03:00
@ttstarck
Copy link
Copy Markdown
Contributor Author

ttstarck commented Apr 1, 2026

@ttstarck ,Thanks for raising the PR. We will review and get back to you soon!

Great @ramya18101, let me know if there is anything I need to address!

ramya18101
ramya18101 previously approved these changes Apr 6, 2026
}

grant := list.ClientGrants[0]
if grant.GetOrganizationUsage() == "require" && organization == "" {
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.

Since organization usage is required here, we should first validate whether the tenant has any organizations configured. If none exist, we can return a clear error to the user.
If organizations are available, instead of relying solely on the --organization flag, we could improve the UX by following a pattern similar to audiencePicker, prompting the user to select from the list of existing organizations.

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.

@ramya18101 so just to clarify this further:

If the --organization flag was not specified and the API client grant for the M2M app requires an organization, we should:

  1. Fail if no organizations exist in the tenant, with a clear error message.
  2. Else: Prompt the User to select from the list of existing organizations similar to the Audience Picker

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.

I'll spend some time working on this addition! Thanks for the feedback

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.

Added this feature in 4dbf75e

Here is the example output when the audience requires an organization but none is specified.

./out/auth0 test token $CLIENT_ID --audience $AUDIENCE
 ▸    Domain    : <domain>
 ▸    Client ID : <client id>
 ▸    Type      : Machine to Machine

 Organization:  [Use arrows to move, type to filter, ? for more help]
> org_name (<org_id>)
...

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.

Thanks for adding this!

@ramya18101
Copy link
Copy Markdown
Contributor

@ttstarck, I've tested the flow and working as expected, Added a minor comment. Please check it out!

@bkiran6398
Copy link
Copy Markdown
Contributor

Hi @ttstarck,
I have reviewed and tested the code. LGTM.
Please address lint errors.

@ttstarck
Copy link
Copy Markdown
Contributor Author

ttstarck commented Apr 7, 2026

@bkiran6398 just pushed the fix to the linter issues ac5c2b7! Thank you for testing this out.

ttstarck and others added 5 commits April 8, 2026 13:40
…dd org support

Moves checkClientIsAuthorizedForAPI out of test.go into utils_shared.go
alongside the other flow helpers it depends on.

Also adds organization support to the client credentials token request:
- BuildOauthTokenParams now accepts an organization parameter
- runClientCredentialsFlow forwards it to both the auth check and token request
- checkClientIsAuthorizedForAPI errors early when organization_usage is
  "require" on the client grant but no organization was provided

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… flow

Wires the --organization flag through to the client credentials token
request for Machine to Machine applications. Auth0 ignores the scope
parameter for client credentials grants (all granted scopes are always
returned), so --scopes now shows a warning and is ignored for M2M apps.

Also adds unit tests for checkClientIsAuthorizedForAPI covering the
organization_usage=require validation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ganization

When the client grant for the selected API has organization_usage=require and
no --organization flag was provided, fetch the tenant's organizations and either
fail with a descriptive error (if none exist) or open an interactive picker so
the user can select one before the token request is made.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers three cases: API error propagation, no organizations exist (with
descriptive error), and the happy path returning correctly shaped picker options.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ttstarck
Copy link
Copy Markdown
Contributor Author

ttstarck commented Apr 8, 2026

I see that commits require verified signatures. I will rebase all the commits to be signed.

@ttstarck ttstarck force-pushed the feat/m2m-organization branch from ac5c2b7 to 3be6520 Compare April 8, 2026 20:44
Rename receiver `cli` to `c` in `pickOrganizationForGrantIfRequired` and
`organizationPickerOptionsForGrant` to be consistent with the rest of the file,
and remove trailing blank lines to satisfy gofmt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ttstarck ttstarck force-pushed the feat/m2m-organization branch from 3be6520 to ac0fcf9 Compare April 8, 2026 20:49
@ramya18101 ramya18101 merged commit 9016c5f into auth0:main Apr 9, 2026
6 checks passed
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