fix(privacy-shield): isolate upstream authorization - #2973
Open
tang-vu wants to merge 2 commits into
Open
Conversation
This was referenced Aug 22, 2026
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.
Why this matters
Privacy Shield authenticates clients with its own Bearer token, then proxies to a separate trust boundary.
_build_upstream_headerscopied the inboundAuthorizationfield before optionally adding the provider key. WithTARGET_API_KEY=not-needed, the Shield credential leaked to the model upstream; with a provider key configured, HTTPX combined both values into one invalid Authorization header.Root cause: Shield-bound credentials were treated as ordinary end-to-end application headers, and the differently-cased replacement key did not overwrite the lowercase dictionary entry.
Behavioral invariant: the Shield Bearer token terminates at the Shield boundary; upstream receives no Authorization header unless
TARGET_API_KEYsupplies exactly one provider credential.Overlap check
Searched open and closed upstream PRs for Privacy Shield authorization/credential/upstream-header/token-forwarding terms and inspected PRs touching
ods/extensions/services/privacy-shield/proxy.py. Current PRs address response information leakage and a missing await, not cross-boundary authorization. No existing PR enforces this invariant.What changed
Authorizationwhile constructing upstream headers.Bearer <TARGET_API_KEY>when a provider key is configured.Validation
pytest tests/test_streaming_proxy.py::TestUpstreamAuthorization -q— 2 passed.pytest tests -q— 54 passed.python -m py_compile proxy.py tests/test_streaming_proxy.py— passed.git diff --check— passed.Platform, risk, and rollback
This affects the shared Python proxy on Linux, macOS, and Windows/WSL. Other client headers and PII processing remain unchanged. Deployments that intentionally reused the Shield credential as an upstream credential must set
TARGET_API_KEYexplicitly; that separation is the intended configuration contract. Rollback is one commit and needs no data migration.Batch compatibility
Validated as an independent ten-PR batch from upstream
main6ff9b4fc5190099705043acaab7e9b6ad9c8b8f1. The final PR heads merged without conflicts in this order: #2964 -> #2965 -> #2967 -> #2969 -> #2970 -> #2971 -> #2972 -> #2973 -> #2974 -> #2975. The resulting local synthetic merge head is4ae60eadad9696a9accb735aad71af87d2be802d.Combined validation on that exact tree:
git diff --check: passed.The scopes are behaviorally independent. The stated order is the tested rollback/merge sequence for shared-file changes; each PR remains individually useful and revertible.