diff --git a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go
index 3b784bbe67..27db742973 100644
--- a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go
+++ b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go
@@ -162,12 +162,12 @@ type OutgoingAuthConfig struct {
// BackendAuthConfig defines authentication configuration for a backend MCPServer
type BackendAuthConfig struct {
// Type defines the authentication type
- // +kubebuilder:validation:Enum=discovered;external_auth_config_ref
+ // +kubebuilder:validation:Enum=discovered;externalAuthConfigRef;external_auth_config_ref
// +kubebuilder:validation:Required
Type string `json:"type"`
// ExternalAuthConfigRef references an MCPExternalAuthConfig resource
- // Only used when Type is "external_auth_config_ref"
+ // Only used when Type is "externalAuthConfigRef" (or deprecated "external_auth_config_ref")
// +optional
ExternalAuthConfigRef *ExternalAuthConfigRef `json:"externalAuthConfigRef,omitempty"`
}
@@ -341,7 +341,11 @@ const (
BackendAuthTypeDiscovered = "discovered"
// BackendAuthTypeExternalAuthConfigRef references an MCPExternalAuthConfig resource
- BackendAuthTypeExternalAuthConfigRef = "external_auth_config_ref"
+ BackendAuthTypeExternalAuthConfigRef = "externalAuthConfigRef"
+
+ // DeprecatedBackendAuthTypeExternalAuthConfigRef is the old snake_case value.
+ // Deprecated: Use BackendAuthTypeExternalAuthConfigRef ("externalAuthConfigRef") instead.
+ DeprecatedBackendAuthTypeExternalAuthConfigRef = "external_auth_config_ref"
)
// Workflow step types
@@ -495,10 +499,10 @@ func (*VirtualMCPServer) validateBackendAuth(backendName string, auth BackendAut
// Validate type-specific configurations
switch auth.Type {
- case BackendAuthTypeExternalAuthConfigRef:
+ case BackendAuthTypeExternalAuthConfigRef, DeprecatedBackendAuthTypeExternalAuthConfigRef:
if auth.ExternalAuthConfigRef == nil {
return fmt.Errorf(
- "spec.outgoingAuth.backends[%s].externalAuthConfigRef is required when type is external_auth_config_ref",
+ "spec.outgoingAuth.backends[%s].externalAuthConfigRef is required when type is externalAuthConfigRef",
backendName)
}
if auth.ExternalAuthConfigRef.Name == "" {
@@ -510,7 +514,7 @@ func (*VirtualMCPServer) validateBackendAuth(backendName string, auth BackendAut
default:
return fmt.Errorf(
- "spec.outgoingAuth.backends[%s].type must be one of: discovered, external_auth_config_ref",
+ "spec.outgoingAuth.backends[%s].type must be one of: discovered, externalAuthConfigRef",
backendName)
}
diff --git a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go
index 73bfe451e0..b6d28bb7be 100644
--- a/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go
+++ b/cmd/thv-operator/api/v1alpha1/virtualmcpserver_types_test.go
@@ -276,7 +276,7 @@ func TestBackendAuthConfigTypes(t *testing.T) {
isValid: true,
},
{
- name: "external_auth_config_ref_valid",
+ name: "externalAuthConfigRef_valid",
authConfig: BackendAuthConfig{
Type: BackendAuthTypeExternalAuthConfigRef,
ExternalAuthConfigRef: &ExternalAuthConfigRef{
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_controller.go b/cmd/thv-operator/controllers/virtualmcpserver_controller.go
index f55dabfbe1..e43e22c674 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_controller.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_controller.go
@@ -1788,7 +1788,7 @@ func (r *VirtualMCPServerReconciler) convertBackendAuthConfigToVMCP(
}, nil
}
- // For type="external_auth_config_ref", fetch and convert the referenced config
+ // For type="externalAuthConfigRef", fetch and convert the referenced config
if crdConfig.ExternalAuthConfigRef != nil {
// Fetch the MCPExternalAuthConfig and convert it
externalAuthConfig, err := ctrlutil.GetExternalAuthConfigByName(
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go b/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go
index 073d9d3eea..eac97e6e23 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_externalauth_test.go
@@ -638,7 +638,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Source: "discovered",
Default: &mcpv1alpha1.BackendAuthConfig{
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "missing-default-auth", // Auth config doesn't exist
},
@@ -676,7 +676,7 @@ func TestBuildOutgoingAuthConfig(t *testing.T) {
Source: "discovered",
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
"api-backend": {
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "missing-backend-auth",
},
@@ -765,7 +765,7 @@ func TestConvertBackendAuthConfigToVMCP(t *testing.T) {
validate func(*testing.T, *authtypes.BackendAuthStrategy)
}{
{
- name: "external_auth_config_ref type",
+ name: "externalAuthConfigRef type",
crdConfig: &mcpv1alpha1.BackendAuthConfig{
Type: mcpv1alpha1.BackendAuthTypeExternalAuthConfigRef,
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go b/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go
index 69365a0afe..4ab18a7812 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_vmcpconfig_test.go
@@ -196,7 +196,7 @@ func TestConvertBackendAuthConfig(t *testing.T) {
Name: "auth-config",
},
},
- // For external_auth_config_ref, the type comes from the referenced MCPExternalAuthConfig
+ // For externalAuthConfigRef, the type comes from the referenced MCPExternalAuthConfig
expectedType: "unauthenticated",
},
}
@@ -219,7 +219,7 @@ func TestConvertBackendAuthConfig(t *testing.T) {
},
}
- // For external_auth_config_ref test, create the referenced MCPExternalAuthConfig
+ // For externalAuthConfigRef test, create the referenced MCPExternalAuthConfig
var converter *vmcpconfigconv.Converter
if tt.authConfig.Type == mcpv1alpha1.BackendAuthTypeExternalAuthConfigRef {
// Create a fake MCPExternalAuthConfig
@@ -259,7 +259,7 @@ func TestConvertBackendAuthConfig(t *testing.T) {
// Note: HeaderInjection and TokenExchange are nil because the CRD's
// BackendAuthConfig only stores type and reference information.
- // For external_auth_config_ref, the actual auth config is resolved
+ // For externalAuthConfigRef, the actual auth config is resolved
// at runtime from the referenced MCPExternalAuthConfig resource.
assert.Nil(t, strategy.HeaderInjection)
assert.Nil(t, strategy.TokenExchange)
diff --git a/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go b/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go
index 2305dc9489..a816da9102 100644
--- a/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go
+++ b/cmd/thv-operator/controllers/virtualmcpserver_watch_test.go
@@ -751,7 +751,7 @@ func TestMapExternalAuthConfigToVirtualMCPServer(t *testing.T) {
Spec: mcpv1alpha1.VirtualMCPServerSpec{
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Default: &mcpv1alpha1.BackendAuthConfig{
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "test-auth",
},
@@ -781,7 +781,7 @@ func TestMapExternalAuthConfigToVirtualMCPServer(t *testing.T) {
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
"backend1": {
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "test-auth",
},
@@ -831,7 +831,7 @@ func TestMapExternalAuthConfigToVirtualMCPServer(t *testing.T) {
Spec: mcpv1alpha1.VirtualMCPServerSpec{
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Default: &mcpv1alpha1.BackendAuthConfig{
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "test-auth",
},
@@ -1406,7 +1406,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Spec: mcpv1alpha1.VirtualMCPServerSpec{
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Default: &mcpv1alpha1.BackendAuthConfig{
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "test-auth",
},
@@ -1424,7 +1424,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
"backend1": {
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "test-auth",
},
@@ -1460,7 +1460,7 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
Spec: mcpv1alpha1.VirtualMCPServerSpec{
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Default: &mcpv1alpha1.BackendAuthConfig{
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "other-auth",
},
@@ -1478,13 +1478,13 @@ func TestVmcpReferencesExternalAuthConfig(t *testing.T) {
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
"backend1": {
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "other-auth",
},
},
"backend2": {
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: "test-auth",
},
diff --git a/cmd/thv-operator/pkg/vmcpconfig/converter.go b/cmd/thv-operator/pkg/vmcpconfig/converter.go
index 4e8d51eed8..2b29aaefce 100644
--- a/cmd/thv-operator/pkg/vmcpconfig/converter.go
+++ b/cmd/thv-operator/pkg/vmcpconfig/converter.go
@@ -452,10 +452,20 @@ func (c *Converter) convertBackendAuthConfig(
}, nil
}
- // If type is "external_auth_config_ref", resolve the MCPExternalAuthConfig
- if crdConfig.Type == mcpv1alpha1.BackendAuthTypeExternalAuthConfigRef {
+ // Handle deprecated snake_case value
+ if crdConfig.Type == mcpv1alpha1.DeprecatedBackendAuthTypeExternalAuthConfigRef {
+ log.FromContext(ctx).Info(
+ "backend auth type \"external_auth_config_ref\" is deprecated,"+
+ " use \"externalAuthConfigRef\" instead",
+ "backend", backendName, "vmcp", vmcp.Name,
+ )
+ }
+
+ // If type is "externalAuthConfigRef" (or deprecated "external_auth_config_ref"), resolve the MCPExternalAuthConfig
+ if crdConfig.Type == mcpv1alpha1.BackendAuthTypeExternalAuthConfigRef ||
+ crdConfig.Type == mcpv1alpha1.DeprecatedBackendAuthTypeExternalAuthConfigRef {
if crdConfig.ExternalAuthConfigRef == nil {
- return nil, fmt.Errorf("backend %s: external_auth_config_ref type requires externalAuthConfigRef field", backendName)
+ return nil, fmt.Errorf("backend %s: externalAuthConfigRef type requires externalAuthConfigRef field", backendName)
}
// Fetch the MCPExternalAuthConfig resource
diff --git a/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml b/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml
index 1ae8c86f14..f919af400e 100644
--- a/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml
+++ b/deploy/charts/operator-crds/files/crds/toolhive.stacklok.dev_virtualmcpservers.yaml
@@ -2136,7 +2136,7 @@ spec:
externalAuthConfigRef:
description: |-
ExternalAuthConfigRef references an MCPExternalAuthConfig resource
- Only used when Type is "external_auth_config_ref"
+ Only used when Type is "externalAuthConfigRef" (or deprecated "external_auth_config_ref")
properties:
name:
description: Name is the name of the MCPExternalAuthConfig
@@ -2149,6 +2149,7 @@ spec:
description: Type defines the authentication type
enum:
- discovered
+ - externalAuthConfigRef
- external_auth_config_ref
type: string
required:
@@ -2165,7 +2166,7 @@ spec:
externalAuthConfigRef:
description: |-
ExternalAuthConfigRef references an MCPExternalAuthConfig resource
- Only used when Type is "external_auth_config_ref"
+ Only used when Type is "externalAuthConfigRef" (or deprecated "external_auth_config_ref")
properties:
name:
description: Name is the name of the MCPExternalAuthConfig
@@ -2178,6 +2179,7 @@ spec:
description: Type defines the authentication type
enum:
- discovered
+ - externalAuthConfigRef
- external_auth_config_ref
type: string
required:
diff --git a/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml b/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml
index 572d3ba010..8e7e666468 100644
--- a/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml
+++ b/deploy/charts/operator-crds/templates/toolhive.stacklok.dev_virtualmcpservers.yaml
@@ -2139,7 +2139,7 @@ spec:
externalAuthConfigRef:
description: |-
ExternalAuthConfigRef references an MCPExternalAuthConfig resource
- Only used when Type is "external_auth_config_ref"
+ Only used when Type is "externalAuthConfigRef" (or deprecated "external_auth_config_ref")
properties:
name:
description: Name is the name of the MCPExternalAuthConfig
@@ -2152,6 +2152,7 @@ spec:
description: Type defines the authentication type
enum:
- discovered
+ - externalAuthConfigRef
- external_auth_config_ref
type: string
required:
@@ -2168,7 +2169,7 @@ spec:
externalAuthConfigRef:
description: |-
ExternalAuthConfigRef references an MCPExternalAuthConfig resource
- Only used when Type is "external_auth_config_ref"
+ Only used when Type is "externalAuthConfigRef" (or deprecated "external_auth_config_ref")
properties:
name:
description: Name is the name of the MCPExternalAuthConfig
@@ -2181,6 +2182,7 @@ spec:
description: Type defines the authentication type
enum:
- discovered
+ - externalAuthConfigRef
- external_auth_config_ref
type: string
required:
diff --git a/docs/operator/crd-api.md b/docs/operator/crd-api.md
index 4789885ba7..b707a8553b 100644
--- a/docs/operator/crd-api.md
+++ b/docs/operator/crd-api.md
@@ -888,8 +888,8 @@ _Appears in:_
| Field | Description | Default | Validation |
| --- | --- | --- | --- |
-| `type` _string_ | Type defines the authentication type | | Enum: [discovered external_auth_config_ref]
Required: \{\}
|
-| `externalAuthConfigRef` _[api.v1alpha1.ExternalAuthConfigRef](#apiv1alpha1externalauthconfigref)_ | ExternalAuthConfigRef references an MCPExternalAuthConfig resource
Only used when Type is "external_auth_config_ref" | | Optional: \{\}
|
+| `type` _string_ | Type defines the authentication type | | Enum: [discovered externalAuthConfigRef external_auth_config_ref]
Required: \{\}
|
+| `externalAuthConfigRef` _[api.v1alpha1.ExternalAuthConfigRef](#apiv1alpha1externalauthconfigref)_ | ExternalAuthConfigRef references an MCPExternalAuthConfig resource
Only used when Type is "externalAuthConfigRef" (or deprecated "external_auth_config_ref") | | Optional: \{\}
|
#### api.v1alpha1.BearerTokenConfig
diff --git a/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go b/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
index fd1d73e47c..564ac7f04a 100644
--- a/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
+++ b/test/e2e/thv-operator/virtualmcp/virtualmcp_external_auth_test.go
@@ -281,7 +281,7 @@ var _ = Describe("VirtualMCPServer Inline Unauthenticated Backend Auth", Ordered
// Explicitly configure unauthenticated for specific backend
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
backendName: {
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: externalAuthConfigName,
},
@@ -328,7 +328,7 @@ var _ = Describe("VirtualMCPServer Inline Unauthenticated Backend Auth", Ordered
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: vmcpServerName, Namespace: testNamespace}, vmcpServer)).To(Succeed())
Expect(vmcpServer.Spec.OutgoingAuth.Source).To(Equal("inline"))
Expect(vmcpServer.Spec.OutgoingAuth.Backends).To(HaveKey(backendName))
- Expect(vmcpServer.Spec.OutgoingAuth.Backends[backendName].Type).To(Equal("external_auth_config_ref"))
+ Expect(vmcpServer.Spec.OutgoingAuth.Backends[backendName].Type).To(Equal("externalAuthConfigRef"))
Expect(vmcpServer.Spec.OutgoingAuth.Backends[backendName].ExternalAuthConfigRef.Name).To(Equal(externalAuthConfigName))
By("Creating MCP client and listing tools")
@@ -680,7 +680,7 @@ var _ = Describe("VirtualMCPServer Inline HeaderInjection Backend Auth", Ordered
// Explicitly configure headerInjection for specific backend
Backends: map[string]mcpv1alpha1.BackendAuthConfig{
backendName: {
- Type: "external_auth_config_ref",
+ Type: "externalAuthConfigRef",
ExternalAuthConfigRef: &mcpv1alpha1.ExternalAuthConfigRef{
Name: externalAuthConfigName,
},
@@ -730,7 +730,7 @@ var _ = Describe("VirtualMCPServer Inline HeaderInjection Backend Auth", Ordered
Expect(k8sClient.Get(ctx, types.NamespacedName{Name: vmcpServerName, Namespace: testNamespace}, vmcpServer)).To(Succeed())
Expect(vmcpServer.Spec.OutgoingAuth.Source).To(Equal("inline"))
Expect(vmcpServer.Spec.OutgoingAuth.Backends).To(HaveKey(backendName))
- Expect(vmcpServer.Spec.OutgoingAuth.Backends[backendName].Type).To(Equal("external_auth_config_ref"))
+ Expect(vmcpServer.Spec.OutgoingAuth.Backends[backendName].Type).To(Equal("externalAuthConfigRef"))
Expect(vmcpServer.Spec.OutgoingAuth.Backends[backendName].ExternalAuthConfigRef.Name).To(Equal(externalAuthConfigName))
By("Creating MCP client and listing tools")