Skip to content
Back to skills

762 Rbac Fcd7e762

ASecurity

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. ---

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added October 11, 2026
devopspythonbashdockerkubernetestestingapidatabaseci/cdsecuritydocumentation

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 762-rbac_fcd7e762 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 762 Rbac Fcd7e762?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 762 Rbac Fcd7e762
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-762-rbac-fcd7e762/badge)](https://www.skillsdirectory.com/skills/tools-only-762-rbac-fcd7e762)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# 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

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.