Support bearer-token authentication in BuilderRWBufferFromHTTP - #110313
Support bearer-token authentication in BuilderRWBufferFromHTTP#110313serxa wants to merge 14 commits into
Conversation
Callers that authenticate with a bearer token currently splice an `Authorization: Bearer` entry into the header list themselves and must also remember not to pass HTTP Basic credentials, because both occupy the same header. The builder now owns that rule: `withBearerToken` attaches the header, and a non-empty token takes precedence over the Basic credentials passed to `create`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
UnityCatalog spliced the bearer into the header list itself and passed never-used HTTP Basic credentials alongside. The catalog helpers now take the token and hand it to the builder, which owns the header formatting and the bearer-over-Basic precedence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Workflow [PR], commit [8543461] Summary: ✅
AI ReviewSummaryThis PR moves bearer-token handling for the Unity and Paimon catalog HTTP paths into Findings
Final VerdictStatus: Minimum required action:
|
The token has one entry point now — the terminal create call — so a conflicting withBearerToken-plus-create state cannot be constructed. Three overloads cover the auth modes: Basic credentials, a bearer token, and both (the non-empty token wins; the two occupy the same `Authorization` header, so a request carries one or the other). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`create` appended the bearer `Authorization` header to the builder's `http_header_entries` member, so reusing a builder would carry over a stale token. Append it to a local copy passed to `ReadWriteBufferFromHTTP` instead, so `create` no longer mutates the builder. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`RestCatalog` (with `OneLakeCatalog`, `BigLakeCatalog`) and `PaimonRestCatalog` built the `Authorization: Bearer` header by hand and passed unused Basic credentials to `create`. `getAuthHeaders` now returns an `AuthHeaders` of a bearer token plus extra headers: the bearer goes to `create` and only genuine extra headers (a user-supplied `auth_header`, `x-goog-user-project`, `User-Agent`) stay in the header list. `OneLakeCatalog`'s pre-obtained token likewise moves from a spliced header to the bearer, so every catalog bearer now flows through `create`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`.create({})` brace-initializes both one-argument overloads, making such
calls ambiguous. Two overloads remain: `create(credentials)` and
`create(bearer_token, credentials)` (the non-empty token wins). The catalog
helper passes empty credentials explicitly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…http-builder-bearer-token
`.create({})` brace-initializes both one-argument overloads, making such calls
ambiguous. Two overloads remain: `create(credentials)` and
`create(bearer_token, credentials)` (the non-empty token wins). The catalog
call sites pass empty credentials explicitly.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A bearer-token overload of `create` would be ambiguous with
`create(credentials)` for `.create({})` call sites, and bearer-only callers
had to pass a throwaway empty credentials object because the buffer stores the
credentials by reference. A distinct `createWithBearerToken` removes the
ambiguity and needs no credentials argument; the single empty-credentials
object now lives once inside the builder instead of at every call site.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The previous commit renamed the declarations but left the out-of-line definitions on the old `create` names; align them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`getAuthHeaders` returned an `AuthHeaders` of a bearer token plus extra headers, so every `RestCatalog` call site had to unpack it. Match `PaimonRestCatalog`'s existing shape instead: `getAuthHeaders` appends its extra headers to a caller-owned list and returns the bearer token. The struct is gone and the call sites just forward their header list and the token to `createWithBearerToken`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…aders `createWithBearerToken` appends the `Authorization: Bearer` header internally without going through the `HTTPHeaderFilter` check, so a user-supplied `onelake_bearer_token` that contains a forbidden or malformed value could reach the request path unchecked. Add the same validation that `RestCatalog` applies to a user-supplied `auth_header` in its own constructor: call `validateAuthHeaders` with the synthetic `Authorization: Bearer <token>` header before storing the token. This restores the pre-refactor behavior where the value went through the header list and was subject to `http_forbid_headers` / CR-LF checks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolve the conflict in `RestCatalog.{h,cpp}`: master's `CatalogState`-based
auth refactor (atomic credential snapshots plus the ALTER framework
`prepareSettingsChanges`/`applySettingsChangesToState`, and `getAuthHeaders`
returning `HTTPHeaderEntries` from a state snapshot) superseded this branch's
`getAuthHeaders` simplification, so `RestCatalog.{h,cpp}` are taken from master.
The branch's remaining contribution is preserved: `createWithBearerToken` on
`BuilderRWBufferFromHTTP` and its adoption in `HTTPBasedCatalogUtils`,
`PaimonRestCatalog` and `UnityCatalog` (which master did not refactor).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Construct OneLakeCatalog with a bearer token containing a newline and assert the constructor rejects it with BAD_ARGUMENTS via validateAuthHeaders, before any request is issued. Locks the fix that routes a pre-obtained bearer token through http_forbid_headers validation instead of splicing it into the header list unchecked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered: 58/80 (72.50%) · Uncovered code |
|
📊 Cloud Performance Report ✅ AI verdict: The only flagged query is clickbench Q15 (+14.0%, median 215 -> 245 ms), which the deterministic gates already suppressed as within master's current variance band [191, 275] and left as not_sure. CPU time is essentially unchanged (2611 vs 2617 ms), so the extra wall time is cache/IO variance rather than added work. This PR changes only DataLake REST-catalog authentication (bearer token vs HTTP Basic credentials) and the shared HTTP read buffer — code Q15 never runs — so there is no plausible path from the diff to this query. Verdict stands: no real regression here. clickbenchFlagged queries (1 of 43)
Change = percent below ×2; the ratio of medians (×N faster/slower) beyond, where percent understates the scale. q-value = BH-FDR adjusted p; smaller is stronger evidence. MIRAI flags a query when q < fdr_q (default 0.10) — the value the verdict is based on. tpch_adapted_1_official🟢 No significant changes Debug info
|
BuilderRWBufferFromHTTPhad no way to authenticate with a bearer token: callers spliced anAuthorization: Bearerentry into the header list themselves and had to remember not to pass HTTP Basic credentials at the same time, because both occupy the same header.createnow takes the credential directly, in three overloads: Basic credentials, a bearer token, or both — with a non-empty token taking precedence, so the either/or rule lives in one place instead of in every caller.createalso appends the bearer header to a local copy of the header list rather than mutating the builder, so a builder can be reused without carrying over a stale token.Every bearer-token call site of the class is migrated to the new overloads:
HTTPBasedCatalogUtilsandUnityCatalog: built the header by hand and passed never-used HTTP Basic credentials alongside; now callcreatewith the token.RestCatalog,OneLakeCatalog,BigLakeCatalog:getAuthHeadersnow returns anAuthHeaders(a bearer token plus extra headers). The bearer goes tocreate; only genuine extra headers (a user-suppliedauth_header,x-goog-user-project,User-Agent) stay in the header list.OneLakeCatalog's pre-obtained token also moved from a spliced header to the bearer.PaimonRestCatalog: thebearertoken provider (thedlfrequest-signing branch keeps its own signed headers).Out of scope — different transport (plain Poco requests or S3-client headers), not
BuilderRWBufferFromHTTP:OpenAIProvider,CloudJWTProvider, ArrowFlightAuthMiddleware, GCSdiskSettings.Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
...