Skip to content

fix(telegram): fail-closed auth fallback when TELEGRAM_ALLOWED_USERS is empty#28494

Merged
teknium1 merged 2 commits into
mainfrom
hermes/hermes-6063e704
May 19, 2026
Merged

fix(telegram): fail-closed auth fallback when TELEGRAM_ALLOWED_USERS is empty#28494
teknium1 merged 2 commits into
mainfrom
hermes/hermes-6063e704

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Salvage of #24468 (@liuhao1024).

Summary

The Telegram adapter's _is_callback_user_authorized fallback returned True when TELEGRAM_ALLOWED_USERS was not set, allowing any Telegram user who discovered the bot to interact with a tool-enabled agent. This changes the fallback to deny by default, requiring explicit GATEWAY_ALLOW_ALL_USERS=true to open access.

The primary auth path in gateway/run.py::_is_user_authorized() already handles GATEWAY_ALLOW_ALL_USERS correctly — this PR closes the parity gap in the adapter-level fallback.

Changes

  • gateway/platforms/telegram.py::_is_callback_user_authorized: replace fail-OPEN default with GATEWAY_ALLOW_ALL_USERS-gated default.
  • tests/gateway/test_telegram_callback_auth_fail_closed.py (new): 5 tests covering the fail-closed behavior.

Validation

  • scripts/run_tests.sh tests/gateway/test_telegram_callback_auth_fail_closed.py tests/gateway/test_telegram_group_gating.py tests/gateway/test_telegram_mention_boundaries.py -q → 41/41 passing.

Follow-up

Stubs _is_callback_user_authorized in test_telegram_group_gating.py fixture so trigger-logic tests don't get blocked by the new fail-closed gate (the fail-closed behavior is covered by the new dedicated test file).

Authorship preserved via cherry-pick.

liuhao1024 and others added 2 commits May 18, 2026 22:06
…is empty

The _is_callback_user_authorized fallback returned True when
TELEGRAM_ALLOWED_USERS was not set, allowing any Telegram user
to interact with the bot. Change to fail-closed: deny by default
unless GATEWAY_ALLOW_ALL_USERS=true is explicitly set.

Fixes #24457
…ixture

After PR #24468 made the empty-allowlist callback auth fail-closed
(and #23795 wired _is_callback_user_authorized into _should_process_message),
trigger-gating tests started failing because their fake messages from
user 111 hit the new deny-by-default path before trigger evaluation.

Force-authorize all senders in _make_adapter() so the trigger logic
under test runs.  The fail-closed behavior itself is covered by
test_telegram_callback_auth_fail_closed.py.
@teknium1 teknium1 merged commit 8439ddc into main May 19, 2026
12 of 17 checks passed
@teknium1 teknium1 deleted the hermes/hermes-6063e704 branch May 19, 2026 05:08
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-6063e704 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8899 on HEAD, 8888 on base (🆕 +11)

🆕 New issues (11):

Rule Count
unresolved-attribute 10
unresolved-import 1
First entries
tests/gateway/test_telegram_callback_auth_fail_closed.py:45: [unresolved-attribute] unresolved-attribute: Unresolved attribute `request` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:42: [unresolved-attribute] unresolved-attribute: Unresolved attribute `error` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:36: [unresolved-attribute] unresolved-attribute: Unresolved attribute `ApplicationBuilder` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:33: [unresolved-attribute] unresolved-attribute: Unresolved attribute `HTTPXRequest` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:27: [unresolved-attribute] unresolved-attribute: Unresolved attribute `NetworkError` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:30: [unresolved-attribute] unresolved-attribute: Unresolved attribute `ParseMode` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:11: [unresolved-import] unresolved-import: Cannot resolve imported module `pytest`
tests/gateway/test_telegram_callback_auth_fail_closed.py:44: [unresolved-attribute] unresolved-attribute: Unresolved attribute `ext` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:26: [unresolved-attribute] unresolved-attribute: Unresolved attribute `BadRequest` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:43: [unresolved-attribute] unresolved-attribute: Unresolved attribute `constants` on type `ModuleType`
tests/gateway/test_telegram_callback_auth_fail_closed.py:25: [unresolved-attribute] unresolved-attribute: Unresolved attribute `TelegramError` on type `ModuleType`

✅ Fixed issues: none

Unchanged: 4653 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/security Security vulnerability or hardening P1 High — major feature broken, no workaround comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter labels May 19, 2026
teknium1 pushed a commit that referenced this pull request May 29, 2026
…SERS is empty

The _on_reaction approval handler used:

    if self._allowed_user_ids and sender not in self._allowed_user_ids:

When MATRIX_ALLOWED_USERS is not configured, _allowed_user_ids is an
empty set. The short-circuit on the empty set caused the deny block to
never execute, allowing any Matrix room member to approve or deny tool
calls via ✅/❎ reactions — even users that run.py's _is_user_authorized
would reject for regular messages.

Fix mirrors the Telegram _is_callback_user_authorized fix (commit
89d3205, PR #28494): deny by default when no allowlist is configured,
unless GATEWAY_ALLOW_ALL_USERS=true is explicitly set.
KKT-OPT pushed a commit to KKT-OPT/hermes-agent that referenced this pull request May 31, 2026
…SERS is empty

The _on_reaction approval handler used:

    if self._allowed_user_ids and sender not in self._allowed_user_ids:

When MATRIX_ALLOWED_USERS is not configured, _allowed_user_ids is an
empty set. The short-circuit on the empty set caused the deny block to
never execute, allowing any Matrix room member to approve or deny tool
calls via ✅/❎ reactions — even users that run.py's _is_user_authorized
would reject for regular messages.

Fix mirrors the Telegram _is_callback_user_authorized fix (commit
89d3205, PR NousResearch#28494): deny by default when no allowlist is configured,
unless GATEWAY_ALLOW_ALL_USERS=true is explicitly set.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P1 High — major feature broken, no workaround platform/telegram Telegram bot adapter type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants