Skip to content

Commit 4b7c6f0

Browse files
authored
Merge pull request #109794 from ShaunaDiaz/OSDOCS-17719
OSDOCS-17719: adds authorization to MCP gateway docs
2 parents 658af29 + a9589e3 commit 4b7c6f0

5 files changed

Lines changed: 174 additions & 13 deletions

File tree

_topic_maps/_topic_map.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,18 @@ Topics:
6969
- Name: Using on-premise DNS with CoreDNS
7070
File: coredns
7171
---
72-
Name: Configuring the MCP gateway, register servers, and create policies
72+
Name: Registering MCP servers and creating policies
7373
Dir: mcp_gateway_config
7474
Distros: rhcl
7575
Topics:
7676
- Name: Registering on-premise MCP servers
7777
File: mcp-gateway-register-on-prem-mcp-servers
7878
- Name: Registering external MCP servers
7979
File: mcp-gateway-register-ext-mcp-servers
80-
- Name: Configuring authentication for the MCP gateway
81-
File: mcp-gateway-authz
8280
- Name: Configuring authentication for the MCP gateway
8381
File: mcp-gateway-authentication
82+
- Name: Configuring authorization for the MCP gateway
83+
File: mcp-gateway-authorization
8484
- Name: Using credentials to access external APIs
8585
File: mcp-gateway-vault
8686
---
@@ -94,8 +94,8 @@ Topics:
9494
File: mcp-gateway-observe
9595
- Name: Troubleshooting MCP gateway
9696
File: mcp-gateway-troubleshooting
97-
#- Name: Troubleshooting Connectivity Link
98-
# File: rhcl-troubleshooting
97+
- Name: Troubleshooting Connectivity Link
98+
File: rhcl-troubleshooting
9999
---
100100
Name: Updating Red Hat Connectivity Link
101101
Dir: updating
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
:_mod-docs-content-type: ASSEMBLY
2+
include::_attributes/attributes.adoc[]
3+
[id="mcp-gateway-authorization"]
4+
= Using authorization with {mcpg}
5+
:context: mcp-gateway-authorization
6+
7+
[role="_abstract"]
8+
You can configure authorization for the {mcpg} by using an additional `AuthPolicy` custom resource (CR) that adds access control for servers, data, and tools.
9+
10+
include::modules/con-understanding-mcp-gateway-authorization.adoc[leveloffset=+1]
11+
12+
include::modules/proc-mcp-gateway-authorization.adoc[leveloffset=+1]

mcp_gateway_config/mcp-gateway-authz.adoc

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Module included in the following assemblies:
2+
//
3+
// *mcp_gateway_config/mcp-gateway-authorization.adoc
4+
5+
:_mod-docs-content-type: CONCEPT
6+
[id="con-understanding-mcp-gateway-authorization_{context}"]
7+
= Understanding authorization in {mcpg}
8+
9+
[role="_abstract"]
10+
By setting up authorization in the MCP gateway, you can control which authenticated users can access specific MCP server tools. The MCP gateway supports authorization approaches including other policy engines and Gateway API policy extensions.
11+
12+
The following steps represent what happens during an authorization evaluation:
13+
14+
* Authentication: A user authenticates and receives a JSON Web Token (JWT) with permissions.
15+
* Tool request: The client makes an MCP tool call, such as `tools/call`.
16+
* Request identity check: An `AuthPolicy` object verifies the JWT and extracts authorization claims.
17+
* Authorization check: A Common Expression Language (CEL) expression evaluates the requested tool against the user's permissions that were extracted from the JWT.
18+
* Access decision: `Allow` or `deny` based on the authorization check result.
19+
20+
To create an authorization evaluation, you must set up authentication, define permissions, and specify access control roles. For example, take the following steps if using {keycloak}:
21+
22+
* Define your permissions and user claims. If you are using {keycloak}, you can add groups or attributes to the default JWT.
23+
* Provide tool-level authorization to control access to individual MCP tools.
24+
* Define role-based access by using {keycloak} client roles and group bindings for permission decisions.
25+
* Configure your identity provider to include Access Control List (ACL) claims in the tokens it issues.
26+
* Define complex authorization logic using Common Expression Language expressions that evaluate the claims and decide whether to let them through.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
2+
// Module included in the following assemblies:
3+
//
4+
// *mcp_gateway_config/mcp-gateway-authorization.adoc
5+
6+
:_mod-docs-content-type: PROCEDURE
7+
[id="proc-mcp-gateway-authorization_{context}"]
8+
= Configuring {mcpg} authorization with an AuthPolicy
9+
10+
[role="_abstract"]
11+
The following example demonstrates using a Kuadrant `AuthPolicy` custom resource (CR) with Common Expression Language (CEL) to implement role-based access control. You can use this procedure as a general pattern for applying the authorization specific to your use case. The {mcpg} supports Istio or Gateway API compatible authorization mechanisms.
12+
13+
.Prerequisites
14+
15+
* You installed {mcpg}.
16+
* You installed {prodname}.
17+
* You configured a `Gateway` object.
18+
* You completed authentication procedures.
19+
* You configured your identity provider to include `group` and `role` claims in JSON Web Tokens (JWT).
20+
21+
.Procedure
22+
23+
. Ensure that your identity provider includes the required `group` and `role` claims in the issued JWTs. In the following example, {keycloak} is used:
24+
+
25+
.Example issued OAuth token claims:
26+
[source,json]
27+
----
28+
{
29+
"resource_access": {
30+
"mcp-ns/arithmetic-mcp-server": {
31+
"roles": ["add", "sum", "multiply", "divide"]
32+
},
33+
"mcp-ns/geometry-mcp-server": {
34+
"roles": ["area", "distance", "volume"]
35+
}
36+
}
37+
}
38+
----
39+
+
40+
* The `"mcp-ns/arithmetic-mcp-server"` specification must match the namespaced name of the `MCPServerRegistration` CR.
41+
* The `"roles": ["add", "sum", "multiply", "divide"]` parameter and values specify the roles representing the allowed tools.
42+
43+
. Configure tool-level authorization by creating an `AuthPolicy` CR that enforces tool-level access control, as shown in the following example:
44+
+
45+
.Example tool-level access control AuthPolicy
46+
[source,yaml,subs="+quotes"]
47+
----
48+
apiVersion: kuadrant.io/v1
49+
kind: AuthPolicy
50+
metadata:
51+
name: _<mcp_tool_auth_policy>_
52+
namespace: _<gateway_system>_
53+
spec:
54+
targetRef:
55+
group: gateway.networking.k8s.io
56+
kind: Gateway
57+
name: _<mcp_gateway>_
58+
sectionName: _<mcps>_
59+
rules:
60+
authentication:
61+
'sso-server':
62+
jwt:
63+
issuerUrl: http://keycloak.example.com:8002/realms/mcp
64+
authorization:
65+
'tool-access-check':
66+
patternMatching:
67+
patterns:
68+
- predicate: |
69+
request.headers['x-mcp-toolname'] in (has(auth.identity.resource_access) && auth.identity.resource_access.exists(p, p == request.headers['x-mcp-servername']) ? auth.identity.resource_access[request.headers['x-mcp-servername']].roles : [])
70+
response:
71+
unauthenticated:
72+
headers:
73+
'WWW-Authenticate':
74+
value: Bearer resource_metadata=http://mcp.example.com:8001/.well-known/oauth-protected-resource/mcp
75+
body:
76+
value: |
77+
{
78+
"error": "Unauthorized",
79+
"message": "MCP Tool Access denied: Authentication required."
80+
}
81+
unauthorized:
82+
body:
83+
value: |
84+
{
85+
"error": "Forbidden",
86+
"message": "MCP Tool Access denied: Insufficient permissions for this tool."
87+
}
88+
----
89+
+
90+
* Replace `metadata.name:` with the name of the `AuthPolicy`.
91+
* Replace `metadata.namespace:` with the namespace where the `AuthPolicy` CR is applied.
92+
* 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
95+
* Authorization Logic: CEL expression checks if user's roles allow access to the requested tool
96+
* CEL Breakdown:
97+
** `request.headers['x-mcp-toolname']`: The name of the requested MCP tool, stripped from prefix.
98+
** `request.headers['x-mcp-servername']`: The namespaced name of the MCP server matching the `MCPServerRegistration` CR.
99+
** `auth.identity.resource_access`: The JWT claim containing all roles representing each allowed tool the user can access, grouped by MCP server.
100+
* Response handling: Custom `401` and `403` responses for unauthenticated and unauthorized access attempts.
101+
102+
. Apply the AuthPolicy CR by running the following command:
103+
+
104+
[source,terminal,subs="+quotes"]
105+
----
106+
$ oc apply -f _<mcp_tool_auth_policy.yaml>_
107+
----
108+
* Replace `_<mcp_tool_auth_policy.yaml>_` with the name of the `AuthPolicy` YAML filename.
109+
110+
.Verification
111+
112+
. Monitor authorization decisions by checking the `AuthPolicy` CR `status` with the following command:
113+
+
114+
[source,terminal]
115+
----
116+
$ oc get authpolicy -A
117+
----
118+
+
119+
.Example output
120+
[source,text]
121+
----
122+
NAMESPACE NAME STATUS
123+
gateway-system mcp-tool-auth-policy Enforced
124+
----
125+
126+
. Check the authorization logs by running the following command:
127+
+
128+
[source,terminal]
129+
----
130+
$ oc logs -n mcp-system -l app.kubernetes.io/name=mcp-gateway
131+
----

0 commit comments

Comments
 (0)