Updated User Permissions Don't Reflect In Replica in Postgres - postgresql

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.

Related

How do I resolve a "permission denied for schema public" error for PostgreSQL on GitHub Actions?

I've been working on maintenance on this GitHub repo that has been left undeveloped for almost a year. When rerunning the GitHub Actions job that finished to completion last May, there are now issues related to permission for CREATE in the public schema in PostgreSQL. At first I suspected, this might be because of the recent PostgreSQL 15 update that made it so that users do not by default have create access on the public schema. However, for our job GitHub Actions uses Postgres 14 for Ubuntu 22.04 (postgresql_14+238), so this change to public schema access in PostgreSQL shouldn't be affecting us. Our previous passing run used Postgres 12 for Ubuntu 20.04 (postgresql-12_12.10-0ubuntu0.20.04.1), so the changed environment could still be relevant.
The job is erroring out during a step where we create a few tables within our database using <user>:
peewee.ProgrammingError: permission denied for schema public
LINE 1: CREATE TABLE IF NOT EXISTS "articles" ("id" INTEGER NOT NULL...
Before this step, we configure the PostgreSQL database, creating the <user> and granting it all permissions to the database: `
CREATE USER <user>;
GRANT ALL PRIVILEGES ON DATABASE <db_name> to <user>
To remedy this problem (while still being confused on why it arose), I tried to explicitly grant <user> permissions on the public schema before attempting any CREATEs following the suggestions from this post: https://www.cybertec-postgresql.com/en/error-permission-denied-schema-public/
GRANT ALL ON SCHEMA public TO <name>;
which seems to go through based on the returned GRANT .
Locally, I'm having no issues with permissions even without the GRANT using PostgreSQL 14, but the permission error still comes up on GitHub Actions, even after granting access to the public schema to the user (and in a desperate attempt--to all users).
I've done a bunch of sanity checks related to making sure that we are in fact using the <user> during the CREATE step, but it seems like the <user> just never ends up getting the permissions even after the GRANT. I followed postgresql - view schema privileges to view schema privileges, and locally, the <user> has permissions to the public schema even before the GRANT. However, on GitHub Actions, the <user> doesn't have permissions before nor after the GRANT, even though there is output confirmation that the GRANT completed successfully.
Does anyone know why I would be having these permission errors now on GitHub Actions, despite the code working locally and on GitHub Actions months ago? Is there any way I can grant permissions differently that might work better in this environment?
The permissions on schema public changed in v15. This change finally got rid of the insecure default setting of letting every user create objects in that schema. Now only the database owner is allowed to create objects by default.
Your GRANT statement is good to allow a user to create objects in schema public:
GRANT CREATE ON SCHEMA public TO user_that_creates_objects;
Just remember that you have to connect to the target database before running that statement. Also, the GRANT must be executed by the database owner or a superuser.
My recommendation is to leave the public schema for extension objects and create your own schema for your application objects.

Can't create new schema in an OVH postgres

I have a PostgreSQL server on OVH's Cloud DB and have been using its databases for my web apps.
So far so good.
I got a project where It's a requirement to have schemas. Strangely enough, I am unable to create schemas on the user with "Administrator" privileges.
I have prepared scripts using schemas, so I just need to run them on a prepared database but I need a database with schemas to run them.
Here is my process:
Create a new database
Select option "Create user"
Select option for privilages: "Administrator"
Commit configuration
Wait for database creation
Connect to database with the new config via PGAdmin
Run command create schema if not exists "vMobile";
Recieve following error:
ERROR: permission denied for database my-database-dev
SQL state: 42501
I created a ticket for this but the wait is taking too long.
Support answer
Ok, so I got a response from the OVH support and there is no option for the user to create new schemas as their CloudDB enables access only to schema public and mentioned privileges Administrator, Read/Write, Read, None are only applicable to the public schema.
Workaround
My solution to this is to create tables with schema name included in their names
like so:
Desired outcome: "vCommon"."Route"
Workaround: "public"."vCommon_Route"

Prevent AWS Postgres Read Only User From Seeing Other Objects

I'm trying to limit the ability of a read only user in postgres to only a certain view. I want to prevent them from seeing other schemas / tables / columns that they don't have permission to.
I tried this:
PostgreSQL Revoking Permissions from pg_catalog tables
This worked on my local test database but not on my AWS database because apparently AWS locks down permissions to many tables in the pg_catalog schema and if I try to revoke select on those tables I get
ERROR: permission denied for relation
Is there a way in an AWS deployed postgres (10.6) database to limit what a read only user can see?

Create read only user for postgres replica

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".

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];