fix(acp): validate method_id in authenticate against advertised provider (#9438) - #9470
Closed
LarHope wants to merge 1 commit into
Closed
fix(acp): validate method_id in authenticate against advertised provider (#9438)#9470LarHope wants to merge 1 commit into
LarHope wants to merge 1 commit into
Conversation
…der (NousResearch#9438) HermesACPAgent.authenticate() previously accepted any method_id as long as some provider was resolvable, so a client could send an arbitrary or stale id and still be authenticated. initialize() advertises exactly one AuthMethodAgent whose id is the resolved provider, so authenticate() must now match against that same id. Changes: - Add a module-level _canonical_provider_id() helper that strips + lowercases both sides of the comparison, so initialize() and authenticate() route the provider spelling through the same path. - authenticate() returns None when no provider is configured, when method_id is not a non-empty string, or when the canonicalized method_id does not match the advertised provider. - Replace the has_provider() monkeypatch in existing tests with a detect_provider() monkeypatch and add regressions for: unknown method_id rejection (the reported bug), case-insensitive matching, non-string method_id, and advertised/authenticate canonicalization agreement.
Collaborator
Contributor
|
Thanks for the contribution, @LarHope! This fix has already landed on This was also flagged by @alt-glitch in the review thread above. Evidence:
Closing as duplicate — the fix is in. Thanks again for the report and clean reproduction! Automated review by hermes-sweeper. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #9438
What does this PR do?
HermesACPAgent.authenticate()ignored themethod_idargument — it returnedAuthenticateResponse()for any requested auth method as long as some provider was configured. Meanwhileinitialize()advertises exactly oneAuthMethodAgentwhoseidis the resolved provider. This PR makesauthenticate()matchmethod_idagainst that same advertised id, so stale/unknown method ids are rejected.To prevent drift between the id
initialize()publishes and the oneauthenticate()compares against, both paths now route the provider spelling through a shared_canonical_provider_id()helper (strip + lowercase + None-guard). Previouslyauthenticate()implicitly depended ondetect_provider()always returning canonical casing — a silent cross-module invariant flagged during review.Related Issue
Fixes #9438
Type of Change
Changes Made
acp_adapter/server.py— add_canonical_provider_id()helper;initialize()canonicalizes the advertised id;authenticate()returnsNonewhen no provider is configured,method_idis not a non-empty string, or the canonicalizedmethod_iddoes not equal the advertised provider (logged at INFO).tests/acp/test_server.py— replace thehas_providermonkeypatch withdetect_provider(whichauthenticate()now uses directly) and add regressions: unknown method_id rejection, case-insensitive match, non-string method_id, and initialize/authenticate canonicalization agreement.Diff: 2 files, +71/-9.
How to Test
Reproduction from the issue:
```python
import asyncio
from unittest.mock import MagicMock
from acp_adapter.server import HermesACPAgent
from acp_adapter.session import SessionManager
import acp_adapter.server as server_mod
async def main():
agent = HermesACPAgent(session_manager=SessionManager(agent_factory=lambda: MagicMock()))
server_mod.detect_provider = lambda: 'openrouter'
print('matching:', (await agent.authenticate(method_id='openrouter')) is not None)
print('bogus: ', (await agent.authenticate(method_id='definitely-not-advertised')) is not None)
asyncio.run(main())
```
Before this PR:
```
matching: True
bogus: True
```
After:
```
matching: True
bogus: False
```
Run the ACP server test module:
```bash
pytest tests/acp/test_server.py -v
```
57 tests pass (52 existing + 5 updated/new around
authenticate).Checklist
Code
acp_adapter/server.pyauthpytest tests/acp/test_server.py -v— all passDocumentation & Housekeeping
Follow-up (not in this PR)
A follow-up could cache the advertised
method_idon the connection/session atinitialize()time instead of recomputingdetect_provider()atauthenticate()time. That would also close a latent TOCTOU between initialize and authenticate (provider credentials changing mid-handshake). Happy to open a separate PR if maintainers want that — keeping this one minimal and focused on the reported issue.