From 3436cae21764aa97d08887da0c763c2132d7bb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CShauna=20Diaz=E2=80=9D?= Date: Tue, 7 Apr 2026 08:23:39 -0400 Subject: [PATCH] OSDOCS-17718: adds authentication to MCP gateway docs --- _topic_maps/_topic_map.yml | 4 +- .../mcp-gateway-authentication.adoc | 12 ++ mcp_gateway_config/mcp-gateway-authn.adoc | 8 - modules/con-mcp-gateway-authentication.adoc | 25 +++ ...-configure-mcp-gateway-authentication.adoc | 192 ++++++++++++++++++ 5 files changed, 231 insertions(+), 10 deletions(-) create mode 100644 mcp_gateway_config/mcp-gateway-authentication.adoc delete mode 100644 mcp_gateway_config/mcp-gateway-authn.adoc create mode 100644 modules/con-mcp-gateway-authentication.adoc create mode 100644 modules/proc-configure-mcp-gateway-authentication.adoc diff --git a/_topic_maps/_topic_map.yml b/_topic_maps/_topic_map.yml index ae9135fb5446..0007aa452b79 100644 --- a/_topic_maps/_topic_map.yml +++ b/_topic_maps/_topic_map.yml @@ -77,8 +77,8 @@ Topics: File: mcp-gateway-register-on-prem-mcp-servers - Name: Configuring authentication for the MCP gateway File: mcp-gateway-authz -- Name: Configuring authorization for the MCP gateway - File: mcp-gateway-authn +- Name: Configuring authentication for the MCP gateway + File: mcp-gateway-authentication - Name: Using credentials to access external APIs File: mcp-gateway-vault --- diff --git a/mcp_gateway_config/mcp-gateway-authentication.adoc b/mcp_gateway_config/mcp-gateway-authentication.adoc new file mode 100644 index 000000000000..dc0df2ae8452 --- /dev/null +++ b/mcp_gateway_config/mcp-gateway-authentication.adoc @@ -0,0 +1,12 @@ +:_mod-docs-content-type: ASSEMBLY +include::_attributes/attributes.adoc[] +[id="mcp-gateway-authentication"] += Using authentication with {mcpg} +:context: mcp-gateway-authentication + +[role="_abstract"] +You can configure authentication for {mcpg} by using an `AuthPolicy` custom resource (CR) with an identity provider, or any Istio or Gateway API compatible mechanism. + +include::modules/con-mcp-gateway-authentication.adoc[leveloffset=+1] + +include::modules/proc-configure-mcp-gateway-authentication.adoc[leveloffset=+1] diff --git a/mcp_gateway_config/mcp-gateway-authn.adoc b/mcp_gateway_config/mcp-gateway-authn.adoc deleted file mode 100644 index bd871f61ff71..000000000000 --- a/mcp_gateway_config/mcp-gateway-authn.adoc +++ /dev/null @@ -1,8 +0,0 @@ -:_mod-docs-content-type: ASSEMBLY -include::_attributes/attributes.adoc[] -[id="mcp-gateway-authn"] -= AuthN with {mcpg} -:context: mcp-gateway-authn - -[role="_abstract"] -FPO assembly diff --git a/modules/con-mcp-gateway-authentication.adoc b/modules/con-mcp-gateway-authentication.adoc new file mode 100644 index 000000000000..ecc9feeeebf5 --- /dev/null +++ b/modules/con-mcp-gateway-authentication.adoc @@ -0,0 +1,25 @@ + +// Module included in the following assemblies: +// +// *mcp_gateway_config/mcp-gateway-authentication.adoc + +:_mod-docs-content-type: CONCEPT +[id="con-mcp-gateway-authentication_{context}"] += Understanding {mcpg} authentication + +[role="_abstract"] +When you enable authentication, the {mcpg} broker component exposes OAuth 2.0 Protected Resource Metadata, enabling MCP clients to discover your authorization server and complete the authentication flow. + +You can implement the following actions by using authentication: + +* Set up the {mcpg} to validate access tokens issued by your identity provider. +* Return a `401` error message with authorization server discovery information. +* Expose OAuth configuration at `/.well-known/oauth-protected-resource`. +* Enable MCP clients to discover and use your identity provider's client registration. + +The following procedure uses a Kuadrant `AuthPolicy` with {keycloak} as an identity provider example. The {mcpg} supports any Istio or Gateway API compatible authentication mechanism. + +[role="_additional-resources"] +.Additional resources + +* link:https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization[MCP Authorization specification] diff --git a/modules/proc-configure-mcp-gateway-authentication.adoc b/modules/proc-configure-mcp-gateway-authentication.adoc new file mode 100644 index 000000000000..88bef25e0318 --- /dev/null +++ b/modules/proc-configure-mcp-gateway-authentication.adoc @@ -0,0 +1,192 @@ +// Module included in the following assemblies: +// +// *mcp_gateway_config/mcp-gateway-authentication.adoc + +:_mod-docs-content-type: PROCEDURE +[id="proc-configure-mcp-gateway-authentication_{context}"] += Configuring {mcpg} authentication with an AuthPolicy + +[role="_abstract"] +Configure authentication for your {mcpg} by using a Kuadrant `AuthPolicy` custom resource (CR) and an identity provider such as {keycloak}. + +[NOTE] +==== +The {mcpg} supports any Istio or Gateway API compatible authentication mechanism. Use the best solution for your {ocp} clusters. +==== + +.Prerequisites + +* You installed {mcpg}. +* You installed {prodname}. +* You configured a `Gateway` object. +* You installed and have ready an identity provider supporting OAuth 2.0 or 2.1, for example, {keycloak}. + +.Procedure + +. Add a listener to the `Gateway` object for your identity provider by using the following command as an example: ++ +[source,json,subs="+quotes"] +---- +$ oc patch gateway __ -n __ --type json -p '[ + { + "op": "add", + "path": "/spec/listeners/-", + "value": { + "name": "keycloak", + "hostname": "keycloak.example.com", + "port": 8002, + "protocol": "HTTP", + "allowedRoutes": { + "namespaces": { + "from": "Selector", + "selector": { + "matchLabels": { + "kubernetes.io/metadata.name": "keycloak" + } + } + } + } + } + } +]' +---- ++ +* Replace `__` with the name of your MCP gateway. +* Replace `__` with the namespace of your `Gateway` object. +* Replace the {keycloak} `__`, `__`, and `__` with your identity provider information. + +. Configure the {mcpg} broker component to respond with OAuth discovery information by setting the following environment variables: ++ +[source,terminal,subs="+quotes"] +---- +$ oc set env deployment/__ \ + OAUTH_RESOURCE_NAME="MCP Server" \ + OAUTH_RESOURCE="http://mcp.example.com:8001/mcp" \ + OAUTH_AUTHORIZATION_SERVERS="http://keycloak.example.com:8002/realms/mcp" \ + OAUTH_BEARER_METHODS_SUPPORTED="header" \ + OAUTH_SCOPES_SUPPORTED="basic,groups,roles,profile" \ + -n __ +---- ++ +* Replace `__` with the name of your MCP gateway. +* Replace `__` with the namespace of your MCP gateway. +* `OAUTH_RESOURCE_NAME`: Human-readable name for the MCP server. +* `OAUTH_RESOURCE`: Canonical URI of the MCP server that is used for token audience validation. +* `OAUTH_AUTHORIZATION_SERVERS`: Authorization server URL for client discovery. +* `OAUTH_BEARER_METHODS_SUPPORTED`: Supported bearer token methods. Valid values are usually `header`, `body`, or `query`. +* `OAUTH_SCOPES_SUPPORTED`: The OAuth scopes this MCP server supports. + +. Create an AuthPolicy CR that validates JWT tokens: ++ +.Example AuthPolicy CR +[source,yaml,subs="+quotes"] +---- +apiVersion: kuadrant.io/v1 +kind: AuthPolicy +metadata: + name: __ + namespace: __ +spec: + targetRef: + group: gateway.networking.k8s.io + kind: Gateway + name: __ + sectionName: __ + defaults: + when: + - predicate: "!request.path.contains('/.well-known')" + rules: + authentication: + 'keycloak': + jwt: + issuerUrl: http://keycloak.example.com:8002/realms/mcp + response: + unauthenticated: + code: 401 + headers: + 'WWW-Authenticate': + value: Bearer resource_metadata=http://mcp.example.com:8001/.well-known/oauth-protected-resource/mcp + body: + value: | + { + "error": "Unauthorized", + "message": "Authentication required." + } +---- ++ +* The `metadata.name:` parameter value is the name of the `AuthPolicy` CR. Replace `__` as needed. +* The `metadata.namespace:` parameter value is the gateway namespace. Replace `__` with the namespace where you created your `Gateway` object to apply the `AuthPolicy` CR to the namespace. +* The `spec.targetRef.name:` parameter value is the name of your MCP gateway. Replace `__` as needed. +* The `spec.targetRef.sectionName:` parameter value is the target gateway listener. In this example, `mcp` is used. +* The `spec.defaults.when` parameter value in this example allows unauthenticated access to `/.well-known` endpoints. +* The `spec.defaults.rules.authentication:` parameter defines which tokens to validate and how. In this case, JWT validation validates tokens against Keycloak's OIDC issuer. +* The `spec.defaults.rules.response.unauthenticated.headers.'WWW-Authenticate':` parameter points clients to OAuth discovery metadata. Replace the `resource_metadata=` information as required. +* The `spec.defaults.rules.response.unauthenticated.body.value:` parameter is set with a standard response. This configuration returns a `401` error in an OAuth error format. + +. Apply the AuthPolicy CR by running the following command: ++ +[source,terminal,subs="+quotes"] +---- +$ oc apply -f __ +---- ++ +Replace `__` with the name of your CR. + +.Verification + +. Test that the broker now serves OAuth discovery information by checking the protected resource metadata endpoint with the following command: ++ +[source,terminal,subs="+quotes"] +---- +$ curl http://__ +---- ++ +* Replace the URL with your protected resource information. ++ +.Example output +[source,text] +---- +{ + "resource_name": "MCP Server", + "resource": "http://example.com:8001/mcp", + "authorization_servers": [ + "http://keycloak.example.com:8002/realms/mcp" + ], + "bearer_methods_supported": [ + "header" + ], + "scopes_supported": [ + "basic", + "groups", + "roles", + "profile" + ] +} +---- + +. Test that protected endpoints now require authentication by running the following command: ++ +[source,terminal,subs="+quotes"] +---- +$ curl -v http://__ \ + -H "Content-Type: application/json" \ + -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}' +---- ++ +Replace `__` with your endpoint. ++ +.Example output +[source,text] +---- +{ + "error": "Unauthorized", + "message": "Authentication required." +} +---- ++ +A `401` error with `WWW-Authenticate` header is expected. + +.Next steps + +* Control which users can access specific tools by configuring authorization policies. +* Connect authenticated external MCP services.