Skip to content

Commit 6baef4e

Browse files
authored
Remove local incoming auth type from operator CRDs (#2759)
The `local` authentication type uses `user.Current()` to get the OS username, which is meaningful for CLI usage but inappropriate in Kubernetes where the container user has no relation to connecting clients. This removes `local` from the CRD layer only, preserving it in pkg/vmcp for CLI use cases.
1 parent 6e0e96c commit 6baef4e

File tree

7 files changed

+21
-22
lines changed

7 files changed

+21
-22
lines changed

cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ type GroupRef struct {
6868

6969
// IncomingAuthConfig configures authentication for clients connecting to the Virtual MCP server
7070
type IncomingAuthConfig struct {
71-
// Type defines the authentication type: anonymous, local, or oidc
72-
// +kubebuilder:validation:Enum=anonymous;local;oidc
71+
// Type defines the authentication type: anonymous or oidc
72+
// +kubebuilder:validation:Enum=anonymous;oidc
7373
// +optional
7474
Type string `json:"type,omitempty"`
7575

deploy/charts/operator-crds/Chart.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ apiVersion: v2
22
name: toolhive-operator-crds
33
description: A Helm chart for installing the ToolHive Operator CRDs into Kubernetes.
44
type: application
5-
version: 0.0.65
5+
version: 0.0.66
66
appVersion: "0.0.1"

deploy/charts/operator-crds/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ToolHive Operator CRDs Helm Chart
22

3-
![Version: 0.0.65](https://img.shields.io/badge/Version-0.0.65-informational?style=flat-square)
3+
![Version: 0.0.66](https://img.shields.io/badge/Version-0.0.66-informational?style=flat-square)
44
![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square)
55

66
A Helm chart for installing the ToolHive Operator CRDs into Kubernetes.

deploy/charts/operator-crds/crds/toolhive.stacklok.dev_virtualmcpservers.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,10 @@ spec:
515515
- type
516516
type: object
517517
type:
518-
description: 'Type defines the authentication type: anonymous,
519-
local, or oidc'
518+
description: 'Type defines the authentication type: anonymous
519+
or oidc'
520520
enum:
521521
- anonymous
522-
- local
523522
- oidc
524523
type: string
525524
type: object

docs/operator/crd-api.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/vmcp-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ group: "engineering-team" # Reference to ToolHive group
2020

2121
# ===== INCOMING AUTHENTICATION (Client → Virtual MCP) =====
2222
incoming_auth:
23-
type: oidc # Options: oidc | anonymous | local
23+
type: oidc # Options: oidc | anonymous
2424
# OIDC configuration
2525
oidc:
2626
issuer: "https://keycloak.example.com/realms/myrealm"

test/e2e/thv-operator/virtualmcp/virtualmcp_inline_auth_test.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ import (
1717
mcpv1alpha1 "github.com/stacklok/toolhive/cmd/thv-operator/api/v1alpha1"
1818
)
1919

20-
var _ = Describe("VirtualMCPServer Inline Auth with Local Incoming", Ordered, func() {
20+
var _ = Describe("VirtualMCPServer Inline Auth with Anonymous Incoming", Ordered, func() {
2121
var (
2222
testNamespace = "default"
23-
mcpGroupName = "test-inline-auth-local-group"
24-
vmcpServerName = "test-vmcp-inline-auth-local"
25-
backend1Name = "backend-fetch-inline-local"
23+
mcpGroupName = "test-inline-auth-anon-group"
24+
vmcpServerName = "test-vmcp-inline-auth-anon"
25+
backend1Name = "backend-fetch-inline-anon"
2626
timeout = 5 * time.Minute
2727
pollingInterval = 5 * time.Second
2828
vmcpNodePort int32
@@ -40,7 +40,7 @@ var _ = Describe("VirtualMCPServer Inline Auth with Local Incoming", Ordered, fu
4040
Namespace: testNamespace,
4141
},
4242
Spec: mcpv1alpha1.MCPGroupSpec{
43-
Description: "Test MCP Group for VirtualMCP inline auth with local incoming",
43+
Description: "Test MCP Group for VirtualMCP inline auth with anonymous incoming",
4444
},
4545
}
4646
Expect(k8sClient.Create(ctx, mcpGroup)).To(Succeed())
@@ -89,7 +89,7 @@ var _ = Describe("VirtualMCPServer Inline Auth with Local Incoming", Ordered, fu
8989
return fmt.Errorf("backend not ready yet, phase: %s", server.Status.Phase)
9090
}, timeout, pollingInterval).Should(Succeed())
9191

92-
By("Creating VirtualMCPServer with local incoming and inline outgoing auth")
92+
By("Creating VirtualMCPServer with anonymous incoming and inline outgoing auth")
9393
vmcpServer := &mcpv1alpha1.VirtualMCPServer{
9494
ObjectMeta: metav1.ObjectMeta{
9595
Name: vmcpServerName,
@@ -100,7 +100,7 @@ var _ = Describe("VirtualMCPServer Inline Auth with Local Incoming", Ordered, fu
100100
Name: mcpGroupName,
101101
},
102102
IncomingAuth: &mcpv1alpha1.IncomingAuthConfig{
103-
Type: "local",
103+
Type: "anonymous",
104104
},
105105
OutgoingAuth: &mcpv1alpha1.OutgoingAuthConfig{
106106
Source: "inline",
@@ -146,21 +146,21 @@ var _ = Describe("VirtualMCPServer Inline Auth with Local Incoming", Ordered, fu
146146
})
147147
})
148148

149-
Context("when using local incoming with inline outgoing auth", func() {
150-
It("should configure inline outgoing auth with local incoming", func() {
149+
Context("when using anonymous incoming with inline outgoing auth", func() {
150+
It("should configure inline outgoing auth with anonymous incoming", func() {
151151
By("Verifying VirtualMCPServer has inline auth configuration")
152152
vmcpServer := &mcpv1alpha1.VirtualMCPServer{}
153153
err := k8sClient.Get(ctx, types.NamespacedName{
154154
Name: vmcpServerName,
155155
Namespace: testNamespace,
156156
}, vmcpServer)
157157
Expect(err).ToNot(HaveOccurred())
158-
Expect(vmcpServer.Spec.IncomingAuth.Type).To(Equal("local"))
158+
Expect(vmcpServer.Spec.IncomingAuth.Type).To(Equal("anonymous"))
159159
Expect(vmcpServer.Spec.OutgoingAuth.Source).To(Equal("inline"))
160160
})
161161

162162
It("should proxy tool calls with inline auth configuration", func() {
163-
By("Creating MCP client with local auth")
163+
By("Creating MCP client with anonymous auth")
164164
serverURL := fmt.Sprintf("http://localhost:%d/mcp", vmcpNodePort)
165165
mcpClient, err := client.NewStreamableHttpClient(serverURL)
166166
Expect(err).ToNot(HaveOccurred())
@@ -196,7 +196,7 @@ var _ = Describe("VirtualMCPServer Inline Auth with Local Incoming", Ordered, fu
196196
}
197197
Expect(targetToolName).ToNot(BeEmpty())
198198

199-
GinkgoWriter.Printf("Calling tool '%s' with local incoming and inline outgoing auth\n", targetToolName)
199+
GinkgoWriter.Printf("Calling tool '%s' with anonymous incoming and inline outgoing auth\n", targetToolName)
200200

201201
callRequest := mcp.CallToolRequest{}
202202
callRequest.Params.Name = targetToolName
@@ -209,7 +209,7 @@ var _ = Describe("VirtualMCPServer Inline Auth with Local Incoming", Ordered, fu
209209
Expect(result).ToNot(BeNil())
210210
Expect(result.Content).ToNot(BeEmpty())
211211

212-
GinkgoWriter.Printf("Local auth with inline outgoing: tool call succeeded\n")
212+
GinkgoWriter.Printf("Anonymous auth with inline outgoing: tool call succeeded\n")
213213
})
214214
})
215215
})

0 commit comments

Comments
 (0)