Skip to content

[BUG][AUTH]: Permission system inconsistencies - Undefined permissions in use #1672

@crivetimihai

Description

@crivetimihai

Summary

Multiple API endpoints use permissions in @require_permission decorators that are not defined in the Permissions class (mcpgateway/db.py). Since the RoleService validates permissions against this class when creating roles (rejecting unknown permissions), these endpoints are effectively admin-only - accessible only to users with the * (wildcard) permission.

Some of these are intentional admin-only endpoints, but others appear to be bugs that prevent normal users from accessing functionality they should have access to.

Related: This issue was discovered while reviewing #1651 which fixed teams.writeteams.manage_members.

Root Cause

The permission validation in role_service.py:201-207 rejects unknown permissions:

valid_permissions = Permissions.get_all_permissions()
valid_permissions.append(Permissions.ALL_PERMISSIONS)  # Allow wildcard
invalid_perms = [p for p in permissions if p not in valid_permissions]
if invalid_perms:
    raise ValueError(f"Invalid permissions: {invalid_perms}")

This means permissions used in @require_permission but not in the Permissions class can never be granted to roles, making those endpoints admin-only by default.


Issues Found

Category 1: Missing Resource Permissions (Likely Bugs)

These permissions follow the standard resource.action pattern but are missing from the Permissions class.

1.1 A2A Agent Permissions

Permission Location Endpoint
a2a.read main.py:2208,2259 GET /a2a/, GET /a2a/{agent_id}
a2a.create main.py:2286 POST /a2a/
a2a.update main.py:2360,2419 PUT /a2a/{agent_id}, POST /a2a/{agent_id}/toggle
a2a.delete main.py:2456 DELETE /a2a/{agent_id}
a2a.invoke main.py:2491 POST /a2a/{agent_name}/invoke

1.2 Gateway Permissions

Permission Location Endpoint
gateways.read main.py:3680,3801 GET /gateways/, GET /gateways/{gateway_id}
gateways.create main.py:3728 POST /gateways/
gateways.update main.py:3636,3819 POST /gateways/{gateway_id}/toggle, PUT /gateways/{gateway_id}
gateways.delete main.py:3879 DELETE /gateways/{gateway_id}

1.3 Server Use Permission

Permission Location Endpoint
servers.use main.py:2010,2049 GET /servers/{server_id}/sse, POST /servers/{server_id}/message

Note: servers.read/create/update/delete/manage exist, but servers.use is missing.

1.4 Tools Invoke Permission

Permission Location Endpoint
tools.invoke main.py:4453,4491 GET /utility/sse, POST /utility/message

Note: tools.execute exists but tools.invoke does not. These may be intended to use tools.execute.

1.5 Tags Read Permission

Permission Location Endpoint
tags.read main.py:4742,4782 GET /tags/, GET /tags/{tag_name}/entities

Category 2: Admin Permissions (Needs Definition)

Permission Location Endpoints
admin.export main.py:4827,4909 Export configuration
admin.import main.py:4963,5030,5055,5073 Import configuration
admin.metrics main.py:4558,4592 Metrics endpoints
admin (bare) admin.py:12433-12649 5 admin UI section endpoints

Category 3: Colon-Notation Permissions (Inconsistent Pattern)

These use : instead of . as separator, inconsistent with the rest of the codebase.

Log Search (routers/log_search.py)

  • logs:read (lines 296, 404)
  • security:read (line 517)
  • audit:read (line 593)
  • metrics:read (line 674)

SSO Providers (routers/sso.py)

  • admin.sso_providers:create (line 242)
  • admin.sso_providers:read (lines 281, 322)
  • admin.sso_providers:update (line 368)
  • admin.sso_providers:delete (line 411)

Recommended Fix

1. Add Missing Permissions to mcpgateway/db.py

class Permissions:
    # ... existing permissions ...

    # A2A permissions
    A2A_CREATE = "a2a.create"
    A2A_READ = "a2a.read"
    A2A_UPDATE = "a2a.update"
    A2A_DELETE = "a2a.delete"
    A2A_INVOKE = "a2a.invoke"

    # Gateway permissions
    GATEWAYS_CREATE = "gateways.create"
    GATEWAYS_READ = "gateways.read"
    GATEWAYS_UPDATE = "gateways.update"
    GATEWAYS_DELETE = "gateways.delete"

    # Additional permissions
    SERVERS_USE = "servers.use"
    TAGS_READ = "tags.read"
    ADMIN_EXPORT = "admin.export"
    ADMIN_IMPORT = "admin.import"
    ADMIN_METRICS = "admin.metrics"

    # Observability permissions
    LOGS_READ = "logs.read"
    SECURITY_READ = "security.read"
    AUDIT_READ = "audit.read"

    # SSO permissions
    ADMIN_SSO_PROVIDERS_CREATE = "admin.sso_providers.create"
    ADMIN_SSO_PROVIDERS_READ = "admin.sso_providers.read"
    ADMIN_SSO_PROVIDERS_UPDATE = "admin.sso_providers.update"
    ADMIN_SSO_PROVIDERS_DELETE = "admin.sso_providers.delete"

2. Standardize Colon-Notation to Dot-Notation

Update routers/log_search.py and routers/sso.py to use . instead of :.

3. Update Bootstrap Roles

Consider adding new permissions to default roles in bootstrap_db.py.


Testing Checklist

  • Verify all new permissions are added to Permissions class
  • Verify colon-notation permissions are updated to dot-notation
  • Verify endpoints still work after permission changes
  • Verify role creation rejects truly invalid permissions
  • Verify non-admin users can access endpoints with proper permissions

Related Issues

Metadata

Metadata

Assignees

Labels

SHOULDP2: Important but not vital; high-value items that are not crucial for the immediate releasebugSomething isn't working

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions