Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

🔌 Epic: Per-Virtual-Server Plugin Selection with Multi-Level RBAC #1247

Open
Assignees
Labels
Milestone
@crivetimihai

Description

🔌 Epic: Per-Virtual-Server Plugin Selection with Multi-Level RBAC

Goal

Implement a hierarchical plugin RBAC system that allows plugins to be:

  1. Enabled (mandatory) by Platform Admins at the global level
  2. Filtered by Team Owners at the team level
  3. Customized by individual users at the personal level
  4. Associated with specific virtual servers for fine-grained control

This creates a flexible, secure plugin governance model where organizations can enforce baseline security policies while allowing teams and users to tailor their plugin configurations to specific workflows and virtual servers.

Why Now?

With ContextForge's growing plugin ecosystem, multi-tenant architecture, and virtual server capabilities, there is an increasing need for fine-grained plugin control:

  1. Security & Compliance: Platform admins need to enforce mandatory security plugins (e.g., PII filters, audit loggers) that cannot be disabled by users
  2. Team Autonomy: Different teams have different needs - engineering teams may need different plugins than security or operations teams
  3. User Flexibility: Individual users should be able to customize their experience with optional plugins while respecting organizational policies
  4. Virtual Server Isolation: Different virtual servers serve different purposes and should have different plugin configurations
  5. Plugin Conflicts: Some plugins may conflict with each other or with certain tools, requiring selective enablement
  6. Performance Optimization: Running only necessary plugins per virtual server reduces overhead
  7. Audit & Compliance: Need visibility into which plugins are enabled where, by whom, and why

By implementing this hierarchical RBAC system, we enable organizations to balance security, governance, and flexibility.


📖 User Stories

US-1: Platform Admin - Define Mandatory Global Plugins

As a Platform Administrator
I want to enable mandatory plugins at the global level that cannot be disabled by teams or users
So that I can enforce baseline security, compliance, and operational policies across the entire platform

Acceptance Criteria:

Given I am a platform administrator
When I configure plugins in plugins/config.yaml with:
 plugins:
 - name: "AuditLoggerPlugin"
 mandatory: true
 enabled_globally: true
 priority: 1
 
 - name: "PIIFilterPlugin"
 mandatory: true
 enabled_globally: true
 priority: 2
 
 - name: "RegexFilterPlugin"
 mandatory: false
 enabled_globally: false
 available_for_teams: true
Then the mandatory plugins should:
 - Be enabled on ALL virtual servers regardless of team/user settings
 - Be non-removable in Team Owner and User interfaces
 - Be marked as "Mandatory" in Admin UI
 - Always execute in priority order
 - Appear in all server plugin lists with [MANDATORY] badge
And optional plugins should:
 - Not be enabled by default
 - Be available for teams/users to enable if available_for_teams: true
 - Be controllable by Team Owners and Users

Technical Requirements:

  • Plugin manifest schema with mandatory, enabled_globally, available_for_teams fields
  • Global plugin registry tracking mandatory vs optional plugins
  • Validation preventing removal of mandatory plugins
  • Admin UI showing plugin governance status
  • API endpoint: GET /admin/plugins/global to list global plugin policies
US-2: Team Owner - Filter and Enable Team-Level Plugins

As a Team Owner
I want to enable additional plugins for my team from the available plugin catalog
So that my team can use plugins that support our specific workflows without affecting other teams

Acceptance Criteria:

Given I am the owner of team "engineering"
And the platform has these available optional plugins:
 - RegexFilterPlugin (available_for_teams: true)
 - DenyFilterPlugin (available_for_teams: true)
 - CustomMetricsPlugin (available_for_teams: false, requires_platform_admin: true)
When I navigate to Team Settings > Plugins
Then I should see:
 - Mandatory plugins: AuditLoggerPlugin, PIIFilterPlugin (greyed out, [MANDATORY] badge)
 - Available optional plugins: RegexFilterPlugin, DenyFilterPlugin (toggle switches)
 - Unavailable plugins: CustomMetricsPlugin (hidden or disabled with tooltip)
When I enable RegexFilterPlugin for my team
Then the plugin should:
 - Be added to team_plugins table with team_id="engineering", enabled=true
 - Be available for all users in my team
 - Be visible in my team's virtual servers as [TEAM DEFAULT]
 - NOT appear in other teams' plugin lists unless they also enable it
When I configure the plugin with team-specific settings:
 config:
 blocked_patterns: ["internal-regex-123", "proprietary-term"]
Then these settings should apply to all users in my team by default
But users should be able to override if allow_user_override: true

Technical Requirements:

  • Database table: team_plugins (team_id, plugin_name, enabled, config, created_by, created_at)
  • Team Owner role check in API middleware
  • API endpoints:
    • GET /teams/{team_id}/plugins - List team plugins
    • POST /teams/{team_id}/plugins - Enable plugin for team
    • PUT /teams/{team_id}/plugins/{plugin_name} - Update team plugin config
    • DELETE /teams/{team_id}/plugins/{plugin_name} - Disable plugin for team
  • UI page: /admin/teams/{team_id}/plugins
  • Plugin availability filtering based on available_for_teams flag
US-3: User - Customize Personal Plugin Preferences

As a User
I want to enable or disable optional plugins for my own virtual servers
So that I can optimize my workflow without affecting other users

Acceptance Criteria:

Given I am user "alice@example.com" in team "engineering"
And my team has enabled RegexFilterPlugin with team defaults
And I have permission to customize plugins (user_plugin_customization_allowed: true)
When I navigate to My Settings > Plugins
Then I should see:
 - Mandatory plugins: AuditLoggerPlugin, PIIFilterPlugin (greyed out, [MANDATORY])
 - Team defaults: RegexFilterPlugin (enabled by default, [TEAM DEFAULT])
 - Available optional plugins: ResourceFilterPlugin, DenyFilterPlugin (toggle switches)
When I customize RegexFilterPlugin with my own patterns:
 config:
 blocked_patterns: ["my-personal-pattern"]
 inherit_team_config: true # Merge with team settings
Then my virtual servers should use:
 - Mandatory plugins (always)
 - Team plugin with merged config (team patterns + my patterns)
 - My personal plugins
When I create a new virtual server
Then it should inherit:
 - All mandatory plugins
 - All team default plugins
 - My personal plugin preferences
But I should be able to override per server (see US-4)

Technical Requirements:

  • Database table: user_plugins (user_id, plugin_name, enabled, config, inherit_team_config, created_at)
  • API endpoints:
    • GET /users/me/plugins - List my plugin preferences
    • POST /users/me/plugins - Enable plugin for myself
    • PUT /users/me/plugins/{plugin_name} - Update my plugin config
    • DELETE /users/me/plugins/{plugin_name} - Disable plugin for myself
  • UI page: /admin/settings/plugins
  • Config merging logic: mandatory → team → user → server
US-4: User - Associate Plugins with Specific Virtual Servers

As a User
I want to enable different plugins for different virtual servers
So that each server can have its own plugin configuration optimized for its purpose

Acceptance Criteria:

Given I have created three virtual servers:
 - "production_tools" (for production operations)
 - "dev_tools" (for development)
 - "external_api" (for public-facing tools)
When I navigate to Server Settings > Plugins for "production_tools"
Then I should see the plugin inheritance chain:
 [MANDATORY] AuditLoggerPlugin (platform)
 [MANDATORY] PIIFilterPlugin (platform)
 [TEAM DEFAULT] RegexFilterPlugin (team: engineering)
 [USER DEFAULT] ResourceFilterPlugin (my preference)
 [SERVER SPECIFIC] (empty - I can add server-specific plugins here)
When I add "DenyFilterPlugin" as server-specific for "production_tools"
With config:
 blocked_tools: ["dangerous-delete-tool"]
Then this plugin should:
 - Only apply to "production_tools" server
 - NOT apply to my other servers
 - Execute after mandatory, team, and user plugins
 - Be marked as [SERVER SPECIFIC] in UI
When I disable ResourceFilterPlugin specifically for "dev_tools"
Then "dev_tools" should use: mandatory + team plugins only
And my other servers should still use ResourceFilterPlugin

Technical Requirements:

  • Database table: server_plugins (server_id, plugin_name, enabled, config, added_by, created_at)
  • Plugin resolution algorithm: merge(mandatory, team, user, server)
  • Handle conflicts: later overrides earlier (server > user > team > mandatory)
  • API endpoints:
    • GET /servers/{server_id}/plugins - List server plugins
    • POST /servers/{server_id}/plugins - Add server-specific plugin
    • PUT /servers/{server_id}/plugins/{plugin_name} - Update server plugin config
    • DELETE /servers/{server_id}/plugins/{plugin_name} - Remove server plugin
  • UI: Server details page with Plugins tab
US-5: Platform Admin - Audit Plugin Usage Across Platform

As a Platform Administrator
I want to see which plugins are enabled where, by whom, and when
So that I can ensure compliance, troubleshoot issues, and optimize plugin usage

Acceptance Criteria:

×ばつ servers grid showing enabled/disabled - Top plugins by adoption: RegexFilterPlugin (45 servers), PIIFilterPlugin (mandatory, 100 servers) - Unused available plugins: CustomMetricsPlugin (0 servers - consider removing?) - Plugin by team: engineering (5 plugins), security (8 plugins) - Recent changes: "alice@example.com enabled DenyFilterPlugin on server 'prod_tools' 2 hours ago" When I filter by plugin "PIIFilterPlugin" Then I should see: - Total servers using it: 100 (all servers - mandatory) - Team-level configs: engineering (custom patterns), security (strict mode) - User-level overrides: 3 users with custom configs - Server-specific overrides: 5 servers with unique settings When I export the report Then I should get CSV/JSON with: server_id, server_name, plugin_name, level (mandatory|team|user|server), enabled, config_summary, modified_by, modified_at">
Given I am a platform administrator
When I navigate to Admin > Plugins > Usage Report
Then I should see:
 - Plugin usage matrix: plugins ×ばつ servers grid showing enabled/disabled
 - Top plugins by adoption: RegexFilterPlugin (45 servers), PIIFilterPlugin (mandatory, 100 servers)
 - Unused available plugins: CustomMetricsPlugin (0 servers - consider removing?)
 - Plugin by team: engineering (5 plugins), security (8 plugins)
 - Recent changes: "alice@example.com enabled DenyFilterPlugin on server 'prod_tools' 2 hours ago"
When I filter by plugin "PIIFilterPlugin"
Then I should see:
 - Total servers using it: 100 (all servers - mandatory)
 - Team-level configs: engineering (custom patterns), security (strict mode)
 - User-level overrides: 3 users with custom configs
 - Server-specific overrides: 5 servers with unique settings
When I export the report
Then I should get CSV/JSON with:
 server_id, server_name, plugin_name, level (mandatory|team|user|server), enabled, config_summary, modified_by, modified_at

Technical Requirements:

  • Aggregate queries across plugin tables (global, team, user, server)
  • Plugin usage metrics and statistics
  • Change audit log: track plugin enablement/disablement events
  • API endpoint: GET /admin/plugins/usage-report
  • UI page: /admin/plugins/usage
  • Export functionality (CSV, JSON)
  • Visualizations: heatmap, bar charts, timeline
US-6: Platform Admin - Prevent Plugin Conflicts

As a Platform Administrator
I want to define plugin compatibility rules and conflicts
So that incompatible plugins cannot be enabled together, preventing errors

Acceptance Criteria:

Given I define plugin conflicts in plugins/config.yaml:
 plugins:
 - name: "PIIFilterPlugin"
 conflicts_with: ["DenyFilterPlugin"] # Both filter content differently
 
 - name: "CachingPlugin"
 requires: ["AuthenticationPlugin"] # Caching needs auth context
When a Team Owner tries to enable DenyFilterPlugin
And their team already has PIIFilterPlugin (mandatory)
Then the system should:
 - Block the enablement
 - Show error: "DenyFilterPlugin conflicts with PIIFilterPlugin (mandatory)"
 - Suggest alternatives or configuration changes
When a user tries to enable CachingPlugin
And AuthenticationPlugin is not enabled
Then the system should:
 - Block the enablement
 - Show error: "CachingPlugin requires AuthenticationPlugin to be enabled"
 - Offer to enable AuthenticationPlugin automatically (if allowed)
When plugins are validated during server creation
Then the system should check entire plugin chain for conflicts:
 mandatory → team → user → server
And reject server creation if conflicts detected

Technical Requirements:

  • Plugin manifest schema with conflicts_with and requires fields
  • Validation logic before enabling plugins at any level
  • Dependency resolution: auto-enable required plugins (with permission)
  • Conflict detection during plugin chain assembly
  • Error messages with actionable guidance
  • API validation in POST/PUT plugin endpoints
US-7: Developer - Test Plugin Configurations Before Deployment

As a Developer
I want to test plugin configurations in isolation before applying them to production servers
So that I can validate behavior without impacting live systems

Acceptance Criteria:

Given I am developing a new regex filter configuration
When I navigate to Plugin Testing > Test Playground
Then I should be able to:
 - Select a plugin: RegexFilterPlugin
 - Provide test configuration:
 blocked_patterns: ["test-pattern-123"]
 - Provide sample request payload:
 {"tool": "search", "query": "test-pattern-123 sensitive"}
 - Click "Test Plugin"
Then the system should:
 - Execute the plugin with test config and sample payload
 - Show plugin output: {"blocked": true, "reason": "Pattern matched: test-pattern-123"}
 - Show modified payload (if any)
 - Show execution time: 2.3ms
 - NOT apply to any real servers
When tests pass
Then I can save the config as:
 - Team default (if Team Owner)
 - User preference (if User)
 - Server-specific (for my servers)

Technical Requirements:

  • API endpoint: POST /admin/plugins/test (accepts plugin_name, config, sample_payload)
  • Isolated execution environment (no side effects)
  • Return detailed execution results
  • UI page: /admin/plugins/test
  • Support for all plugin types and hooks
  • Save successful configs to appropriate level
US-8: Platform Admin - Migrate Plugins Between Levels

As a Platform Administrator
I want to promote or demote plugins between global, team, user, and server levels
So that I can adjust governance as requirements change

Acceptance Criteria:

Given RegexFilterPlugin is currently team-optional
When I decide it should be mandatory for compliance
Then I can promote it to mandatory global level:
 - Navigate to Admin > Plugins > Global Policies
 - Select RegexFilterPlugin
 - Click "Make Mandatory"
 - Confirm impact: "This will enable RegexFilterPlugin on all 100 servers"
Then the system should:
 - Update global plugin config: mandatory=true, enabled_globally=true
 - Remove from team_plugins, user_plugins, server_plugins tables (now redundant)
 - Add to all existing servers' plugin chains
 - Send notification to all Team Owners: "RegexFilterPlugin is now mandatory"
 - Log the change in audit trail
Given DenyFilterPlugin is mandatory but no longer required
When I demote it to team-optional
Then the system should:
 - Update global plugin config: mandatory=false, available_for_teams=true
 - Keep plugin enabled on servers that are currently using it
 - Allow teams/users to disable it going forward
 - Notify teams of the policy change

Technical Requirements:

  • API endpoints:
    • POST /admin/plugins/{plugin_name}/promote-to-mandatory
    • POST /admin/plugins/{plugin_name}/demote-to-optional
  • Validation: check impact before migration
  • Database cleanup: remove redundant entries
  • Notification system: inform affected users/teams
  • Rollback capability in case of issues
  • Audit logging of policy changes

🏗 Architecture

Plugin Hierarchy Model

graph TB
 subgraph "Plugin Governance Hierarchy"
 PlatformAdmin[Platform Admin<br/>Global Mandatory Plugins]
 TeamOwner[Team Owner<br/>Team Default Plugins]
 User[User<br/>Personal Plugin Preferences]
 Server[Virtual Server<br/>Server-Specific Plugins]
 
 PlatformAdmin -->|Mandatory<br/>Cannot Disable| TeamOwner
 PlatformAdmin -->|Optional<br/>Available if allowed| TeamOwner
 TeamOwner -->|Team Defaults<br/>Inheritable| User
 User -->|User Defaults<br/>Inheritable| Server
 Server -->|Server Overrides<br/>Highest Priority| Server
 end
 
 subgraph "Plugin Resolution"
 Global[Global Plugins<br/>mandatory=true]
 Team[Team Plugins<br/>team_plugins table]
 UserP[User Plugins<br/>user_plugins table]
 ServerP[Server Plugins<br/>server_plugins table]
 
 Global -->|Merge| Team
 Team -->|Merge| UserP
 UserP -->|Merge| ServerP
 ServerP -->|Final Chain| Execute[Plugin Chain Execution]
 end
Loading

Plugin Resolution Algorithm

def resolve_plugins_for_server(server_id: UUID) -> list[PluginConfig]:
 """
 Resolve the final plugin chain for a virtual server.
 Priority: Mandatory (global) > Team > User > Server-specific
 """
 server = get_server(server_id)
 user = get_user(server.owner_id)
 team = get_team(user.team_id) if user.team_id else None
 
 plugins = {}
 
 # 1. Start with mandatory global plugins (cannot be disabled)
 global_plugins = get_global_plugins(mandatory=True)
 for plugin in global_plugins:
 plugins[plugin.name] = PluginConfig(
 name=plugin.name,
 enabled=True,
 level="mandatory",
 config=plugin.config,
 priority=plugin.priority,
 )
 
 # 2. Add team default plugins (if user is in a team)
 if team:
 team_plugins = get_team_plugins(team.id)
 for plugin in team_plugins:
 if plugin.name not in plugins: # Don't override mandatory
 plugins[plugin.name] = PluginConfig(
 name=plugin.name,
 enabled=plugin.enabled,
 level="team",
 config=plugin.config,
 priority=plugin.priority or 50,
 )
 else:
 # Merge config if plugin allows team overrides
 if plugins[plugin.name].allow_team_override:
 plugins[plugin.name].config = merge_configs(
 plugins[plugin.name].config,
 plugin.config
 )
 
 # 3. Add user plugin preferences
 user_plugins = get_user_plugins(user.id)
 for plugin in user_plugins:
 if plugin.name not in plugins: # New plugin
 plugins[plugin.name] = PluginConfig(
 name=plugin.name,
 enabled=plugin.enabled,
 level="user",
 config=plugin.config,
 priority=plugin.priority or 60,
 )
 elif plugins[plugin.name].allow_user_override:
 # User can override non-mandatory plugins
 if plugin.inherit_team_config:
 plugins[plugin.name].config = merge_configs(
 plugins[plugin.name].config,
 plugin.config
 )
 else:
 plugins[plugin.name].config = plugin.config
 plugins[plugin.name].enabled = plugin.enabled
 
 # 4. Add server-specific plugins (highest priority)
 server_plugins = get_server_plugins(server.id)
 for plugin in server_plugins:
 if plugin.name not in plugins: # New plugin
 plugins[plugin.name] = PluginConfig(
 name=plugin.name,
 enabled=plugin.enabled,
 level="server",
 config=plugin.config,
 priority=plugin.priority or 70,
 )
 elif plugins[plugin.name].allow_server_override:
 # Server can override non-mandatory plugins
 plugins[plugin.name].config = plugin.config
 plugins[plugin.name].enabled = plugin.enabled
 
 # 5. Filter enabled plugins and sort by priority
 enabled_plugins = [p for p in plugins.values() if p.enabled]
 enabled_plugins.sort(key=lambda p: p.priority)
 
 # 6. Validate for conflicts
 validate_plugin_conflicts(enabled_plugins)
 
 return enabled_plugins

Database Schema

-- Global plugin registry (loaded from plugins/config.yaml)
-- This is the source of truth for available plugins
CREATE TABLE global_plugin_registry (
 id UUID PRIMARY KEY,
 name VARCHAR(100) UNIQUE NOT NULL,
 kind VARCHAR(255) NOT NULL, -- Python import path
 version VARCHAR(20),
 description TEXT,
 mandatory BOOLEAN DEFAULT FALSE,
 enabled_globally BOOLEAN DEFAULT FALSE,
 available_for_teams BOOLEAN DEFAULT TRUE,
 available_for_users BOOLEAN DEFAULT TRUE,
 allow_team_override BOOLEAN DEFAULT TRUE,
 allow_user_override BOOLEAN DEFAULT TRUE,
 allow_server_override BOOLEAN DEFAULT TRUE,
 requires JSONB DEFAULT '[]', -- ['PluginA', 'PluginB']
 conflicts_with JSONB DEFAULT '[]', -- ['PluginC']
 default_config JSONB DEFAULT '{}',
 default_priority INTEGER DEFAULT 50,
 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Team-level plugin enablement
CREATE TABLE team_plugins (
 id UUID PRIMARY KEY,
 team_id UUID REFERENCES teams(id) ON DELETE CASCADE,
 plugin_name VARCHAR(100) REFERENCES global_plugin_registry(name),
 enabled BOOLEAN DEFAULT TRUE,
 config JSONB DEFAULT '{}',
 priority INTEGER,
 added_by UUID REFERENCES users(id),
 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 UNIQUE(team_id, plugin_name)
);
-- User-level plugin preferences
CREATE TABLE user_plugins (
 id UUID PRIMARY KEY,
 user_id UUID REFERENCES users(id) ON DELETE CASCADE,
 plugin_name VARCHAR(100) REFERENCES global_plugin_registry(name),
 enabled BOOLEAN DEFAULT TRUE,
 config JSONB DEFAULT '{}',
 inherit_team_config BOOLEAN DEFAULT TRUE,
 priority INTEGER,
 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 UNIQUE(user_id, plugin_name)
);
-- Server-specific plugin configuration
CREATE TABLE server_plugins (
 id UUID PRIMARY KEY,
 server_id UUID REFERENCES servers(id) ON DELETE CASCADE,
 plugin_name VARCHAR(100) REFERENCES global_plugin_registry(name),
 enabled BOOLEAN DEFAULT TRUE,
 config JSONB DEFAULT '{}',
 priority INTEGER,
 added_by UUID REFERENCES users(id),
 created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 UNIQUE(server_id, plugin_name)
);
-- Plugin change audit log
CREATE TABLE plugin_audit_log (
 id UUID PRIMARY KEY,
 timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 action VARCHAR(50), -- 'enabled', 'disabled', 'config_changed', 'promoted', 'demoted'
 level VARCHAR(20), -- 'global', 'team', 'user', 'server'
 plugin_name VARCHAR(100),
 entity_id UUID, -- team_id, user_id, or server_id
 entity_type VARCHAR(20), -- 'team', 'user', 'server'
 performed_by UUID REFERENCES users(id),
 old_config JSONB,
 new_config JSONB,
 reason TEXT,
 INDEX idx_plugin_name (plugin_name),
 INDEX idx_timestamp (timestamp),
 INDEX idx_entity (entity_type, entity_id)
);
-- Indexes for performance
CREATE INDEX idx_team_plugins_team_id ON team_plugins(team_id);
CREATE INDEX idx_user_plugins_user_id ON user_plugins(user_id);
CREATE INDEX idx_server_plugins_server_id ON server_plugins(server_id);
CREATE INDEX idx_plugin_audit_log_entity ON plugin_audit_log(entity_type, entity_id);

📋 Implementation Tasks

Phase 1: Database Schema & Models ✅

  • Alembic Migration

    • Create migration for new tables: global_plugin_registry, team_plugins, user_plugins, server_plugins, plugin_audit_log
    • Add indexes for performance
    • Add foreign key constraints with CASCADE
    • Create migration for existing plugins table (if needed)
  • SQLAlchemy ORM Models

    • GlobalPluginRegistry model with all fields
    • TeamPlugin model with team relationship
    • UserPlugin model with user relationship
    • ServerPlugin model with server relationship
    • PluginAuditLog model for change tracking
    • Relationships: Team ↔ TeamPlugins, User ↔ UserPlugins, Server ↔ ServerPlugins
  • Repository Layer

    • PluginRepository with CRUD operations for all tables
    • Methods: get_global_plugins(), get_team_plugins(team_id), get_user_plugins(user_id), get_server_plugins(server_id)
    • Methods: add_team_plugin(), update_plugin_config(), remove_plugin()
    • Method: log_plugin_change() for audit trail
    • Caching layer for frequently accessed plugins (Redis)

Phase 2: Plugin Resolution Engine ✅

  • Plugin Resolver Service

    • Create PluginResolverService class
    • Implement resolve_plugins_for_server(server_id) -> list[PluginConfig]
    • Merge logic: mandatory → team → user → server
    • Config merging: support inherit_team_config, deep merge of JSONB
    • Priority-based sorting
    • Cache resolved plugin chains (per server, invalidate on change)
  • Conflict Detection

    • Implement validate_plugin_conflicts(plugins) -> list[Conflict]
    • Check conflicts_with field from global_plugin_registry
    • Check requires field and ensure dependencies are present
    • Return user-friendly error messages
    • Suggest resolution steps (e.g., "Enable AuthenticationPlugin first")
  • Override Validation

    • Check allow_team_override, allow_user_override, allow_server_override flags
    • Prevent overriding mandatory plugins at any level
    • Enforce read-only nature of mandatory plugins in UI/API

Phase 3: Admin API Endpoints ✅

  • Global Plugin Management (Platform Admin only)

    • GET /admin/plugins/global - List global plugin registry
    • POST /admin/plugins/global - Add plugin to registry (or sync from YAML)
    • PUT /admin/plugins/global/{name} - Update global plugin config (e.g., make mandatory)
    • DELETE /admin/plugins/global/{name} - Remove plugin from registry
    • POST /admin/plugins/{name}/promote-to-mandatory - Promote plugin to mandatory
    • POST /admin/plugins/{name}/demote-to-optional - Demote plugin to optional
  • Team Plugin Management (Team Owner role required)

    • GET /teams/{team_id}/plugins - List plugins for team (inherited + team-specific)
    • POST /teams/{team_id}/plugins - Enable plugin for team
    • PUT /teams/{team_id}/plugins/{name} - Update team plugin config
    • DELETE /teams/{team_id}/plugins/{name} - Disable plugin for team
    • Role check: user must be team owner or platform admin
  • User Plugin Management (Self-service for own user)

    • GET /users/me/plugins - List my plugin preferences
    • POST /users/me/plugins - Enable plugin for myself
    • PUT /users/me/plugins/{name} - Update my plugin config
    • DELETE /users/me/plugins/{name} - Disable plugin for myself
  • Server Plugin Management (Server owner only)

    • GET /servers/{server_id}/plugins - List plugins for server (with inheritance indicators)
    • POST /servers/{server_id}/plugins - Add server-specific plugin
    • PUT /servers/{server_id}/plugins/{name} - Update server plugin config
    • DELETE /servers/{server_id}/plugins/{name} - Remove server plugin
    • Permission check: user must own the server
  • Plugin Testing API

    • POST /admin/plugins/test - Test plugin with sample config and payload
    • Isolated execution (no side effects, no DB writes)
    • Return: plugin output, modified payload, execution time, errors
  • Plugin Audit & Reporting

    • GET /admin/plugins/usage-report - Generate usage report (plugins ×ばつ servers)
    • GET /admin/plugins/audit-log - Query plugin change audit log
    • Filters: plugin_name, entity_type, date_range, performed_by
    • Export: CSV, JSON

Phase 4: Admin UI Pages ✅

  • Global Plugin Management UI (Platform Admin)

    • Page: /admin/plugins/global
    • Table: Plugin name, version, mandatory, enabled globally, available for teams/users
    • Actions: Edit, Make Mandatory, Make Optional, Sync from YAML
    • Form: Add new plugin (or sync from plugins/config.yaml)
    • Visual indicators: [MANDATORY], [OPTIONAL], [DEPRECATED]
  • Team Plugin Management UI (Team Owners)

    • Page: /admin/teams/{team_id}/plugins
    • Show inherited mandatory plugins (greyed out, non-editable)
    • Show available optional plugins with toggle switches
    • Config editor: YAML or JSON for plugin config
    • Save button with validation
  • User Plugin Preferences UI (All Users)

    • Page: /admin/settings/plugins
    • Show plugin hierarchy: Mandatory (global) > Team Defaults > My Preferences
    • Toggle switches for optional plugins
    • Config editor for user-level overrides
    • Checkbox: "Inherit team config" (merge vs replace)
  • Server Plugin Configuration UI (Server Owners)

    • Tab: Server Details > Plugins
    • Show plugin chain with level indicators: [MANDATORY], [TEAM DEFAULT], [USER DEFAULT], [SERVER SPECIFIC]
    • Add server-specific plugin button
    • Remove/disable server plugins (except mandatory)
    • Config editor for server-level overrides
  • Plugin Usage Report UI (Platform Admin)

    • Page: /admin/plugins/usage
    • Heatmap: Plugins ×ばつ Servers (color-coded by level)
    • Bar chart: Plugin adoption rates
    • Table: Recent changes (audit log)
    • Filters: Plugin name, team, user, date range
    • Export button (CSV, JSON)
  • Plugin Test Playground UI (Developers)

    • Page: /admin/plugins/test
    • Dropdown: Select plugin
    • Editor: Plugin config (YAML/JSON)
    • Editor: Sample request payload
    • Button: Test Plugin
    • Results panel: Output, modified payload, execution time, errors
    • Save to: Team / User / Server (with dropdown)

Phase 5: Integration with Plugin Manager ✅

  • Modify PluginManager to Use Resolver

    • Update PluginManager.load_plugins_for_server(server_id) to call PluginResolverService
    • Replace static plugin loading from YAML with dynamic resolution
    • Cache resolved plugin chains (invalidate on config change)
    • Log plugin chain for debugging: "Server abc-123 using plugins: [Audit, PII, Regex]"
  • Plugin Config Merging

    • Implement deep merge for JSONB configs
    • Handle arrays: merge (extend) vs replace
    • Handle objects: merge keys, replace values
    • Respect inherit_team_config flag
  • Plugin Chain Execution

    • Execute plugins in priority order (sorted by priority field)
    • Pass context with level indicators: mandatory=True, level="team"
    • Log plugin execution: "Executing PIIFilterPlugin (mandatory) with config: {...}"

Phase 6: Configuration & Deployment ✅

  • Update plugins/config.yaml Schema

    • Add fields: mandatory, enabled_globally, available_for_teams, available_for_users
    • Add fields: allow_team_override, allow_user_override, allow_server_override
    • Add fields: requires, conflicts_with
    • Example configurations for common scenarios (mandatory security plugins, team-optional tools)
  • Sync Script: YAML → Database

    • Create script: python -m mcpgateway.cli plugins sync
    • Read plugins/config.yaml
    • Insert/update global_plugin_registry table
    • Preserve existing team/user/server plugin settings
    • Log changes and conflicts
  • Environment Variables

    • MCPGATEWAY_PLUGIN_RBAC_ENABLED=true - Enable this feature
    • MCPGATEWAY_USER_PLUGIN_CUSTOMIZATION_ALLOWED=true - Allow user-level overrides
    • MCPGATEWAY_PLUGIN_CACHE_TTL=300 - Cache resolved plugins for 5 minutes

Phase 7: Permissions & Authorization ✅

  • Role Checks

    • Platform Admin: Full access to global plugins, all teams/users/servers
    • Team Owner: Can manage team plugins for their team(s)
    • User: Can manage own plugins, own servers
    • Guest: Read-only access to public plugins
  • Permission Middleware

    • Create check_team_owner() decorator
    • Create check_server_owner() decorator
    • Apply to API endpoints (e.g., POST /teams/{team_id}/plugins requires team owner)
  • Audit Logging

    • Log all plugin changes to plugin_audit_log table
    • Capture: action, level, plugin_name, entity_id, performed_by, old/new config
    • Include reason field (optional user-provided explanation)

Phase 8: Testing ✅

  • Unit Tests

    • Test plugin resolution algorithm (all combinations: mandatory, team, user, server)
    • Test config merging (inherit vs replace)
    • Test conflict detection (conflicts_with, requires)
    • Test priority sorting
    • Test override validation (allow_*_override flags)
    • Test permission checks (team owner, server owner)
    • Test audit log insertion
  • Integration Tests

    • Test full workflow: Platform admin enables mandatory plugin → appears in all servers
    • Test team plugin enablement → inherited by team users
    • Test user plugin customization → merged with team defaults
    • Test server-specific plugin → overrides user defaults
    • Test conflict prevention (enable conflicting plugins)
    • Test dependency enforcement (enable plugin without required dependency)
    • Test plugin testing API (isolated execution)
  • E2E Tests (Playwright)

    • Test Admin UI: Enable mandatory plugin, verify it appears in all servers
    • Test Team UI: Team owner enables plugin, verify inheritance
    • Test User UI: User customizes plugin, verify merge
    • Test Server UI: Add server-specific plugin, verify override
    • Test Plugin Testing Playground: Test plugin, save to server
  • Performance Tests

    • Benchmark plugin resolution (<50ms for 95th percentile)
    • Test with 100 servers, 10 teams, 50 users, 20 plugins
    • Test cache effectiveness (hit rate >95%)
    • Test concurrent plugin changes (race conditions)

Phase 9: Documentation ✅

  • User Guide

    • Create docs/docs/features/plugin-rbac.md
    • Explain hierarchical plugin model
    • Examples: How to enable plugins at each level
    • Best practices: When to use team vs user vs server plugins
    • Troubleshooting: Conflicts, permissions, inheritance
  • Admin Guide

    • Document governance model: Mandatory vs optional plugins
    • How to design plugin hierarchy for your organization
    • Plugin lifecycle: Enable → Configure → Test → Deploy → Audit
    • Compliance: Tracking plugin usage for audits
    • Migration: Moving plugins between levels
  • API Documentation

    • OpenAPI spec for all plugin API endpoints
    • Example API calls (curl, Python)
    • Permission requirements for each endpoint
    • Response schemas
  • Configuration Reference

    • Document plugins/config.yaml schema
    • Field descriptions: mandatory, available_for_teams, conflicts_with, etc.
    • Example configurations for common use cases

Phase 10: Quality & Polish ✅

  • Code Quality

    • Run make autoflake isort black
    • Run make flake8 and fix all issues
    • Run make pylint and address warnings
    • Run make doctest to validate examples
    • Pass make verify checks
  • Security Review

    • Review permission checks (prevent privilege escalation)
    • Review SQL injection risks (validate JSONB inputs)
    • Review audit trail completeness
    • Test access control bypass attempts
  • Performance Optimization

    • Add database indexes for hot queries
    • Implement Redis caching for plugin chains
    • Batch audit log insertions
    • Profile and optimize resolution algorithm

⚙️ Configuration Examples

Global Mandatory Plugins (Platform Admin)

# plugins/config.yaml
plugins:
 # Mandatory security plugins (cannot be disabled)
 - name: "AuditLoggerPlugin"
 kind: "plugins.audit.audit.AuditLoggerPlugin"
 version: "1.0.0"
 description: "Logs all tool invocations for compliance"
 mandatory: true
 enabled_globally: true
 available_for_teams: false # Not needed, already mandatory
 allow_team_override: false
 allow_user_override: false
 allow_server_override: false
 priority: 1
 config:
 log_level: "INFO"
 log_all_payloads: true
 
 - name: "PIIFilterPlugin"
 kind: "plugins.pii_filter.pii_filter.PIIFilterPlugin"
 version: "1.0.0"
 description: "Filters PII from tool responses"
 mandatory: true
 enabled_globally: true
 allow_team_override: true # Teams can customize patterns
 allow_user_override: false
 allow_server_override: false
 priority: 2
 config:
 pii_patterns:
 - "\\b\\d{3}-\\d{2}-\\d{4}\\b" # SSN
 - "\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b" # Email
 
 # Optional plugins (teams can enable)
 - name: "RegexFilterPlugin"
 kind: "plugins.regex_filter.regex_filter.RegexFilterPlugin"
 version: "1.0.0"
 description: "Custom regex-based content filtering"
 mandatory: false
 enabled_globally: false
 available_for_teams: true
 available_for_users: true
 allow_team_override: true
 allow_user_override: true
 allow_server_override: true
 priority: 50
 config:
 blocked_patterns: [] # Default: no patterns
 
 - name: "DenyFilterPlugin"
 kind: "plugins.deny_filter.deny_filter.DenyFilterPlugin"
 version: "1.0.0"
 description: "Deny access to specific tools"
 mandatory: false
 enabled_globally: false
 available_for_teams: true
 available_for_users: true
 conflicts_with: ["PIIFilterPlugin"] # Example conflict
 priority: 50
 config:
 blocked_tools: []
 
 - name: "CachingPlugin"
 kind: "plugins.caching.caching.CachingPlugin"
 version: "1.0.0"
 description: "Cache tool responses for performance"
 mandatory: false
 enabled_globally: false
 available_for_teams: true
 requires: ["AuthenticationPlugin"] # Dependency example
 priority: 60
 config:
 cache_ttl: 300

Team Plugin Configuration (Team Owner)

-- engineering team enables RegexFilterPlugin with custom patterns
INSERT INTO team_plugins (id, team_id, plugin_name, enabled, config, added_by)
VALUES (
 gen_random_uuid(),
 'team-engineering-uuid',
 'RegexFilterPlugin',
 true,
 '{"blocked_patterns": ["internal-secret-123", "proprietary-algorithm"]}'::jsonb,
 'alice@example.com'
);
-- security team enables stricter PII filter (override mandatory config)
INSERT INTO team_plugins (id, team_id, plugin_name, enabled, config, added_by)
VALUES (
 gen_random_uuid(),
 'team-security-uuid',
 'PIIFilterPlugin',
 true,
 '{"pii_patterns": ["\\b\\d{3}-\\d{2}-\\d{4}\\b", "\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b", "confidential"]}'::jsonb,
 'bob@security.com'
);

User Plugin Preferences

-- alice customizes RegexFilterPlugin with personal patterns (merged with team)
INSERT INTO user_plugins (id, user_id, plugin_name, enabled, config, inherit_team_config)
VALUES (
 gen_random_uuid(),
 'user-alice-uuid',
 'RegexFilterPlugin',
 true,
 '{"blocked_patterns": ["my-personal-secret"]}'::jsonb,
 true -- Merge with team patterns
);
-- alice enables ResourceFilterPlugin for herself
INSERT INTO user_plugins (id, user_id, plugin_name, enabled, config)
VALUES (
 gen_random_uuid(),
 'user-alice-uuid',
 'ResourceFilterPlugin',
 true,
 '{"allowed_resources": ["github", "jira"]}'::jsonb
);

Server-Specific Plugins

-- production_tools server has extra strict deny filter
INSERT INTO server_plugins (id, server_id, plugin_name, enabled, config, added_by)
VALUES (
 gen_random_uuid(),
 'server-prod-tools-uuid',
 'DenyFilterPlugin',
 true,
 '{"blocked_tools": ["dangerous-delete-tool", "experimental-beta-feature"]}'::jsonb,
 'alice@example.com'
);
-- dev_tools server disables RegexFilterPlugin (less restrictive)
INSERT INTO server_plugins (id, server_id, plugin_name, enabled, config, added_by)
VALUES (
 gen_random_uuid(),
 'server-dev-tools-uuid',
 'RegexFilterPlugin',
 false, -- Disabled for dev
 '{}'::jsonb,
 'alice@example.com'
);

✅ Success Criteria

  • Hierarchical Plugin Model: Plugins can be enabled at global, team, user, and server levels
  • Mandatory Enforcement: Mandatory plugins are enabled on all servers and cannot be disabled
  • Team Autonomy: Team owners can enable optional plugins for their teams
  • User Flexibility: Users can customize plugin preferences without affecting others
  • Server Isolation: Different servers can have different plugin configurations
  • Conflict Prevention: System blocks enabling conflicting plugins
  • Dependency Enforcement: System ensures required plugins are enabled
  • Config Merging: Configs merge correctly across levels (inherit vs replace)
  • Permission Checks: Role-based access control enforced for all operations
  • Audit Trail: All plugin changes logged with metadata
  • Admin UI: Complete UI for managing plugins at all levels
  • API Endpoints: RESTful APIs for all plugin operations
  • Testing: 100+ tests with 90%+ coverage
  • Performance: Plugin resolution <50ms for 95th percentile
  • Documentation: Complete user guide, admin guide, API docs
  • Quality: Passes all linting, formatting, verification checks

🏁 Definition of Done

  • Database schema migrated (5 new tables)
  • ORM models and repository layer complete
  • Plugin resolution algorithm implemented and tested
  • Config merging logic (inherit vs replace) working
  • Conflict detection and dependency enforcement working
  • API endpoints implemented for all levels (global, team, user, server)
  • Permission middleware enforcing role checks
  • Audit logging to plugin_audit_log table
  • Admin UI pages: Global plugins, Team plugins, User preferences, Server plugins
  • Plugin usage report UI with export functionality
  • Plugin testing playground UI
  • Integration with PluginManager (dynamic resolution)
  • Caching layer (Redis) for resolved plugin chains
  • 100+ unit tests with 90%+ coverage
  • Integration tests for all workflows
  • E2E tests (Playwright) for UI flows
  • Performance benchmarked (<50ms resolution time)
  • Documentation complete (user guide, admin guide, API docs, config reference)
  • Code passes make verify checks
  • Security review completed
  • Migration script for syncing YAML to database
  • Ready for production deployment

📝 Additional Notes

🔹 Design Principles:

  • Least Privilege: Users have minimal permissions by default
  • Defense in Depth: Mandatory plugins cannot be bypassed
  • Flexibility: Teams and users can customize within boundaries
  • Transparency: Full audit trail for compliance

🔹 Use Cases:

  • Enterprise Security: Enforce mandatory security plugins (PII filter, audit logger)
  • Team Workflows: Engineering uses different plugins than Security
  • Server Isolation: Production servers have stricter plugins than dev
  • Compliance: Track plugin usage for audits (HIPAA, SOC2)

🔹 Future Enhancements:

  • Plugin Marketplace: Browse and install plugins from registry
  • Plugin Versioning: Support multiple versions, rollback capability
  • Plugin Templates: Pre-configured plugin sets (security-baseline, dev-productivity)
  • Conditional Plugins: Enable plugins based on request attributes (time, IP, MFA)
  • Plugin Analytics: Track plugin performance, success rates, error rates
  • Cross-Gateway Plugin Sync: Federate plugin configs across gateways

🔹 Performance Considerations:

  • Cache resolved plugin chains (Redis, 5 min TTL)
  • Invalidate cache on plugin config change
  • Batch audit log insertions (every 10s or 100 records)
  • Database indexes on hot queries (server_id, team_id, user_id)

🔹 Security Considerations:

  • Validate JSONB configs to prevent injection attacks
  • Enforce permissions at API layer (not just UI)
  • Audit all plugin changes (who, what, when, why)
  • Prevent privilege escalation (users cannot make plugins mandatory)

🔗 Related Issues


📚 References

Metadata

Metadata

Labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    AltStyle によって変換されたページ (->オリジナル) /