Skip to content

Conversation

crivetimihai
Copy link
Member

@crivetimihai crivetimihai commented Aug 10, 2025

PR: Add Configurable MCP Client Authentication for Proxy Deployments closes #705

Overview

This PR implements configurable MCP client authentication to support enterprise deployments where MCP Gateway operates behind authentication proxies. This addresses Issue #705 - "Option to completely remove Bearer token auth to MCP gateway".

Problem Statement

Previously, MCP Gateway required JWT bearer token authentication for all MCP client operations, even when deployed behind enterprise authentication proxies (OAuth2 Proxy, Authelia, Cloudflare Access, etc.). This created unnecessary complexity as organizations had to manage JWT tokens despite having centralized authentication at the proxy layer.

The AUTH_REQUIRED=false setting only made authentication optional but didn't fully disable JWT validation, and there was no way to trust proxy-provided user headers.

Solution Implemented

New Configuration Options

Added three new environment variables to enable proxy authentication:

  1. MCP_CLIENT_AUTH_ENABLED (default: true)

    • Controls JWT authentication for MCP client operations
    • When false, bypasses JWT validation entirely
    • Independent from AUTH_REQUIRED (which controls admin UI auth)
  2. TRUST_PROXY_AUTH (default: false)

    • Must be explicitly set to true when disabling MCP client auth
    • Acts as a safety flag to prevent accidental security misconfiguration
    • Logs a warning if MCP auth is disabled without this flag
  3. PROXY_USER_HEADER (default: X-Authenticated-User)

    • Configurable header name for extracting authenticated username
    • Supports different proxy configurations (X-Remote-User, X-Auth-Request-Email, etc.)

Key Changes

1. Configuration (mcpgateway/config.py)

  • Added new configuration fields with Pydantic validation
  • Implemented safety check that warns when MCP_CLIENT_AUTH_ENABLED=false without TRUST_PROXY_AUTH=true
  • Maintains backward compatibility with existing deployments

2. Authentication Logic (mcpgateway/utils/verify_credentials.py)

  • Modified require_auth() to support proxy authentication
  • When proxy auth is enabled, extracts user from configured header
  • Returns user info with source: "proxy" indicator for traceability
  • Falls back to "anonymous" when no proxy header is present

3. WebSocket Security (mcpgateway/main.py)

  • Fixed existing authentication gap in WebSocket endpoint
  • Added support for both JWT tokens and proxy headers
  • Tokens can be passed via query params or headers
  • Properly closes connections with code 1008 when auth fails

4. Test Updates

  • Updated tests/conftest.py - Added mcp_client_auth_enabled=False to test settings
  • Fixed tests/unit/mcpgateway/utils/test_verify_credentials.py - Added mock Request objects for new parameter
  • Fixed tests/unit/mcpgateway/test_main.py - Updated WebSocket test mocking strategy
  • Fixed tests/unit/mcpgateway/test_main_extended.py - Updated WebSocket error scenario test
  • Added tests/unit/mcpgateway/utils/test_proxy_auth.py - Comprehensive proxy auth test suite
  • All existing tests remain passing (1563 tests pass)

Security Considerations

The implementation includes multiple security safeguards:

  1. Explicit Opt-in: Requires setting both MCP_CLIENT_AUTH_ENABLED=false AND TRUST_PROXY_AUTH=true
  2. Warning System: Logs security warning if misconfigured
  3. Backward Compatible: Default behavior unchanged (JWT auth enabled)
  4. Audit Trail: Proxy-authenticated requests include source: "proxy" in user context

Testing

Unit Tests Added (tests/unit/mcpgateway/utils/test_proxy_auth.py)

Comprehensive test coverage including:

  • Standard JWT auth still works when enabled
  • Proxy auth with/without headers
  • Custom proxy header names
  • Security warning scenarios
  • WebSocket authentication
  • Mixed authentication scenarios

Manual Testing Scenarios

# Scenario 1: Proxy authentication enabled
MCP_CLIENT_AUTH_ENABLED=false
TRUST_PROXY_AUTH=true
PROXY_USER_HEADER=X-Authenticated-User

# Test with proxy header
curl -H "X-Authenticated-User: [email protected]" http://localhost:4444/tools
# ✅ Returns tools for authenticated user

# Test without proxy header  
curl http://localhost:4444/tools
# ✅ Returns "anonymous" access

# Scenario 2: Security misconfiguration (warning)
MCP_CLIENT_AUTH_ENABLED=false
TRUST_PROXY_AUTH=false
# ⚠️ Logs warning about security risk

# Scenario 3: Backward compatibility (default)
# No configuration changes
# ✅ Existing JWT authentication works as before

Documentation

Created Documentation Files

  1. docs/docs/deployment/proxy-auth.md - Deployment guide with examples for:

    • OAuth2 Proxy setup
    • Authelia configuration
    • Cloudflare Access integration
    • AWS ALB with Cognito
    • Kubernetes with Istio
    • Complete Docker Compose examples
  2. docs/docs/manage/proxy.md - Comprehensive management guide with:

    • Architecture diagrams (Mermaid)
    • Security best practices
    • Troubleshooting guide
    • Migration strategies
    • Performance considerations
    • Monitoring setup

Updated Files

  • .env.example - Added new configuration options with descriptions
  • Test configurations - Added proxy auth settings

Quality Assurance

All quality checks pass:

  • make doctest - All doctests pass (452 passed)
  • make test - All unit tests pass (1563 passed, 10 skipped)
  • make htmlcov - Coverage report generation works
  • make smoketest - Smoke tests pass
  • make lint-web - Web linting passes (0 vulnerabilities)
  • make flake8 - No Python linting issues
  • make bandit - No security issues identified
  • make interrogate - Full docstring coverage (100%)
  • make pylint - Code rated 10.00/10
  • make verify - Package verification passes (Mascarpone rating)

Migration Path

For existing deployments:

  1. No changes needed - Default behavior unchanged
  2. To enable proxy auth:
    # Add to .env
    MCP_CLIENT_AUTH_ENABLED=false
    TRUST_PROXY_AUTH=true
    PROXY_USER_HEADER=X-Authenticated-User  # Or your proxy's header
  3. Gradual migration - Can run both auth methods during transition

Use Cases Enabled

This implementation enables common enterprise patterns:

  1. OAuth2 Proxy deployments (Google, GitHub, OIDC)
  2. Service Mesh authentication (Istio, Linkerd)
  3. API Gateways (Kong, Traefik, AWS API Gateway)
  4. Cloud IAM (AWS ALB/Cognito, Google IAP, Azure AD)
  5. Zero Trust Networks (Cloudflare Access, Tailscale)

Benefits

  1. Simplified Operations - No JWT token management when using proxy auth
  2. Enterprise Ready - Aligns with standard enterprise auth patterns
  3. Flexible - Supports multiple authentication strategies
  4. Secure - Multiple safety checks and explicit configuration
  5. Compatible - Maintains full backward compatibility

Related Links

Files Changed Summary

Core Implementation

  • mcpgateway/config.py - Added proxy auth configuration
  • mcpgateway/utils/verify_credentials.py - Modified authentication logic
  • mcpgateway/main.py - Fixed WebSocket auth gap, added proxy support

Tests

  • tests/conftest.py - Updated test configuration
  • tests/unit/mcpgateway/utils/test_verify_credentials.py - Fixed for new params
  • tests/unit/mcpgateway/test_main.py - Fixed WebSocket tests
  • tests/unit/mcpgateway/test_main_extended.py - Fixed error scenario tests
  • tests/unit/mcpgateway/utils/test_proxy_auth.py - New comprehensive test suite

Documentation

  • docs/docs/deployment/proxy-auth.md - Complete deployment guide
  • docs/docs/manage/proxy.md - Management and architecture guide
  • .env.example - Updated with new variables

Checklist

  • Code implementation complete
  • Unit tests added and passing (1563 tests)
  • Documentation created (2 comprehensive guides)
  • Security considerations addressed (safety checks, warnings)
  • Backward compatibility maintained (defaults unchanged)
  • All quality checks passing (10/10 pylint, 100% interrogate)
  • Migration guide provided
  • Examples for common deployments included (OAuth2, Istio, Kong, etc.)

@CalebBartleMAA
Copy link

Hello,

I would be happy to help test this on my end as well, but from an enterprise deployment perspective, this allows us to treat the MCP gateway was a MCP routing engine, providing tool grouping and MCP server management, while allowing our reverse proxy that has IAM external governance to maintain API level access and handle Authorization (Azure API Management).

@MohanLaksh
Copy link
Collaborator

MohanLaksh commented Aug 11, 2025

PR Test summary

make serve - pass
make test - pass (83%, === 1563 passed, 10 skipped, 57 warnings in 75.50s (0:01:15) ===)
make autoflake isort black flake8 - pass
make pylint - pass (Your code has been rated at 10.00/10 )
make smoketest - ✅ Smoketest passed!
make doctest - pass (55%, 444 passed, 8 skipped, 1 warning in 13.04s)

Testing:

  1. ✅ Existing JWT authentication works

  2. ✅ Proxy authentication enabled - - DID NOT OBSERVE "anonymous" IN THE LOGS
    export MCP_CLIENT_AUTH_ENABLED=false
    export TRUST_PROXY_AUTH=true
    export PROXY_USER_HEADER=X-Authenticated-User

    curl -H "X-Authenticated-User: [email protected]" http://localhost:4444/tools
    (Lists all the tools)
    curl http://localhost:4444/tools
    (Lists all the tools) -

    DID NOT OBSERVE "anonymous" IN THE LOGS

  3. ✅ Security misconfiguration (warning) -

image
export MCP_CLIENT_AUTH_ENABLED=false
export TRUST_PROXY_AUTH=false
curl -H "X-Authenticated-User: [email protected]" http://localhost:4444/tools
(Lists all the tools)
curl http://localhost:4444/tools
(Lists all the tools)

⚠️ Log warnings about security risk during server start-up

06:24:02 - mcpgateway.config - WARNING - MCP client authentication is disabled but trust_proxy_auth is not set. This is a security risk! Set TRUST_PROXY_AUTH=true only if MCP Gateway is behind a trusted authentication proxy.

@crivetimihai
Copy link
Member Author

Correct, you won't see 'anonymous' and the warning is correct.

@crivetimihai crivetimihai merged commit 36898ef into main Aug 11, 2025
37 checks passed
@crivetimihai crivetimihai deleted the 705-configurable-mcp-auth branch August 11, 2025 09:39
@shams858
Copy link
Contributor

With the following configuration, MCP CLIENT requests to the virtual MCP server endpoint /servers//mcp fails with 401 even though X-Authenticated-User header is set correctly.

MCP_CLIENT_AUTH_ENABLED=false TRUST_PROXY_AUTH=true PROXY_USER_HEADER=X-Authenticated-User

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request]: Option to completely remove Bearer token auth to MCP gateway
4 participants