Skip to content

Conversation

@jonpspri
Copy link
Collaborator

Summary

  • Fixes authentication credential handling in A2A agent invocation - credentials were stored encrypted but never decrypted before being passed to backend agents
  • Adds regression tests for Basic Auth, Bearer Token, and X-API-Key authentication
  • Adds demo A2A agent script with CLI support for all authentication types

Depends on: #2001 (must be merged first)

Closes #2002

Changes

Core Fix (mcpgateway/services/a2a_service.py)

  • Import decode_auth (was commented out)
  • Check for any configured auth type (not just api_key and bearer)
  • Decrypt auth_value using decode_auth() before applying headers

Tests (tests/unit/mcpgateway/services/test_a2a_service.py)

  • test_invoke_agent_with_basic_auth - verifies Basic Auth header is decoded and passed
  • test_invoke_agent_with_bearer_auth - verifies Bearer token is decoded and passed
  • test_invoke_agent_with_custom_headers - verifies X-API-Key headers are decoded and passed

Demo Script (scripts/demo_a2a_agent_auth.py)

  • New CLI-based demo agent supporting --auth-type {none,basic,bearer,apikey}
  • Auto-generates secure credentials when not provided
  • Supports auto-registration with ContextForge via --auto-register

Makefile

  • make demo-a2a-up - Start 3 demo agents (basic, bearer, apikey) with auto-registration
  • make demo-a2a-down - Stop all demo agents
  • make demo-a2a-status - Show agent status

Test plan

  • Run make test-unit - all tests pass
  • Run make demo-a2a-up with dev server running
  • Verify agents appear in Admin UI under A2A Agents
  • Use "Test" button to invoke each agent type
  • Verify HTTP 200 responses (not 401)

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings January 10, 2026 18:51
Copy link
Contributor

Copilot AI left a 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:
Copy link

Copilot AI Jan 10, 2026

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.

Suggested change
def register_agent(port: int) -> str | None:
def register_agent(port: int) -> Optional[str]:

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

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
Copy link

Copilot AI Jan 10, 2026

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.

Suggested change
# Standard

Copilot uses AI. Check for mistakes.
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
Copy link

Copilot AI Jan 10, 2026

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.

Suggested change
# Standard

Copilot uses AI. Check for mistakes.

def create_jwt_token(username: str = "[email protected]") -> str:
"""Create a JWT token for ContextForge authentication."""
import datetime as dt
Copy link

Copilot AI Jan 10, 2026

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'.

Copilot uses AI. Check for mistakes.
@jonpspri jonpspri force-pushed the 2002-a2a-authentication branch 5 times, most recently from bc5360f to 9da14fd Compare January 11, 2026 19:32
@crivetimihai crivetimihai force-pushed the 2002-a2a-authentication branch from 9da14fd to 4b744d1 Compare January 12, 2026 02:08
…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]>
@crivetimihai crivetimihai force-pushed the 2002-a2a-authentication branch from 4b744d1 to 8678902 Compare January 12, 2026 02:30
@crivetimihai crivetimihai self-assigned this Jan 12, 2026
@crivetimihai crivetimihai merged commit f658e57 into main Jan 12, 2026
52 checks passed
@crivetimihai crivetimihai deleted the 2002-a2a-authentication branch January 12, 2026 02:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]:Unable to authenticate and use Basic Auth and X-API-Key A2A agents

3 participants