Postgres Grant CRUD on DATABASE to USER - postgresql

I have an application which uses a postgres database. I have a superadmin user. Now I need two more users: One "application-user" with CRUD-privileges and one with ALTER and CREATE-privileges (to apply migrations). These are all users I need, because the application has its own User-Access management and it is not at all planned to change that.
I want something like: GRANT SELECT, INSERT, UPDATE, DELETE ON DATABASE MyDatabase TO myuser
I've read here that postgres provides pre defined roles. This is good - but these roles apply globally (as pointed out in one comment). MyDatabase is on public schema which becomes problematic because some system tables are on public too - and I don't want myuser to be able to read from or write to these.
I'd be fine with GRANT pg_read_all_data, pg_write_all_data ON DATABASE MyDatabase TO myuser but this doesn't work.
As I'll not change these privileges often I'd even be fine with GRANT pg_read_all_data ON MyDatabase.MyTable TO myuser as well. But this doesn't work either.
Any ideas on this?

There are no ALTER and CREATE privileges in PostgreSQL. The database user that should be able to run ALTER and CREATE statements will have to be the owner of the database objects. If you already have objects owned by a different user, you will have to change the ownership.
For the other user, you will have to grant privileges on each and every object. Privileges on the database won't help – there is no inheritance of privileges between objects. Don't forget to grant USAGE on the schemas.
I recommend that you create more schemas than public. If you have a separate schema for your application's objects, you can use statements like
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA myapp TO someuser;

Related

GRANT/REVOKE from all tables in database

I've created a database in Postgres, like so:
CREATE DATABASE mydb
I've created a user (role), like so:
CREATE USER myuser
I would now like to GRANT certain permissions (e.g. SELECT) to this user for all tables in this database. How can I achieve this?
The closest thing I can find is the GRANT ... ON ALL TABLES IN SCHEMA someschema, but I don't think this addresses the issue, since a single "database" can have multiple "schema", and I'd like these permissions to apply to all existing tables in all existing schema, as well as all future tables in all future schema.
Similarly, what would then be the equivalent to REVOKE all permissions for all tables in a database?

Safely drop a user in Postgres

I am very new to Postgress security topic. I have used the following commands to create a user.
CREATE USER myuser WITH PASSWORD 'PASSWORD';
GRANT CONNECT ON DATABASE "MyDB" TO myuser;
GRANT ALL PRIVILEGES ON DATABASE "MyDB" TO myuser;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO myuser;
Immediately afterwards I wanted to drop this user by I receive an error similar to:
ERROR: role "tempuser" cannot be dropped because some objects depend on it
DETAIL:
privileges for view myView
privileges for table myTable
... [rest of views and tables]
It kinda scares me. How can I safely drop a user without affecting the data and other objects in database?
Reverse each of your GRANT with a corresponding REVOKE.
It kinda scares me. How can I safely drop a user without affecting the data and other objects in database?
If you consider a REVOKE to be "affecting the objects", then you can't drop the user without affecting the objects. Why does this scare you? As you can see, the system won't let you do this implicitly, so what is there to be scared of?

Readonly admin user in postgresql

we have a postgres database we want to run a number of checks against. Part of the tool involves looping over database all the database tables and views, checking grants and other things - so it would be entirely pointless if we had to grant access to this user to individual tables.
We want to be able to create a user that has full read privileges to anything, regardless of what permissions are set in the database - like a db owner - but has no write access at all.
Is this possible in any way?
The only way to do this is granting the SELECT privilege on every individual object that needs to be examined. You can make the work easier with
GRANT SELECT ON ALL TABLES/SEQUENCES/... IN SCHEMA ... TO ...;
You can also use ALTER DEFAULT PRIVILEGES to set the permissions on future objects.
I recommend that you create a readonly role and do all that once. Then you can create a read-only user by making the user a member of that role.
With postgresql 14 you can just do:
GRANT pg_read_all_data TO my_role;
https://www.postgresql.org/docs/14/predefined-roles.html

How to add admin user to existing postgres database?

We have an existing postgres database gsrdb in production with superuser gsr. We have been doing all the database maintenance with that user gsr. Also, the same user gsr is used by our app service to do transactions on the database.
We want to change this now. We want a separate superuser gsr_admin(whose credentials are managed by Vault) that can do the dba maintenance but still have our app service use existing user gsr.
The problem I am facing is that all the database objects so far are owned by gsr user and if I run updates, as user gsr_admin, on the database w.r.t. either table constraints or sequences it fails saying error: must be owner of relation...blah blah
How can I fix this?
So I was thinking if I could create a superuser admin group role called admin_group and reassign all the ownerships of all the database objects to it from user gsr and then alter both users gsr and gsr_admin to belong to this admin group role. Wouldn't that way everything that has been created so far would be owned by role admin_group ? And whether I create new objects as a user gsr or as gsr_admin either of them can still update the objects?
I might be wrong. Would really appreciate some inputs.
Simply run
ALTER ROLE gsr NOSUPERUSER;
ALTER ROLE gsr RENAME TO gsr_admin; -- needs a new password now
CREATE ROLE gsr LOGIN;
GRANT USAGE ON SCHEMA myschema TO gsr;
GRANT SELECT, INSERT, UPDATE, DELETE
ON ALL TABLES IN SCHEMA myschema TO gsr;
Similarly, grant USAGE on sequences and other required privileges. You may want to run some ALTER DEFAULT PRIVILEGES for future objects as well.

Postgres role with usage privilige but not DELETE

I have a postgres instance with a user root that has full admin privileges.
I have two databases db1 and db2.
For every database, I would like to have two users dbN_user and dbN_admin. dbN_user will be the used by my application, and dbN_admin will be used for migrations that change the table structure.
No rows are ever deleted by the application, and I would like to enforce that with user privileges.
db1_user should be able to connect to db1, and be able to SELECT, INSERT and UPDATE, but not DELETE.
db1_admin should have additional privileges to DELETE, CREATE TABLE, ALTER TABLE.
What are the SQL statements to set this up?
dbN_admin would be the owner of the objects, so that user would have all privileges automatically.
You need to GRANT the privileges for dbN_user on the tables and other objects themselves, not on the database.
Just add the correct GRANT statements after the CREATE TABLE statements in the SQL script that populates the database.
You need to GRANT the USAGE privilege on the schema that contains the objects to dbN_user as well.
There is the possibility to define default privileges in a database:
ALTER DEFAULT PRIVILEGES FOR dbN_admin
GRANT SELECT, INSERT, UPDATE ON TABLES
TO dbN_user;
This will grant the privileges automatically whenever dbN_admin creates a new table (but it does not affect tables created before the ALTER DEFAULT PRIVILEGES command).
admin:
create user db1_admin;
create schema app_relations;
alter schema app_relations owner to db1_admin;
app:
create user db1_user;
grant CONNECT ON DATABASE db1 to db1_user; --only if you have restricted connections on db previously
grant usage on schema app_relations to db1_user;
grant select,insert,update on all tables in schema app_relations to db1_user;