Skip to content

feat: add universal-portals setup command (Beta) - #1595

Draft
jacobovidal wants to merge 4 commits into
betafrom
feat/qs-universal-portals
Draft

feat: add universal-portals setup command (Beta)#1595
jacobovidal wants to merge 4 commits into
betafrom
feat/qs-universal-portals

Conversation

@jacobovidal

Copy link
Copy Markdown

Description:

🔧 Changes

Adds auth0 universal-portals setup (alias: auth0 up setup) as a new top-level command that provisions all Auth0 resources required by a Universal Portals application in a single step:

  • Resource servers (idempotent — skips silently if already exists):
    • Auth0 My Account API (https://<tenant>/me/)
    • Auth0 My Organization API (https://<tenant>/my-org/)
  • Regular Web App client with refresh token policies, session transfer, and OIDC backchannel logout configured
  • Three client grants with the correct subject_type per audience (My Account/My Org APIs → user, Management API → client)

The portal domain is resolved automatically: uses the tenant's default custom domain if one is active, otherwise falls back to the tenant domain. Client ID is rendered as a clickable OSC8 hyperlink to the Management Dashboard. After setup, the portal URL is shown and optionally opened in the browser.

Raw HTTP is used for client and grant creation because session_transfer, refresh_token.policies, and subject_type are absent from the vendored go-auth0 SDK.

⚠️ Form and Portal provisioning are not yet implemented (TODOs in place — payloads TBD).

📚 References

  • TBC

🔬 Testing

Requires an active Auth0 CLI session (auth0 login) on a beta-enabled tenant.

# Interactive
auth0-beta up setup

# Non-interactive
auth0-beta up setup --name "My Portal"
auth0-beta universal-portals setup -n "My Portal"

Expected output:

  1. Domain line (custom or tenant)
  2. Name prompt (skipped if --name provided)
  3. ✓ / (already exists) for each resource server
  4. ✓ Application created with masked client secret and clickable client ID
  5. ✓ for each of the three client grants
  6. Portal URL + "Press Enter" to open in browser

Re-running the command should not fail — resource servers return (already exists).

Note: make docs is blocked by a local vendor/modules.txt inconsistency unrelated to this change; docs will regenerate in CI.

📝 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)

jacobovidal and others added 4 commits August 1, 2026 00:48
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Derives manage and forms base URLs from the tenant domain without
hardcoding auth0.com. Public tenants use 2-letter region codes (us,
eu, ca, jp, uk) that appear only in the URL path, not the host.
All other environments preserve the full domain suffix.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Adds `auth0 universal-portals setup` (alias: `auth0 up setup`) which
provisions all Auth0 resources required by a Universal Portals app:

  - Auth0 My Account API + My Organization API (idempotent, 409 = skip)
  - Regular Web App client with refresh_token policies, session_transfer,
    and OIDC backchannel logout (raw HTTP due to SDK gaps)
  - Three client grants with subject_type (raw HTTP due to SDK gap)

Domain is resolved from the default custom domain when available,
falling back to the tenant domain. Portal URL is opened in the browser
after setup completes.

Form and Portal provisioning are stubbed with TODO comments pending
payload from the UP team.

Note: make docs blocked by local vendor/modules.txt inconsistency;
docs will regenerate in CI.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Apply deep module principle and explicit dependency injection:

- Orchestrator owns all display; business fns return (value, error)
- ensurePortalResourceServer returns (alreadyExisted bool, err) instead
  of calling the renderer internally
- ansi.Waiting moved to the orchestrator, not embedded in business fns
- buildPortalGrants is now a pure function (no I/O, fully testable)
- createPortalGrant is a single-grant fn; loop lives in the orchestrator
- rawAPIPost helper eliminates duplicated HTTP error-decode pattern
- Business fns take ctx + minimum interface (ResourceServerAPI,
  HTTPClientAPI, CustomDomainAPI) instead of *cli
- portalManageClientURL is pure: explicit params, no struct access
- portalResourceServers() extracted to make the RS list data-driven

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@jacobovidal
jacobovidal requested a review from a team as a code owner August 3, 2026 13:21
@jacobovidal
jacobovidal marked this pull request as draft August 3, 2026 13:22
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.

1 participant