Skip to content

fix: pass security credentials to external A2A sub-agents - #3636

Open
2862282695gjh-afk wants to merge 1 commit into
ModelEngine-Group:developfrom
2862282695gjh-afk:fix/a2a-security-v2
Open

fix: pass security credentials to external A2A sub-agents#3636
2862282695gjh-afk wants to merge 1 commit into
ModelEngine-Group:developfrom
2862282695gjh-afk:fix/a2a-security-v2

Conversation

@2862282695gjh-afk

Copy link
Copy Markdown

Problem

When a Nexent agent calls an external A2A sub-agent via the SDK execution path (ExternalA2AAgentProxy), the configured security credentials are not sent in the request headers, causing 403 Forbidden from external agents that require authentication (e.g., X-HW-ID + X-HW-APPKEY, Bearer JWT).

Root Cause

The backend a2a_client_service.call_agent already handles security credentials via _build_security_request_parts. However, the SDK execution path (managed agents, used when a local agent calls an external A2A sub-agent) goes through ExternalA2AAgentProxy that only supports a simple Bearer token (api_key) — it never receives the configured security_credentials.

Data chain broken at 4 levels:

  1. query_external_sub_agents does not return security_credentials
  2. _build_external_agent_config does not read/pass credentials
  3. ExternalA2AAgentConfig / A2AAgentInfo have no security headers field
  4. _build_headers ignores securitySchemes

Fix (4 files, +90 lines)

backend/database/a2a_agent_db.py (+3 lines)

query_external_sub_agents returns security_schemes, security_requirements, security_credentials.

backend/agents/create_agent_info.py (+38 lines)

New _build_security_headers(agent):

  • Reads security_schemes + security_requirements + security_credentials
  • Builds headers per A2A securitySchemes spec:
    • apiKeySecurityScheme (header) → headers[name] = credential
    • httpAuthSecurityScheme (bearer/basic) → Authorization: "<scheme> <credential>"
  • Supports wrapper + flat scheme format, case-insensitive location
  • _build_external_agent_config passes result as custom_headers

sdk/nexent/core/agents/agent_model.py (+6 lines)

  • ExternalA2AAgentConfig adds custom_headers field
  • to_a2a_agent_info() passes custom_headers

sdk/nexent/core/agents/a2a_agent_proxy.py (+4 lines)

  • A2AAgentInfo adds custom_headers field
  • _build_headers() merges custom_headers

Supported Auth

  • apiKey in header: any name (X-HW-ID, X-HW-APPKEY, etc.) ✅
  • httpAuth: Bearer/basic/JWT → Authorization ✅
  • Mixed combinations ✅
  • Wrapper + flat scheme formats ✅

Tests

test/backend/agents/test_a2a_security_headers.py:

  • apiKey double-header (X-HW-ID + X-HW-APPKEY)
  • httpAuth Bearer JWT
  • No credentials → empty

🤖 Generated with Claude Code

@2862282695gjh-afk
2862282695gjh-afk force-pushed the fix/a2a-security-v2 branch 4 times, most recently from 0f8bbff to 157f39a Compare August 12, 2026 08:05
@codecov

codecov Bot commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@2862282695gjh-afk
2862282695gjh-afk force-pushed the fix/a2a-security-v2 branch 11 times, most recently from 43394b6 to badbf54 Compare August 13, 2026 02:40
Co-Authored-By: Claude <noreply@anthropic.com>
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.

2 participants