Skip to content

fix(gateway): delegate Telegram callback auth to shared user authorizer#18016

Closed
premie wants to merge 1 commit into
NousResearch:mainfrom
premie:fix/telegram-callback-auth-delegates-to-authorizer
Closed

fix(gateway): delegate Telegram callback auth to shared user authorizer#18016
premie wants to merge 1 commit into
NousResearch:mainfrom
premie:fix/telegram-callback-auth-delegates-to-authorizer

Conversation

@premie

@premie premie commented Apr 30, 2026

Copy link
Copy Markdown

Summary

TelegramAdapter._is_callback_user_authorized only checked the TELEGRAM_ALLOWED_USERS env var, bypassing the gateway's full auth path (pairing store + global allowlists). This meant inline-button callback events were authorized inconsistently with inbound messages — users paired through the gateway could be silently rejected on approval-button clicks even though their messages were accepted.

Changes

  • BasePlatformAdapter: add _user_authorizer field + set_user_authorizer() injector
  • TelegramAdapter._is_callback_user_authorized: call the injected authorizer when present; fall back to the env-only check for tests / unwired adapters
  • GatewayRunner: wire _is_user_id_authorized into every adapter on connect so callbacks go through the same auth path as inbound messages
  • Add regression test confirming callback auth delegates to the injected authorizer

Test plan

  • New unit test: tests/gateway/test_telegram_approval_buttons.py — callback auth delegates to injected authorizer
  • Manual: paired user can approve via inline button; un-paired user cannot
  • In production on a Hermes deploy for ~10 days before the most recent hermes update accidentally reverted it

Isolate the WhatsApp bridge package-lock change since it's unrelated.

The _is_callback_user_authorized method on TelegramAdapter was checking
only TELEGRAM_ALLOWED_USERS env var, bypassing the gateway's full auth
path (pairing store + global allowlists). This meant inline-button
callbacks could succeed for users rejected by the normal message auth
flow.

Changes:
- BasePlatformAdapter: add _user_authorizer field + set_user_authorizer()
- TelegramAdapter: _is_callback_user_authorized now calls injected authorizer
  when available, falls back to env-only check in tests
- GatewayRunner: wire _is_user_id_authorized into every adapter on connect
- Add test: callback auth delegates to injected authorizer
@alt-glitch alt-glitch added type/bug Something isn't working P1 High — major feature broken, no workaround comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter area/auth Authentication, OAuth, credential pools labels Apr 30, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #17862 which addresses the same Telegram inline callback auth bypass. This PR adds a more general injector pattern via BasePlatformAdapter.

@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to #17862 which addresses the same Telegram inline callback auth bypass. This PR takes a slightly different approach (injected authorizer vs delegating to runner).

@teknium1

Copy link
Copy Markdown
Contributor

Automated hermes-sweeper review: this appears to be implemented on current main via the merged #18180 salvage path, so this PR is now superseded.

Evidence:

  • gateway/platforms/telegram.py:527 now recovers the attached gateway runner from the adapter's bound message handler and calls the shared _is_user_authorized() path.
  • gateway/platforms/telegram.py:539 builds a Telegram SessionSource with chat/user/thread context before delegating authorization.
  • gateway/platforms/telegram.py:555 keeps the legacy TELEGRAM_ALLOWED_USERS fallback for tests or unwired adapters.
  • gateway/run.py:4750 wires adapters with adapter.set_message_handler(self._handle_message), which is what lets Telegram callbacks reach the runner-backed auth path.
  • fix(telegram): enforce gateway auth for inline approval callbacks (#17862) #18180 merged commit cd1eda657cc85130d6d63bf362f0b8c6b223a2cc; its maintainer discussion explicitly called it a salvage of the related Telegram callback auth bypass and noted it likely supersedes this PR.

The implementation differs from this PR's exact injector pattern, but the bug this PR targets — inline-button callbacks bypassing pairing/global gateway authorization — is fixed on main.

@teknium1 teknium1 closed this Jun 10, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/auth Authentication, OAuth, credential pools comp/gateway Gateway runner, session dispatch, delivery P1 High — major feature broken, no workaround platform/telegram Telegram bot adapter sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants