Skip to content

test: the Iceberg REST readers' server-file gate, and no borrowed environment token (#1341 items 8, 9, 14, 52) - #1409

Merged
jdatcmd merged 1 commit into
mainfrom
test/1341-iceberg-rest-privilege
Oct 15, 2026
Merged

jdatcmd merged 1 commit into
mainfrom
test/1341-iceberg-rest-privilege

Conversation

@jdatcmd

@jdatcmd jdatcmd commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

Part of #1341: items 8, 9, 14 and 52, the Iceberg REST privilege items handed to me on #1283.

What's added

Items 8 and 52: the REST readers' server-file gate (server_file_privilege.sh). The table of read entry points gains:

  • iceberg_rest_table_location, iceberg_rest_scan, iceberg_rest_namespaces, iceberg_rest_tables;
  • the Iceberg wrapper's scan, through a foreign table.

Each row checks that a role without pg_read_server_files is refused by name, and that a role with it gets past the gate. The REST rows use a URL nothing listens on, so a privileged call fails on the connection without naming the role.

Items 9 and 14: no borrowed environment token (iceberg_rest_server.sh). After the restart that sets PGCOLUMNAR_ICEBERG_REST_TOKEN, a login role holds every other grant but has no token mapping:

  • it is refused with 28000, and the catalog fixture logs no new request;
  • it cannot mark its own mapping credentials_required 'false' (42501);
  • control: with that setting made by a superuser, the same role reads through the environment token. So the first arm's refusal is the credential rule, not a broken path.

The helper reports ok, a value, or noconnect, so an empty capture can't pass.

Evidence

run result
clean, PG15–19 server_file_privilege 58/58, iceberg_rest_server 29/29 on each
iceberg_rest_table_location without its gate (PG16) 57 + 1: no role is refused by the pg_read_server_files gate: iceberg_rest_table_location: got [no]
resolver letting every role borrow the environment token 28 + 1: `got [file:///…/00001.metadata.json
validator letting a non-superuser set credentials_required false 28 + 1: got [ok] want [42501]

Bookkeeping

🤖 Generated with Claude Code

https://claude.ai/code/session_019VvWuX1zUwk6Y513waRd4N

@jdatcmd

jdatcmd commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

Rebased onto 217f23b (#1408), with the ledger paragraph restated: 2774 + 87 = 2861 rows, 2095 + 84 = 2179 never, 679 + 3 = 682 dated. suites_not_covered still goes 234 -> 232. No code change. On the rebased tree, server_file_privilege passes 58/58 and iceberg_rest_server 29/29 on each of PG15-19. The gate passes against origin/main. The earlier CI red on 10cb828 was a pip hash mismatch while installing the pinned packages (a download fault), not a test. Needs review on 1df237b.

@OffgridwithJD OffgridwithJD left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at 1df237b.

  • What it holds: the four REST readers and the Iceberg wrapper's scan refuse a role without pg_read_server_files by name and let one with it past. A non-superuser with no token mapping is refused 28000 before any request reaches the catalog, can't set its own credentials_required 'false', and reads with the environment token once a superuser sets it.
  • Red (PG17): turning off iceberg_rest_table_location's gate, and separately iceberg_rest_tables's, gives 56 + 2: no role is refused by the pg_read_server_files gate: iceberg_rest_table_location: got [no] want [yes], and the same for iceberg_rest_tables. The resolver with ambientOk = true gives 28 + 1: got [file:///tmp/pgc_rest/db/events/metadata/00001.metadata.json|2] want [28000|0]. The validator without its superuser check gives 28 + 1: got [ok] want [42501]. The .so md5 changed for each mutant and came back to the clean one on restore.
  • Green: 58/58 and 29/29 on PG17 and PG18. The census, 2861 rows / 2179 never / 682 dated, matches the tsv. The gate passes against origin/main at 232.
  • One correction, not blocking: the comment above the REST rows (and the description) says the privileged role "fails on the connection". It doesn't get that far: printing its reply, all four REST rows stop at columnar: endpoint "127.0.0.1:1" is not in pgcolumnar.objstore_allowed_endpoints. That is still past the role gate, so the arm holds, but the comment should say that the allow-list is what stops it.

🤖 Generated with Claude Code

…ironment token (#1341 items 8, 9, 14, 52)

server_file_privilege's table of read entry points gains the four REST
catalog readers and the Iceberg wrapper's scan: each refuses a role
without pg_read_server_files and lets one with it past the gate.

iceberg_rest_server gains three arms after the restart that sets
PGCOLUMNAR_ICEBERG_REST_TOKEN: a non-superuser holding every other grant
but no token mapping is refused (28000) before any request reaches the
catalog; it cannot mark its own mapping credentials_required false
(42501); and with that set by a superuser it reads by the environment
token (the control). Each is red under its own mutation.

Both suites enter the ledger seeded; suites_not_covered 234 -> 232.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019VvWuX1zUwk6Y513waRd4N
@jdatcmd
jdatcmd force-pushed the test/1341-iceberg-rest-privilege branch from 1df237b to 195946a Compare October 15, 2026 16:13
@jdatcmd

jdatcmd commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator Author

@OffgridwithJD, I restated this as 195946a, on main 57f6e0e after #1401 merged. Your approval at 1df237b needs renewing.

  • Same patch except the budget. The per-file md5 of the ^[-+] lines from 217f23b to 1df237b equals the one from 57f6e0e to 195946a for check_ledger.tsv, iceberg_rest_server.sh and server_file_privilege.sh. Only check_ledger_budget.txt differs.
  • The budget agrees with its tsv. The paragraph now sits on top of fix: pgcolumnar.truncate() checks ownership before its lock and its type check (#1384) #1401's: 2786 + 87 = 2873 rows, 2095 + 84 = 2179 never, 691 + 3 = 694 dated. Derived from 195946a's tsv: 2873 rows, 2179 never, 694 dated. The file is sorted, with no duplicate keys. suites_not_covered is 232.
  • On the rebased tree: server_file_privilege passes 58/58 and iceberg_rest_server 29/29 on each of PG15 to PG19. The gate against origin/main gives rc=0: 285 suites registered, the census agrees, and the ceiling goes 234 -> 232.

🤖 Generated with Claude Code

@jdatcmd
jdatcmd merged commit 7da848d into main Oct 15, 2026
15 checks passed
This was referenced Oct 15, 2026
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.

2 participants