Skip to content

Give console and Pod SSO buttons their authorization link - #142

Merged
Jinx-1120 merged 1 commit into
AgentBull:mainfrom
Jinx-1120:claude/sso-login-path
Oct 30, 2026
Merged

Jinx-1120 merged 1 commit into
AgentBull:mainfrom
Jinx-1120:claude/sso-login-path

Conversation

@Jinx-1120

@Jinx-1120 Jinx-1120 commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

On the Site Admin Console sign-in page (/sessions/new?purpose=console), clicking an enterprise SSO button such as Feishu opens /null?purpose=console&return_to=... and fails with Phoenix.Router.NoRouteError. The Pod sign-in page has the same fault.

Cause. Since d20cc01 the sign-in page builds each SSO button with new URL(provider.loginPath, window.location.origin) instead of a fixed /sessions/oidc/:provider_id/authorization path. AnkoleWeb.BrowserAuth adds login_path to OIDC providers only for oauth and tenant-targeted site logins. For console and pod logins it returns LoginPolicy.login_providers() directly, and those entries have no login_path. loginProviders therefore returned loginPath: null (although the response declares it non-null), and new URL(null, origin) resolves to /null.

Fix.

  • A console login gives each OIDC provider the path /sessions/oidc/:provider_id/authorization on the current host. Console login always runs on the site host and Targets.resolve/2 rejects it on Pod hosts. A Pod origin would point to the privileged tenant's subdomain.
  • A pod login gives each OIDC provider that endpoint on the target Pod origin (PodURL.origin/2), as oauth and site logins already do. A Pod target can come from an explicit tenant_id on a non-Pod host, and the SSO button does not forward tenant_id, so a relative path would lose the tenant.
  • provider_login_path/2 takes the origin. PodURL.oidc_authorization_path/1 owns the path, and oidc_authorization_url/3 returns the same URLs as before.

BrowserSessions.md states which host loginPath uses for each ceremony. Changelog: 2.1.0-alpha.6.

Verification

  • auth_controller_test.exs: the console OIDC test now reads loginPath from GET /api/v2/browser/identity-providers?purpose=console and follows it to the upstream redirect, instead of using a hard-coded path. Without the fix, it fails with loginPath nil.
  • pod_membership_authentication_test.exs: the Pod SSO provider assertion now checks the host and path of loginPath. Without the fix, the FOSS branch fails because loginPath is missing.
  • bun run control-plane:test: 5222 tests, 0 failures.
  • With ANKOLE_EDITION=saas, the two changed test files and the private browser flow tests pass (37 tests). The oauth assertion on loginPath in the private tests is unchanged.
  • mix format --check-formatted, mix compile --warnings-as-errors, and mix credo --strict on the changed files: no new findings.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Fixed enterprise SSO sign-in links on the Site Admin Console and Pod sign-in pages. Selecting an SSO provider now opens the correct provider sign-in page instead of an invalid /null page.
    • Pod sign-in links now direct users to the authorization page for the relevant Pod, helping ensure sign-in starts in the correct context.
  • Documentation
    • Updated the browser sign-in documentation to clarify where enterprise SSO links direct users.

The sign-in page builds each enterprise SSO button from the provider's
loginPath. BrowserAuth set loginPath only for oauth and site logins, so
the console and Pod login pages received null, and the browser opened
/null?purpose=console&... and hit Phoenix.Router.NoRouteError.

Console providers now link to /sessions/oidc/:provider_id/authorization
on the current site host, because console login never leaves that host.
Pod providers link to the same endpoint on the target Pod origin, as
oauth and site providers already do. PodURL.oidc_authorization_path/1
owns the path, and BrowserSessions.md states which host each ceremony
uses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Walkthrough

OIDC provider login paths now combine an authorization path with the appropriate origin. Console logins use the current site host; Pod, OAuth, and tenant-targeted site logins use the target Pod host. Tests, documentation, and the changelog describe the updated behavior.

Changes: OIDC login paths

Layer / File(s) Summary
Construct and verify provider login paths
app/control_plane/lib/ankole_web/pod_url.ex, app/control_plane/lib/ankole_web/browser_auth.ex, app/control_plane/test/ankole_web/controllers/auth_controller_test.exs, app/control_plane/test/ankole_web/pod_membership_authentication_test.exs, docs/design-docs/BrowserSessions.md, CHANGELOG.md
PodURL provides an encoded OIDC authorization path. Browser authentication combines it with the selected origin for OIDC providers. Tests check the returned Console and Pod login paths. Documentation and the changelog describe the behavior and reported fix.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: 0xding

Merge Risk: Minimal · up to 52d87

SSO links use the intended hosts. No material merge risk was identified.

Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: providing authorization links for console and Pod SSO buttons.
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 4 files. (2 skipped: 2 unsupported.)

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit hops past /null today,
The SSO path points the right way.
Site and Pod hosts join the track,
Encoded paths lead sign-ins back.
Soft paws celebrate the fix.

Comment @coderabbitai help to get the list of available commands.

@Jinx-1120
Jinx-1120 merged commit 6ba28d9 into AgentBull:main Oct 30, 2026
4 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.

1 participant