Skip to content

Conversation

@amirejaz
Copy link
Contributor

Summary

Implements the controller logic and runtime integration for bearer token authentication in Kubernetes, building on the foundation laid in PR #3224. This completes the bearer token authentication flow by adding reconciliation, RunConfig generation, environment variable management, and secret watching capabilities.

Context

This PR builds on PR #3224 which added:

  • BearerTokenConfig CRD type in MCPExternalAuthConfig
  • ExternalAuthTypeBearerToken enum value
  • Webhook validation for bearer token configuration
  • Basic type definitions and API structure

This PR implements the operational logic to make bearer tokens work end-to-end.

Changes

Controller Implementation

  • MCPExternalAuthConfig Controller:

    • Added reconciliation logic for bearerToken type in mcpexternalauthconfig_controller.go
    • Implements secret watch to trigger reconciliation when referenced secrets change
    • Calculates config hash including secret content (SHA256, truncated to 16 hex chars) for change detection
    • Refactored secret reference finding into dedicated functions:
      • findMCPExternalAuthConfigsReferencingSecret() - finds configs referencing a secret
      • configReferencesSecret() - checks if a config references a specific secret
  • MCPRemoteProxy Controller:

    • Integrated bearer token configuration into RunConfig generation (mcpremoteproxy_runconfig.go)
    • Converts Kubernetes Secret references to CLI format ("secret-name,target=bearer_token")
    • Validates secret existence and key presence before deployment
    • Generates environment variables for bearer token secrets

Environment Variable Management

  • GenerateBearerTokenEnvVar(): Creates TOOLHIVE_SECRET_{secret-name} env vars from Secret references
  • EnsureRequiredEnvVars(): Auto-detects TOOLHIVE_SECRET_* env vars and sets TOOLHIVE_SECRETS_PROVIDER=environment
    • Checks all env vars (not just specific ones) for TOOLHIVE_SECRET_* prefix
    • Only sets provider when actual secrets are present (excludes provider env var itself)
    • Ensures secrets provider is correctly configured for CLI-format secret resolution

Secret Resolution Flow

  1. User creates MCPExternalAuthConfig with bearerToken type referencing a Kubernetes Secret
  2. Controller validates secret exists and contains required key
  3. Controller generates TOOLHIVE_SECRET_{secret-name} env var in pod spec
  4. EnsureRequiredEnvVars detects secret env vars and sets TOOLHIVE_SECRETS_PROVIDER=environment
  5. RunConfig contains CLI-format secret reference: "secret-name,target=bearer_token"
  6. At runtime, EnvironmentProvider resolves secret from TOOLHIVE_SECRET_* env var
  7. Bearer token is injected into Authorization header for remote MCP server requests

Testing

  • Comprehensive unit tests for bearer token RunConfig generation (mcpremoteproxy_runconfig_test.go)
  • Tests for environment variable generation and validation
  • Tests for EnsureRequiredEnvVars with 13 test cases covering:
    • Default env var setting
    • Secret detection with different naming patterns
    • Edge cases (empty lists, mixed vars, provider exclusion, etc.)
  • Tests for secret watch and reconciliation triggers (mcpexternalauthconfig_controller_test.go)
  • Integration tests for end-to-end bearer token flow

Examples & Documentation

  • Added mcpremoteproxy_with_bearer_token.yaml example demonstrating bearer token configuration
  • Updated example files to use generic names (removed PostHog-specific references)
  • Cleaned up examples to focus on essential configuration

Security

  • Only secret references supported (no plaintext values)
  • Secrets validated before deployment
  • Secret changes trigger automatic reconciliation via watch mechanism
  • Config hash includes secret content for change detection (ensures dependent resources reconcile when secrets change)

Technical Details

Secret Watch Implementation

  • Controller watches Secrets and triggers reconciliation of MCPExternalAuthConfig resources that reference them
  • Uses Watches(&corev1.Secret{}, secretHandler) in SetupWithManager
  • Ensures changes to secret values propagate to dependent resources

Config Hash with Secret Content

  • calculateConfigHash() now includes SHA256 hash (truncated to 16 hex chars) of referenced secret values
  • Enables change detection when secrets are updated
  • Triggers reconciliation of dependent MCPServer and MCPRemoteProxy resources

Related

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Large PR Detected

This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.

How to unblock this PR:

Add a section to your PR description with the following format:

## Large PR Justification

[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformation

Alternative:

Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.

See our Contributing Guidelines for more details.


This review will be automatically dismissed once you add the justification section.

@github-actions github-actions bot added the size/XL Extra large PR: 1000+ lines changed label Jan 28, 2026
@codecov
Copy link

codecov bot commented Jan 28, 2026

Codecov Report

❌ Patch coverage is 60.46512% with 68 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.25%. Comparing base (ebf0f55) to head (ae32676).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
...or/controllers/mcpexternalauthconfig_controller.go 37.93% 49 Missing and 5 partials ⚠️
...d/thv-operator/pkg/controllerutil/tokenexchange.go 79.59% 5 Missing and 5 partials ⚠️
...-operator/controllers/mcpremoteproxy_deployment.go 66.66% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3487      +/-   ##
==========================================
+ Coverage   65.23%   65.25%   +0.01%     
==========================================
  Files         398      398              
  Lines       38793    38985     +192     
==========================================
+ Hits        25308    25439     +131     
- Misses      11525    11573      +48     
- Partials     1960     1973      +13     

☔ 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.

@amirejaz amirejaz marked this pull request as draft January 28, 2026 17:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra large PR: 1000+ lines changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants