Create read only user for postgres replica - postgresql

I've recently implemented streaming replication and need to create a "report user" for the replica. This user will be used to access the database via ODBC to generate reports with.
On the slave (replica DB), It seems I cannot create new users. I also need to change the password of 'postgres' user on the slave. Here's what I've tried and the errors I get:
CREATE ROLE readaccess;
ERROR: cannot execute CREATE ROLE in a read-only transaction
\password postgres
ERROR: cannot execute ALTER ROLE in a read-only transaction
How can I create a new read only user for my replica?
How can I change the password of the user 'postgres' on the replica?
Note: I do realize that for a replica, you can (or should) only have read-only access.
Thank you.

As you have discovered, the replica is read-only anyway. So you have a few choices.
Just use any of your accounts from the primary. They will have the same permissions on the replica (except that they cannot change data).
Create a special user that only has 'select' permissions on the primary, and that user flow through to the replica.
As for having different passwords on the primary and replica, you can't. If that is a hard requirement for you, you'll have to look into "logical replication".

Related

How to set or change role upon login automatically in postgres?

I have an existing postgres 11 database called host_db and we have an existing application called host_app that has been using this database for a long time. This service uses superuser host_app_user to connect to database and do all the transactions. Hence, all the database objects are owned by this database superuser.
Now, we want to create db_admin superuser role too in our database whose credentials will be maintained by Vault. But to not mix up database ownership, I was thinking that whenever db_admin logs in to the database, it assumes the role of host_app_user. That way whatever changes the logged admin does will all be done as host_app_user.
My question is: Is there a way I can automatically set the role of logged in user in postgres at the time of logging in?
Use:
alter role db_admin set role host_app_user;
db_admin's role will be set to host_app_user on login.
Note though that db_admin must be a member of host_app_user.
I think the answer is no. But you could do this:
grant db_admin to host_app_user;
Then host_app_user will have all the permissions that db_admin has.

How to block update to the postgresql database

We have a production postgres database which is accessible by all team members.
We use pgadmin to administer the database.
For safety reasons, I am willing to make the database readonly. So that, only data can be viewed and cannot be modified
(blocking any update operation to the database).
If any database update is required, then I can make the database to readwrite mode, make the modification
and change to readonly again.
There are ROLES AND PRIVILEGES options which can be used for achieving this functionality.
But I am wondering if there is any Pgadmin UI options for making the database readonly.
Thanks in advance.
Why don't you use Roles and Privileges ??
create multiple users
master_user
readonly_user
etc
Once you have users created, you can grant access on database/ schema or even table level.
Share the readonly user with the team and keep the master user for admins / applications etc
More info on postgres roles and privileges: https://www.postgresql.org/docs/current/user-manag.html

Updated User Permissions Don't Reflect In Replica in Postgres

I have a master-slave configuration of PostgreSQL servers and there are multiple schemas defined in the database. Now both of master and replication servers have a user readonly which initially had only access to the public schema.
I have another schema, let's say alt_schema; and I want to give readonly user access to all it's tables.
Henceforth, I run the following query in master server to provide access of the schema to the user.
GRANT ALL ON ALL TABLES IN SCHEMA alt_schema TO readonly;
The above command successfully provided access of the schema's tables to the user.
But, the permissions are not propagated to the replication server (I waited for about 30 mins expecting there maybe some lag). Since, the automated replication failed, I tried to run the above query manually in the replication server itself, but obviously it gave me the below error:
ERROR: cannot execute GRANT in a read-only transaction
Is there way to achieve the above.
Note: My Postgres Servers are hosted in Google Cloud SQL.

Setting session_replication_role for GCP Cloud SQL

I am trying to run SET session_replication_role = 'replica'; in a GCP Cloud SQL Postgres 9.6 instance, however I'm encountering this error ERROR: permission denied to set parameter "session_replication_role" even if the postgres user is a cloudsql admin user. Do I have to spin up my own self managed instance to solve the problem or is there a way around it?
Unfortunately, it is not connected with the service is in Beta or not, you can't set session_replication_role in GCP Cloud SQL.
You need to have superuser privileges to do that operation, but GCP Cloud only allows to cloudsqlsuperuser privileges. It's features as follows:
When you create a new Cloud SQL for PostgreSQL instance, the default postgres user is already created for you, though you must set its password.
The postgres user is part of the cloudsqlsuperuser role, and has the following attributes (privileges): CREATEROLE, CREATEDB, and LOGIN. It does not have the SUPERUSER or REPLICATION attributes.
You can find much more information in this blog post.
From what I was looking at, since the service is currently in Beta, there are still some features that are not available, such as that. Therefore we would need to wait a bit more for Google to realease the final version of their product.
We also encountered same issue . This is because postgres user does not have Replication permission.
To resolve this issue:
a) Login with postgres user
b) Since postgres user has Create role permission. Now create a new user with below command:
CREATE USER <YOUR_USER> WITH PASSWORD '<YOUR_PASSWORD>' CREATEDB CREATEROLE REPLICATION IN GROUP cloudsqlsuperuser;
replace <YOUR_USER> with your user name and <YOUR_PASSWORD> with password.
c) Login with newly created user and run
SET session_replication_role = 'replica';
if you see response SET then you are good to go

How do I whitelist access to a PostgreSQL schema?

I have a certain schema in a PG database that contains some very sensitive data. I'd like to prevent access to it for every role except one, but I can't figure it out from the documentation on permissions.
To begin with, I figured I'd only give CONNECT access to that one special role, but then every other role can connect to the schema. To make things worse, every role can also CREATE, DROP, and do everything else.
What have I missed?
Side question: in time, this schema will be a streaming destination from another instance of postgresql. In short, we have a master db server that supports a live web site, and we need a secondary, read-only copy of it on another machine to perform some computationally intensive queries on. We figured that streaming was the answer. Does this make sense? Is it still possible to protect access to it?
We are using version 9.5, in case this is relevant.
You can edit the file /etc/postgresql/9.5/main/pg_hba.conf and put this content:
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# IPv4 local connections:
host all YOUR_USER [USER_IP]/32 md5
It will allow connections with a password for this specific user from this specific LAN/WAN IP.
Only this user and postgres will be allowed.
in time, this database will be a streaming destination from another instance of postgresql.
When this database becomes a replication master you can add the following to the same file:
# Allow replication connections from localhost, by a user with the
# replication privilege.
host replication REPL_USER [REPL_HOST]/32 md5
More info on how to set up the replication here: https://www.gab.lc/articles/replication_postgresql
After the changes you need to reload PostgreSQL with:
service postgresql reload
You can drop the roles you don't want to allow.
Update:
If you wish to revoke privileges with a query you can run:
-- Grant privileges to whitelisted user:
GRANT ALL PRIVILEGES ON [database name] TO [good_user];
-- Revoke privileges for other users:
REVOKE ALL PRIVILEGES ON [database name] FROM [bad_user];