stacklok / stacklok/toolhive

Add a group-aware UpstreamFilter implementation for the embedded auth server

Open
#6,675 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

needs-triage
Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

Problem

In a multi-upstream VirtualMCPServer, without a custom UpstreamFilter, users walk the full upstream authorization chain regardless of their identity or group membership.

A user who does not have an account on one of the upstream providers is prompted for OAuth login, which fails and blocks the entire authorization flow — even though they only need credentials from a subset of upstream providers for the backends they are entitled to use.

This is not just a UX issue but an authentication failure: a single upstream that is unavailable to a particular principal can prevent the user from accessing other backends they are authorized to use.

Background

#5724 / #5725 added the UpstreamFilter interface and the callback handler hook that consults it after the first upstream resolves.

The integration is complete — computeChain calls FilterUpstreams when a filter is present — but no concrete implementation ships with ToolHive and no CRD surface exposes the configuration.

Proposal

Provide a built-in UpstreamFilter implementation that narrows the upstream chain based on claims from the first-leg principal, initially supporting group membership.

Operators could configure a mapping from identity groups to upstream subsets, so that users in different groups walk different authorization chains.

This would also require a CRD field on VirtualMCPServer (e.g. authServerConfig.upstreamFilter) to configure the filter without requiring a custom Go build.

The exact configuration shape is open for discussion.

This proposal is intentionally limited to authentication-chain selection. It does not replace backend or tool authorization; backend-scoped Cedar authorization remains responsible for determining which backend capabilities the principal may access.

Given the OSS / Enterprise boundary described in #5383, I’d also like to confirm whether a group-aware UpstreamFilter exposed through the VirtualMCPServer CRD would fall under the Connector Gateway / Enterprise boundary as well.

Related

  • #5724 / #5725 — UpstreamFilter interface and handler hook (merged)
  • #5383 — per-user federated-IdP composition (linked-account model)
  • #5483 / #6487 — backend-scoped Cedar authorization

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with computeChain and the FilterUpstreams hook described in #5724/#5725, then inspect the VirtualMCPServer CRD configuration. Clarify the group-to-upstream mapping shape and whether this belongs in the OSS or Enterprise boundary before implementation. Done means a built-in group-aware filter, CRD configuration, and tests covering group-based chain selection.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes
Domain
authentication, authorization, backend-api-design
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.