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] " ]
}
}
}
}
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
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" : [ "*" ]
}
}
}
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
}
}
}
}
}
}
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
}
}
}
}
}
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:
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
Principle of least privilege
Grant minimum required permissions:
Start with restrictive defaults
Add permissions as needed
Regular permission audits
Remove unused permissions
Use team-based permissions
Manage permissions at the team level:
Easier to maintain
Consistent across users
Scales better
Clear ownership
Implement approval workflows
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:
{
"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