Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions api/v1alpha1/mcp_route.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ type MCPRouteSecurityPolicy struct {
//
// +optional
ExtAuth *egv1a1.ExtAuth `json:"extAuth,omitempty"`

// Authorization defines the configuration for the MCP spec compatible authorization.
//
// +optional
Authorization *MCPRouteAuthorization `json:"authorization,omitempty"`
}

// MCPRouteOAuth defines a MCP spec compatible OAuth authentication configuration for a MCPRoute.
Expand Down Expand Up @@ -227,6 +232,99 @@ type MCPRouteOAuth struct {
ProtectedResourceMetadata ProtectedResourceMetadata `json:"protectedResourceMetadata"`
}

// MCPRouteAuthorization defines the authorization configuration for a MCPRoute.
type MCPRouteAuthorization struct {
// Rules defines a list of authorization rules.
// These rules are evaluated in order, the first matching rule will be applied,
// and the rest will be skipped.
//
// +optional
Rules []MCPRouteAuthorizationRule `json:"rules,omitempty"`

// DefaultAction defines the default action to be taken if no rules match.
// If not specified, the default action is Deny.
// +optional
DefaultAction *egv1a1.AuthorizationAction `json:"defaultAction"`
}

// MCPRouteAuthorizationRule defines an authorization rule for MCPRoute based on the MCP authorization spec.
// Reference: https://modelcontextprotocol.io/specification/draft/basic/authorization#scope-challenge-handling
type MCPRouteAuthorizationRule struct {
// Source defines the authorization source for this rule.
//
// +kubebuilder:validation:Required
Source MCPAuthorizationSource `json:"source"`

// Target defines the authorization target for this rule.
//
// +kubebuilder:validation:Required
Target MCPAuthorizationTarget `json:"target"`

// Action defines whether to allow or deny requests that match this rule.
//
// +kubebuilder:validation:Required
Action egv1a1.AuthorizationAction `json:"action"`
}

type MCPAuthorizationTarget struct {
// Tools defines the list of tools this rule applies to.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=16
Tools []ToolCall `json:"tools"`
}

type MCPAuthorizationSource struct {
// JWTSource defines the JWT scopes required for this rule to match.
//
// +kubebuilder:validation:Optional
JWTSource *JWTSource `json:"jwtSource,omitempty"`
}

type JWTSource struct {
// Scopes defines the list of JWT scopes required for the rule.
// If multiple scopes are specified, all scopes must be present in the JWT for the rule to match.
//
// +kubebuilder:validation:Required
// +kubebuilder:validation:MinItems=1
// +kubebuilder:validation:MaxItems=16
Scopes []egv1a1.JWTScope `json:"scopes"`

// TODO : we can add more fields in the future, e.g., audiences, claims, etc.
}

type ToolCall struct {
// BackendName is the name of the backend this tool belongs to.
//
// +kubebuilder:validation:Required
BackendName string `json:"backendName"`

// ToolName is the name of the tool.
//
// +kubebuilder:validation:Required
ToolName string `json:"toolName"`

// Arguments defines the arguments that must be present in the tool call for this rule to match.
//
// +optional
// Arguments map[string]string `json:"arguments,omitempty"`
}

/*type ToolArgument struct {
// Name is the name of the argument.
Name string `json:"name"`

// Value is the value of the argument.
Value ArgumentValues `json:"value"`
}

type ArgumentValues struct {
Include []string `json:"include,omitempty"`

IncludeRegex []string `json:"includeRegex,omitempty"`
}*/

// JWKS defines how to obtain JSON Web Key Sets (JWKS) either from a remote HTTP/HTTPS endpoint or from a local source.
// +kubebuilder:validation:XValidation:rule="has(self.remoteJWKS) || has(self.localJWKS)", message="either remoteJWKS or localJWKS must be specified."
// +kubebuilder:validation:XValidation:rule="!(has(self.remoteJWKS) && has(self.localJWKS))", message="remoteJWKS and localJWKS cannot both be specified."
Expand Down
124 changes: 124 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ require (
github.com/envoyproxy/go-control-plane v0.14.0
github.com/envoyproxy/go-control-plane/envoy v1.36.0
github.com/go-logr/logr v1.4.3
github.com/golang-jwt/jwt/v4 v4.5.2
github.com/golang-jwt/jwt/v5 v5.3.0
github.com/google/cel-go v0.26.1
github.com/google/go-cmp v0.7.0
github.com/google/jsonschema-go v0.3.0
Expand Down Expand Up @@ -158,7 +158,6 @@ require (
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
github.com/goccy/go-yaml v1.18.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.7.0 // indirect
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,6 @@ github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7Lk
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
Expand Down
62 changes: 62 additions & 0 deletions internal/filterapi/mcpconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ type MCPRoute struct {

// Backends is the list of backends that this route can route to.
Backends []MCPBackend `json:"backends"`

// Authorization is the authorization configuration for this route.
Authorization *MCPRouteAuthorization `json:"authorization,omitempty"`
}

// MCPBackend is the MCP backend configuration.
Expand Down Expand Up @@ -58,3 +61,62 @@ type MCPToolSelector struct {

// MCPRouteName is the name of the MCP route.
type MCPRouteName = string

// MCPRouteAuthorization defines the authorization configuration for a MCPRoute.
type MCPRouteAuthorization struct {
// Rules defines a list of authorization rules.
// These rules are evaluated in order, the first matching rule will be applied,
// and the rest will be skipped.
Rules []MCPRouteAuthorizationRule `json:"rules,omitempty"`

// DefaultAction defines the action to take when no rules match.
// If unset, the default is Deny.
DefaultAction *AuthorizationAction `json:"defaultAction,omitempty"`
}

// MCPRouteAuthorizationRule defines an authorization rule for MCPRoute based on the MCP authorization spec.
// Reference: https://modelcontextprotocol.io/specification/draft/basic/authorization#scope-challenge-handling
type MCPRouteAuthorizationRule struct {
// Source defines the authorization source for this rule.
Source MCPAuthorizationSource `json:"source"`

// Target defines the authorization target for this rule.
Target MCPAuthorizationTarget `json:"target"`

// Action defines whether to allow or deny requests that match this rule.
Action AuthorizationAction `json:"action"`
}

// AuthorizationAction represents an authorization decision.
type AuthorizationAction string

const (
// AuthorizationActionAllow allows the request.
AuthorizationActionAllow AuthorizationAction = "Allow"
// AuthorizationActionDeny denies the request.
AuthorizationActionDeny AuthorizationAction = "Deny"
)

type MCPAuthorizationTarget struct {
// Tools defines the list of tools this rule applies to.
Tools []ToolCall `json:"tools"`
}

type MCPAuthorizationSource struct {
// JWTSource defines the JWT scopes required for this rule to match.
JWTSource JWTSource `json:"jwtSource,omitempty"`
}

type JWTSource struct {
// Scopes defines the list of JWT scopes required for the rule.
// If multiple scopes are specified, all scopes must be present in the JWT for the rule to match.
Scopes []string `json:"scopes"`
}

type ToolCall struct {
// BackendName is the name of the backend this tool belongs to.
BackendName string `json:"backendName"`

// ToolName is the name of the tool.
ToolName string `json:"toolName"`
}
Loading
Loading