Skip to content

feat(auth): authorize query-auth reads and carry the grant on the split - #758

Open
plusplusjiajia wants to merge 1 commit into
apache:mainfrom
plusplusjiajia:query-auth-carry-grant
Open

feat(auth): authorize query-auth reads and carry the grant on the split#758
plusplusjiajia wants to merge 1 commit into
apache:mainfrom
plusplusjiajia:query-auth-carry-grant

Conversation

@plusplusjiajia

@plusplusjiajia plusplusjiajia commented Aug 27, 2026

Copy link
Copy Markdown
Member

Purpose

A query-auth.enabled table makes the server return a per-user row filter and column masking that the 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 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

TableScan::plan authorizes once and stamps the result on every split, as Java wraps each split in a QueryAuthSplit. TableRead::to_arrow then decides from the splits: each must carry a grant, from this handle,
and unrestricted — per split, since split lists can be concatenated across plans.

Whether a table is query-auth comes from the server, not the loaded handle: the option can be set after a load, and a cached false would skip authorization entirely. Sync read boundaries cannot ask, so they
read a marker the splits carry. Unlike the grant it survives serialization, so a round-tripped split still demands authorization and, having lost the grant, fails closed.

Four refusals are deliberate. A restricted grant fails at planning, since a plan carries row counts and min/max that engines answer COUNT/MIN/MAX from without reading a row. A time-travelled, branch, or
decorated (db.t$branch_x, db.t$files) handle is refused, since the server rules on the current schema while those read other files. A plan is refused when a data file still carries statistics for a column the
current schema no longer has — value_stats and write_cols are public on every split. And the request names no columns, which the server expands to the real schema fields — Java sends the read type's names
instead. Naming a reserved system column would fail the server's permission check and deny an otherwise authorized user, so a read that reaches one is refused client-side instead; the cost is that a user
authorized for only a subset of columns is still refused, as today.

AuthTableQueryResponse rejects unknown fields, unlike every other response: an absent field reads as "no rule", so protocol drift would look like an unrestricted grant.

@plusplusjiajia
plusplusjiajia force-pushed the query-auth-carry-grant branch 11 times, most recently from e324972 to f67b381 Compare August 30, 2026 12:44
@plusplusjiajia
plusplusjiajia force-pushed the query-auth-carry-grant branch from f67b381 to 96e1832 Compare August 30, 2026 13:13
@plusplusjiajia
plusplusjiajia marked this pull request as ready for review August 30, 2026 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant