Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions agentex/src/domain/services/agent_acp_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,10 @@ async def get_headers(
agent: AgentEntity,
request_headers: dict[str, str] | None = None,
) -> dict[str, str]:
# Fall back to inbound request headers when callers don't pass them, so
# allowlisted client x-* headers are forwarded to the agent.
if request_headers is None:
request_headers = dict(self._request.headers)
Comment thread
rehmanmuradali marked this conversation as resolved.
filtered_request_headers = filter_request_headers(request_headers)
delegation_headers = self.get_delegation_headers(agent)
auth_headers = await self.get_agent_auth_headers(agent)
Expand Down
55 changes: 55 additions & 0 deletions agentex/tests/unit/services/test_agent_acp_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,61 @@ async def test_get_headers_server_request_id_wins_over_passthrough(
assert headers["x-request-id"] != "client-request-id"
assert len(headers["x-request-id"]) > 0

async def test_get_headers_falls_back_to_inbound_request_headers(
self,
agent_acp_service,
mock_request,
sample_agent,
):
"""When request_headers is omitted, safe inbound x-* headers are forwarded."""
mock_request.state.principal_context = None
mock_request.state.agent_identity = None
mock_request.headers = {
"x-trace-id": "trace-789",
"x-user-id": "user-123",
"x-api-key": "must-not-forward",
"authorization": "Bearer must-not-forward",
"user-agent": "must-not-forward",
}

with patch.object(
agent_acp_service,
"get_agent_auth_headers",
new=AsyncMock(return_value={}),
):
headers = await agent_acp_service.get_headers(sample_agent)

assert headers["x-trace-id"] == "trace-789"
assert headers["x-user-id"] == "user-123"
assert "x-api-key" not in headers
assert "authorization" not in headers
assert "user-agent" not in headers

async def test_get_headers_empty_request_headers_forwards_none(
self,
agent_acp_service,
mock_request,
sample_agent,
):
"""Passing an explicit empty dict forwards no client headers (no fallback)."""
mock_request.state.principal_context = None
mock_request.state.agent_identity = None
mock_request.headers = {"x-trace-id": "should-not-be-used"}

with patch.object(
agent_acp_service,
"get_agent_auth_headers",
new=AsyncMock(return_value={}),
):
headers = await agent_acp_service.get_headers(
sample_agent,
request_headers={},
)

assert "x-trace-id" not in headers
# Only the server-generated x-request-id should remain.
assert set(headers.keys()) == {"x-request-id"}

async def test_send_message_success_data(
self,
agent_acp_service,
Expand Down
Loading