Skip to content

Commit 6db8faa

Browse files
authored
Wire scopes through VirtualMCPServer to auth middleware (#3005)
Complete the scopes support for VirtualMCPServer by wiring the Scopes field through the vmcpconfig converter and auth factory: - Map Scopes from oidc.OIDCConfig to vmcpconfig.OIDCConfig in converter - Pass Scopes to TokenValidatorConfig in incoming auth factory - Add test coverage for scopes in converter tests This ensures scopes configured in VirtualMCPServer CRD are properly advertised in the RFC 9728 well-known endpoint. Fixes: #2783
1 parent 6355e13 commit 6db8faa

File tree

5 files changed

+29
-3
lines changed

5 files changed

+29
-3
lines changed

cmd/thv-operator/pkg/vmcpconfig/converter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ func mapResolvedOIDCToVmcpConfig(
204204
Resource: resolved.ResourceURL,
205205
ProtectedResourceAllowPrivateIP: resolved.JWKSAllowPrivateIP,
206206
InsecureAllowHTTP: resolved.InsecureAllowHTTP,
207-
// Scopes are not currently in oidc.OIDCConfig - should be added later
207+
Scopes: resolved.Scopes,
208208
}
209209

210210
// Handle client secret - the deployment controller mounts secrets as environment variables

cmd/thv-operator/pkg/vmcpconfig/converter_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,29 @@ func TestConverter_IncomingAuthRequired(t *testing.T) {
13151315
},
13161316
description: "Should correctly convert OIDC auth config",
13171317
},
1318+
{
1319+
name: "oidc auth with scopes",
1320+
incomingAuth: &mcpv1alpha1.IncomingAuthConfig{
1321+
Type: "oidc",
1322+
OIDCConfig: &mcpv1alpha1.OIDCConfigRef{
1323+
Type: "inline",
1324+
Inline: &mcpv1alpha1.InlineOIDCConfig{
1325+
Issuer: "https://accounts.google.com",
1326+
ClientID: "google-client",
1327+
Audience: "google-audience",
1328+
Scopes: []string{"https://www.googleapis.com/auth/drive.readonly", "openid"},
1329+
},
1330+
},
1331+
},
1332+
expectedAuthType: "oidc",
1333+
expectedOIDCConfig: &vmcpconfig.OIDCConfig{
1334+
Issuer: "https://accounts.google.com",
1335+
ClientID: "google-client",
1336+
Audience: "google-audience",
1337+
Scopes: []string{"https://www.googleapis.com/auth/drive.readonly", "openid"},
1338+
},
1339+
description: "Should correctly convert OIDC auth config with scopes",
1340+
},
13181341
}
13191342

13201343
for _, tt := range tests {
@@ -1342,6 +1365,7 @@ func TestConverter_IncomingAuthRequired(t *testing.T) {
13421365
Issuer: tt.expectedOIDCConfig.Issuer,
13431366
ClientID: tt.expectedOIDCConfig.ClientID,
13441367
Audience: tt.expectedOIDCConfig.Audience,
1368+
Scopes: tt.expectedOIDCConfig.Scopes,
13451369
}, nil)
13461370
} else {
13471371
mockResolver.EXPECT().Resolve(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
@@ -1365,6 +1389,7 @@ func TestConverter_IncomingAuthRequired(t *testing.T) {
13651389
assert.Equal(t, tt.expectedOIDCConfig.Issuer, config.IncomingAuth.OIDC.Issuer, tt.description)
13661390
assert.Equal(t, tt.expectedOIDCConfig.ClientID, config.IncomingAuth.OIDC.ClientID, tt.description)
13671391
assert.Equal(t, tt.expectedOIDCConfig.Audience, config.IncomingAuth.OIDC.Audience, tt.description)
1392+
assert.Equal(t, tt.expectedOIDCConfig.Scopes, config.IncomingAuth.OIDC.Scopes, tt.description)
13681393
} else {
13691394
assert.Nil(t, config.IncomingAuth.OIDC, tt.description)
13701395
}

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.81
5+
version: 0.0.82
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.81](https://img.shields.io/badge/Version-0.0.81-informational?style=flat-square)
3+
![Version: 0.0.82](https://img.shields.io/badge/Version-0.0.82-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.

pkg/vmcp/auth/factory/incoming.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ func newOIDCAuthMiddleware(
8080
ResourceURL: oidcCfg.Resource,
8181
AllowPrivateIP: oidcCfg.ProtectedResourceAllowPrivateIP,
8282
InsecureAllowHTTP: oidcCfg.InsecureAllowHTTP,
83+
Scopes: oidcCfg.Scopes,
8384
}
8485

8586
// pkg/auth.GetAuthenticationMiddleware now returns middleware that creates Identity

0 commit comments

Comments
 (0)