feat(auth): authorize query-auth reads and carry the grant on the split - #758
Draft
plusplusjiajia wants to merge 1 commit into
Draft
feat(auth): authorize query-auth reads and carry the grant on the split#758plusplusjiajia wants to merge 1 commit into
plusplusjiajia wants to merge 1 commit into
Conversation
plusplusjiajia
force-pushed
the
query-auth-carry-grant
branch
9 times, most recently
from
August 30, 2026 04:08
adad11b to
f78b584
Compare
plusplusjiajia
force-pushed
the
query-auth-carry-grant
branch
from
August 30, 2026 04:39
f78b584 to
e324972
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.
Purpose
A
query-auth.enabledtable makes the server return a per-user row filter and column masking that a client is expected to apply. This client cannot apply them yet, so it refuses to read such a table at all — even for a user the server reports as unrestricted. This first slice fetches the authorization at scan-plan time and carries it to the read, so that user can read. A user with rules gets the same refusal as before.Brief change log
Table::authorize_readasks the server once per plan, andTableScan::planstamps the result on every split — Java wraps each split in aQueryAuthSplitfor the same reason.TableRead::to_arrowthen decides from the splits: each must carry a grant, obtained through this table's own handle, and unrestricted. Per split, not just the first, since split lists can be concatenated across plans.Whether a table is query-auth is read from the server, not from the loaded handle: the option can be turned on after a table was loaded, and a cached
falsewould skip authorization altogether. That check doubles as the first half of a freshness bracket around the auth call, which refuses a table that was re-created or evolved in the meantime, or whose identity the server no longer reports.QueryAuthGrantkeeps the response unparsed — parsing belongs with the code that applies it — and the request carries no explicit select, which the server expands to the real schema fields. Naming a reserved system column would fail its column-permission check and deny an otherwise authorized user, so a read that reaches one is refused client-side instead. A user authorized for a subset is therefore still refused, as today.AuthTableQueryResponserejects unknown fields, unlike every other response: an absent field reads as "no rule", so a drifted protocol would otherwise look like an unrestricted grant.Two refusals are deliberate: a restricted grant fails at planning, since a plan carries row counts and min/max that engines answer
COUNT/MIN/MAXfrom without reading a row; and a time-travelled or branch copy is refused, since the server rules on the current schema. Only the query-auth part ofReadBuilder::new_read's gate moved toto_arrow, where the split's grant is visible; the engine-served type check stays there, since a table's declared type is known without a grant.