You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hermes Agent currently has a binary authorization model for gateway platforms: users are either fully authorized (all commands, all tools, full terminal access) or completely blocked. There is no concept of permission levels, roles, or per-user capability restrictions.
This proposal introduces a tiered permission system (Owner → Admin → User → Guest) for the gateway/messenger platforms (Telegram, Discord, WhatsApp, Slack). Each tier gets a defined set of allowed commands, tools, and capabilities. This is essential for anyone running Hermes Agent as a shared service — e.g., a team lead who wants colleagues to use the agent for research/search but not have full terminal access to the host machine.
The idea is straightforward: the person who deployed Hermes Agent should be able to share it with others while controlling what those others can do. Right now, sharing means giving full access to everything — including terminal, write_file, schedule_cronjob, process management, and configuration commands like /model and /update. This is a significant security and trust barrier to multi-user adoption.
Research Findings
Current Authorization Architecture
The existing system (gateway/run.py:532-595, _is_user_authorized()) checks in this order:
Per-platform allow-all flag (TELEGRAM_ALLOW_ALL_USERS=true)
DM pairing approval (pairing_store.is_approved())
Per-platform allowlist env var (TELEGRAM_ALLOWED_USERS=id1,id2)
Global allowlist (GATEWAY_ALLOWED_USERS=id1,id2)
Global allow-all (GATEWAY_ALLOW_ALL_USERS=true)
Default: deny
Key limitations:
All-or-nothing: Every authorized user gets identical capabilities — same tools, same commands, same terminal access
No per-command gating: All slash commands (/model, /update, /reload-mcp, /sethome, /personality) are available to every authorized user — meaning any user can change the model, update the agent, or reconfigure it
Toolset is uniform: _HERMES_CORE_TOOLS (defined in toolsets.py:31-67) is identical across all platform toolsets — every authorized user gets terminal, write_file, schedule_cronjob, process, etc.
Session sharing: Non-WhatsApp DMs share a single session per platform, meaning all authorized users see the same conversation history and memory
Global safety only: HERMES_EXEC_ASK=1 applies uniformly — no way to auto-approve for admins but require approval for regular users
Config mutations are unprotected: /model and /personality modify ~/.hermes/config.yaml, meaning any authorized user can change settings for all users
How Other Platforms Handle This
Telegram bot ecosystem: The dominant pattern for AI bots (chatgpt-telegram-bot, TeleChat) uses tiered env var lists:
ADMIN_USER_IDS=12345,67890 — no budget limits, admin commands
ALLOWED_TELEGRAM_USER_IDS=12345,67890,11111 — standard access, per-user budgets
Guest budget pool for unlisted users in groups
Telegram's native BotCommandScope API supports command visibility scoping (show different command menus to admins vs regular users).
AI agent platforms: MCP servers and agent frameworks are converging on role-to-tool mapping — each role defines which tools are accessible. Enforcement happens at the tool dispatch layer, not just the UI layer.
Universal pattern: Define tiers in config, enforce via middleware at boundaries, default to least privilege, support both platform-native and custom role mapping.
Issue #476 proposes a mode system where tool access is scoped by mode (Code, Ask, Architect, etc.). Modes are self-selected by the user — they choose which mode to operate in. The permission system proposed here is admin-imposed — the operator decides what each user can do. These are complementary:
Permissions define what a user is allowed to do (ceiling)
Modes define what a user chooses to do within their permissions (self-restriction)
A natural integration: admins can force certain user tiers into specific modes. E.g., "user" tier users are locked to "ask" mode (read-only tools), while admins can switch freely.
Per-user session isolation option (separate sessions per user instead of shared)
Pros & Cons
Pros
Unlocks multi-user sharing: The Terminal tool #1 barrier to sharing Hermes Agent with teammates, family, or community is that authorization = full access. This removes that barrier entirely.
Security posture: Currently any authorized Telegram user can terminal rm -rf / or read sensitive files. Tiered permissions provide defense-in-depth beyond the binary allowlist.
Cost control: Guests and regular users can be rate-limited and budget-capped, preventing runaway API costs from shared access.
Backward compatible: No permissions config = today's behavior. Zero migration friction.
Leverages existing infrastructure: The allowlist env vars, pairing system, toolset system, and hook system all provide natural integration points.
Platform-native integration: Can leverage Telegram admin status and Discord roles instead of requiring manual user ID configuration.
Complexity: Adds a new subsystem to the gateway. The permission resolution logic (config tiers + env vars + platform roles + pairing + defaults) could become hard to reason about.
Configuration burden: Users need to assign roles to user IDs. Mitigated by sensible defaults (first allowlist entry = owner, pairing = user tier).
False sense of security: Tool filtering happens at the agent level, but the LLM could potentially instruct users to bypass restrictions (e.g., "run this command in your terminal"). This is access control, not a security sandbox. Should be documented clearly.
Session sharing complications: If user A (admin) and user B (user) share a DM session, whose permissions apply? Need clear policy (most restrictive? per-message? separate sessions?). This is solvable but needs design decisions.
Platform role detection latency: Querying Telegram/Discord APIs for role info on every message adds latency. Needs caching with reasonable TTL.
Testing surface: Every command and tool needs permission checks. Easy to miss one and create a bypass.
Open Questions
Session sharing policy: When users of different tiers share a group session, whose tier applies? Options: (a) most restrictive tier in the chat, (b) per-message tier based on who sent it, (c) configurable. Option (b) is most flexible but most complex.
Backward compatibility for env vars: Should the existing TELEGRAM_ALLOWED_USERS env var entries default to owner tier (preserving current behavior) or admin tier? Recommendation: owner for first entry, admin for the rest, configurable via default_tier.
Guest access model: Should guests (unauthenticated users in groups with ALLOW_ALL_USERS=true) get any tool access by default, or chat-only? Recommendation: chat-only (no tools) by default, configurable.
Tool-level vs toolset-level filtering: Filter individual tools, or entire toolsets? Individual tools gives finer granularity but more config. Recommendation: individual tools, with toolset shorthand (e.g., tools: ["@web"] expands to web_search + web_extract).
Interaction with MCP tools: MCP tools are dynamically discovered. Should they be allowed/denied per tier? Recommendation: MCP tools follow the same tier rules, with a config option for default MCP tool policy per tier.
Overview
Hermes Agent currently has a binary authorization model for gateway platforms: users are either fully authorized (all commands, all tools, full terminal access) or completely blocked. There is no concept of permission levels, roles, or per-user capability restrictions.
This proposal introduces a tiered permission system (Owner → Admin → User → Guest) for the gateway/messenger platforms (Telegram, Discord, WhatsApp, Slack). Each tier gets a defined set of allowed commands, tools, and capabilities. This is essential for anyone running Hermes Agent as a shared service — e.g., a team lead who wants colleagues to use the agent for research/search but not have full terminal access to the host machine.
The idea is straightforward: the person who deployed Hermes Agent should be able to share it with others while controlling what those others can do. Right now, sharing means giving full access to everything — including
terminal,write_file,schedule_cronjob, process management, and configuration commands like/modeland/update. This is a significant security and trust barrier to multi-user adoption.Research Findings
Current Authorization Architecture
The existing system (
gateway/run.py:532-595,_is_user_authorized()) checks in this order:TELEGRAM_ALLOW_ALL_USERS=true)pairing_store.is_approved())TELEGRAM_ALLOWED_USERS=id1,id2)GATEWAY_ALLOWED_USERS=id1,id2)GATEWAY_ALLOW_ALL_USERS=true)Key limitations:
/model,/update,/reload-mcp,/sethome,/personality) are available to every authorized user — meaning any user can change the model, update the agent, or reconfigure it_HERMES_CORE_TOOLS(defined intoolsets.py:31-67) is identical across all platform toolsets — every authorized user getsterminal,write_file,schedule_cronjob,process, etc.HERMES_EXEC_ASK=1applies uniformly — no way to auto-approve for admins but require approval for regular users/modeland/personalitymodify~/.hermes/config.yaml, meaning any authorized user can change settings for all usersHow Other Platforms Handle This
Telegram bot ecosystem: The dominant pattern for AI bots (chatgpt-telegram-bot, TeleChat) uses tiered env var lists:
ADMIN_USER_IDS=12345,67890— no budget limits, admin commandsALLOWED_TELEGRAM_USER_IDS=12345,67890,11111— standard access, per-user budgetsTelegram's native
BotCommandScopeAPI supports command visibility scoping (show different command menus to admins vs regular users).Discord bot ecosystem: Rich built-in permission infrastructure —
@commands.has_permissions(),@commands.has_role(),@commands.is_owner()decorators. Permission bitfields, role-based checks, channel-level permission overwrites. Discord bots commonly map server roles to bot permission tiers.AI agent platforms: MCP servers and agent frameworks are converging on role-to-tool mapping — each role defines which tools are accessible. Enforcement happens at the tool dispatch layer, not just the UI layer.
Universal pattern: Define tiers in config, enforce via middleware at boundaries, default to least privilege, support both platform-native and custom role mapping.
Relationship to Issue #476 (Agent Mode System)
Issue #476 proposes a mode system where tool access is scoped by mode (Code, Ask, Architect, etc.). Modes are self-selected by the user — they choose which mode to operate in. The permission system proposed here is admin-imposed — the operator decides what each user can do. These are complementary:
A natural integration: admins can force certain user tiers into specific modes. E.g., "user" tier users are locked to "ask" mode (read-only tools), while admins can switch freely.
Current State in Hermes Agent
What we have:
gateway/run.py:532-595)gateway/pairing.py)SessionSourceinsession.py:30-103)command:*events (gateway/hooks.py)What we don't have:
Relevant files that would need changes:
gateway/run.py— Authorization check, command dispatch, agent creationgateway/config.py— Permission tier definitionsgateway/session.py— User role injection into session contextgateway/pairing.py— Pairing with role assignmenttoolsets.py— Per-user tool filteringtools/registry.py— Tool dispatch with permission checksImplementation Plan
Core Architecture: Classification
This is a core codebase change, not a skill or tool. Per CONTRIBUTING.md criteria:
Permission Tier Design
Default tier permissions (configurable via config.yaml):
/modelcommand/personality/update/reload-mcp/sethome/usage/new,/reset/helpConfiguration Format
What We'd Need
gateway/permissions.py) — loads tier config, resolves user→tier, checks tool/command access, caches lookups_is_user_authorized()→_get_user_permission(source) -> PermissionTier— returns the tier instead of bool (tier=BLOCKED means unauthorized)permission_manager.can_execute_command(source, command)enabled_toolsetsthroughpermission_manager.get_allowed_tools(source)before passing toAIAgent()/users list,/users set <user_id> <tier>,/users remove <user_id>getChatMember()or Discord member roles at authorization timePhased Rollout
Phase 1: Core Permission Engine + Tool Filtering
PermissionManagerclass with tier resolutionconfig.yaml(tiers, user assignments, default_tier)AIAgent()permissionsconfig exists, behave exactly as today (all authorized users = owner)Phase 2: User Management + Rate Limiting
/userscommand family for runtime user management (list, set tier, remove)/usagecommand)Phase 3: Platform-Native Roles + Advanced Features
getChatMemberAPI)Pros & Cons
Pros
terminal rm -rf /or read sensitive files. Tiered permissions provide defense-in-depth beyond the binary allowlist.permissionsconfig = today's behavior. Zero migration friction.Cons / Risks
Open Questions
Session sharing policy: When users of different tiers share a group session, whose tier applies? Options: (a) most restrictive tier in the chat, (b) per-message tier based on who sent it, (c) configurable. Option (b) is most flexible but most complex.
Backward compatibility for env vars: Should the existing
TELEGRAM_ALLOWED_USERSenv var entries default toownertier (preserving current behavior) oradmintier? Recommendation:ownerfor first entry,adminfor the rest, configurable viadefault_tier.Guest access model: Should guests (unauthenticated users in groups with
ALLOW_ALL_USERS=true) get any tool access by default, or chat-only? Recommendation: chat-only (no tools) by default, configurable.Tool-level vs toolset-level filtering: Filter individual tools, or entire toolsets? Individual tools gives finer granularity but more config. Recommendation: individual tools, with toolset shorthand (e.g.,
tools: ["@web"]expands to web_search + web_extract).Interaction with MCP tools: MCP tools are dynamically discovered. Should they be allowed/denied per tier? Recommendation: MCP tools follow the same tier rules, with a config option for default MCP tool policy per tier.
Integration with Feature: Agent Mode System — Persona + Tool Scoping + Behavioral Constraints (inspired by Kilocode) #476 modes: Should this be built to compose with modes from day 1, or independently first? Recommendation: build independently in Phase 1, add mode integration in Phase 3.
References
gateway/run.py:532-595toolsets.py:31-67gateway/pairing.pyBotCommandScopeAPI@has_permissions(),@has_role(),@is_owner()decorators, permission bitfieldsrelaybot < user < admintiered config