Skip to content

Add AuthServerConfigRef CRD field, config model, and JwksAllowPrivateIP#4286

Open
jhrozek wants to merge 1 commit intomainfrom
vmcp-add-as-scaffolding-1
Open

Add AuthServerConfigRef CRD field, config model, and JwksAllowPrivateIP#4286
jhrozek wants to merge 1 commit intomainfrom
vmcp-add-as-scaffolding-1

Conversation

@jhrozek
Copy link
Contributor

@jhrozek jhrozek commented Mar 20, 2026

Summary

  • The vMCP embedded authorization server feature (Phase 1: Foundation — add AuthServerConfig model, CRD field, and structural validation #4140) needs CRD and config scaffolding before the runtime can be wired. This PR adds the foundational types and validation without changing any runtime behavior.
  • Add AuthServerConfigRef field to VirtualMCPServerSpec for referencing an MCPExternalAuthConfig with type embeddedAuthServer
  • Add AuthServer field (*authserver.RunConfig) to the vMCP runtime config model
  • Add JwksAllowPrivateIP to OIDCConfig for loopback JWKS fetches when the embedded auth server's OIDC discovery endpoint is on a private address
  • Move ExternalAuthConfigRef to mcpexternalauthconfig_types.go (same package, pure code organization)
  • Add structural validation and condition constants for the new field

Fixes #4140

Type of change

  • New feature

Test plan

  • e2e testing as part of a large branch from which I cherry-picked this PR from

Changes

File Change
cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go Add AuthServerConfigRef field with godoc, kubebuilder markers, and validation
cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go Table-driven tests for validateAuthServerConfig()
cmd/thv-operator/api/v1alpha1/mcpexternalauthconfig_types.go Move ExternalAuthConfigRef here from mcpserver_types.go
cmd/thv-operator/api/v1alpha1/mcpserver_types.go Remove ExternalAuthConfigRef (moved)
pkg/vmcp/config/config.go Add RuntimeConfig.AuthServer and OIDCConfig.JwksAllowPrivateIP
pkg/vmcp/auth/factory/incoming.go OR JwksAllowPrivateIP with ProtectedResourceAllowPrivateIP
Generated files deepcopy, CRD manifests, CRD reference docs

Does this introduce a user-facing change?

No. This adds CRD fields and config types but does not wire them into any runtime code path yet.

Special notes for reviewers

  • JwksAllowPrivateIP is OR'd with ProtectedResourceAllowPrivateIP in the auth factory so that either flag enables private-IP JWKS fetches. This is needed because the embedded auth server runs on a loopback address in-cluster.
  • The AuthServerConfigRef validation only checks structural correctness (non-empty name, correct type). Full semantic validation (e.g., referenced resource exists and is ready) will come in a follow-up controller reconciliation PR.

Generated with Claude Code

- Move ExternalAuthConfigRef to mcpexternalauthconfig_types.go (same
  package, pure code organization)
- Add AuthServerConfigRef field to VirtualMCPServerSpec for referencing
  an MCPExternalAuthConfig with type embeddedAuthServer
- Add AuthServerConfigValidated condition type and reason constants
- Add validateAuthServerConfig() structural validation
- Add AuthServer field (*authserver.RunConfig) to vmcp config.Config
- Add JwksAllowPrivateIP to OIDCConfig, OR with ProtectedResourceAllowPrivateIP
  in the auth factory for loopback JWKS fetches
- Regenerate deepcopy, CRD manifests, and CRD reference docs

Fixes: #4140
@github-actions github-actions bot added the size/S Small PR: 100-299 lines changed label Mar 20, 2026
@codecov
Copy link

codecov bot commented Mar 20, 2026

Codecov Report

❌ Patch coverage is 34.78261% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.05%. Comparing base (f52b6d0) to head (cdf5325).

Files with missing lines Patch % Lines
pkg/vmcp/config/config.go 0.00% 14 Missing ⚠️
pkg/vmcp/auth/factory/incoming.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4286      +/-   ##
==========================================
+ Coverage   68.54%   69.05%   +0.51%     
==========================================
  Files         471      471              
  Lines       47732    47675      -57     
==========================================
+ Hits        32717    32924     +207     
+ Misses      12247    12187      -60     
+ Partials     2768     2564     -204     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment on lines +77 to +82
// AuthServerConfigRef references an MCPExternalAuthConfig resource that configures
// an embedded OAuth authorization server. When set, the vMCP server acts as
// an OIDC issuer, drives users through upstream IDPs, and issues ToolHive JWTs.
// The referenced MCPExternalAuthConfig must have type "embeddedAuthServer" and exist
// in the same namespace.
// +optional
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: explain how this relates to the auth config available in config. "If set, then the embedded auth server will be used for inbound auth and config.inbound (or whatever the field is)."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will do (and will keep the comment unresolved until I do)

Comment on lines +162 to +173
// RuntimeConfig extends Config with runtime-only fields that are populated
// post-deserialization by the converter (Kubernetes) or CLI loader.
// These fields are never part of the CRD schema.
type RuntimeConfig struct {
Config

// AuthServer configures an embedded OAuth authorization server.
// When set, the vMCP server acts as an OIDC issuer, drives users through upstream IDPs,
// accumulates tokens, and issues ToolHive JWTs. When nil, behavior is unchanged.
// Populated by the converter from AuthServerConfigRef or by the CLI loader.
AuthServer *AuthServerConfig
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Blocker: Can we inline AuthServer into Config? This follows the pattern with other config fields that may be overwritten by "refs." It's nice to have this inline in the config because operators who don't want to bother with the external CRD may define the configuration directly on the vMCP. Also, it simplifies the plumbing of config for developers. The operator just reads the ref'ed CRD and writes it into the config, which already exists on the spec and plumbs through predictably.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/S Small PR: 100-299 lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 1: Foundation — add AuthServerConfig model, CRD field, and structural validation

2 participants