Skip to content

fix(gateway): honor config-driven access policies over legacy env fallbacks#34515

Closed
Frowtek wants to merge 1 commit into
NousResearch:mainfrom
Frowtek:fix/gateway-honor-config-access-policies
Closed

fix(gateway): honor config-driven access policies over legacy env fallbacks#34515
Frowtek wants to merge 1 commit into
NousResearch:mainfrom
Frowtek:fix/gateway-honor-config-access-policies

Conversation

@Frowtek

@Frowtek Frowtek commented May 29, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes gateway authorization so config-driven access policies are enforced before the legacy env-based fallback.

Before this change, documented platform policies such as dm_policy, allow_from, group_policy, and group_allow_from could be ignored when no env allowlist was set, causing the gateway to deny requests before adapter-level policy logic could run. This PR aligns gateway auth with the configured platform policy surface and keeps unauthorized DM behavior consistent with those policies.

Related Issue

N/A

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Security fix
  • Documentation update
  • Tests (adding or improving test coverage)
  • Refactor (no behavior change)
  • New skill (bundled or hub)

Changes Made

  • Added gateway-side evaluation for config-driven access policies in gateway/run.py
  • Applied config policy handling for WECOM, WEIXIN, YUANBAO, and QQBOT
  • Updated unauthorized DM behavior resolution so allowlist / disabled policies do not fall through to pairing
  • Added regression coverage in tests/gateway/test_unauthorized_dm_behavior.py for:
    • WeCom DM allowlist authorization
    • WeCom unauthorized DM ignore behavior
    • WeCom per-group sender allowlist authorization
    • Weixin group allowlist authorization
    • Yuanbao open DM authorization
    • QQ group allowlist authorization
    • Config-driven unauthorized DM behavior resolution

How to Test

  1. Run the targeted gateway/platform regression suite:
    • tests/gateway/test_unauthorized_dm_behavior.py
    • tests/gateway/test_wecom.py
    • tests/gateway/test_weixin.py
    • tests/gateway/test_qqbot.py
    • tests/gateway/test_platform_registry.py
    • tests/gateway/test_telegram_group_gating.py
    • tests/gateway/test_whatsapp_group_gating.py
    • tests/test_yuanbao_pipeline.py
  2. Confirm that config-only access policies authorize the expected DM/group flows without requiring env allowlists.
  3. Confirm that unauthorized DMs under config allowlists are ignored instead of triggering pairing.

Checklist

Code

  • I've read the Contributing Guide
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

Test result for the targeted regression/platform suite:

  • 505 passed, 4 warnings

Warnings were pre-existing runtime warnings in tests/gateway/test_qqbot.py and are not caused by this change.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/wecom WeCom / WeChat Work adapter platform/qqbot QQ Bot adapter area/auth Authentication, OAuth, credential pools labels May 29, 2026
teknium1 added a commit that referenced this pull request May 29, 2026
…#34515)

Config-driven platform policies (dm_policy / group_policy / allow_from /
group_allow_from) for WeCom, Weixin, Yuanbao, and QQBot now work without
also setting a PLATFORM_ALLOWED_USERS env var.

These adapters enforce their access policy at intake — a message is dropped
inside the adapter and never dispatched unless it already passed the policy.
The gateway's env-based check (_is_user_authorized) ran afterward and, with
no env allowlist set, fell through to an env-only default-deny — silently
rejecting `dm_policy: open` and config-only allowlists the adapter had
already authorized.

Rather than re-implement each adapter's policy a second time in run.py
(which would drift), adapters that own their gate now declare it via a new
BasePlatformAdapter.enforces_own_access_policy property (default False). The
gateway trusts that flag and skips the env-only default-deny for those
platforms. Env allowlists still take precedence when set.

Also resolves unauthorized DM behavior from config dm_policy so allowlist /
disabled policies drop unauthorized DMs silently instead of leaking pairing
codes, while an explicit pairing policy opts back in.

Co-authored-by: Frowtek <frowte3k@gmail.com>
@teknium1

Copy link
Copy Markdown
Contributor

Merged via #34572#34572

Thanks for catching this, @Frowtek. The bug was real and confirmed on main: WeCom, Weixin, Yuanbao, and QQBot enforce their dm_policy/group_policy at adapter intake, but the gateway's _is_user_authorized re-checked afterward and fell through to an env-only default-deny when no PLATFORM_ALLOWED_USERS was set — silently rejecting dm_policy: open and config-only allowlists.

We took your fix in a slightly different shape to avoid maintaining a second copy of each adapter's policy logic in gateway/run.py (which would drift from the adapters over time). Instead, adapters that own their access gate now declare a single enforces_own_access_policy flag on BasePlatformAdapter, and the gateway trusts it. Your dm_policy-aware unauthorized-DM behavior fix was kept. Your authorship is preserved in git via a Co-authored-by trailer on the salvage commit (fd09b2c55 on main), and you've been added to the contributor map.

Closing in favor of the merged PR. Appreciate the contribution!

KKT-OPT pushed a commit to KKT-OPT/hermes-agent that referenced this pull request May 31, 2026
…NousResearch#34515)

Config-driven platform policies (dm_policy / group_policy / allow_from /
group_allow_from) for WeCom, Weixin, Yuanbao, and QQBot now work without
also setting a PLATFORM_ALLOWED_USERS env var.

These adapters enforce their access policy at intake — a message is dropped
inside the adapter and never dispatched unless it already passed the policy.
The gateway's env-based check (_is_user_authorized) ran afterward and, with
no env allowlist set, fell through to an env-only default-deny — silently
rejecting `dm_policy: open` and config-only allowlists the adapter had
already authorized.

Rather than re-implement each adapter's policy a second time in run.py
(which would drift), adapters that own their gate now declare it via a new
BasePlatformAdapter.enforces_own_access_policy property (default False). The
gateway trusts that flag and skips the env-only default-deny for those
platforms. Env allowlists still take precedence when set.

Also resolves unauthorized DM behavior from config dm_policy so allowlist /
disabled policies drop unauthorized DMs silently instead of leaking pairing
codes, while an explicit pairing policy opts back in.

Co-authored-by: Frowtek <frowte3k@gmail.com>
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 P2 Medium — degraded but workaround exists platform/qqbot QQ Bot adapter platform/wecom WeCom / WeChat Work adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants