Skip to content

Add SSO connection routing for org-scoped login and pc target re-auth#86

Open
austin-denoble wants to merge 1 commit intomainfrom
adenoble/sso-support
Open

Add SSO connection routing for org-scoped login and pc target re-auth#86
austin-denoble wants to merge 1 commit intomainfrom
adenoble/sso-support

Conversation

@austin-denoble
Copy link
Copy Markdown
Collaborator

@austin-denoble austin-denoble commented Apr 13, 2026

Problem

We currently do not support SSO in the CLI, and need to enable this for customers using this.

Solution

When authenticating into an organization that has SSO enforced, the CLI now passes the Auth0 connection name as a connection= parameter to the authorization endpoint, routing the browser directly to the org's identity provider rather than the generic login page.

Both pc login and pc auth login accept a new --org flag to scope the login to a specific organization. pc target already passes the org ID implicitly. In all cases the SSO connection is resolved by calling the dashboard organizations API with the user's existing token; the lookup is best-effort and non-fatal — if it fails the flow falls back to the
standard login page transparently.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Infrastructure change (CI configs, etc)
  • Non-code change (docs, etc)
  • None of the above: (explain here)

Test Plan


Note

Medium Risk
Changes the OAuth login URL construction and adds a best-effort dashboard API call to influence SSO routing; failures should fall back, but regressions could impact authentication flows for org-scoped login and pc target re-auth.

Overview
Adds --org to pc login and pc auth login, passing an optional OrgId through the login flow to scope authentication to an organization.

When an org ID is provided, the login flow now optionally looks up the org’s Auth0 SSO connection via the dashboard organizations API and, if SSO is enforced, appends connection=<name> to the Auth0 authorize URL (best-effort with transparent fallback).

Updates oauth.Auth.GetAuthURL to accept the new connection parameter and extends tests to cover SSO connection lookup and URL parameterization.

Reviewed by Cursor Bugbot for commit befaf31. Bugbot is set up for automated code reviews on this repo. Configure here.

  When authenticating into an organization that has SSO enforced, the CLI
  now passes the Auth0 connection name as a connection= parameter to the
  authorization endpoint, routing the browser directly to the org's
  identity provider rather than the generic login page.

  Both pc login and pc auth login accept a new --org flag to scope the
  login to a specific organization. pc target already passes the org ID
  implicitly. In all cases the SSO connection is resolved by calling the
  dashboard organizations API with the user's existing token; the lookup
  is best-effort and non-fatal — if it fails the flow falls back to the
  standard login page transparently.
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit befaf31. Configure here.

if conn != "" {
ssoConnection = &conn
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SSO lookup always fails because token is unavailable

High Severity

FetchSSOConnection calls oauth.Token(ctx) to authenticate the dashboard API request, but it's only ever invoked when a new login is needed — meaning the token is either missing, expired, or was just cleared by oauth.Logout(). For the pc target re-auth flow, oauth.Logout() explicitly clears the token immediately before GetAndSetAccessToken is called, so the SSO lookup always gets an empty token and silently skips. For pc login --org, either no token exists (fresh login), the session is expired (token fetch errors), or the user is already authenticated (the "already logged in" guard returns before the SSO code is reached). The SSO connection routing feature can never activate in any code path.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit befaf31. Configure here.

if conn != "" {
ssoConnection = &conn
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Duplicated SSO lookup blocks across two functions

Low Severity

The SSO connection lookup logic (nil-check orgId, call FetchSSOConnection, wrap result in pointer) is duplicated identically in getAndSetAccessTokenJSON and getAndSetAccessTokenInteractive. Extracting this into a small helper would reduce the maintenance surface and ensure any future fix to the lookup logic is applied in one place.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit befaf31. Configure here.

// OrgId pins the login flow to a specific organization. When set, the SSO
// connection for that org is looked up and passed to Auth0, routing the
// browser directly to the org's identity provider if SSO is enforced.
OrgId *string
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Early-resume JSON path ignores org flag

Medium Severity

In Run(), the early-resume path for JSON mode at line 69 passes nil as orgId to getAndSetAccessTokenJSON, while the main path at line 106 correctly passes opts.OrgId. This means when a user runs pc login --org org-B --json and a pending session for a different org already exists, the org-mismatch guard inside getAndSetAccessTokenJSON (which checks orgId != nil) is bypassed, and the stale session for the wrong org is silently resumed instead of being rejected or cleaned up.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit befaf31. Configure here.

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