Allow pg_read_all_stats to read replication origin status
Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.
You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:
docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253352psql -h localhost -U postgresBuilt from patchset v2 (message #2), October 22, 2026 at 04:12 AM.
Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:
git clone --branch t253352_2 https://github.com/hackorum-dev/postgres.gitIn a checkout you already have, add the fork once:
git remote add hackorum https://github.com/hackorum-dev/postgres.gitthen, for this patchset and every later one:
git fetch hackorum t253352_2 && git checkout t253352_2Patchset v2 (message #2) is on t253352_2
Hi,
I have been looking at the requirement for providing non-superuser
read access to specific catalog relations, specifically
pg_replication_origin_status. During this, I reviewed the capabilities
of the pg_read_all_stats role.
Looks like pg_read_all_stats was originally designed to grant access
to all pg_stats_* views, a few other monitoring views defined in
system_views.sql have been included over time. However, access to
pg_replication_origin_status remains restricted and is not currently
covered by existing roles such as pg_read_all_stats, pg_read_all_data,
or pg_monitor.
The attached patch grants pg_read_all_stats read access to the
pg_replication_origin_status view and its underlying function,
consistent with the existing approach for monitoring views in
system_views.sql. I have also included the relevant regression tests.
On pgsql-hackers, I noted a previous discussion [1]/messages/by-id/CAPdiE1zUeSycQ-VHrZQMDR4vkPthYTSxeQPXM-ZfH8QHDBCE=Q@mail.gmail.com regarding granting
this access; however, that discussion focused on the pg_monitor role
rather than pg_read_all_stats and never got commited.
[1]: /messages/by-id/CAPdiE1zUeSycQ-VHrZQMDR4vkPthYTSxeQPXM-ZfH8QHDBCE=Q@mail.gmail.com
Thanks,
Virender
Attached is the updated patch, rebased onto the latest master to fix
apply conflicts.
Commitfest entry: https://commitfest.postgresql.org/patch/7183/
Thanks,
Virender
Show quoted text
On Sat, Aug 8, 2026 at 8:16 PM Virender Singla <virender.cse@gmail.com> wrote:
Hi,
I have been looking at the requirement for providing non-superuser
read access to specific catalog relations, specifically
pg_replication_origin_status. During this, I reviewed the capabilities
of the pg_read_all_stats role.Looks like pg_read_all_stats was originally designed to grant access
to all pg_stats_* views, a few other monitoring views defined in
system_views.sql have been included over time. However, access to
pg_replication_origin_status remains restricted and is not currently
covered by existing roles such as pg_read_all_stats, pg_read_all_data,
or pg_monitor.The attached patch grants pg_read_all_stats read access to the
pg_replication_origin_status view and its underlying function,
consistent with the existing approach for monitoring views in
system_views.sql. I have also included the relevant regression tests.On pgsql-hackers, I noted a previous discussion [1] regarding granting
this access; however, that discussion focused on the pg_monitor role
rather than pg_read_all_stats and never got commited.[1] /messages/by-id/CAPdiE1zUeSycQ-VHrZQMDR4vkPthYTSxeQPXM-ZfH8QHDBCE=Q@mail.gmail.com
Thanks,
Virender
Hi Virender,
Looks like pg_read_all_stats was originally designed to grant access
to all pg_stats_* views, a few other monitoring views defined in
system_views.sql have been included over time. However, access to
pg_replication_origin_status remains restricted and is not currently
covered by existing roles such as pg_read_all_stats, pg_read_all_data,
or pg_monitor.
Not sure, does pg_replication_origin_status contain statistics? I expected
statistics means some cumulative data, but this view contains node ids and LSNs.
Can you give us a background why the idea allowing pg_monitor to read the view
was not accepted?
Best regards,
Hayato Kuroda
FUJITSU LIMITED
Thanks Hayato for taking a look.
Not sure, does pg_replication_origin_status contain statistics? I expected
statistics means some cumulative data, but this view contains node ids and LSNs.
I observed that there are other similar views granted read privileges
to pg_read_all_stats [1]https://github.com/postgres/postgres/blob/master/src/backend/catalog/system_views.sql. Views like pg_shmem_allocations,
pg_backend_memory_contexts, and pg_aios are real-time, point-in-time
snapshots of the system's internal state. It looks like the definition
of "stats" for this role has practically evolved to cover general
system observability, monitoring, and telemetry data. Also,
pg_read_all_stats is granted to pg_monitor anyway.
Can you give us a background why the idea allowing pg_monitor to read the view
was not accepted?
There actually was prior discussion on granting this to
pg_read_all_stats instead of pg_monitor. However, the work was split
across multiple changes. The first change, which related to removing
the hardcoded superuser check, was committed, but the thread stalled
before the second change (granting access to pg_read_all_stats) could
be completed.
[1]: https://github.com/postgres/postgres/blob/master/src/backend/catalog/system_views.sql
Thanks,
Virender
Hi Virender,
I observed that there are other similar views granted read privileges
to pg_read_all_stats [1]. Views like pg_shmem_allocations,
pg_backend_memory_contexts, and pg_aios are real-time, point-in-time
snapshots of the system's internal state. It looks like the definition
of "stats" for this role has practically evolved to cover general
system observability, monitoring, and telemetry data.
For me pg_shmem_allocations and pg_backend_memory_contexts are something like a
statistics because they show the size of total allocated memory. But, hmm, pg_aios
might be a good example.
Also, pg_read_all_stats is granted to pg_monitor anyway.
Yes, IIUC pg_monitor is a superset of the pg_read_all_stats.
There actually was prior discussion on granting this to
pg_read_all_stats instead of pg_monitor. However, the work was split
across multiple changes. The first change, which related to removing
the hardcoded superuser check, was committed, but the thread stalled
before the second change (granting access to pg_read_all_stats) could
be completed.
While checking the old discussion, there was alternative approach to export the
pg_replication_origin_status to public [1]/messages/by-id/20200608.174456.238992210909952383.horikyota.ntt@gmail.com, which might also be good. local_id is
an internal identifier which is not sensitive, external_id is already public on
pg_replication_origin, and remote/local_lsn are also visible on other views.
Can you evaluate it also?
[1]: /messages/by-id/20200608.174456.238992210909952383.horikyota.ntt@gmail.com
Best regards,
Hayato Kuroda
FUJITSU LIMITED
While checking the old discussion, there was alternative approach to export the
pg_replication_origin_status to public [1], which might also be good. local_id is
an internal identifier which is not sensitive, external_id is already public on
pg_replication_origin, and remote/local_lsn are also visible on other views.
Can you evaluate it also?
Thanks for pointing that out. I looked at how the existing
replication related views handle access.
Open to PUBLIC (all rows, all columns):
pg_replication_slots restart_lsn, confirmed_flush_lsn, etc.
slotfuncs.c notes that nothing here
should be sensitive.
pg_stat_subscription received_lsn, latest_end_lsn
Row visible to PUBLIC, LSNs need pg_read_all_stats:
pg_stat_replication state, *_lsn, *_lag, sync_* are NULL
without pg_read_all_stats, even for
the user's own walsender rows. Only the
connection columns (client_addr,
backend_start, ...) follow the usual
"own role or pg_read_all_stats" rule.
pg_stat_wal_receiver all columns except pid are NULL
So I don't see a single consistent rule for choosing between the two
approaches. There are existing replication-related views following
both models: pg_replication_slots and pg_stat_subscription expose
replication LSNs publicly, while pg_stat_replication and
pg_stat_wal_receiver expose only the PID publicly and require
pg_read_all_stats for the detailed replication state and LSN
information.
Given this mixed precedent, granting access to pg_read_all_stats seems
like the more conservative option for pg_replication_origin_status.
Regards,
Virender
Hi Virender, Kuroda-san,
I reviewed v2 of this patch.
Build and tests
---------------
The patch applies cleanly on master at 4545cee303 and builds with
--enable-cassert. make check passes (239/239 tests, including privileges).
Functional testing
------------------
On a fresh initdb cluster with the patch applied, I created an origin with
pg_replication_origin_create() and advanced it with
pg_replication_origin_advance(). Then:
- A role that is a member of pg_read_all_stats can SELECT from
pg_replication_origin_status and call
pg_show_replication_origin_status().
- A member of pg_monitor can do the same.
- A role with neither membership gets "permission denied" for both the
view and the function.
- On a separate server built without this patch, the pg_read_all_stats
member was denied on the view.
I also tested with a live logical replication setup: a publisher and a
subscriber on the same machine, with the patch on the subscriber. After
CREATE SUBSCRIPTION, a pg_read_all_stats member could see the origin that
was created automatically (pg_16401). After inserting rows on the
publisher, its remote_lsn advanced to 0/017F5920, matching the
publisher's pg_current_wal_lsn(). A role without the membership was still
denied, and the monitoring role could not read the replicated table
itself, so the grant exposes replication progress but not table data.
Regression tests
----------------
The new lines in privileges.sql check both the view and the function
before and after GRANT pg_read_all_stats, and query the view as the
granted role, in the same style as the existing pg_aios and
pg_shmem_allocations checks. I also removed the two GRANT lines from
system_views.sql while keeping the new tests, and the privileges test
failed as expected, so the tests do exercise the change.
Docs
----
I did not find text that becomes incorrect. The sentence in
func-admin.sgml already says replication origin functions are
superuser-only by default and can be granted to others. The
pg_read_all_stats description in user-manag.sgml mentions pg_stat_* views,
but that is equally true of pg_aios and the other views already granted
to the role, so it may not need a change. The patch has no doc changes,
so I did not build the docs.
pg_read_all_stats grant as proposed.
Access can be widened later more easily than it can be narrowed, and the
view is restricted today. In my testing the view showed only origin names
and LSNs and no table data, so making it public later looks low-risk if
a committer prefers that. I would leave that decision to a committer.
Thanks for working on this.
Regards,
Shubhra Jain
[image: Shubhra Jain]
Shubhra Jain
Junior Software Engineer
[image: Phone] (+91) 9752683649 <(+91)+9752683649> [image: Website]
www.ksolves.com [image: Ksolves - AI First, Always]
On Tue, Sep 29, 2026 at 1:24 PM Virender Singla <virender.cse@gmail.com>
wrote:
Show quoted text
While checking the old discussion, there was alternative approach to
export the
pg_replication_origin_status to public [1], which might also be good.
local_id is
an internal identifier which is not sensitive, external_id is already
public on
pg_replication_origin, and remote/local_lsn are also visible on other
views.
Can you evaluate it also?
Thanks for pointing that out. I looked at how the existing
replication related views handle access.Open to PUBLIC (all rows, all columns):
pg_replication_slots restart_lsn, confirmed_flush_lsn, etc.
slotfuncs.c notes that nothing here
should be sensitive.
pg_stat_subscription received_lsn, latest_end_lsnRow visible to PUBLIC, LSNs need pg_read_all_stats:
pg_stat_replication state, *_lsn, *_lag, sync_* are NULL
without pg_read_all_stats, even for
the user's own walsender rows. Only the
connection columns (client_addr,
backend_start, ...) follow the usual
"own role or pg_read_all_stats" rule.
pg_stat_wal_receiver all columns except pid are NULLSo I don't see a single consistent rule for choosing between the two
approaches. There are existing replication-related views following
both models: pg_replication_slots and pg_stat_subscription expose
replication LSNs publicly, while pg_stat_replication and
pg_stat_wal_receiver expose only the PID publicly and require
pg_read_all_stats for the detailed replication state and LSN
information.
Given this mixed precedent, granting access to pg_read_all_stats seems
like the more conservative option for pg_replication_origin_status.Regards,
Virender