feat(proxy/blockheaders): emit X-Pipelock-Block-Reason on every block path#469
Open
luckyPipewrench wants to merge 3 commits intofeat/block-reason-headerfrom
Open
feat(proxy/blockheaders): emit X-Pipelock-Block-Reason on every block path#469luckyPipewrench wants to merge 3 commits intofeat/block-reason-headerfrom
luckyPipewrench wants to merge 3 commits intofeat/block-reason-headerfrom
Conversation
First transport in the block-reason header rollout. Adds shared helpers (reasonFromScanner mapper, severityFromReason and retryFromReason classifiers, blockInfo and blockInfoFor constructors, writeBlockedError drop-in for http.Error) and refactors forward proxy's 9 block sites: envelope verify, scanner unavailable, missing host, header DLP, scanner result with hint, escalated scanner result, session-airlock detail, escalation level, and budget admission. Helper file is 100 percent covered. Existing forward proxy tests all pass with no parity regression. Subsequent commits stack the same pattern onto intercept, fetch, reverse, MCP HTTP, and WebSocket transports. Stacks on PR #467 (the schema and emit package). Merges back to main only after PR #467 lands.
…reverse, MCP HTTP, WebSocket Stacks the second batch onto the forward proxy refactor. Five transports now emit the X-Pipelock-Block-Reason header set on every block path. Fetch handler (the writeJSON-based path in proxy.go) lands as a separate stacked commit because its block sites use a different writer than http.Error and warrant their own focused review. Intercept: 14 block sites covering envelope verify, kill switch, authority mismatch, airlock, scanner result with hint, escalated scanner result, A2A header DLP, body-scan blocks (general DLP and A2A flavors), header secret, CEE block, escalation level, and envelope-injection failure. The 502 BadGateway upstream-error path stays unannotated since it is not a security block. Reverse: writeReverseProxyBlock signature gains a blockreason.Info parameter so every caller is forced to supply a reason. Seven call sites updated covering scanner unavailable, envelope verify, kill switch, URL DLP, header DLP, body-scan fail-closed and enforce paths, and envelope-injection blocked-error. MCP HTTP: method-not-allowed and compressed-response blocks both emit. WebSocket: 13 pre-upgrade http.Error sites use writeBlockedError; seven post-upgrade plwsutil.WriteCloseFrame sites carry the JSON document via Info.CloseFramePayload(), giving WebSocket transport parity through close frames instead of headers (per docs/specs/block-reason-header.md transport-coverage table). Free-text closeReason is preserved for receipt logging; only the wire payload swaps. session_api.go gets a small tierNone constant extraction unrelated to the header work; goconst tripped because the new package raised the cross-package none/transient/policy literal count over the threshold. Full proxy and mcp test suites pass with no parity regression. Stacks on PR #467.
Closes the transport refactor. Fetch handler now emits the X-Pipelock-Block-Reason header set on every block path, completing parity with forward, intercept, reverse, MCP HTTP, and WebSocket. Adds writeBlockedJSON helper (the writeJSON analogue of writeBlockedError). The fetch endpoint's block sites use writeJSON to deliver a structured FetchResponse; setting the header set before writeJSON keeps the response headers consistent with the JSON body's BlockReason field. Thirteen block sites refactored: envelope verify, airlock drain (twice — initial fetch and pre-budget recheck), session escalation level (twice), header secret, CEE block, envelope-injection failure, redirect/upstream blocked-error, compressed-response fail-closed, browser shield oversize, media policy, and three response-scan prompt-injection blocks (enforce, ask-no-approver, ask-deny). Status arg kept on the helper signature for forward compat with future non-403 fetch block paths. Full proxy test suite passes (38s, no parity regression). Lint clean. Stacks on PR #467.
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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
Wires the X-Pipelock-Block-Reason header set onto every pipelock block path. Stacks on PR #467 (the schema and emit package); merges back to main only after that PR lands.
Done-state criterion 3 of the v2.4 release spec: schema specified AND implemented across forward, intercept, fetch, reverse, MCP HTTP, and WebSocket. No transport split.
Coverage by transport
Helper layer
internal/proxy/blockheaders.goadds reasonFromScanner (maps scanner.Scanner* labels to blockreason.Reason), severityFromReason and retryFromReason classifiers (canonical per spec), blockInfo and blockInfoFor constructors, plus writeBlockedError (drop-in for http.Error) and writeBlockedJSON (drop-in for the fetch handler's writeJSON).Compatibility
Anti-scope-creep
Stacked on