Skip to content

[SECURITY]: MCP authentication controls and team membership validation #2125

@crivetimihai

Description

@crivetimihai

Summary

Implement configurable authentication requirements and consistent authorization controls across all MCP protocol endpoints and entity types, bringing them to full parity with REST API security features.

Motivation

MCP endpoints serve as the primary interface for AI agents and MCP clients to interact with tools, resources, prompts, and A2A agents. As deployments scale to multi-tenant environments, operators need:

  1. Configurable authentication - Choose between open public access or strict authentication requirements
  2. Consistent authorization - Same visibility and team-scoping rules across all entity types
  3. Real-time membership validation - Users removed from teams should lose access immediately, not at token expiry

Implementation Status

Component Status
MCP_REQUIRE_AUTH config ✅ Complete
MCP team membership validation ✅ Complete
Template resource read access ✅ Complete
A2A listing access control ✅ Complete
A2A get/invoke access control ✅ Complete
Resource templates listing ✅ Complete
Visibility parameter precedence ✅ Complete
Nginx cache isolation ✅ Complete

Features

1. Configurable MCP Authentication (MCP_REQUIRE_AUTH)

Setting Default Behavior
MCP_REQUIRE_AUTH=false Unauthenticated requests allowed with public-only access
MCP_REQUIRE_AUTH=true All requests must include valid Bearer token

2. Team Membership Validation

  • Cache-first lookup (60s TTL) for performance
  • Database validation on cache miss
  • Immediate access revocation when users are removed from teams
  • 403 Forbidden response for invalid team membership

3. Visibility-Based Access Control

Access control rules based on token_teams JWT claim:

  • token_teams=None: Admin unrestricted access (sees all entities)
  • token_teams=[]: Public-only access (no owner access to private entities)
  • token_teams=[...]: Team-scoped access with owner access to private entities

Security Fixes

  1. A2A Listing Unscoped - Added _apply_visibility_filter() to enforce team/visibility scoping
  2. A2A Direct Access Bypass - Added _check_agent_access() for get/invoke operations
  3. Resource Templates Unfiltered - Added visibility filtering to list_resource_templates()
  4. Visibility Parameter Precedence - Fixed schema default overriding endpoint parameter
  5. Nginx Cache Data Leakage - Added $http_authorization to cache key

Configuration

# Require authentication for /mcp endpoints (default: false)
MCP_REQUIRE_AUTH=false

# Enable JWT authentication for MCP (default: true)
MCP_CLIENT_AUTH_ENABLED=true

Files Changed

  • mcpgateway/config.py - Added mcp_require_auth configuration
  • mcpgateway/main.py - Updated A2A endpoints with access context
  • mcpgateway/services/a2a_service.py - Added visibility filtering and access checks
  • mcpgateway/services/resource_service.py - Added visibility filtering
  • mcpgateway/transports/streamablehttp_transport.py - Team membership validation
  • infra/nginx/nginx.conf - Per-user cache key isolation

Migration

No migration required. Default behavior (MCP_REQUIRE_AUTH=false) maintains backward compatibility.

For multi-tenant deployments, enable strict authentication:

MCP_REQUIRE_AUTH=true
MCP_CLIENT_AUTH_ENABLED=true

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestrbacRole-based Access ControlsecurityImproves security

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions