Question

I would like to give a user all the permissions on a database without making it an admin. The reason why I want to do that is that at the moment DEV and PROD are different DBs on the same cluster so I don't want a user to be able to change production objects but it must be able to change objects on DEV.

I tried:

grant ALL on database MY_DB to group MY_GROUP;

but it doesn't seem to give any permission.

Then I tried:

grant all privileges on schema MY_SCHEMA to group MY_GROUP;

and it seems to give me permission to create objects but not to query\delete objects on that schema that belong to other users

I could go on by giving USAGE permission to the user on MY_SCHEMA but then it would complain about not having permissions on the table ...

So I guess my question is: is there any easy way of giving all the permissions to a user on a DB?

I'm working on PostgreSQL 8.1.23.

Was it helpful?

Solution

All commands must be executed while connected to the right database cluster. Make sure of it.

Roles are objects of the database cluster. All databases of the same cluster share the set of defined roles. Privileges are granted / revoked per database / schema / table etc.

A role needs access to the database, obviously. That's granted to PUBLIC by default. Else:

GRANT CONNECT ON DATABASE my_db TO my_user;

Basic privileges for Postgres 14 or later

Postgres 14 adds the predefined, non-login roles pg_read_all_data / pg_write_all_data.
They have SELECT / INSERT, UPDATE, DELETE privileges for all tables, views, and sequences. Plus USAGE on schemas. We can GRANT membership in these roles:

GRANT pg_read_all_data TO my_user;
GRANT pg_write_all_data TO my_user;

This covers all basic DML commands (but not DDL, and not some special commands like TRUNCATE or the EXECUTE privilege for functions!). The manual:

pg_read_all_data

Read all data (tables, views, sequences), as if having SELECT rights on those objects, and USAGE rights on all schemas, even without having it explicitly. This role does not have the role attribute BYPASSRLS set. If RLS is being used, an administrator may wish to set BYPASSRLS on roles which this role is GRANTed to.

pg_write_all_data

Write all data (tables, views, sequences), as if having INSERT, UPDATE, and DELETE rights on those objects, and USAGE rights on all schemas, even without having it explicitly. This role does not have the role attribute BYPASSRLS set. If RLS is being used, an administrator may wish to set BYPASSRLS on roles which this role is GRANTed to.

All privileges without using predefined roles (any Postgres version)

Commands must be executed while connected to the right database. Make sure of it.

The role needs (at least) the USAGE privilege on the schema. Again, if that's granted to PUBLIC, you are covered. Else:

GRANT USAGE ON SCHEMA public TO my_user;

Or grant USAGE on all custom schemas:

DO
$$
BEGIN
   -- RAISE NOTICE '%', (  -- use instead of EXECUTE to see generated commands
   EXECUTE (
   SELECT string_agg(format('GRANT USAGE ON SCHEMA %I TO my_user', nspname), '; ')
   FROM   pg_namespace
   WHERE  nspname <> 'information_schema' -- exclude information schema and ...
   AND    nspname NOT LIKE 'pg\_%'        -- ... system schemas
   );
END
$$;

Then, all permissions for all tables (requires Postgres 9.0 or later).
And don't forget sequences (if any):

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO my_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO my_user;

Alternatively, you could use the "Grant Wizard" of pgAdmin 4 to work with a GUI.

This covers privileges for existing objects. To also cover future objects, set DEFAULT PRIVILEGES. See:

There are some other objects, the manual for GRANT has the complete list. As of Postgres 14:

privileges on a database object (table, column, view, foreign table, sequence, database, foreign-data wrapper, foreign server, function, procedure, procedural language, schema, or tablespace)

But the rest is rarely needed. More details:

Consider upgrading to a current version.

OTHER TIPS

GRANT ALL PRIVILEGES ON DATABASE "my_db" to my_user;

In PostgreSQL 9.0+ you would do the following:

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA MY_SCHEMA TO MY_GROUP;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA MY_SCHEMA TO MY_GROUP;

If you want to enable this for newly created relations too, then set the default permissions:

ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
  GRANT ALL PRIVILEGES ON TABLES TO MY_GROUP;
ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
  GRANT ALL PRIVILEGES ON SEQUENCES TO MY_GROUP;

However, seeing that you use 8.1 you have to code it yourself:

CREATE FUNCTION grant_all_in_schema (schname name, grant_to name) RETURNS integer AS $$
DECLARE
  rel RECORD;
BEGIN
  FOR rel IN
    SELECT c.relname
    FROM pg_class c
    JOIN pg_namespace s ON c.namespace = s.oid
    WHERE s.nspname = schname
  LOOP
    EXECUTE 'GRANT ALL PRIVILEGES ON ' || quote_ident(schname) || '.' || rel.relname || ' TO ' || quote_ident(grant_to);
  END LOOP;
  RETURN 1;
END; $$ LANGUAGE plpgsql STRICT;
REVOKE ALL ON FUNCTION grant_all_in_schema(name, name) FROM PUBLIC;

This will set the privileges on all relations: tables, views, indexes, sequences, etc. If you want to restrict that, filter on pg_class.relkind. See the pg_class docs for details.

You should run this function as superuser and as regular as your application requires. An option would be to package this in a cron job that executes every day or every hour.

I did the following to add a role 'eSumit' on PostgreSQL 9.4.15 database and provide all permission to this role :

CREATE ROLE eSumit;

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO eSumit;

GRANT ALL PRIVILEGES ON DATABASE "postgres" to eSumit;

ALTER USER eSumit WITH SUPERUSER;

Also checked the pg_table enteries via :

select * from pg_roles; enter image description here

Database queries snapshot : enter image description here

In PostgreSQL 12 and later, it is possible to grant all privileges of a table in a database to a role/user/account.

The syntax is:

GRANT ALL ON table_name TO role_name;

If you want to grant it to all tables in the database then the syntax will be:

GRANT ALL ON ALL TABLES TO role_name;

If you want to grant it to all tables of a schema in the database then the syntax will be:

GRANT ALL ON ALL TABLES IN SCHEMA schema_name TO role_name;

Note: Remember you will need to select the database before you can grant its privileges to a user.

Resources: PostgreSQL GRANT

That's all

I hope this helps

GRANT USAGE ON SCHEMA schema_name TO user;

GRANT ALL ON SCHEMA schema_name TO user_name;

Give all permissions to a user on a PostgreSQL database:

Command:

grant all privileges on database [database_name] to [database_user_name];

Example:

grant all privileges on database studentdb to shaifullah;

OR

GRANT ALL PRIVILEGES ON DATABASE studentdb TO shaifullah;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top