agentic-community / agentic-community/mcp-gateway-registry
Add custom authorizer endpoint support for external policy engine integration
- Lenguaje dominante
- Python
- Estrellas
- 911
- Forks
- 234
- Merge medio
- 1 d 11 h
- PR fusionados (30 d)
- 62
Descripción
Add support for calling an external custom authorizer endpoint as part of the `/validate` authentication flow. This enables enterprises to integrate with their existing authorization systems (Open Policy Agent, AWS Cedar, custom policy engines, etc.) while optionally retaining native JWT/OAuth2 validation.
## Problem Statement
Enterprises deploying the MCP Gateway Registry may need authorization logic that goes beyond standard JWT/OAuth2 validation:
- Integration with enterprise policy engines (OPA, AWS Cedar, etc.)
- Custom attribute-based access control (ABAC) decisions
- Time-based or context-aware authorization rules
- Integration with internal approval workflows
- Cross-referencing with CMDB or asset management systems
- Custom audit/logging requirements
## Proposed Solution
### Three Authorization Modes
| Mode | Behavior |
|------|----------|
| `native` | Current functionality - only JWT/OAuth2 validation (default) |
| `custom` | Only call custom authorizer - skip native auth entirely |
| `both` | Native auth first, then custom authorizer - both must succeed |
### Flow Diagram
```
/validate request
|
v
+-------------------+
| Extract headers |
| X-Original-URL |
| Authorization |
| X-Body, etc. |
+--------+----------+
|
v
+-------------------+
| Check AUTHORIZER_ |
| MODE |
+--------+----------+
|
+-------------------+-------------------+
| | |
v v v
MODE=native MODE=custom MODE=both
| | |
v v |
Native Auth Custom Auth +---+---+
(JWT/OAuth2) Endpoint | |
| | v v
v v Native Then
Return result Return result Auth Custom
| |
+---+---+
|
v
Both must
succeed
```
### New Environment Variables
```bash
# Authorization mode: native, custom, or both
AUTHORIZER_MODE=native
# Custom authorizer endpoint URL
CUSTOM_AUTHORIZER_URL=http://policy-engine:8080/authorize
# Timeout for custom authorizer calls in seconds
CUSTOM_AUTHORIZER_TIMEOUT=5
# Optional: API key for authenticating to custom authorizer
CUSTOM_AUTHORIZER_API_KEY=
```
### Request to Custom Authorizer
Auth server will POST full request context:
```json
{
"request": {
"method": "GET",
"path": "/api/servers",
"original_url": "http://gateway.example.com/api/servers",
"headers": {"authorization": "Bearer ***...xyz"},
"body": null,
"client_ip": "10.0.1.50"
},
"native_auth_result": {
"valid": true,
"username": "john.doe@example.com",
"scopes": ["mcp-servers/read"],
"groups": ["mcp-registry-user"],
"auth_method": "keycloak"
},
"context": {
"timestamp": "2026-01-12T10:30:45Z",
"request_id": "req-abc123"
}
}
```
### Response from Custom Authorizer
**Success (HTTP 200):**
```json
{
"authorized": true,
"username": "john.doe@example.com",
"scopes": ["mcp-servers/read", "custom:approved"],
"groups": ["mcp-registry-user"],
"auth_method": "custom",
"metadata": {"policy_name": "enterprise-policy-v2"}
}
```
**Denial (HTTP 200 with authorized=false, or HTTP 403):**
```json
{
"authorized": false,
"error": {
"code": "POLICY_VIOLATION",
"message": "Access denied: User not in approved list"
}
}
```
## Registry Compatibility
The response MUST include fields required by registry's `nginx_proxied_auth()`:
- `username` - User identity (maps to X-Username header)
- `scopes` - List of scopes (space-joined for X-Scopes header)
- `auth_method` - Auth method identifier (X-Auth-Method header)
In `both` mode, scopes/groups from native and custom auth are merged (additive).
## Security Considerations
- Authorization headers are masked before sending to custom authorizer
- Fail-closed: if custom authorizer unavailable, deny access (503)
- Custom authorizer is a trusted component - secure appropriately
- Use HTTPS in production
## Implementation Tasks
- [ ] Create Pydantic models for custom authorizer request/response
- [ ] Implement custom authorizer service with async HTTP client
- [ ] Add environment variable configuration and validation
- [ ] Integrate with `/validate` endpoint for all three modes
- [ ] Add Terraform variables for deployment
- [ ] Add comprehensive logging with request correlation
- [ ] Write unit tests for each mode
- [ ] Write integration tests for failure scenarios
- [ ] Update deployment documentation
- [ ] Create example custom authorizer implementations (OPA, Lambda)
## Example Integrations
### Open Policy Agent (OPA)
```bash
AUTHORIZER_MODE=both
CUSTOM_AUTHORIZER_URL=http://opa:8181/v1/data/mcp/authz
```
### AWS Lambda Authorizer
```bash
AUTHORIZER_MODE=custom
CUSTOM_AUTHORIZER_URL=https://xyz.execute-api.us-east-1.amazonaws.com/authorize
```
## Design Document
Full design document: `.scratchpad/design-custom-authorizer-endpoint-2026-01-12.md`
## Related
- Issue #357 - Network-trusted mode for bypassing auth in trusted networks
- `registry/auth/dependencies.py` - Registry auth dependencies
- `auth_server/server.py` - Auth server validate endpoint
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.