Skip to content

Commit cd1c260

Browse files
update mcp-gateway authn/authz guides
Signed-off-by: Patryk Stefanski <pstefans@redhat.com>
1 parent c384fd7 commit cd1c260

2 files changed

Lines changed: 53 additions & 21 deletions

File tree

modules/proc-configure-mcp-gateway-authentication.adoc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ The {mcpg} supports any Istio or Gateway API compatible authentication mechanism
1818

1919
* You installed {mcpg}.
2020
* You installed {prodname}.
21-
* You configured a `Gateway` object.
21+
* You configured a `Gateway` object with an `mcp` listener.
2222
* You installed and have ready an identity provider supporting OAuth 2.0 or 2.1, for example, {keycloak}.
2323
2424
.Procedure
@@ -105,7 +105,7 @@ spec:
105105
code: 401
106106
headers:
107107
'WWW-Authenticate':
108-
value: Bearer resource_metadata=http://mcp.example.com:8001/.well-known/oauth-protected-resource/mcp
108+
value: Bearer resource_metadata=http://mcp.example.com:8001/.well-known/oauth-protected-resource
109109
body:
110110
value: |
111111
{
@@ -127,18 +127,18 @@ spec:
127127
+
128128
[source,terminal,subs="+quotes"]
129129
----
130-
$ oc apply -f _<mcp_jwt_authpolicy.yaml>_
130+
$ oc apply -f - <<EOF
131+
<AuthPolicy CR from the previous step>
132+
EOF
131133
----
132-
+
133-
Replace `_<mcp_jwt_authpolicy.yaml>_` with the name of your CR.
134134

135135
.Verification
136136

137137
. Test that the broker now serves OAuth discovery information by checking the protected resource metadata endpoint with the following command:
138138
+
139139
[source,terminal,subs="+quotes"]
140140
----
141-
$ curl http://_<mcp.example.com:8001/.well_known/oauth_protected_resource>_
141+
$ curl http://_<mcp.example.com:8001>_/.well-known/oauth-protected-resource
142142
----
143143
+
144144
* Replace the URL with your protected resource information.

modules/proc-mcp-gateway-authorization.adoc

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
// Module included in the following assemblies:
32
//
43
// *mcp_gateway_config/mcp-gateway-authorization.adoc
@@ -14,12 +13,40 @@ The following example demonstrates using a Kuadrant `AuthPolicy` custom resource
1413

1514
* You installed {mcpg}.
1615
* You installed {prodname}.
17-
* You configured a `Gateway` object.
18-
* You completed authentication procedures.
16+
* You configured a `Gateway` object with an `mcp` listener.
17+
* You completed authentication procedures, including creating an `AuthPolicy` CR on the `mcp` listener.
1918
* You configured your identity provider to include `group` and `role` claims in JSON Web Tokens (JWT).
19+
* The identity provider client IDs match the namespaced `MCPServerRegistration` name in the format `_<namespace>_/_<mcpserverregistration_name>_`.
2020
2121
.Procedure
2222

23+
. Add an `mcps` listener to the `Gateway` object for internal `tools/call` routing by using the following command as an example:
24+
+
25+
[source,json,subs="+quotes"]
26+
----
27+
$ oc patch gateway _<mcp_gateway>_ -n _<gateway_system>_ --type json -p '[
28+
{
29+
"op": "add",
30+
"path": "/spec/listeners/-",
31+
"value": {
32+
"name": "mcps",
33+
"port": 8080,
34+
"protocol": "HTTP",
35+
"hostname": "*.mcp-internal.example.com",
36+
"allowedRoutes": {
37+
"namespaces": {
38+
"from": "All"
39+
}
40+
}
41+
}
42+
}
43+
]'
44+
----
45+
+
46+
* Replace `_<mcp_gateway>_` with the name of your MCP gateway.
47+
* Replace `_<gateway_system>_` with the namespace of your `Gateway` object.
48+
* Replace `*.mcp-internal.example.com` with a wildcard hostname for your environment.
49+
2350
. Ensure that your identity provider includes the required `group` and `role` claims in the issued JWTs. In the following example, {keycloak} is used:
2451
+
2552
.Example issued OAuth token claims:
@@ -37,10 +64,15 @@ The following example demonstrates using a Kuadrant `AuthPolicy` custom resource
3764
}
3865
----
3966
+
40-
* The `"mcp-ns/arithmetic-mcp-server"` specification must match the namespaced name of the `MCPServerRegistration` CR.
67+
* The `"mcp-ns/arithmetic-mcp-server"` specification must match the namespaced name of the `MCPServerRegistration` CR in the format `{namespace}/{name}`. For example, if your `MCPServerRegistration` is named `arithmetic-mcp-server` in the `mcp-ns` namespace, the {keycloak} client ID must be `mcp-ns/arithmetic-mcp-server`.
4168
* The `"roles": ["add", "sum", "multiply", "divide"]` parameter and values specify the roles representing the allowed tools.
4269
43-
. Configure tool-level authorization by creating an `AuthPolicy` CR that enforces tool-level access control, as shown in the following example:
70+
. Configure tool-level authorization by creating an `AuthPolicy` CR that enforces tool-level access control on the `mcps` listener, as shown in the following example:
71+
+
72+
[IMPORTANT]
73+
====
74+
The authorization `AuthPolicy` must target the `mcps` listener, not the `mcp` listener. The `mcp` listener handles public traffic (`initialize`, `tools/list`, `/.well-known`) and has the authentication-only `AuthPolicy`.
75+
====
4476
+
4577
.Example tool-level access control AuthPolicy
4678
[source,yaml,subs="+quotes"]
@@ -60,7 +92,7 @@ spec:
6092
authentication:
6193
'sso-server':
6294
jwt:
63-
issuerUrl: http://keycloak.example.com:8002/realms/mcp
95+
issuerUrl: https://_<keycloak.example.com>_/realms/mcp
6496
authorization:
6597
'tool-access-check':
6698
patternMatching:
@@ -71,7 +103,7 @@ spec:
71103
unauthenticated:
72104
headers:
73105
'WWW-Authenticate':
74-
value: Bearer resource_metadata=http://mcp.example.com:8001/.well-known/oauth-protected-resource/mcp
106+
value: Bearer resource_metadata=http://_<mcp.example.com:8001>_/.well-known/oauth-protected-resource
75107
body:
76108
value: |
77109
{
@@ -90,8 +122,8 @@ spec:
90122
* Replace `metadata.name:` with the name of the `AuthPolicy`.
91123
* Replace `metadata.namespace:` with the namespace where the `AuthPolicy` CR is applied.
92124
* Replace `spec.targetRef.name:` with the name of the `Gateway` CR.
93-
* The `spec.targetRef.sectionName:` value targets the MCP server listener.
94-
* Authentication: Validates the JWT token using the configured issuer URL
125+
* The `spec.targetRef.sectionName:` value must be `mcps`, the internal listener for tool-call authorization. This listener must exist on your `Gateway` object.
126+
* Authentication: Validates the JWT token using the configured issuer URL. Replace `_<keycloak.example.com>_` with your identity provider hostname.
95127
* Authorization Logic: CEL expression checks if user's roles allow access to the requested tool
96128
* CEL Breakdown:
97129
** `request.headers['x-mcp-toolname']`: The name of the requested MCP tool, stripped from prefix.
@@ -103,24 +135,24 @@ spec:
103135
+
104136
[source,terminal,subs="+quotes"]
105137
----
106-
$ oc apply -f _<mcp_tool_auth_policy.yaml>_
138+
$ oc apply -f - <<EOF
139+
<AuthPolicy CR from the previous step>
140+
EOF
107141
----
108-
* Replace `_<mcp_tool_auth_policy.yaml>_` with the name of the `AuthPolicy` YAML filename.
109142

110143
.Verification
111144

112145
. Monitor authorization decisions by checking the `AuthPolicy` CR `status` with the following command:
113146
+
114-
[source,terminal]
147+
[source,terminal,subs="+quotes"]
115148
----
116-
$ oc get authpolicy -A
149+
$ oc get authpolicy _<mcp_tool_auth_policy>_ -n _<gateway_system>_ -o jsonpath='{.status.conditions[?(@.type=="Enforced")].status}'
117150
----
118151
+
119152
.Example output
120153
[source,text]
121154
----
122-
NAMESPACE NAME STATUS
123-
gateway-system mcp-tool-auth-policy Enforced
155+
True
124156
----
125157

126158
. Check the authorization logs by running the following command:

0 commit comments

Comments
 (0)