-
Notifications
You must be signed in to change notification settings - Fork 464
fix(#2002): properly decode and pass A2A agent authentication credentials #2024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a critical authentication bug where A2A agent credentials were stored encrypted but never decrypted before being passed to backend agents, causing HTTP 401 errors. The fix adds proper credential decryption using decode_auth() before applying authentication headers.
Changes:
- Core authentication fix: Import and use
decode_auth()to decrypt stored credentials before HTTP requests - Comprehensive regression tests for Basic Auth, Bearer Token, and X-API-Key authentication
- New demo A2A agent scripts with CLI support for all authentication types and auto-registration
- Enhanced admin UI with modal dialog for testing A2A agents with custom queries
- Makefile targets for managing demo agents
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| mcpgateway/services/a2a_service.py | Core fix: imports decode_auth, checks for any auth type, decrypts auth_value before applying headers; adds error handling for tool creation |
| tests/unit/mcpgateway/services/test_a2a_service.py | Adds three regression tests for Basic Auth, Bearer Token, and custom header authentication |
| tests/unit/mcpgateway/test_issue_840_a2a_agent.py | New comprehensive test suite for Issue #840 covering A2A agent testing and tool listing |
| scripts/demo_a2a_agent_auth.py | New demo agent supporting multiple auth types with CLI interface and auto-registration |
| scripts/demo_a2a_agent.py | New basic demo agent for Issue #840 testing |
| mcpgateway/templates/admin.html | Adds A2A test modal with query input field for user-provided test queries |
| mcpgateway/static/admin.js | Implements A2A test modal functionality with proper event handling and cleanup |
| mcpgateway/admin.py | Updates test endpoint to accept user-provided query from request body |
| mcpgateway/services/tool_service.py | Ensures A2A tools default to "public" visibility for Global Tools Tab |
| Makefile | Adds demo-a2a-up/down/status targets for managing demo agents |
| mcpgateway/services/gateway_service.py | Code formatting improvements (line length) |
| mcpgateway/services/export_service.py | Code formatting improvements (line length) |
| mcpgateway/services/event_service.py | Adds misplaced comment marker |
| mcpgateway/version.py | Adds misplaced comment marker |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return jwt.encode(payload, JWT_SECRET, algorithm="HS256") | ||
|
|
||
|
|
||
| def register_agent(port: int) -> str | None: |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type hint str | None uses Python 3.10+ union syntax. For compatibility with Python 3.9, this should use Optional[str] from the typing module instead. Note that Optional[str] is already imported at the top of the file.
| def register_agent(port: int) -> str | None: | |
| def register_agent(port: int) -> Optional[str]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not make any changes.
| except (ModuleNotFoundError, AttributeError) as e: | ||
| # ModuleNotFoundError: redis package not installed | ||
| # AttributeError: 'redis' exists but isn't a proper package (e.g., shadowed by a file) | ||
| # Standard |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "# Standard" appears to be misplaced here. It seems like it should be associated with the import statement on line 92, but the import is inside an except block. This comment placement is confusing and should either be moved to line 74 before the import logging statement, or removed if it's not adding value in this context.
| # Standard |
| except (ModuleNotFoundError, AttributeError) as e: | ||
| # ModuleNotFoundError: redis package not installed | ||
| # AttributeError: 'redis' exists but isn't a proper package (e.g., shadowed by a file) | ||
| # Standard |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment "# Standard" appears to be misplaced here. It seems like it should be associated with the import statement on line 74, but the import is inside an except block. This comment placement is confusing and should either be moved to line 61 before other imports, or removed if it's not adding value in this context.
| # Standard |
scripts/demo_a2a_agent_auth.py
Outdated
|
|
||
| def create_jwt_token(username: str = "[email protected]") -> str: | ||
| """Create a JWT token for ContextForge authentication.""" | ||
| import datetime as dt |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Module 'datetime' is imported with both 'import' and 'import from'.
bc5360f to
9da14fd
Compare
9da14fd to
4b744d1
Compare
…ials A2A agents configured with Basic Auth, Bearer Token, or X-API-Key authentication were failing with HTTP 401 because credentials were not being decrypted and passed to the backend agent. Changes: - Fix a2a_service.py to decode auth_value using decode_auth() before making HTTP requests (follows gateway_service pattern) - Handle all auth types (basic, bearer, authheaders) not just api_key/bearer - Fail fast with A2AAgentError if auth decryption fails (don't silently proceed with empty headers) - Add 3 regression tests for authenticated invocation - Add demo_a2a_agent_auth.py script for manual testing with CLI args - Add Makefile targets: demo-a2a-up, demo-a2a-down, demo-a2a-status - Fix pre-existing flake8 errors (unused variables, comparison to False) Closes #2002 Signed-off-by: Mihai Criveti <[email protected]>
4b744d1 to
8678902
Compare
Summary
Depends on: #2001 (must be merged first)
Closes #2002
Changes
Core Fix (
mcpgateway/services/a2a_service.py)decode_auth(was commented out)api_keyandbearer)auth_valueusingdecode_auth()before applying headersTests (
tests/unit/mcpgateway/services/test_a2a_service.py)test_invoke_agent_with_basic_auth- verifies Basic Auth header is decoded and passedtest_invoke_agent_with_bearer_auth- verifies Bearer token is decoded and passedtest_invoke_agent_with_custom_headers- verifies X-API-Key headers are decoded and passedDemo Script (
scripts/demo_a2a_agent_auth.py)--auth-type {none,basic,bearer,apikey}--auto-registerMakefile
make demo-a2a-up- Start 3 demo agents (basic, bearer, apikey) with auto-registrationmake demo-a2a-down- Stop all demo agentsmake demo-a2a-status- Show agent statusTest plan
make test-unit- all tests passmake demo-a2a-upwith dev server running🤖 Generated with Claude Code