Skip to content

Granting Permissions

Processor grants (pgrelay role)

The pgrelay role is granted exactly the minimum set of privileges it needs to process events — nothing more. These grants are applied automatically during CREATE EXTENSION, and can be re-applied at any time with:

SELECT pgrelay.grant_relay('pgrelay');

If you want to run a second Processor connecting as a different role, grant it the same set:

SELECT pgrelay.grant_relay('my_processor_role');

grant_relay grants: USAGE ON SCHEMA pgrelay plus EXECUTE on queue_has_work, queue_probe, request_reload, queue_pending_ids, process_one, _queue_claim, _fetch_action, _write_log, _queue_mark_done, _queue_delete, _queue_insert_retry, and preflight. It does not grant the action-type management functions — those are for application users, via grant_user. grant_user additionally grants the fleet-control functions (request_reload, start, stop, pause_for, pause_to) and the options store functions (set_option, get_option).

Application user grants (grant_user)

The quickest way to give a role the full management set is pgrelay.grant_user() — the application-user counterpart to grant_relay. It is callable only by a superuser, since EXECUTE is revoked from PUBLIC on all the management functions:

SELECT pgrelay.grant_user('my_app_role');

This grants USAGE ON SCHEMA pgrelay plus EXECUTE on all channel management functions (register, update, enable, disable, unregister, get, list), action type management functions (register_action_type, update_action_type, delete_action_type), maintenance functions (purge, purge_queue), and the options store functions (set_option, get_option). notify() and list_action_types() are already granted to PUBLIC and are not included here.

Re-run grant_user after a pg_dump/pg_restore that recreates the extension's functions.

Management function grants (manual)

If you need finer control than grant_user() gives you, grant individual functions explicitly:

GRANT EXECUTE ON FUNCTION pgrelay.register(text, text, text, boolean, int, text, text, boolean) TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.update(text, text, text, int, text, text, boolean)            TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.enable(text)                                   TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.disable(text)                                  TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.unregister(text)                               TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.get(text)                                      TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.list(boolean)                                  TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.register_action_type(text, text, int, boolean) TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.update_action_type(text, text, int, boolean)   TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.delete_action_type(text)                       TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.purge(int, int)                                TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.purge_queue(int)                               TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.set_option(text, text)                         TO my_dba_role;
GRANT EXECUTE ON FUNCTION pgrelay.get_option(text)                               TO my_dba_role;

Action function grants

When your channel's action SQL calls a function you own, grant EXECUTE on it to the pgrelay role:

GRANT EXECUTE ON FUNCTION my_schema.my_function(text) TO pgrelay;

If the action needs to touch a table directly (using plain SQL in the action string, rather than calling a function), grant the appropriate table privilege:

GRANT SELECT ON my_schema.my_table TO pgrelay;

Preflight — verifying grants are correct

The Processor calls pgrelay.preflight() on startup and refuses to start if any required grant is missing. You can also call it manually at any time to check the state of the grants:

SELECT * FROM pgrelay.preflight();

Each row is one check. The status values are: ok (grant confirmed), warn (advisory only — for example, the queue table is part of a replication set), and error (a required grant is missing). If you see an error after a CREATE EXTENSION or a pg_dump/pg_restore, run SELECT pgrelay.grant_relay('pgrelay') to repair it.


Continue to Database Tables Reference for the full schema of every pg_relay table.