Back to skills
SKILL.md
762 Rbac Fcd7e762
ASecurityRole-based access control (RBAC) defines which actions users or teams can perform in MCP Gateway. This document covers the security model, token scoping semantics, and best practices for access control. ---
- 9 stars
- 0 votes
- 0 copies
- 2 views
- Added October 11, 2026
Works with
Security analysis
100/100npx -y skills add tools-only/X-Skills --skill 762-rbac_fcd7e762 --agent claude-codeAre you the author of 762 Rbac Fcd7e762?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-762-rbac-fcd7e762)# RBAC Configuration
Role-based access control (RBAC) defines which actions users or teams can perform in MCP Gateway. This document covers the security model, token scoping semantics, and best practices for access control.
---
## Overview
MCP Gateway implements a multi-layered access control system:
1. **Authentication**: Verify user identity via JWT, SSO, or API tokens
2. **Team Membership**: Group users for collective access policies
3. **Token Scoping**: Restrict token capabilities to specific resources
4. **Visibility Filtering**: Control which resources users can discover
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Access Control Layers │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Request → Authentication → Team Resolution → Token Scoping → Visibility │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ JWT │ │ User │ │ Token │ │ Resource │ │ Filtered │ │
│ │ Token │──▶│ Identity │──▶│ Teams │──▶│ Access │──▶│ Results │ │
│ │ │ │ │ │ │ │ │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## Core Concepts
### Subjects
Users authenticated via:
- JWT tokens (session or API)
- SSO providers (OAuth 2.0/OIDC)
- Basic authentication (development only)
### Teams
Logical groups that:
- Organize users for access boundaries
- Own resources (tools, prompts, resources)
- Map from external identity providers (SSO groups)
### Roles
Current role types:
- **Admin**: Full management access, can bypass team restrictions
- **Maintainer**: Manage servers, tools, prompts, configurations
- **Viewer**: Read-only access and metrics
### Resources
Protected entities:
- Servers (MCP gateways and virtual servers)
- Tools, Prompts, Resources (MCP primitives)
- System configuration and audit logs
---
## Token Scoping Model
Token scoping controls what resources a token can access based on the `teams` claim in the JWT payload. This provides fine-grained access control for automation tokens, service accounts, and restricted user sessions.
### Teams Claim Semantics
The `teams` claim in JWT tokens determines resource visibility:
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Token Teams Claim Handling │
├─────────────────────────────────────────────────────────────────────────────┤
│ JWT Claim State │ Admin User │ Non-Admin User │
├───────────────────────────┼───────────────────────┼─────────────────────────┤
│ No "teams" key │ UNRESTRICTED │ PUBLIC-ONLY (secure) │
│ teams: null │ UNRESTRICTED │ PUBLIC-ONLY (secure) │
│ teams: [] │ PUBLIC-ONLY │ PUBLIC-ONLY │
│ teams: ["team-id"] │ Team + Public │ Team + Public │
│ teams: ["t1", "t2"] │ Both Teams + Public │ Both Teams + Public │
└───────────────────────────┴───────────────────────┴─────────────────────────┘
```
### Security Design Principles
1. **Principle of Least Privilege**
- Non-admin tokens without explicit team scope default to public-only access
- This prevents accidental exposure of team resources
2. **Scoped Automation Tokens**
- Admin tokens with `teams: []` are intentionally restricted to public resources
- Use case: CI/CD pipelines, monitoring systems, public API clients
3. **Backward Compatible Admin Access**
- Admin session tokens (from UI login) omit the teams claim entirely
- This grants unrestricted access for administrative operations
### Tool Name Separator
The gateway uses a separator to combine the gateway name and tool name (e.g., `gateway-tool`).
- **Default**: `-` (dash)
- **Configurable**: Yes, via `GATEWAY_TOOL_NAME_SEPARATOR` env var
- **Supported values**: `-`, `--`, `_`, `.`
```bash
# Example: Use double underscore (legacy behavior)
GATEWAY_TOOL_NAME_SEPARATOR=__
```
```
┌──────────────────┐
│ JWT Token │
│ Received │
└────────┬─────────┘
│
▼
┌───────────────────────┐
│ Extract "teams" │
│ claim from JWT │
└───────────┬───────────┘
│
┌───────────────┴───────────────┐
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ "teams" key exists │ │ "teams" key missing │
│ with non-null value │ │ OR teams: null │
└──────────┬──────────┘ └──────────┬──────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ Use explicit scope │ │ Check is_admin flag │
│ teams = [...] or [] │ └──────────┬──────────┘
└──────────┬──────────┘ │
│ ┌───────────┴───────────┐
│ │ │
│ ▼ ▼
│ ┌──────────────────┐ ┌──────────────────┐
│ │ Admin: teams = │ │ Non-Admin: │
│ │ None (bypass) │ │ teams = [] │
│ │ UNRESTRICTED │ │ PUBLIC-ONLY │
│ └────────┬─────────┘ └────────┬─────────┘
│ │ │
└───────────────┴──────────────────────┘
│
▼
┌───────────────────────┐
│ Apply visibility │
│ filter to query │
└───────────────────────┘
```
### Visibility Levels
Resources in MCP Gateway have three visibility levels:
| Visibility | Description | Who Can See |
|------------|-------------|-------------|
| `public` | Accessible to all authenticated users | Everyone with valid token |
| `team` | Accessible to team members only | Team members + admins (unrestricted) |
| `private` | Accessible to owner only | Resource owner + admins (unrestricted) |
### Enforcement Points
Token scoping is enforced consistently across all access paths:
| Layer | Location | Description |
|-------|----------|-------------|
| Middleware | `token_scoping.py` | Request-level access control |
| REST API | `main.py` | `/tools`, `/resources`, `/prompts` endpoints |
| RPC Handler | `main.py` | `tools/list`, `resources/list`, `prompts/list` |
| MCP Transport | `streamablehttp_transport.py` | Streamable HTTP protocol filtering |
| Service Layer | `*_service.py` | Database query filtering |
---
## Token Types and Use Cases
### Session Tokens (UI Login)
Generated when users log in via the Admin UI:
```json
{
"sub": "user@example.com",
"is_admin": true,
"iss": "mcpgateway",
"aud": "mcpgateway-api",
"exp": 1234567890
// Note: No "teams" key for admin users = unrestricted access
}
```
**Behavior**: Admin session tokens omit the `teams` claim, granting unrestricted access to all resources.
### API Tokens (Programmatic Access)
Generated via the Admin UI or API for automation:
```json
{
"sub": "service-account@example.com",
"is_admin": false,
"teams": ["team-uuid-1", "team-uuid-2"],
"iss": "mcpgateway",
"aud": "mcpgateway-api",
"exp": 1234567890
}
```
**Behavior**: Access restricted to public resources plus resources owned by specified teams.
### Scoped Automation Tokens
For CI/CD, monitoring, or public API access:
```json
{
"sub": "ci-pipeline@example.com",
"is_admin": true,
"teams": [], // Explicitly empty = public-only
"iss": "mcpgateway",
"aud": "mcpgateway-api",
"exp": 1234567890
}
```
**Behavior**: Even admin tokens with `teams: []` are restricted to public resources only. This enables creating limited-scope tokens for automation that shouldn't access team-internal resources.
---
## Generating Scoped Tokens
### Using the CLI Tool
```bash
# Unrestricted admin token (no teams key)
python3 -m mcpgateway.utils.create_jwt_token \
--username admin@example.com \
--exp 60 \
--secret $JWT_SECRET_KEY
# Team-scoped token
python3 -m mcpgateway.utils.create_jwt_token \
--username user@example.com \
--exp 60 \
--secret $JWT_SECRET_KEY \
--teams '["team-uuid-1"]'
# Public-only scoped token (for automation)
python3 -m mcpgateway.utils.create_jwt_token \
--username ci@example.com \
--exp 60 \
--secret $JWT_SECRET_KEY \
--teams '[]'
```
### Using the Admin UI
1. Navigate to **Admin UI → Tokens**
2. Click **Create Token**
3. Select team scope:
- **No team selected**: Public resources only (secure default)
- **Specific team(s)**: Team + public resources
4. Configure additional restrictions (IP, permissions, expiry)
!!! warning "Token Scope Warning"
Tokens created without selecting a team will have access to **public resources only**.
This is the secure default to prevent accidental exposure of team resources.
---
## Best Practices
### Token Lifecycle
1. **Use short expiration times** for interactive sessions (hours)
2. **Use longer expiration** for service accounts with IP restrictions
3. **Rotate tokens regularly** (recommended: 90 days for long-lived tokens)
4. **Revoke tokens immediately** when access should be removed
### Team Organization
1. **Create purpose-specific teams**:
- `platform-admins` - Full administrative access
- `developers` - Development and testing resources
- `ci-automation` - CI/CD pipeline access
- `monitoring` - Read-only observability access
2. **Map SSO groups to teams** for automatic membership management
3. **Use personal teams** for individual resource ownership
### Scoping Strategy
| Use Case | Recommended Token Scope |
|----------|------------------------|
| Admin UI access | Session token (no teams key) |
| CI/CD pipeline | `teams: []` (public-only) |
| Service integration | Specific team(s) |
| Developer access | Personal team + project teams |
| Monitoring/alerting | `teams: []` with read permissions |
---
## Troubleshooting
### Token Not Seeing Expected Resources
1. **Check token claims**: Decode the JWT to verify `teams` claim
```bash
# Decode JWT payload (middle section)
echo "$TOKEN" | cut -d. -f2 | base64 -d | jq .
```
2. **Verify resource visibility**: Check the resource's `visibility` and `team_id`
```bash
curl -H "Authorization: Bearer $ADMIN_TOKEN" /tools/{id} | jq '{visibility, teamId}'
```
3. **Check user admin status**: Non-admin users without teams get public-only access
### Admin Token Being Restricted
If an admin token is unexpectedly restricted:
1. **Check for explicit `teams` claim**: `teams: []` restricts even admins
2. **Verify `is_admin` flag**: Must be `true` in JWT or database user
3. **Check middleware logs**: Look for "token_teams" in debug output
### Inconsistent Results Between Endpoints
If REST and RPC endpoints return different results:
1. **Check for caching**: REST list endpoints may have cached data
2. **Wait for cache TTL**: Default is 60 seconds for registry cache
3. **Use direct GET**: `/tools/{id}` bypasses list cache
---
## Bootstrap Custom Roles
MCP Gateway allows you to define custom roles that are automatically created during database bootstrap. This is useful for organizations that need to pre-configure roles before deployment.
### Configuration
Enable custom role bootstrapping with these environment variables:
| Variable | Default | Description |
|----------|---------|-------------|
| `MCPGATEWAY_BOOTSTRAP_ROLES_IN_DB_ENABLED` | `false` | Enable loading additional roles from file |
| `MCPGATEWAY_BOOTSTRAP_ROLES_IN_DB_FILE` | `additional_roles_in_db.json` | Path to the JSON file containing role definitions |
### Role Definition Format
Create a JSON file containing an array of role definitions:
```json
[
{
"name": "data_analyst",
"description": "Read-only access for data analysis",
"scope": "team",
"permissions": ["tools.read", "resources.read", "prompts.read"],
"is_system_role": true
},
{
"name": "auditor",
"description": "Compliance audit access",
"scope": "global",
"permissions": ["tools.read", "resources.read", "prompts.read", "servers.read", "gateways.read"],
"is_system_role": true
}
]
```
**Required fields:**
- `name` - Unique role name
- `scope` - Either `team` (team-level access) or `global` (system-wide access)
- `permissions` - Array of permission strings (e.g., `tools.read`, `resources.create`)
**Optional fields:**
- `description` - Human-readable description
- `is_system_role` - Set to `true` to prevent users from modifying/deleting the role
### Available Permissions
| Resource | Permissions |
|----------|-------------|
| Tools | `tools.create`, `tools.read`, `tools.update`, `tools.delete`, `tools.execute` |
| Resources | `resources.create`, `resources.read`, `resources.update`, `resources.delete` |
| Prompts | `prompts.create`, `prompts.read`, `prompts.update`, `prompts.delete` |
| Servers | `servers.create`, `servers.read`, `servers.update`, `servers.delete` |
| Gateways | `gateways.create`, `gateways.read`, `gateways.update`, `gateways.delete` |
| Teams | `teams.create`, `teams.read`, `teams.update`, `teams.delete`, `teams.join` |
### Docker Compose Example
```yaml
services:
gateway:
environment:
- MCPGATEWAY_BOOTSTRAP_ROLES_IN_DB_ENABLED=true
- MCPGATEWAY_BOOTSTRAP_ROLES_IN_DB_FILE=/app/custom_roles.json
volumes:
- ./custom_roles.json:/app/custom_roles.json:ro
```
### Kubernetes/Helm Example
```yaml
# values.yaml
mcpContextForge:
env:
MCPGATEWAY_BOOTSTRAP_ROLES_IN_DB_ENABLED: "true"
MCPGATEWAY_BOOTSTRAP_ROLES_IN_DB_FILE: "/config/custom_roles.json"
# Mount ConfigMap with role definitions
extraVolumes:
- name: custom-roles
configMap:
name: mcp-gateway-roles
extraVolumeMounts:
- name: custom-roles
mountPath: /config
```
### Error Handling
- **File not found**: Bootstrap continues with default roles only; warning logged
- **Invalid JSON**: Bootstrap continues with default roles only; error logged
- **Malformed entries**: Invalid role entries are skipped with warnings; valid entries are processed
!!! tip "Idempotent Bootstrap"
Bootstrap is idempotent - running it multiple times won't duplicate roles. Existing roles are detected and skipped.
---
## Related Documentation
- [Team Management](teams.md) - Setting up teams and SSO mapping
- [Security Features](securing.md) - Comprehensive security configuration
- [Configuration Reference](configuration.md) - Environment variables
- [API Usage](api-usage.md) - Token usage in API calls
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.