Skip to content

RFC for multiple upstream providers in authserver#52

Merged
tgrunnagle merged 3 commits intomainfrom
authserver-multi-provider_2026-03-10
Mar 13, 2026
Merged

RFC for multiple upstream providers in authserver#52
tgrunnagle merged 3 commits intomainfrom
authserver-multi-provider_2026-03-10

Conversation

@tgrunnagle
Copy link
Contributor

@tgrunnagle tgrunnagle commented Mar 10, 2026

Related issue: stacklok/stacklok-epics#251

What this RFC proposes

The embedded OAuth authorization server (pkg/authserver/) currently hard-rejects configuration with more than one upstream Identity Provider. This RFC lifts that restriction.

Core design: sequential authorization chain. When a client calls GET /oauth/authorize, the auth server redirects the user through each configured upstream IDP in sequence — accumulating one token set per provider — before issuing the final authorization code. The client performs a single standard OAuth2 flow; all intermediate redirects are server-driven and transparent.

Token delivery via Identity. After JWT validation, the auth middleware calls GetAllUpstreamTokens and populates Identity.UpstreamTokens map[string]string (provider name → access token). Downstream middleware (e.g. upstreamswap) reads from this struct field — no storage calls, no context extraction.

Key changes across four implementation phases

Phase Scope Highlights
1 — Storage pkg/authserver/storage/ Add providerName param to Store/Get; add GetAllUpstreamTokens; new Redis key pattern + session index SET; eviction uses max(access, refresh) ExpiresAt
2 — Handler pkg/authserver/server/handlers/ Replace single upstream field with map + orderedSlice; implement authorize/callback chain logic; add nextMissingUpstream
3 — Config pkg/authserver/config.go, pkg/runner/, operator CRDs Remove len > 1 rejection from auth server; add it to proxy runner; move CRD restriction from MCPExternalAuthConfig to per-workload admission webhooks so VirtualMCPServer is unrestricted; remove Config.GetUpstream()
4 — Identity & middleware pkg/auth/, pkg/auth/upstreamswap/, pkg/runner/middleware.go Add UpstreamTokens to Identity; enrich in auth middleware; remove StorageGetter from upstreamswap; derive ProviderName in addUpstreamSwapMiddleware

What is explicitly out of scope

  • Multi-upstream support in the CLI proxy runner (thv proxy) or MCPServer/MCPRemoteProxy workload types — they remain single-upstream.
  • Token refresh / re-authorization flows.
  • User account linking across providers.
  • Step-up authentication signaling.
  • Full Redis migration tooling.

@tgrunnagle tgrunnagle requested review from jerm-dro and jhrozek March 10, 2026 15:34
@tgrunnagle tgrunnagle marked this pull request as ready for review March 10, 2026 15:35
Copy link
Contributor

@jhrozek jhrozek left a comment

Choose a reason for hiding this comment

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

I think this looks good, I'd like to give the RFC one more read before merging, but I don't see anything blocking

Copy link
Contributor

@jerm-dro jerm-dro left a comment

Choose a reason for hiding this comment

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

The vMCP changes LGTM. I'll defer to @jhrozek for approval since he's better suited to review the bulk of the content.

@jhrozek
Copy link
Contributor

jhrozek commented Mar 11, 2026

I'm fine merging as long as we plan the token storage passing down the session stack to accomodate for refresh token, lmk if you want to merge as-is or do any changes @tgrunnagle

@tgrunnagle
Copy link
Contributor Author

@jhrozek I think the only open question is how we make sure refreshed tokens are given to the upstream_inject handler - seems like retrieving the Identity's UpstreamTokens per request is the answer, and using the UpstreamTokenService in the authz middleware to do that.

@tgrunnagle tgrunnagle merged commit 7ee87b8 into main Mar 13, 2026
1 check passed
@tgrunnagle tgrunnagle deleted the authserver-multi-provider_2026-03-10 branch March 13, 2026 16:57
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