Skip to content

hermes: require an authorized sender for adapter-local commands and thread creation - #105

Closed
teknium1 wants to merge 1 commit into
inline-chat:mainfrom
teknium1:hermes-catalog/gate-local-commands
Closed

teknium1 wants to merge 1 commit into
inline-chat:mainfrom
teknium1:hermes-catalog/gate-local-commands

Conversation

@teknium1

Copy link
Copy Markdown

Why

With only INLINE_TOKEN configured, _dm_policy/_group_policy default to open, so _allowed() passes every sender. Core then default-denies the model turn (it trusts enforces_own_access_policy only under allowlist), but a few adapter-local paths run before core's authz and were reachable by anyone who could message the bot:

  • /threads on|off|auto|reset — persists per-chat settings to disk
  • /follow / /unfollow — flips the dialog follow mode via the sidecar
  • /inline-sync — re-uploads the full command + skill catalog to Inline; /inline-version — discloses plugin/Hermes versions
  • automatic reply-thread creation for the incoming message
  • th: thread buttons — _thread_action_allowed fell back to _allowed(), unlike every other button family which uses _actor_authorized

README already says /inline_sync works "from an authorized chat" and that buttons never become a bypass when intake is open; the code did not enforce that. Found in the Hermes plugin-catalog review of NousResearch/hermes-agent#125406.

What

adapter.py only:

  • In _dispatch_message, compute actor_authorized = self._actor_authorized(chat_type, from_id) once after the intake checks and require it for the three local command handlers and for reply-thread creation. Unauthorized senders' text now simply continues to handle_message, where core applies its own authz (pairing/ignore/decline as configured).
  • _thread_action_allowed drops the _allowed() fallback so th: buttons use the same default-deny check as the other action families.

Behaviour for authorized users (allowlist, INLINE_ALLOW_ALL_USERS, GATEWAY_ALLOWED_USERS, wizard-configured setups) is unchanged.

Tests: four existing cases in tests/adapter-python.test.ts that exercised these paths with the bare base_extra now set allow_from for their sender; one new case (assert_local_commands_require_authorized_sender) covers a stranger under the default policy — red on main, green here. The embedded Python suite passes (adapter python smoke ok); hermes plugins validate on plugin/inline → ok, install scanner → safe.

…hread creation

/threads, /follow, /inline-sync, /inline-version and reply-thread creation
ran after _allowed() but before core authz, so under the default open
policy any sender could reach them. Gate them (and th: buttons) on the
same default-deny _actor_authorized check the other button actions use.

Signed-off-by: teknium1 <teknium1@users.noreply.github.com>
@morajabi

Copy link
Copy Markdown
Contributor

Closed by #107

@morajabi morajabi closed this Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants