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.
Related
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;
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
I'm coming to postgreSQL with a SQL Server background and was naively applying the same concepts to postgreSQL in order to allow different users to share 'by default' some objects within a database.
This is what I did:
CREATE DATABASE testdb;
CREATE ROLE testdb_role_full INHERIT;
GRANT ALL PRIVILEGES ON DATABASE testdb TO testdb_role_full;
CREATE USER user1 INHERIT;
GRANT testdb_role_full TO user1;
CREATE USER user2 INHERIT;
GRANT testdb_role_full TO user2;
Once done, I created a table t1 using the user1.
Then, I tried, as user2, to read the t1 table and I received a "permission denied error"... :-(
By reading the documentation, it seems that I have to issue a SET ROLE testdb_role_full first so as to act as the testdb_role_full.
However, this is not really that I want. I do not want the user to be aware of this.
So my question:
Is there any way to make this work?
Thanks a lot,
José
You've granted some privileges on the database, but that doesn't mean any user with the role testdb_role_full would have all privileges on all objects inside that database. To quote from the documentation:
When an object is created, it is assigned an owner. The owner is normally the role that executed the creation statement. For most kinds of objects, the initial state is that only the owner (or a superuser) can do anything with the object. To allow other roles to use it, privileges must be granted.
So after the user1 created the table t1, he is the owner and only he has the privileges on it. He would need to run
GRANT ALL PRIVILEGES ON TABLE t1 TO testdb_role_full;
then user2 would be able to access it as well (without having to switch any roles - that's only necessary when it has the NOINHERIT attribute on the role).
If you don't want your users to have to execute GRANT each time they create a new object in the database, you can alter the default privileges that will be applied whenever an object is created by user2:
ALTER DEFAULT PRIVILEGES FOR user2
GRANT ALL PRIVILEGES ON TABLES TO testdb_role_full;
Notice these specify the initial value only, and user2 could revoke the privileges on his tables if he wanted to prevent others from seeing them.
I have a database with a template_schema.I cloned this template schema and created a database user with password. I need to provide access to cloned schema only, for the created user.
SELECT clone_schema('my_template_schema','john_smith_gmail_com');
CREATE USER john_smith_gmail_com WITH PASSWORD 'mypassword';
Upto this Ok. Then I need to grant access to this user for this cloned schema(john_smith_gmail_com) only
Method :1
I tried to revoke all privileges on all tables of cloned schema(john_smith_gmail_com) for the user and grant select to the user. But my question is, can this user get SELECT access on other schema tables?
REVOKE ALL ON ALL TABLES IN SCHEMA john_smith_gmail_com FROM john_smith_gmail_com;
GRANT SELECT ON ALL TABLES IN SCHEMA john_smith_gmail_com TO john_smith_gmail_com;
Method :2
Create a role with only SELECT access and assign or grant this role to newly created user. If I do this, for which schema I grant access,because I clone schema dynamically?
Which method is best one?
From postgresql version 9.0 and forward, the best way is probably to use ALTER DEFAULT PRIVILEGES.
...the default privileges for any object type normally grant all grantable permissions to the object owner, and may grant some privileges to PUBLIC as well. However, this behavior can be changed by altering the global default privileges with ALTER DEFAULT PRIVILEGES.
So if all users like "john_smith_gmail_com" should only have SELECT access to tables in "their own" schema, after creating the schema and user, you can run:
ALTER DEFAULT PRIVILEGES IN SCHEMA john_smith_gmail_com GRANT SELECT ON TABLES TO john_smith_gmail_com;
I’m developing a web based application with PostgreSQL as the back End Database & perl handling the scripting
I hold the login info in a separate file similar to advice here where to store global database connection parameters so depending on what the script needs to achieve it could point to different login credentials Currently it’s the default PostgreSQL account this obviously needs changing.
I need to get my head around how to set up user accounts in PostgreSQL
I think I need two one that allows users to query the Database eg web_user the other will need to submit changes eg web_admin.
The web_admin account will need to log into the webpage
In pgAdmin or on the command line how do I create the login Rolls and give the what ever the required permissions are?
EDIT Please Clarify
I’ve had a stab at creating two accounts but am unclear if this is correct way to do it
CREATE USER web_user PASSWORD 'password1';
GRANT SELECT to web_user on Table1; // Read Only
CREATE USER web_admin PASSWORD 'password2';
GRANT SELECT,INSERT,UPDATE,DELETE to web_admin on Table1; // Read Insert and update / delete rows within a existing table but not able to create, alter or delete a Table or column
Edit 2 ooops
So I’ve executed the following in pgAdmin window
CREATE USER web_user PASSWORD 'password1';
GRANT SELECT to web_user in schema PUBLIC; // Read Only
CREATE USER web_admin PASSWORD 'password2';
GRANT SELECT,INSERT,UPDATE,DELETE to web_admin in schema PUBLIC
The web_user account allows just read access to a database the problem the web_admin account has the same read access
I’ve tried drop web_user & revoke by
revoke all privileges on database mydb from web_admin;
but it fails with errors about dependencies listing all tables in mydb
I've attempted to see what privileges web_admin actually has but have been unable to.
How do I drop this account
What is wrong with the syntax for grant web_user?
To create users you can use CREATE USER command in SQL. (it is the same as CREATE ROLE ... WITH LOGIN) Afterwards you use GRANT to grant privileges.
I'm not sure what you mean by "default PostgreSQL account". If you are talking about "postgres" account, it's superuser, and has rights to everything.
The topic of privileges, and securing is quite complex, I wrote about it at least couple of times:
How to grant privileges on all tables in PostgreSQL < 9.0
How to grant privileges on all tables in PostgreSQL > 9.0
How to secure your database