Skip to content

Release v2.8.0

Choose a tag to compare

@github-actions github-actions released this 23 Jul 17:04
df5fd80

Stacks on #59 (feature/logout-and-persistent-tenant-switch). Merge #59 first — until then this PR's diff includes #59's commits. The link endpoint reuses the IngressExtensions.cs / WellKnownPaths.cs changes from #59.

Adds the AuthProxy half of the "add a credential" proof-of-control flow for Cratis/Studio#862: a session-preserving link challenge that authenticates a second identity-provider login for an already signed-in user and hands the freshly authenticated subject to the application — without replacing the primary session.

Added

  • GET /.cratis/link/{scheme} — a session-preserving credential-linking challenge. It authenticates the requested provider for an already signed-in user but, on the provider callback, captures the authenticated subject and posts it to the application instead of signing the new identity in, so the user's primary session is preserved. The one-time link token and a same-site-only returnUrl travel through the flow. (Cratis/Studio#862)
  • Cratis:AuthProxy:Link:ExchangeUrl configuration — the application back-channel endpoint AuthProxy posts { subject, identityProvider } to (with the link token as the bearer credential), the link counterpart of Cratis:AuthProxy:Invite:ExchangeUrl. (Cratis/Studio#862)

Security

  • The link challenge requires an authenticated session (anonymous → 401), validates the provider scheme (unknown → 404) and requires a one-time token (missing → 400). returnUrl is constrained to a same-site relative path so the endpoint can never be turned into an open redirect. The subject is delivered to the application server-to-server from a real provider authentication — never trusted from client input. (Cratis/Studio#862)

Notes for review

  • Not an iframe. The design in the issue calls for an iframe, but provider consent pages send X-Frame-Options: DENY and AuthProxy cookies are SameSite=Lax, so the flow is a popup / top-level redirect, as agreed in the issue's posted design.
  • Session preservation is achieved by short-circuiting OnTicketReceived with context.HandleResponse() before the RemoteAuthenticationHandler signs the ticket into the cookie scheme (the "capture sub/iss and short-circuit" option from the design), rather than a throwaway sign-in scheme.
  • Same-account limitation (assumption): the challenge does not force prompt=select_account, so a provider with an active SSO session may silently return the same account. Left out because prompt handling differs across OIDC/OAuth and GitHub has no standard equivalent; flagging for review — it can be added if linking a different account of the same provider must be guaranteed.

🤖 Generated with Claude Code