Skip to content

feat(gateway): per-user tool restrictions (RBAC) via user_roles config#3995

Open
Mibayy wants to merge 2 commits into
NousResearch:mainfrom
Mibayy:feat/gateway-user-rbac
Open

feat(gateway): per-user tool restrictions (RBAC) via user_roles config#3995
Mibayy wants to merge 2 commits into
NousResearch:mainfrom
Mibayy:feat/gateway-user-rbac

Conversation

@Mibayy

@Mibayy Mibayy commented Mar 30, 2026

Copy link
Copy Markdown
Contributor

Closes #3897

Problem

All authorized gateway users get identical access to every enabled tool, including terminal and execute_code. Prompt-based restrictions are unreliable — the LLM can ignore them.

Solution

Code-level per-user tool filtering, configured in config.yaml under gateway.user_roles. The filter runs in _run_agent before the AIAgent is created, so restricted toolsets are never registered with the model in the first place.

Config example

gateway:
  user_roles:
    "123456789":        # Telegram user ID — admin, full access
      role: admin
      allowed_tools: all
    "987654321":        # Manager — no terminal / code execution
      role: manager
      blocked_tools: [terminal, execute_code, bash]
    default:            # Everyone else — MCP tools only
      role: viewer
      allowed_tools: [mcp__*]

Precedence:

  • allowed_tools (allowlist, supports fnmatch wildcards like mcp__*): takes full precedence. Special value all skips filtering.
  • blocked_tools (denylist): applied when allowed_tools is absent.
  • default entry matches any user not explicitly listed.
  • If neither field is set, all toolsets pass through unchanged.

Changes

gateway/config.py

  • New UserRole dataclass with role, allowed_tools, blocked_tools
  • UserRole.apply(toolsets) — pure filter function using fnmatch
  • GatewayConfig.user_roles: Dict[str, UserRole] field
  • GatewayConfig.get_user_role(user_id) — lookup with default fallback
  • from_dict / to_dict support

gateway/run.py

  • In _run_agent, after enabled_toolsets is resolved, call get_user_role(source.user_id).apply(enabled_toolsets)
  • Errors are caught and logged at DEBUG level — never block a message

What this is NOT

This is not authentication (covered by TELEGRAM_ALLOWED_USERS etc.) — it's a second layer that controls what tools an already-authenticated user can invoke. It operates at toolset granularity (same keys as platform_toolsets in config). Fine-grained per-tool filtering within a toolset can be added later if needed.

@George-RD

Copy link
Copy Markdown

I want this for WhatsApp too.

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery area/config Config system, migrations, profiles labels May 2, 2026
@bashrusakh

Copy link
Copy Markdown

Hi, any status updates?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Per-user tool restrictions in gateway (RBAC)

4 participants