Skip to content

fix: make get_queue_info reader-callable#267

Open
NikolayS wants to merge 2 commits into
mainfrom
fix/get-queue-info-reader-perms-2
Open

fix: make get_queue_info reader-callable#267
NikolayS wants to merge 2 commits into
mainfrom
fix/get-queue-info-reader-perms-2

Conversation

@NikolayS
Copy link
Copy Markdown
Owner

@NikolayS NikolayS commented Jun 2, 2026

Bug

pgque.get_queue_info() and pgque.get_queue_info(text) are granted to pgque_reader and documented in docs/reference.md / docs/monitoring.md as reader-usable monitoring functions, but a pgque_reader session fails at runtime:

ERROR:  permission denied for function seq_getval
CONTEXT:  PL/pgSQL function pgque.get_queue_info(text) line 58 at assignment
PL/pgSQL function pgque.get_queue_info() line 26 at FOR over SELECT rows

Root cause

get_queue_info is inherited from upstream PgQ as SECURITY INVOKER. The 1-arg overload internally calls pgque.seq_getval(text) to compute ev_new, and that helper's ACL is admin-only ({postgres, pgque_admin}). A reader therefore cannot execute it. The sibling functions get_consumer_info and get_batch_info are SECURITY DEFINER for exactly this reason and work fine for readers — get_queue_info was the odd one out.

Fix

Promote both get_queue_info overloads to SECURITY DEFINER with SET search_path = pgque, pg_catalog (mandatory for all SECURITY DEFINER per CLAUDE.md), mirroring the existing get_consumer_info / get_batch_info pattern. This grants no privilege beyond reading queue metadata plus the queue event sequence — the same surface the function already exposes to its (intended) readers.

  • Patch added to build/transform.sh (the source of truth for the generated installs), with a guard asserting exactly 2 overloads are promoted.
  • Regenerated sql/pgque.sql and sql/pgque-tle.sql so generated and source stay consistent. Rebuild is reproducible (re-running transform.sh yields no diff).

Audited the other reader-granted observability functions for the same trap: only get_queue_info calls seq_getval under SECURITY INVOKER. get_batch_info / get_consumer_info are 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 in tests/run_all.sql) creates a queue, ticks it, then under set role pgque_reader calls both overloads and asserts success + populated ev_new.

  • Against pre-fix SQL: fails with permission denied for function seq_getval (verified).
  • Against the fix: passes. Full tests/run_all.sql suite passes on PostgreSQL 18.

Manual verification

select pgque.create_queue('bug_q');
set role pgque_reader;
select count(*) from pgque.get_queue_info();        -- was: permission denied; now: succeeds
select queue_name, ev_new from pgque.get_queue_info('bug_q');
reset role;

Fixes #265

NikolayS and others added 2 commits June 2, 2026 14:43
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>
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.

docs: evidence-backed functional verification of every documented command

1 participant