How do you create a read-only user in PostgreSQL? - postgresql

I'd like to create a user in PostgreSQL that can only do SELECTs from a particular database. In MySQL the command would be:
GRANT SELECT ON mydb.* TO 'xxx'#'%' IDENTIFIED BY 'yyy';
What is the equivalent command or series of commands in PostgreSQL?
I tried...
postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;
But it appears that the only things you can grant on a database are CREATE, CONNECT, TEMPORARY, and TEMP.

Grant usage/select to a single table
If you only grant CONNECT to a database, the user can connect but has no other privileges. You have to grant USAGE on namespaces (schemas) and SELECT on tables and views individually like so:
GRANT CONNECT ON DATABASE mydb TO xxx;
-- This assumes you're actually connected to mydb..
GRANT USAGE ON SCHEMA public TO xxx;
GRANT SELECT ON mytable TO xxx;
Multiple tables/views (PostgreSQL 9.0+)
In the latest versions of PostgreSQL, you can grant permissions on all tables/views/etc in the schema using a single command rather than having to type them one by one:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;
This only affects tables that have already been created. More powerfully, you can automatically have default roles assigned to new objects in future:
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO xxx;
Note that by default this will only affect objects (tables) created by the user that issued this command: although it can also be set on any role that the issuing user is a member of. However, you don't pick up default privileges for all roles you're a member of when creating new objects... so there's still some faffing around. If you adopt the approach that a database has an owning role, and schema changes are performed as that owning role, then you should assign default privileges to that owning role. IMHO this is all a bit confusing and you may need to experiment to come up with a functional workflow.
Multiple tables/views (PostgreSQL versions before 9.0)
To avoid errors in lengthy, multi-table changes, it is recommended to use the following 'automatic' process to generate the required GRANT SELECT to each table/view:
SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;'
FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S');
This should output the relevant GRANT commands to GRANT SELECT on all tables, views, and sequences in public, for copy-n-paste love. Naturally, this will only be applied to tables that have already been created.

Reference taken from this blog:
Script to Create Read-Only user:
CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234'
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';
\connect YourDatabaseName;
Assign permission to this read-only user:
GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User;
GRANT USAGE ON SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
Assign permissions to read all newly tables created in the future
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User;

From PostgreSQL v14 on, you can do that simply by granting the predefined pg_read_all_data role:
GRANT pg_read_all_data TO xxx;

Do note that PostgreSQL 9.0 (today in beta testing) will have a simple way to do that:
test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;

Here is the best way I've found to add read-only users (using PostgreSQL 9.0 or newer):
$ sudo -upostgres psql postgres
postgres=# CREATE ROLE readonly WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE';
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
Then log in to all related machines (master + read-slave(s)/hot-standby(s), etc..) and run:
$ echo "hostssl <PUT_DBNAME_HERE> <PUT_READONLY_USERNAME_HERE> 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/9.2/main/pg_hba.conf
$ sudo service postgresql reload

By default new users will have permission to create tables. If you are planning to create a read-only user, this is probably not what you want.
To create a true read-only user with PostgreSQL 9.0+, run the following steps:
# This will prevent default users from creating tables
REVOKE CREATE ON SCHEMA public FROM public;
# If you want to grant a write user permission to create tables
# note that superusers will always be able to create tables anyway
GRANT CREATE ON SCHEMA public to writeuser;
# Now create the read-only user
CREATE ROLE readonlyuser WITH LOGIN ENCRYPTED PASSWORD 'strongpassword';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser;
If your read-only user doesn't have permission to list tables (i.e. \d returns no results), it's probably because you don't have USAGE permissions for the schema. USAGE is a permission that allows users to actually use the permissions they have been assigned. What's the point of this? I'm not sure. To fix:
# You can either grant USAGE to everyone
GRANT USAGE ON SCHEMA public TO public;
# Or grant it just to your read only user
GRANT USAGE ON SCHEMA public TO readonlyuser;

I’ve created a convenient script for that; pg_grant_read_to_db.sh. This script grants read-only privileges to a specified role on all tables, views and sequences in a database schema and sets them as default.

I read trough all the possible solutions, which are all fine, if you remember to connect to the database before you grant the things ;) Thanks anyway to all other solutions!!!
user#server:~$ sudo su - postgres
create psql user:
postgres#server:~$ createuser --interactive
Enter name of role to add: readonly
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
start psql cli and set a password for the created user:
postgres#server:~$ psql
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
Type "help" for help.
postgres=# alter user readonly with password 'readonly';
ALTER ROLE
connect to the target database:
postgres=# \c target_database
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
You are now connected to database "target_database" as user "postgres".
grant all the needed privileges:
target_database=# GRANT CONNECT ON DATABASE target_database TO readonly;
GRANT
target_database=# GRANT USAGE ON SCHEMA public TO readonly ;
GRANT
target_database=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly ;
GRANT
alter default privileges for targets db public shema:
target_database=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES

If your database is in the public schema, it is easy (this assumes you have already created the readonlyuser)
db=> GRANT SELECT ON ALL TABLES IN SCHEMA public to readonlyuser;
GRANT
db=> GRANT CONNECT ON DATABASE mydatabase to readonlyuser;
GRANT
db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public to readonlyuser;
GRANT
If your database is using customschema, execute the above but add one more command:
db=> ALTER USER readonlyuser SET search_path=customschema, public;
ALTER ROLE

The not straightforward way of doing it would be granting select on each table of the database:
postgres=# grant select on db_name.table_name to read_only_user;
You could automate that by generating your grant statements from the database metadata.

Taken from a link posted in response to despesz' link.
Postgres 9.x appears to have the capability to do what is requested. See the Grant On Database Objects paragraph of:
http://www.postgresql.org/docs/current/interactive/sql-grant.html
Where it says: "There is also an option to grant privileges on all objects of the same type within one or more schemas. This functionality is currently supported only for tables, sequences, and functions (but note that ALL TABLES is considered to include views and foreign tables)."
This page also discusses use of ROLEs and a PRIVILEGE called "ALL PRIVILEGES".
Also present is information about how GRANT functionalities compare to SQL standards.

CREATE USER username SUPERUSER password 'userpass';
ALTER USER username set default_transaction_read_only = on;

Related

Setting default privileges on tables not working as expected in Postgres 13

Setup: I'm using Google Cloud Platform's managed Postgres 13 instance, which is a fresh install with no existing tables or users (expect for the postgres admin).
Goal: I want to create a new database called my_db and have two new users steve and mike be able to execute DDL and DML commands on future tables (e.g., create new tables, insert data, read, etc). This also means steve and mike should be able to modify and read/write each other's tables.
Problem: Even when I create the users and set the default privileges in schema public grant all to tables in my_db only the creator (steve) of the new table can read/write the table while mike cannot. Furthermore, even the postgres admin cannot read the new table!
Steps: How to recreate
First I'll create the new database and users, plus give them lenient permissions to alter/read/write future tables in my_db.
-- Logged in as user = postgres (Connection 1)
\c postgres
create database my_db;
-- connect to my_db and create the new users
\c my_db
-- steve user
CREATE USER steve WITH PASSWORD 'pass123';
GRANT connect ON DATABASE my_db TO steve;
alter default privileges in schema public grant all on tables to steve;
-- mike user
CREATE USER mike WITH PASSWORD 'pass456';
GRANT connect ON DATABASE my_db TO mike;
alter default privileges in schema public grant all on tables to mike;
If my understanding is correct, steve and mike can now create and modify tables in my_db. Let's test this.
Then login as steve in a new connection #2 and create a new test table:
-- Logged in as user = steve (Connection 2)
\c my_db
create table test_tbl ( id int4 ); -- success
select * from test_tbl; -- 0 records
Now let's see if mike can read from the test_tbl which he should given the default privileges. We create connection #3 for mike:
-- Logged in as user = mike (Connection 3)
\c my_db
select * from test_tbl; -- ERROR: steve does not have permissions to read test_tbl!
This is my first point of confusion as I thought default permissions would let mike read the test_tbl created by steve.
As a final oddity I decided to circle back to the postgres user to test reading test_tbl:
-- Logged in as user = postgres (Connection 1)
\c my_db
select * from test_tbl; -- ERROR: steve does not have permissions to read test_tbl!
GRANT SELECT, INSERT, UPDATE, delete ON ALL TABLES IN SCHEMA public TO mike; -- same error above!
So not even the admin user postgres can read this new table NOR can I grant permissions...
The only thing that worked is logging back in as steve--the original table creator--and granting postgres and mike permissions:
-- Logged in as user = steve (Connection 2)
\c my_db
GRANT SELECT, INSERT, UPDATE, delete ON ALL TABLES IN SCHEMA public TO postgres; -- success
GRANT SELECT, INSERT, UPDATE, delete ON ALL TABLES IN SCHEMA public TO mike; -- success
This all seems backwards. The default privileges in schema public grant all should take care of allowing users to modify future tables, right? What am I missing?
Thanks in advance.
ALTER DEFAULT PRIVILEGES without the FOR ROLE clause affects only objects created by the role that ran the ALTER DEFAULT PRIVILEGES statement.
You would need two such statements to get what you want:
ALTER DEFAULT PRIVILEGES FOR ROLE mike GRANT ... TO steve;
ALTER DEFAULT PRIVILEGES FOR ROLE steve GRANT ... TO mike;
The other thing you want cannot be had in a straigtforward fashion. Only the owner (or members of that role) and superusers can ALTER or DROP an object. There is no way to grant that privilege. Your only solution would be to have a common table_owner role and have both users be a member of the role:
CREATE ROLE table_owner NOLOGIN;
GRANT CREATE ON SCHEMA myschema TO table_owner;
ALTER ROLE mike NOINHERIT;
ALTER ROLE steve NOINHERIT;
GRANT table_owner TO mike, steve;
Now both users need to SET ROLE to create a table in the schema:
SET ROLE table_owner;
CREATE TABLE myschema.atable (...);
That table is then owned by table_owner, and both users can ALTER or DROP it.

Create roles and users only in a certain database and not in the default postgres database

I'm trying to setup a database with a readwrite user jirauser and a readonly user controlling_ro. This is my script to set it up based on this Blog article. testuser is the master user.
PGPASSWORD=XXX psql \
--dbname=postgres \
--host=XXX.XXX.eu-central-1.rds.amazonaws.com \
--port=5432 \
--username=testuser \
<<EOF
-- Clean DB
DROP DATABASE jiradb;
DROP USER jirauser;
DROP USER controlling_ro;
DROP SCHEMA jiraschema;
DROP ROLE readonly;
DROP ROLE readwrite;
-- Create DB
CREATE DATABASE jiradb;
\connect jiradb;
CREATE SCHEMA jiraschema;
-- Revoke privileges from 'public' role
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE jiradb FROM PUBLIC;
-- Read-only role
CREATE ROLE readonly;
GRANT CONNECT ON DATABASE jiradb TO readonly;
GRANT USAGE ON SCHEMA jiraschema TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA jiraschema TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT SELECT ON TABLES TO readonly;
-- Read/write role
CREATE ROLE readwrite;
GRANT CONNECT ON DATABASE jiradb TO readwrite;
GRANT USAGE, CREATE ON SCHEMA jiraschema TO readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA jiraschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA jiraschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT USAGE ON SEQUENCES TO readwrite;
-- Users creation
CREATE USER controlling_ro WITH PASSWORD 'XXX';
CREATE USER jirauser WITH PASSWORD 'XXX';
-- Grant privileges to users
GRANT readonly TO controlling_ro;
GRANT readwrite TO jirauser;
EOF
After running this script I expect the roles and the users only to be in the jiradb database. However looking into the default database postgres with dbeaver they are also there. Does this mean they also have access to the postgres database?
That's just an artifact of your client tool.
In reality, PostgreSQL users don't belong to any database; they are shared by all databases. So no matter to which database you are connected when you create a user, it will equally exist for all databases.
You can use the CONNECT permission on the database object or (more typically) configure pg_hba.conf to determine which user can access which database.
According to https://www.postgresql.org/docs/current/sql-createrole.html:
CREATE ROLE adds a new role to a PostgreSQL database cluster. A role is an entity that can own database objects and have database privileges; a role can be considered a “user”, a “group”, or both depending on how it is used. Refer to Chapter 21 and Chapter 20 for information about managing users and authentication. You must have CREATEROLE privilege or be a database superuser to use this command.
Note that roles are defined at the database cluster level, and so are valid in all databases in the cluster.
So it's just your GUI misleading you.

Why is my read-only Postgresql user being denied read permissions on tables?

I am aware that similar questions have been asked before, but the answers do not appear to solve my problem, so I think a more complete answer would be valuable.
I would like to create a read-only user for a postgresql database. I have already granted access to the server for my user using the pg_hba.conf file.
As the postgres admin user, I have run the following commands:
CREATE ROLE read_only_user NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION;
GRANT CONNECT ON DATABASE the_database TO read_only_user;
GRANT USAGE ON SCHEMA public to read_only_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only_user;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO read_only_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO read_only_user;
ALTER ROLE read_only_user WITH PASSWORD '*********************';
ALTER ROLE read_only_user VALID UNTIL 'infinity';
ALTER ROLE read_only_user WITH LOGIN;
ALTER USER read_only_user SET search_path = public;
As a result, I am able to log in to the the_database DB locally, and remotely using a DB client, with username and password authentication and I can list the tables in the database. However, any attempt to select or view the contents of the database results in
ERROR: permission denied for relation the_table
What other permissions are needed, since as far as I can tell, all the necessary permissions are granted.

Read only postgres user [duplicate]

I'd like to create a user in PostgreSQL that can only do SELECTs from a particular database. In MySQL the command would be:
GRANT SELECT ON mydb.* TO 'xxx'#'%' IDENTIFIED BY 'yyy';
What is the equivalent command or series of commands in PostgreSQL?
I tried...
postgres=# CREATE ROLE xxx LOGIN PASSWORD 'yyy';
postgres=# GRANT SELECT ON DATABASE mydb TO xxx;
But it appears that the only things you can grant on a database are CREATE, CONNECT, TEMPORARY, and TEMP.
Grant usage/select to a single table
If you only grant CONNECT to a database, the user can connect but has no other privileges. You have to grant USAGE on namespaces (schemas) and SELECT on tables and views individually like so:
GRANT CONNECT ON DATABASE mydb TO xxx;
-- This assumes you're actually connected to mydb..
GRANT USAGE ON SCHEMA public TO xxx;
GRANT SELECT ON mytable TO xxx;
Multiple tables/views (PostgreSQL 9.0+)
In the latest versions of PostgreSQL, you can grant permissions on all tables/views/etc in the schema using a single command rather than having to type them one by one:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO xxx;
This only affects tables that have already been created. More powerfully, you can automatically have default roles assigned to new objects in future:
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO xxx;
Note that by default this will only affect objects (tables) created by the user that issued this command: although it can also be set on any role that the issuing user is a member of. However, you don't pick up default privileges for all roles you're a member of when creating new objects... so there's still some faffing around. If you adopt the approach that a database has an owning role, and schema changes are performed as that owning role, then you should assign default privileges to that owning role. IMHO this is all a bit confusing and you may need to experiment to come up with a functional workflow.
Multiple tables/views (PostgreSQL versions before 9.0)
To avoid errors in lengthy, multi-table changes, it is recommended to use the following 'automatic' process to generate the required GRANT SELECT to each table/view:
SELECT 'GRANT SELECT ON ' || relname || ' TO xxx;'
FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
WHERE nspname = 'public' AND relkind IN ('r', 'v', 'S');
This should output the relevant GRANT commands to GRANT SELECT on all tables, views, and sequences in public, for copy-n-paste love. Naturally, this will only be applied to tables that have already been created.
Reference taken from this blog:
Script to Create Read-Only user:
CREATE ROLE Read_Only_User WITH LOGIN PASSWORD 'Test1234'
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';
\connect YourDatabaseName;
Assign permission to this read-only user:
GRANT CONNECT ON DATABASE YourDatabaseName TO Read_Only_User;
GRANT USAGE ON SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO Read_Only_User;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO Read_Only_User;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
Assign permissions to read all newly tables created in the future
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO Read_Only_User;
From PostgreSQL v14 on, you can do that simply by granting the predefined pg_read_all_data role:
GRANT pg_read_all_data TO xxx;
Do note that PostgreSQL 9.0 (today in beta testing) will have a simple way to do that:
test=> GRANT SELECT ON ALL TABLES IN SCHEMA public TO joeuser;
Here is the best way I've found to add read-only users (using PostgreSQL 9.0 or newer):
$ sudo -upostgres psql postgres
postgres=# CREATE ROLE readonly WITH LOGIN ENCRYPTED PASSWORD '<USE_A_NICE_STRONG_PASSWORD_PLEASE';
postgres=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;
Then log in to all related machines (master + read-slave(s)/hot-standby(s), etc..) and run:
$ echo "hostssl <PUT_DBNAME_HERE> <PUT_READONLY_USERNAME_HERE> 0.0.0.0/0 md5" | sudo tee -a /etc/postgresql/9.2/main/pg_hba.conf
$ sudo service postgresql reload
By default new users will have permission to create tables. If you are planning to create a read-only user, this is probably not what you want.
To create a true read-only user with PostgreSQL 9.0+, run the following steps:
# This will prevent default users from creating tables
REVOKE CREATE ON SCHEMA public FROM public;
# If you want to grant a write user permission to create tables
# note that superusers will always be able to create tables anyway
GRANT CREATE ON SCHEMA public to writeuser;
# Now create the read-only user
CREATE ROLE readonlyuser WITH LOGIN ENCRYPTED PASSWORD 'strongpassword';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser;
If your read-only user doesn't have permission to list tables (i.e. \d returns no results), it's probably because you don't have USAGE permissions for the schema. USAGE is a permission that allows users to actually use the permissions they have been assigned. What's the point of this? I'm not sure. To fix:
# You can either grant USAGE to everyone
GRANT USAGE ON SCHEMA public TO public;
# Or grant it just to your read only user
GRANT USAGE ON SCHEMA public TO readonlyuser;
I’ve created a convenient script for that; pg_grant_read_to_db.sh. This script grants read-only privileges to a specified role on all tables, views and sequences in a database schema and sets them as default.
I read trough all the possible solutions, which are all fine, if you remember to connect to the database before you grant the things ;) Thanks anyway to all other solutions!!!
user#server:~$ sudo su - postgres
create psql user:
postgres#server:~$ createuser --interactive
Enter name of role to add: readonly
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
start psql cli and set a password for the created user:
postgres#server:~$ psql
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
Type "help" for help.
postgres=# alter user readonly with password 'readonly';
ALTER ROLE
connect to the target database:
postgres=# \c target_database
psql (10.6 (Ubuntu 10.6-0ubuntu0.18.04.1), server 9.5.14)
You are now connected to database "target_database" as user "postgres".
grant all the needed privileges:
target_database=# GRANT CONNECT ON DATABASE target_database TO readonly;
GRANT
target_database=# GRANT USAGE ON SCHEMA public TO readonly ;
GRANT
target_database=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly ;
GRANT
alter default privileges for targets db public shema:
target_database=# ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES
If your database is in the public schema, it is easy (this assumes you have already created the readonlyuser)
db=> GRANT SELECT ON ALL TABLES IN SCHEMA public to readonlyuser;
GRANT
db=> GRANT CONNECT ON DATABASE mydatabase to readonlyuser;
GRANT
db=> GRANT SELECT ON ALL SEQUENCES IN SCHEMA public to readonlyuser;
GRANT
If your database is using customschema, execute the above but add one more command:
db=> ALTER USER readonlyuser SET search_path=customschema, public;
ALTER ROLE
The not straightforward way of doing it would be granting select on each table of the database:
postgres=# grant select on db_name.table_name to read_only_user;
You could automate that by generating your grant statements from the database metadata.
Taken from a link posted in response to despesz' link.
Postgres 9.x appears to have the capability to do what is requested. See the Grant On Database Objects paragraph of:
http://www.postgresql.org/docs/current/interactive/sql-grant.html
Where it says: "There is also an option to grant privileges on all objects of the same type within one or more schemas. This functionality is currently supported only for tables, sequences, and functions (but note that ALL TABLES is considered to include views and foreign tables)."
This page also discusses use of ROLEs and a PRIVILEGE called "ALL PRIVILEGES".
Also present is information about how GRANT functionalities compare to SQL standards.
CREATE USER username SUPERUSER password 'userpass';
ALTER USER username set default_transaction_read_only = on;

Permission denied for relation

I tried to run simple SQL command:
select * from site_adzone;
and I got this error
ERROR: permission denied for relation site_adzone
What could be the problem here?
I tried also to do select for other tables and got same issue. I also tried to do this:
GRANT ALL PRIVILEGES ON DATABASE jerry to tom;
but I got this response from console
WARNING: no privileges were granted for "jerry"
Does anyone have any idea what can be wrong?
GRANT on the database is not what you need. Grant on the tables directly.
Granting privileges on the database mostly is used to grant or revoke connect privileges. This allows you to specify who may do stuff in the database if they have sufficient other permissions.
You want instead:
GRANT ALL PRIVILEGES ON TABLE side_adzone TO jerry;
This will take care of this issue.
Posting Ron E answer for grant privileges on all tables as it might be useful to others.
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO jerry;
Connect to the right database first, then run:
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO jerry;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public to jerry;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public to jerry;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public to jerry;
1st and important step is connect to your db:
psql -d yourDBName
2 step, grant privileges
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO userName;
To grant permissions to all of the existing tables in the schema use:
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA <schema> TO <role>
To specify default permissions that will be applied to future tables use:
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema>
GRANT <privileges> ON TABLES TO <role>;
e.g.
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO admin;
If you use SERIAL or BIGSERIAL columns then you will probably want to do the same for SEQUENCES, or else your INSERT will fail (Postgres 10's IDENTITY doesn't suffer from that problem, and is recommended over the SERIAL types), i.e.
ALTER DEFAULT PRIVILEGES IN SCHEMA <schema> GRANT ALL ON SEQUENCES TO <role>;
See also my answer to PostgreSQL Permissions for Web App for more details and a reusable script.
Ref:
GRANT
ALTER DEFAULT PRIVILEGES
This frequently happens when you create a table as user postgres and then try to access it as an ordinary user.
In this case it is best to log in as the postgres user and change the ownership of the table with the command:
alter table <TABLE> owner to <USER>;
Make sure you log into psql as the owner of the tables.
to find out who own the tables use \dt
psql -h CONNECTION_STRING DBNAME -U OWNER_OF_THE_TABLES
then you can run the GRANTS
You should:
connect to the database by means of the DBeaver with postgres user
on the left tab open your database
open Roles tab/dropdown
select your user
on the right tab press 'Permissions tab'
press your schema tab
press tables tab/dropdown
select all tables
select all required permissions checkboxes (or press Grant All)
press Save
As you are looking for select permissions, I would suggest you to grant only select rather than all privileges. You can do this by:
GRANT SELECT ON <table> TO <role>;
I ran into this after switching a user to another user that also needed to have the same rights, I kept getting the error: "must be owner of relation xx"
fix was to simply give all rights from old user to new user:
postgres-# Grant <old user> to <new user>;
For PostgreSQL. On bash terminal, run this:
psql db_name -c "GRANT ALL ON ALL TABLES IN SCHEMA public to db_user;"
psql db_name -c "GRANT ALL ON ALL SEQUENCES IN SCHEMA public to db_user;"
psql db_name -c "GRANT ALL ON ALL FUNCTIONS IN SCHEMA public to db_user;"