Repository navigation
Add ug --header / UG_HEADERS for per-launch request headers - #1248
Conversation
ae23db6 to
6103e12
Compare
|
/ug-review |
Polly AI ReviewBlocking issues
Security vulnerabilitiesThe first blocker affects authentication-header integrity. No additional credential leak, authorization bypass, or exploitable injection was established. Invalid control acceptance alone does not demonstrate request smuggling. Non-blocking notes
ApproachKeep the shared parser and launch-only Codex overlay. A shared case-insensitive, add-only merge helper would enforce the same precedence across request clients without duplicating Codex’s private helper. SummaryDiff size (computed): 16 files; +184 / -2 lines (186 changed text lines); 0 binary files.
Shares use additions + deletions, including generated text and lockfiles. Binary files have no line count. Tests include fixtures/helpers under test paths and colocated test/spec files; categories are path-based, not coverage measurements. ChangesThe change adds the flag/environment parser, launch-scoped Codex overlays, header propagation through ug’s request clients, documentation, and focused tests. No dependencies or generated assets change. The size is proportional to the cross-client outcome. The main implementation simplification is centralizing header precedence instead of repeating dictionary updates and spreads. Added source comments are concise. TestsTest-by-test assessmentNo pytest suite was run during this review. Network-free probes verified header replacement and value-serialization behavior; the PR’s reported suite results were not independently reproduced.
Existing launch-header export, managed-provider-header, request-authentication, OAuth, routing, and MCP tests provide reusable scenarios. They do not establish propagation of this newly introduced variable across every changed client. Child inheritance, Windows Codex, and the legacy profile path remain unverified; these gaps alone do not establish additional bugs. For local verification, run ScopeAll inspected changes support per-launch request headers. No clearly unrelated changes were found. Claude’s native header integration remains explicitly outside this PR; the documented legacy-Codex and Windows limitations are validation boundaries, not unrelated scope. Automated review by Polly · workflow run |
`ug --header "Name: value"` (repeatable) or `UG_HEADERS` (one `Name: value` per line) adds headers to one launch's Databricks requests, e.g. a LiteSwap `x-databricks-traffic-id`: - Codex: added to the launch's `-c` provider headers, plain and smart-routed, never to a config file, so concurrent launches don't share them. A header ug or the admin already sends keeps its value. - ug's own requests: workspace APIs, the MCP proxy, web search, smart-routing route selection, and the MCP OAuth probe. ug validates the value up front, so a malformed line fails the command before any request. Co-authored-by: Isaac <no-reply@databricks.com>
Address review feedback on `ug --header` / UG_HEADERS: - ug's own requests (workspace APIs, web search, smart routing, the MCP OAuth probe) add only header names they don't already set, in any case, so a launch header can no longer replace the bearer `Authorization`, `Content-Type`, or a caller's header. One `with_ug_headers` helper does it. - A later line replaces an earlier one with the same name in any case, so `X-A` and `x-a` are never both sent and `--header` overrides an inherited value. - Header values must be sendable: no control characters, Latin-1 only. - A bad `--header` still fails the command, but the error names only the flag's position, never the value. A bad inherited UG_HEADERS line is skipped with a warning instead of blocking every command, `ug revert` included, and ug hands agents only the valid lines. - The pre-0.134 Codex `--profile` launch warns that the headers aren't sent instead of dropping them silently. Co-authored-by: Isaac <no-reply@databricks.com>
Spread `ug_headers()` first in each urllib header dict instead of a `with_ug_headers` helper: urllib capitalizes names and keeps the last value, so ug's own headers still win in any case. Drop the inherited-line warning and rewrite, since the parser already skips bad lines, and the pre-0.134 Codex warning, since ug requires Codex 0.145. Co-authored-by: Isaac <no-reply@databricks.com>
68efcd3 to
39f7522
Compare
🥞 Stacked PR
Use this link to review incremental changes.
Summary
ug --header "Name: value"(repeatable) orUG_HEADERS(oneName: valueper line) adds headers to one launch's Databricks requests, for example a LiteSwap traffic ID:ug --header "x-databricks-traffic-id: testenv://liteswap/<pod>" codex-cprovider headers, for both plain and smart-routed launches. They're never written to~/.codex/ucode.config.toml, so concurrent launches don't share them. A header name that ug or the admin already sends keeps its value. Codex merges config layers leaf by leaf, so a new name from-csurvives/etc/codex/managed_config.toml, and a name the managed file already sets wins.databricks.py), the MCP proxy, web search, smart-routing route selection, and the MCP OAuth probe. The MCP proxy and web search run as children of the agent and inheritUG_HEADERS. A header name ug already sets, such asAuthorizationorContent-Type, keeps its value in any case: each request listsUG_HEADERSfirst and ug's own headers after, and urllib keeps the last value for a name.ug_headers.py). A valid line has an HTTP token name and a value with no control characters, in Latin-1. A later line replaces an earlier one with the same name in any case.--headerfails the command. The error names only the flag's position, never the value.UG_HEADERSline is skipped, so it never blocks a command,ug revertincluded.Claude Code support is in the stacked PR #1240. Claude takes
ANTHROPIC_CUSTOM_HEADERSwhole from managed settings, so it needs a mod.Testing
test_ug_headers.py: the parser, plus--headerappending toUG_HEADERSand rejecting a malformed line.test_agent_codex.py: a plain launch sends the header in-cand leaves the profile file unchanged, and a smart-routed launch adds new names while keeping existing ones.test_databricks.py: ug's GET and POST helpers carry the headers.test_e2e_user_agentis excluded because it fails on this dev box, where managed settings override its capture server's URL. Ruff and ty are clean onsrc/.--profilepath (before 0.134, below ug's 0.145 minimum) doesn't get the headers.ug codexlaunch against the gateway, and Windows Codex.This pull request and its description were written by Isaac.