fix: make get_queue_info reader-callable#267
Conversation
Failing regression: a pgque_reader session calling pgque.get_queue_info() / get_queue_info(text) hits "permission denied for function seq_getval" because the function is SECURITY INVOKER but calls the admin-only pgque.seq_getval(text). Reproduces issue #265. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
get_queue_info(text) calls the admin-only pgque.seq_getval(text) but ships as SECURITY INVOKER, so a pgque_reader session -- the exact role it is granted to and documented for -- fails at runtime with "permission denied for function seq_getval". Promote both get_queue_info overloads to SECURITY DEFINER with SET search_path = pgque, pg_catalog (mandatory per CLAUDE.md), mirroring the sibling get_consumer_info / get_batch_info. Patch added to build/transform.sh and the generated sql/pgque.sql and sql/pgque-tle.sql regenerated so source and generated stay in sync. Grants no privilege beyond reading queue metadata. Fixes #265 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
REV Code Review ReportStatus: PASS Scope reviewed: #267 at Checks:
No blockers found. This is ready from REV/code-review perspective. |
samorev Code Review Report
No issues found. Reviewed for security, bugs, tests, guidelines, and documentation. Result: PASSED Summary
Note:
Review metadatasamorev-assisted review (AI analysis by Tanya301/samorev) |
Post-merge code review — thorough passReviewed the full diff against CLAUDE.md rules (SECURITY DEFINER contract, generated-file consistency, red/green TDD, SQL style) and verified the key claims empirically on PostgreSQL 18 in Docker. Verdict: no blocking findings. The fix is correct, minimal, properly tested, and reproducible. Details below, including the security angle I checked hardest. Correctness — clean
Security — PUBLIC-execute trap checked and NOT presentThe one real risk when flipping a function to
Audit claim ("get_queue_info was the only one") — confirmedEnumerated every
Sibling reader-granted monitoring functions Consistency — reproducible build
Tests — genuine red/greenRan
Nits (non-blocking, no action needed)
Reviewed by an independent post-merge pass (build reproduced + tests run red/green + ACLs checked on PostgreSQL 18). |
samorev Code Review Report
No blocking issues. Reviewed for security, bugs, tests, guidelines, and documentation. Two candidates were examined and filtered as non-issues (see below). Result: PASSED What was verified
Filtered (candidates examined, excluded as non-issues)
Summary
Note:
Review metadatasamorev-assisted review (AI analysis by Tanya301/samorev) |
Bug
pgque.get_queue_info()andpgque.get_queue_info(text)are granted topgque_readerand documented indocs/reference.md/docs/monitoring.mdas reader-usable monitoring functions, but apgque_readersession fails at runtime:Root cause
get_queue_infois inherited from upstream PgQ asSECURITY INVOKER. The 1-arg overload internally callspgque.seq_getval(text)to computeev_new, and that helper's ACL is admin-only ({postgres, pgque_admin}). A reader therefore cannot execute it. The sibling functionsget_consumer_infoandget_batch_infoareSECURITY DEFINERfor exactly this reason and work fine for readers —get_queue_infowas the odd one out.Fix
Promote both
get_queue_infooverloads toSECURITY DEFINERwithSET search_path = pgque, pg_catalog(mandatory for allSECURITY DEFINERper CLAUDE.md), mirroring the existingget_consumer_info/get_batch_infopattern. This grants no privilege beyond reading queue metadata plus the queue event sequence — the same surface the function already exposes to its (intended) readers.build/transform.sh(the source of truth for the generated installs), with a guard asserting exactly 2 overloads are promoted.sql/pgque.sqlandsql/pgque-tle.sqlso generated and source stay consistent. Rebuild is reproducible (re-runningtransform.shyields no diff).Audited the other reader-granted observability functions for the same trap: only
get_queue_infocallsseq_getvalunderSECURITY INVOKER.get_batch_info/get_consumer_infoare already DEFINER;status()is admin-only by design and left as-is.Test (red/green TDD)
New regression
tests/test_get_queue_info_reader.sql(registered intests/run_all.sql) creates a queue, ticks it, then underset role pgque_readercalls both overloads and asserts success + populatedev_new.permission denied for function seq_getval(verified).tests/run_all.sqlsuite passes on PostgreSQL 18.Manual verification
Fixes #265