|
| 1 | +# MCP Authorization |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +The MCP Authorization policy provides fine-grained access control for Model Context Protocol (MCP) server resources. It enables API administrators to define authorization rules based on user claims and scopes extracted from validated JWT tokens, controlling access to specific MCP tools, resources, prompts, and JSON-RPC methods. |
| 6 | + |
| 7 | +> **Prerequisite**: The MCP Authorization policy requires the [MCP Authentication policy](./mcp-authentication.md) to be applied first. The MCP Authentication policy validates and extracts JWT claims that are used by the authorization policy for access control decisions. |
| 8 | +
|
| 9 | +## Features |
| 10 | + |
| 11 | +- **Tool-Level Access Control**: Restrict access to specific MCP tools based on user claims and scopes |
| 12 | +- **Resource-Level Access Control**: Control access to specific MCP resources based on authorization rules |
| 13 | +- **Prompt-Level Access Control**: Manage access to specific MCP prompts |
| 14 | +- **JSON-RPC Method-Level Access Control**: Apply authorization rules at the JSON-RPC method level (e.g., `tools/call`, `resources/read`, `prompts/get`) for fine-grained control. Only methods under `tools/`, `resources/`, and `prompts/` are evaluated. |
| 15 | +- **Flexible Rule-Based Authorization**: Define multiple authorization rules with attribute matching (exact or wildcard) |
| 16 | +- **Claim-Based Validation**: Validate custom claims (e.g., department, role, team) in user tokens |
| 17 | +- **Scope-Based Validation**: Require specific OAuth scopes for accessing protected resources |
| 18 | +- **Wildcard Matching**: Use wildcard patterns ("*") to create default rules for all resources of a type |
| 19 | + |
| 20 | +## Configuration |
| 21 | + |
| 22 | +The MCP Authorization policy uses a single-level configuration model where all parameters are configured per-MCP-API/route in the API definition YAML. |
| 23 | + |
| 24 | +### User Parameters (API Definition) |
| 25 | + |
| 26 | +These parameters are configured per MCP Proxy by the API developer: |
| 27 | + |
| 28 | +| Parameter | Type | Required | Default | Description | |
| 29 | +|-----------|------|----------|---------|-------------| |
| 30 | +| `rules` | array | Yes | - | List of authorization rules that define access control policies for MCP resources. | |
| 31 | +| `rules[].attribute` | object | Yes | - | The MCP resource attribute to which the authorization rule applies. | |
| 32 | +| `rules[].attribute.type` | string | Yes | - | Type of MCP resource: "tool", "resource", "prompt", "method". | |
| 33 | +| `rules[].attribute.name` | string | No | - | Name or identifier of the resource. Use "*" for wildcard matching (applies to all resources of the specified type). Examples: "list_files" for tools, "file:///some_resource" for resources, "weather_summary" for prompts, "tools/call" for methods. | |
| 34 | +| `rules[].requiredScopes` | array | No | - | List of OAuth scopes required to access this resource. The token must contain all of the specified scopes. | |
| 35 | +| `rules[].requiredClaims` | object | No | - | Map of claim names to expected values. All specified claims must be present in the token with matching values. | |
| 36 | + |
| 37 | +## MCP Proxy Definition Examples |
| 38 | + |
| 39 | +### Example 1: Basic Tool Access Control |
| 40 | + |
| 41 | +Restrict access to specific tools based on scopes: |
| 42 | + |
| 43 | +```yaml |
| 44 | +apiVersion: gateway.api-platform.wso2.com/v1alpha1 |
| 45 | +kind: Mcp |
| 46 | +metadata: |
| 47 | + name: mcp-server-api-v1.0 |
| 48 | +spec: |
| 49 | + displayName: mcp-server-api |
| 50 | + version: v1.0 |
| 51 | + context: /mcpserver |
| 52 | + vhost: mcp1.gw.example.com |
| 53 | + upstream: |
| 54 | + url: https://mcp-backend:8080 |
| 55 | + policies: |
| 56 | + - name: mcp-auth |
| 57 | + version: v0.1.0 |
| 58 | + params: |
| 59 | + issuers: |
| 60 | + - PrimaryIDP |
| 61 | + - name: mcp-authz |
| 62 | + version: v0.1.0 |
| 63 | + params: |
| 64 | + rules: |
| 65 | + - attribute: |
| 66 | + type: tool |
| 67 | + name: list_files |
| 68 | + requiredScopes: |
| 69 | + - mcp:tool:read |
| 70 | + - attribute: |
| 71 | + type: tool |
| 72 | + name: create_file |
| 73 | + requiredScopes: |
| 74 | + - mcp:tool:write |
| 75 | + - attribute: |
| 76 | + type: tool |
| 77 | + name: "*" |
| 78 | + requiredScopes: |
| 79 | + - mcp:tool:execute |
| 80 | + tools: |
| 81 | + ... |
| 82 | +``` |
| 83 | +
|
| 84 | +### Example 2: Claim-Based Resource Access |
| 85 | +
|
| 86 | +Control resource access based on user claims: |
| 87 | +
|
| 88 | +```yaml |
| 89 | +apiVersion: gateway.api-platform.wso2.com/v1alpha1 |
| 90 | +kind: Mcp |
| 91 | +metadata: |
| 92 | + name: mcp-server-api-v1.0 |
| 93 | +spec: |
| 94 | + displayName: mcp-server-api |
| 95 | + version: v1.0 |
| 96 | + context: /mcpserver |
| 97 | + vhost: mcp1.gw.example.com |
| 98 | + upstream: |
| 99 | + url: https://mcp-backend:8080 |
| 100 | + policies: |
| 101 | + - name: mcp-auth |
| 102 | + version: v0.1.0 |
| 103 | + params: |
| 104 | + issuers: |
| 105 | + - PrimaryIDP |
| 106 | + - name: mcp-authz |
| 107 | + version: v0.1.0 |
| 108 | + params: |
| 109 | + rules: |
| 110 | + - attribute: |
| 111 | + type: resource |
| 112 | + name: "file:///private/main" |
| 113 | + requiredClaims: |
| 114 | + department: "engineering" |
| 115 | + requiredScopes: |
| 116 | + - mcp:resource:read |
| 117 | + - attribute: |
| 118 | + type: resource |
| 119 | + name: "file:///public/main" |
| 120 | + requiredScopes: |
| 121 | + - mcp:resource:read |
| 122 | + tools: |
| 123 | + ... |
| 124 | +``` |
| 125 | +
|
| 126 | +### Example 3: Role-Based Prompt Access |
| 127 | +
|
| 128 | +Restrict prompt access based on user roles: |
| 129 | +
|
| 130 | +```yaml |
| 131 | +apiVersion: gateway.api-platform.wso2.com/v1alpha1 |
| 132 | +kind: Mcp |
| 133 | +metadata: |
| 134 | + name: mcp-server-api-v1.0 |
| 135 | +spec: |
| 136 | + displayName: mcp-server-api |
| 137 | + version: v1.0 |
| 138 | + context: /mcpserver |
| 139 | + vhost: mcp1.gw.example.com |
| 140 | + upstream: |
| 141 | + url: https://mcp-backend:8080 |
| 142 | + policies: |
| 143 | + - name: mcp-auth |
| 144 | + version: v0.1.0 |
| 145 | + params: |
| 146 | + issuers: |
| 147 | + - PrimaryIDP |
| 148 | + - name: mcp-authz |
| 149 | + version: v0.1.0 |
| 150 | + params: |
| 151 | + rules: |
| 152 | + - attribute: |
| 153 | + type: prompt |
| 154 | + name: "admin_summary" |
| 155 | + requiredClaims: |
| 156 | + role: "admin" |
| 157 | + requiredScopes: |
| 158 | + - mcp:prompt:admin |
| 159 | + - attribute: |
| 160 | + type: prompt |
| 161 | + name: "*" |
| 162 | + requiredScopes: |
| 163 | + - mcp:prompt:read |
| 164 | + tools: |
| 165 | + ... |
| 166 | +``` |
| 167 | +
|
| 168 | +### Example 4: Multi-Level Authorization |
| 169 | +
|
| 170 | +Combine different resource types with varying access requirements: |
| 171 | +
|
| 172 | +```yaml |
| 173 | +apiVersion: gateway.api-platform.wso2.com/v1alpha1 |
| 174 | +kind: Mcp |
| 175 | +metadata: |
| 176 | + name: mcp-server-api-v1.0 |
| 177 | +spec: |
| 178 | + displayName: mcp-server-api |
| 179 | + version: v1.0 |
| 180 | + context: /mcpserver |
| 181 | + vhost: mcp1.gw.example.com |
| 182 | + upstream: |
| 183 | + url: https://mcp-backend:8080 |
| 184 | + policies: |
| 185 | + - name: mcp-auth |
| 186 | + version: v0.1.0 |
| 187 | + params: |
| 188 | + issuers: |
| 189 | + - PrimaryIDP |
| 190 | + requiredScopes: |
| 191 | + - mcp:access |
| 192 | + - name: mcp-authz |
| 193 | + version: v0.1.0 |
| 194 | + params: |
| 195 | + rules: |
| 196 | + # Restrictive tool access |
| 197 | + - attribute: |
| 198 | + type: tool |
| 199 | + name: "execute_command" |
| 200 | + requiredClaims: |
| 201 | + department: "platform" |
| 202 | + role: "admin" |
| 203 | + requiredScopes: |
| 204 | + - mcp:tool:execute:admin |
| 205 | + # General tool access |
| 206 | + - attribute: |
| 207 | + type: tool |
| 208 | + name: "*" |
| 209 | + requiredScopes: |
| 210 | + - mcp:tool:execute |
| 211 | + # Resource access for finance department |
| 212 | + - attribute: |
| 213 | + type: resource |
| 214 | + name: "file:///finance/*" |
| 215 | + requiredClaims: |
| 216 | + department: "finance" |
| 217 | + requiredScopes: |
| 218 | + - mcp:resource:read:finance |
| 219 | + # Public resources |
| 220 | + - attribute: |
| 221 | + type: resource |
| 222 | + name: "*" |
| 223 | + requiredScopes: |
| 224 | + - mcp:resource:read |
| 225 | + tools: |
| 226 | + ... |
| 227 | +``` |
| 228 | +
|
| 229 | +## Authorization Decision Examples |
| 230 | +
|
| 231 | +**Scenario 1**: User with scope `mcp:tool:read` attempts to call `list_files` tool |
| 232 | +- Rule: `attribute.type="tool", attribute.name="list_files", requiredScopes=["mcp:tool:read"]` |
| 233 | +- Result: ✅ Access Granted |
| 234 | + |
| 235 | +**Scenario 2**: User with scope `mcp:tool:execute` (no write scope) attempts to call `create_file` tool |
| 236 | +- Rule: `attribute.type="tool", attribute.name="create_file", requiredScopes=["mcp:tool:write"]` |
| 237 | +- Result: ❌ Access Denied (insufficient scopes) |
| 238 | + |
| 239 | +**Scenario 3**: User with claim `department="engineering"` attempts to read resource `file:///private/code` |
| 240 | +- Rule: `attribute.type="resource", attribute.name="file:///private/code", requiredClaims={department="engineering"}` |
| 241 | +- Result: ✅ Access Granted |
| 242 | + |
| 243 | +**Scenario 4**: User with claim `department="finance"` (no engineering) attempts to read resource `file:///private/code` |
| 244 | +- Rule: `attribute.type="resource", attribute.name="file:///private/code", requiredClaims={department="engineering"}` |
| 245 | +- Result: ❌ Access Denied (claim mismatch) |
| 246 | + |
| 247 | +## Error Handling |
| 248 | + |
| 249 | +When authorization fails, the policy returns: |
| 250 | +- **HTTP Status**: `403 Forbidden` |
| 251 | +- **Response Body**: JSON error response with a reason message |
| 252 | +- **WWW-Authenticate Header**: Contains information about required scopes for the denied resource |
| 253 | + |
| 254 | +## Related Policies |
| 255 | + |
| 256 | +- [MCP Authentication Policy](./mcp-authentication.md) - Validates JWT tokens and is a prerequisite for MCP Authorization |
| 257 | +- [JWT Authentication Policy](../../../gateway/policies/jwt-authentication.md) - Base JWT token validation mechanism |
0 commit comments