diff --git a/contrib/test_decoding/expected/replorigin.out b/contrib/test_decoding/expected/replorigin.out
index 3b249f4856f..80773187554 100644
--- a/contrib/test_decoding/expected/replorigin.out
+++ b/contrib/test_decoding/expected/replorigin.out
@@ -1,5 +1,34 @@
-- predictability
SET synchronous_commit = on;
+-- superuser required by default
+CREATE ROLE regress_origin_replication REPLICATION;
+SET ROLE regress_origin_replication;
+SELECT pg_replication_origin_advance('regress_test_decoding: perm', '0/1');
+ERROR: permission denied for function pg_replication_origin_advance
+SELECT pg_replication_origin_create('regress_test_decoding: perm');
+ERROR: permission denied for function pg_replication_origin_create
+SELECT pg_replication_origin_drop('regress_test_decoding: perm');
+ERROR: permission denied for function pg_replication_origin_drop
+SELECT pg_replication_origin_oid('regress_test_decoding: perm');
+ERROR: permission denied for function pg_replication_origin_oid
+SELECT pg_replication_origin_progress('regress_test_decoding: perm', false);
+ERROR: permission denied for function pg_replication_origin_progress
+SELECT pg_replication_origin_session_is_setup();
+ERROR: permission denied for function pg_replication_origin_session_is_setup
+SELECT pg_replication_origin_session_progress(false);
+ERROR: permission denied for function pg_replication_origin_session_progress
+SELECT pg_replication_origin_session_reset();
+ERROR: permission denied for function pg_replication_origin_session_reset
+SELECT pg_replication_origin_session_setup('regress_test_decoding: perm');
+ERROR: permission denied for function pg_replication_origin_session_setup
+SELECT pg_replication_origin_xact_reset();
+ERROR: permission denied for function pg_replication_origin_xact_reset
+SELECT pg_replication_origin_xact_setup('0/1', '2013-01-01 00:00');
+ERROR: permission denied for function pg_replication_origin_xact_setup
+SELECT pg_show_replication_origin_status();
+ERROR: permission denied for function pg_show_replication_origin_status
+RESET ROLE;
+DROP ROLE regress_origin_replication;
CREATE TABLE origin_tbl(id serial primary key, data text);
CREATE TABLE target_tbl(id serial primary key, data text);
SELECT pg_replication_origin_create('regress_test_decoding: regression_slot');
diff --git a/contrib/test_decoding/sql/replorigin.sql b/contrib/test_decoding/sql/replorigin.sql
index 8979b306160..b68f819fa1f 100644
--- a/contrib/test_decoding/sql/replorigin.sql
+++ b/contrib/test_decoding/sql/replorigin.sql
@@ -1,6 +1,24 @@
-- predictability
SET synchronous_commit = on;
+-- superuser required by default
+CREATE ROLE regress_origin_replication REPLICATION;
+SET ROLE regress_origin_replication;
+SELECT pg_replication_origin_advance('regress_test_decoding: perm', '0/1');
+SELECT pg_replication_origin_create('regress_test_decoding: perm');
+SELECT pg_replication_origin_drop('regress_test_decoding: perm');
+SELECT pg_replication_origin_oid('regress_test_decoding: perm');
+SELECT pg_replication_origin_progress('regress_test_decoding: perm', false);
+SELECT pg_replication_origin_session_is_setup();
+SELECT pg_replication_origin_session_progress(false);
+SELECT pg_replication_origin_session_reset();
+SELECT pg_replication_origin_session_setup('regress_test_decoding: perm');
+SELECT pg_replication_origin_xact_reset();
+SELECT pg_replication_origin_xact_setup('0/1', '2013-01-01 00:00');
+SELECT pg_show_replication_origin_status();
+RESET ROLE;
+DROP ROLE regress_origin_replication;
+
CREATE TABLE origin_tbl(id serial primary key, data text);
CREATE TABLE target_tbl(id serial primary key, data text);
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index a8d57f4e39a..b65aa28f344 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -24614,7 +24614,9 @@ postgres=# SELECT * FROM pg_walfile_name_offset(pg_stop_backup());
, and
for information about the underlying features.
- Use of functions for replication origin is restricted to superusers.
+ Use of functions for replication origin is only allowed to the
+ superuser by default, but may be allowed to other users by using the
+ GRANT command.
Use of functions for replication slots is restricted to superusers
and users having REPLICATION privilege.
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 56420bbc9d6..5314e9348fa 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1463,6 +1463,19 @@ REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text) FROM public;
REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint) FROM public;
REVOKE EXECUTE ON FUNCTION pg_read_binary_file(text,bigint,bigint,boolean) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_advance(text, pg_lsn) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_create(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_drop(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_oid(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_progress(text, boolean) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_is_setup() FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_progress(boolean) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_reset() FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_setup(text) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_reset() FROM public;
+REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_setup(pg_lsn, timestamp with time zone) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_show_replication_origin_status() FROM public;
+
REVOKE EXECUTE ON FUNCTION pg_stat_file(text) FROM public;
REVOKE EXECUTE ON FUNCTION pg_stat_file(text,boolean) FROM public;
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index dec9e951195..1b220315dff 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -182,11 +182,6 @@ static ReplicationState *session_replication_state = NULL;
static void
replorigin_check_prerequisites(bool check_slots, bool recoveryOK)
{
- if (!superuser())
- ereport(ERROR,
- (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- errmsg("only superusers can query or manipulate replication origins")));
-
if (check_slots && max_replication_slots == 0)
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),