Skip to main content

Overview

MCP Gateway’s access control system allows you to define granular permissions for teams and users. Control who can access which MCP servers, which tools they can use, and what operations they can perform.

Access Control Model

The gateway uses a hierarchical permission model:
Organization

Teams (Engineering, Data Science, etc.)

Users ([email protected], [email protected])

Servers (github, filesystem, database)

Tools (read_file, write_file, query_db)
Permissions can be defined at any level and are inherited downward.

Permission Types

Server-Level Permissions

Control access to entire MCP servers:
{
  "accessControl": {
    "servers": {
      "github": {
        "allowedTeams": ["engineering", "devops"],
        "deniedUsers": ["[email protected]"]
      },
      "database": {
        "allowedTeams": ["data-science"],
        "allowedUsers": ["[email protected]"]
      }
    }
  }
}

Tool-Level Permissions

Restrict specific tools within servers:
{
  "accessControl": {
    "tools": {
      "filesystem.write_file": {
        "allowedTeams": ["engineering"],
        "deniedInProduction": true
      },
      "github.delete_repository": {
        "allowedUsers": ["[email protected]"],
        "requiresApproval": true
      },
      "database.execute_query": {
        "allowedTeams": ["data-science"],
        "rateLimit": {
          "requests": 100,
          "window": "1h"
        }
      }
    }
  }
}

Operation-Level Permissions

Define permissions for read/write operations:
{
  "accessControl": {
    "operations": {
      "read": {
        "allowedTeams": ["*"]
      },
      "write": {
        "allowedTeams": ["engineering", "data-science"],
        "auditLog": true
      },
      "delete": {
        "allowedUsers": ["[email protected]"],
        "requiresMFA": true
      }
    }
  }
}

Configuring Access Control

1

Define teams and roles

Create team definitions in your gateway configuration:
{
  "teams": {
    "engineering": {
      "name": "Engineering",
      "members": [
        "[email protected]",
        "[email protected]"
      ],
      "defaultPermissions": ["mcp:read", "mcp:write"]
    },
    "data-science": {
      "name": "Data Science",
      "members": [
        "[email protected]"
      ],
      "defaultPermissions": ["mcp:read"]
    },
    "admins": {
      "name": "Administrators",
      "members": [
        "[email protected]"
      ],
      "defaultPermissions": ["*"]
    }
  }
}
2

Set server access rules

Define which teams can access which servers:
{
  "accessControl": {
    "servers": {
      "github": {
        "allowedTeams": ["engineering", "admins"],
        "description": "GitHub repository access"
      },
      "filesystem": {
        "allowedTeams": ["engineering"],
        "allowedPaths": ["/workspace", "/tmp"],
        "deniedPaths": ["/etc", "/root"]
      },
      "database": {
        "allowedTeams": ["data-science", "admins"],
        "readOnly": true,
        "exceptions": {
          "admins": {
            "readOnly": false
          }
        }
      }
    }
  }
}
3

Configure tool restrictions

Set fine-grained tool permissions:
{
  "accessControl": {
    "tools": {
      "github.create_pull_request": {
        "allowedTeams": ["engineering"],
        "rateLimit": {
          "requests": 50,
          "window": "1h"
        }
      },
      "filesystem.write_file": {
        "allowedTeams": ["engineering"],
        "validation": {
          "maxFileSize": "10MB",
          "allowedExtensions": [".js", ".ts", ".py", ".md"]
        }
      },
      "database.execute_query": {
        "allowedTeams": ["data-science"],
        "constraints": {
          "readOnly": true,
          "timeout": "30s",
          "maxRows": 10000
        }
      }
    }
  }
}
4

Apply and test permissions

Restart the gateway and verify permissions:
# Test as a specific user
curl -X POST http://localhost:8787/mcp/tools/call \
  -H "Authorization: Bearer user-token" \
  -H "Content-Type: application/json" \
  -d '{
    "server": "github",
    "tool": "list_repositories"
  }'
Use the gateway console to preview effective permissions for users and teams.

Role-Based Access Control (RBAC)

Define reusable roles with specific permissions:
{
  "roles": {
    "developer": {
      "permissions": [
        "mcp:read",
        "mcp:write",
        "github:*",
        "filesystem:read",
        "filesystem:write"
      ],
      "restrictions": {
        "filesystem": {
          "allowedPaths": ["/workspace"]
        }
      }
    },
    "analyst": {
      "permissions": [
        "mcp:read",
        "database:query",
        "filesystem:read"
      ],
      "restrictions": {
        "database": {
          "readOnly": true
        }
      }
    },
    "admin": {
      "permissions": ["*"],
      "restrictions": {}
    }
  },
  "users": {
    "[email protected]": {
      "roles": ["developer"],
      "team": "engineering"
    },
    "[email protected]": {
      "roles": ["analyst"],
      "team": "data-science"
    }
  }
}

Dynamic Access Control

Implement context-aware permissions based on request attributes:

Time-Based Access

Restrict access to specific time windows:
{
  "accessControl": {
    "timeRestrictions": {
      "production-database": {
        "allowedHours": "09:00-17:00",
        "allowedDays": ["monday", "tuesday", "wednesday", "thursday", "friday"],
        "timezone": "America/New_York"
      }
    }
  }
}

Resource-Based Access

Control access based on resource attributes:
{
  "accessControl": {
    "resourcePolicies": {
      "filesystem": {
        "rules": [
          {
            "condition": "path.startsWith('/workspace/team-${user.team}')",
            "allow": true
          },
          {
            "condition": "path.startsWith('/shared')",
            "allow": true,
            "operations": ["read"]
          }
        ],
        "default": "deny"
      }
    }
  }
}

IP-Based Access

Restrict access by network location:
{
  "accessControl": {
    "ipRestrictions": {
      "allowedRanges": [
        "10.0.0.0/8",
        "192.168.1.0/24"
      ],
      "deniedRanges": [],
      "exceptions": {
        "admins": {
          "allowAnyIP": true
        }
      }
    }
  }
}

Rate Limiting

Protect servers from overuse with rate limiting:
{
  "accessControl": {
    "rateLimits": {
      "perUser": {
        "requests": 1000,
        "window": "1h"
      },
      "perTeam": {
        "requests": 10000,
        "window": "1h"
      },
      "perServer": {
        "github": {
          "requests": 5000,
          "window": "1h",
          "burst": 100
        },
        "database": {
          "requests": 100,
          "window": "1m"
        }
      },
      "perTool": {
        "filesystem.write_file": {
          "requests": 100,
          "window": "1m"
        }
      }
    }
  }
}
Rate limits are enforced per user/team and tracked across all gateway instances using shared state.

Approval Workflows

Require approval for sensitive operations:
{
  "accessControl": {
    "approvalWorkflows": {
      "database.execute_update": {
        "requiresApproval": true,
        "approvers": ["[email protected]"],
        "autoApprove": {
          "conditions": [
            "user.team == 'admins'"
          ]
        },
        "timeout": "1h"
      },
      "github.delete_repository": {
        "requiresApproval": true,
        "approvers": ["[email protected]", "[email protected]"],
        "requiredApprovals": 2
      }
    }
  }
}

Audit Logging

All access control decisions are automatically logged:
{
  "timestamp": "2026-03-03T10:30:00Z",
  "type": "access_control",
  "decision": "allow",
  "user": "[email protected]",
  "team": "engineering",
  "server": "github",
  "tool": "create_pull_request",
  "reason": "User has required permissions",
  "context": {
    "ip": "192.168.1.100",
    "userAgent": "Claude-Desktop/1.0"
  }
}
Access audit logs via the gateway API:
curl http://localhost:8787/v1/audit/[email protected]&from=2026-03-01

Managing Access at Scale

Sync with Identity Provider

Automatically sync teams and users from your IdP:
{
  "accessControl": {
    "identityProvider": {
      "type": "okta",
      "syncInterval": "1h",
      "teamMapping": {
        "okta-group-id-123": "engineering",
        "okta-group-id-456": "data-science"
      },
      "roleMapping": {
        "Developer": "developer",
        "Analyst": "analyst",
        "Admin": "admin"
      }
    }
  }
}

Bulk Updates

Update permissions for multiple users/teams:
curl -X POST http://localhost:8787/v1/access-control/bulk \
  -H "Authorization: Bearer admin-token" \
  -d '{
    "teams": {
      "engineering": {
        "addServers": ["new-server"],
        "removeServers": ["deprecated-server"]
      }
    }
  }'

Emergency Access Revocation

Instantly revoke all access for a user or team:
curl -X POST http://localhost:8787/v1/access-control/revoke \
  -H "Authorization: Bearer admin-token" \
  -d '{
    "user": "[email protected]",
    "reason": "Contract ended",
    "revokeTokens": true
  }'
Emergency revocation is immediate and affects all active sessions. Use with caution.

Testing Permissions

Test permissions before applying:
# Test access for a specific user
curl http://localhost:8787/v1/access-control/test \
  -H "Authorization: Bearer admin-token" \
  -d '{
    "user": "[email protected]",
    "server": "github",
    "tool": "create_pull_request"
  }'

# Response
{
  "allowed": true,
  "reason": "User is member of engineering team which has github access",
  "effectivePermissions": [
    "mcp:read",
    "mcp:write",
    "github:*"
  ]
}

Best Practices

Grant minimum required permissions:
  • Start with restrictive defaults
  • Add permissions as needed
  • Regular permission audits
  • Remove unused permissions
Manage permissions at the team level:
  • Easier to maintain
  • Consistent across users
  • Scales better
  • Clear ownership
Require approval for sensitive operations:
  • Data modifications
  • Resource deletion
  • Production access
  • Cost-intensive operations
Set up monitoring for access patterns:
  • Failed access attempts
  • Unusual access patterns
  • Permission changes
  • Rate limit violations
Periodically review access:
  • Quarterly user reviews
  • Remove inactive users
  • Update team memberships
  • Validate permissions

Complete Example

Here’s a comprehensive access control configuration:
gateway-config.json
{
  "teams": {
    "engineering": {
      "name": "Engineering",
      "members": ["[email protected]", "[email protected]"],
      "defaultPermissions": ["mcp:read", "mcp:write"]
    },
    "data-science": {
      "name": "Data Science",
      "members": ["[email protected]"],
      "defaultPermissions": ["mcp:read"]
    }
  },
  "accessControl": {
    "servers": {
      "github": {
        "allowedTeams": ["engineering"]
      },
      "database": {
        "allowedTeams": ["data-science"],
        "readOnly": true
      }
    },
    "tools": {
      "github.delete_repository": {
        "allowedUsers": ["[email protected]"],
        "requiresApproval": true
      },
      "filesystem.write_file": {
        "allowedTeams": ["engineering"],
        "validation": {
          "maxFileSize": "10MB"
        }
      }
    },
    "rateLimits": {
      "perUser": {
        "requests": 1000,
        "window": "1h"
      }
    },
    "audit": {
      "enabled": true,
      "logAll": true,
      "retention": "90d"
    }
  }
}

Next Steps

Authentication

Learn about authentication methods

Monitoring

Set up access monitoring and alerts

Deployment

Deploy to production

API Reference

Explore the complete API

Build docs developers (and LLMs) love