stacklok / stacklok/toolhive

Surface baselineClientScopes misconfig via MCPExternalAuthConfig / VirtualMCPServer status condition

Open
#5,252 0 comments 0 reactions 1 assignee View on GitHub

@jhrozek is already working on this.

Since May 11, 2026.

authentication kubernetes operator
Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

Background

PR #5233 added baselineClientScopes to EmbeddedAuthServerConfig with a startup-time subset check (RunConfig.Validate: every entry must be in scopesSupported). If an operator misconfigures the baseline (a value absent from scopesSupported), the auth-server pod fails inside NewEmbeddedAuthServer and CrashLoopBackOffs. The error is loud in pod logs ("invalid run config: baseline_client_scopes contains ..."), but the CR itself carries no signal — operators have to know to read pod logs.

Raised by @tgrunnagle in PR #5233 review F7. Deferred from #5233 to keep that PR's scope tight.

Proposal

Pre-validate baselineClientScopes against the upstream-derived scopesSupported in the reconciler and surface the result as a status condition before the workload rolls.

Two CRDs are affected (per .claude/rules/operator.md "Status condition parity"):

  • MCPExternalAuthConfig (consumed by MCPServer, MCPRemoteProxy)
  • VirtualMCPServer (spec.authServerConfig embeds EmbeddedAuthServerConfig inline)

Both must emit the same condition (e.g. BaselineScopesValid with status False + reason BaselineScopeNotSupported + message listing the offending scope). Status writes must go through controllerutil.MutateAndPatchStatus per the operator status-writes rule.

Acceptance criteria

  • Reconciler resolves the effective scopesSupported (from oidcConfig.Scopes for MCPServer path, from the resolved vmcp Config for VirtualMCPServer) and checks baselineClientScopes is a subset before allowing the workload to roll.
  • BaselineScopesValid condition (or equivalent name) emitted on both MCPExternalAuthConfig.status and VirtualMCPServer.status with parity per .claude/rules/operator.md.
  • On invalid baseline: condition False, reason names the offending scope, the auth-server pod is NOT spawned (or its rollout is paused — design choice).
  • Status-writer follows the controllerutil.MutateAndPatchStatus contract (fresh Get, sole owner of Conditions array).
  • Existing CrashLoopBackOff path still works as a backstop for any case the reconciler misses.

Out of scope

  • Generalizing scope validation to other *Scopes fields (this issue is specifically about baselineClientScopes).
  • Auto-correction (e.g. silently dropping the unsupported scope).

References

  • Original feature issue: #5224
  • PR introducing the field: #5233
  • Operator status rules: .claude/rules/operator.md

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.