fix(acp): forward allowlisted client headers on all ACP paths - #384
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes ACP header propagation by ensuring allowlisted client x-* headers are forwarded to agent ACP servers on ACP paths where get_headers(agent) was previously called without explicit request_headers.
Changes:
- Add a fallback in
AgentACPService.get_headers()to use inboundRequest.headerswhenrequest_headersis not provided. - Preserve existing behavior when
request_headersis explicitly passed (including opting out by passing{}).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
rehmanmuradali
marked this pull request as draft
July 29, 2026 12:22
rehmanmuradali
marked this pull request as ready for review
July 29, 2026 12:26
rehmanmuradali
force-pushed
the
fix/acp-forward-client-headers
branch
2 times, most recently
from
July 31, 2026 07:56
775527b to
15e0cbb
Compare
rehmanmuradali
enabled auto-merge (squash)
July 31, 2026 08:02
jenniechung
approved these changes
Aug 3, 2026
MeeSo-Scale
approved these changes
Aug 3, 2026
Several ACP paths call get_headers(agent) without threading the inbound
client headers, so filter_request_headers(None) returned {} and no
allowlisted client x-* headers reached the agent. Fall back to the
inbound request headers so the existing allowlist forwards them.
Co-authored-by: Cursor <cursoragent@cursor.com>
Assert that omitting request_headers forwards allowlisted inbound x-*
headers (dropping sensitive ones), and that passing {} forwards none.
Co-authored-by: Cursor <cursoragent@cursor.com>
rehmanmuradali
force-pushed
the
fix/acp-forward-client-headers
branch
from
August 3, 2026 22:01
15e0cbb to
bda8767
Compare
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.
Summary
get_headers(agent)is called from several ACP paths (send_message_stream,create_task, cancel/interrupt) without threading the inbound client headers.filter_request_headers(None)returned{}, so no allowlisted clientx-*headers ever reached the agent.Test plan
send_message_stream) and confirm allowlisted clientx-*headers now reach the agent.request_headersis explicitly passed.Made with Cursor
Greptile Summary
This PR fixes a bug where allowlisted
x-*client headers were never forwarded to the agent on most ACP paths becauseget_headers()receivedrequest_headers=Noneandfilter_request_headers(None)returned{}. The fix adds a four-line fallback that readsself._request.headerswhen no headers are explicitly passed, consistent with howget_delegation_headers()already reads the same source.get_headers()now falls back todict(self._request.headers)whenrequest_headers is None; the existingBLOCKED_HEADERS+x-*-allowlist filtering infilter_request_headers()is unchanged, so credentials (authorization,x-api-key, etc.) remain blocked.request_headers={}explicitly opt out of the fallback — the empty dict short-circuitsfilter_request_headersand no client headers are forwarded.authorization,x-api-key) are not forwarded.Confidence Score: 5/5
Safe to merge. The change is minimal and scoped to a single fallback in
get_headers(); the security-sensitive filtering path (filter_request_headers+BLOCKED_HEADERS) is untouched.The four-line fallback is consistent with how
get_delegation_headers()already readsself._request.headers. Credential headers remain blocked by the existing allowlist. The two new tests directly exercise both the fallback and the opt-out paths with correct assertions on sensitive header names.Files Needing Attention: No files require special attention.
Important Files Changed
get_headers()so inboundx-*client headers are forwarded when callers don't explicitly passrequest_headers. Security filtering viafilter_request_headersandBLOCKED_HEADERSis unchanged.request_headersuses inbound headers) and the explicit empty-dict opt-out path. Both cover the security-critical header filtering cases.Sequence Diagram
sequenceDiagram participant Client participant ACPPath as ACP Path participant GetHeaders as get_headers participant FilterHeaders as filter_request_headers participant AgentPod as Agent Pod Client->>ACPPath: "HTTP request with x-* headers" ACPPath->>GetHeaders: get_headers(agent) alt Before fix GetHeaders->>FilterHeaders: filter_request_headers(None) FilterHeaders-->>GetHeaders: "{} empty dict" else After fix GetHeaders->>GetHeaders: "request_headers = dict(self._request.headers)" GetHeaders->>FilterHeaders: filter_request_headers(inbound headers) FilterHeaders-->>GetHeaders: "allowlisted x-* headers only" end GetHeaders-->>ACPPath: merged headers with delegation + auth + x-request-id ACPPath->>AgentPod: JSON-RPC with forwarded allowlisted headersReviews (5): Last reviewed commit: "test(acp): cover get_headers inbound-hea..." | Re-trigger Greptile