How do you view users that have been issued GRANT CONNECT ON DATABASE <database> TO <user>?
\dp - lists table/view permissions
\dn+ - lists schema permissions
\l+ does not list all users that can access the database
A bit odd if the \l+ command just displays some of the users that have permission/privilege to connect to the database. I could not repeat that myself on a PostgreSQL 8.4 installation (Ubuntu 10.04 LTS). What version are you using?
Anyway, perhaps you could check the table holding the ACL's for that particular database and from that deduce whether the user has the correct privileges or not:
SELECT datname as "Relation", datacl as "Access permissions" FROM pg_database WHERE datname = 'databasename';
If you just want to check one user you could do something like this:
SELECT * FROM has_database_privilege('username', 'database', 'connect');
How are the permissions/privileges to interpreted? The privileges are to be read like this:
user = privileges / granted by
Omitting user means that PUBLIC is granted the privilege, ie all roles. For example if the privilege is =Tc/postgres then all roles may connect and create temporary tables in that particular database and it is the postgres user who granted the privilege.
There is a synopsis at the PostgreSQL site explaining the different privileges: https://www.postgresql.org/docs/current/ddl-priv.html#PRIVILEGE-ABBREVS-TABLE.
rolename=xxxx -- privileges granted to a role
=xxxx -- privileges granted to PUBLIC
r -- SELECT ("read")
w -- UPDATE ("write")
a -- INSERT ("append")
d -- DELETE
D -- TRUNCATE
x -- REFERENCES
t -- TRIGGER
X -- EXECUTE
U -- USAGE
C -- CREATE
c -- CONNECT
T -- TEMPORARY
arwdDxt -- ALL PRIVILEGES (for tables, varies for other objects)
* -- grant option for preceding privilege
/yyyy -- role that granted this privilege
I'm using psql from postgres 8.4 and postgres 9.0, and the command \l or \l+ gives me column Access Privileges where I have entry:
<user_name>=c/<database_name>
and earlier I gave the user the connect privilege as you wanted.
As it states on the page http://www.postgresql.org/docs/9.0/static/sql-grant.html, the c letter here means Connect.
Related
I'm trying to achieve the following:
I have user1 which is created.
This user1 has databases user1_db1, user1_db2 , user1_db3
When I grant the owner of user1 to all the databases, I am able to do everything with them,except if I create user1_user1 , grant All access ( without the owner ) to user1_db. Then user1_user1 will throw errors like :
user1_user1=> ALTER DATABASE "user1_dbl" SET bytea_output = 'escape';
ERROR: must be owner of database user1_db1
What I need is a special user ( in this case user1_user1 ) to be able to do everything with the database that all access have been granted and is still visible in phppgadmin ( when $conf['owned_only'] = true; is set ) when logged with user1 , or if needed I can create a special user for PHPpgAdmin but must view the databases that are with prefix user1 only.
Maybe my approach is not proper so please let me know how can I achieve this.
The goal is to have 1 user , able to access/modify all those databases and in the same scenario , user1_user1 is able to do the same but not accessing phppgadmin. The limitation that I am seeing is the ownership only and I am not able to bypass it...
Thank you for your advices!
You can use the same user for all of the databases, but you will need to give that user access to each database. You can do that by running the following SQL:
GRANT ALL PRIVILEGES ON DATABASE user1_db1 TO user1_user1; GRANT ALL PRIVILEGES ON DATABASE user1_db2 TO user1_user1; GRANT ALL PRIVILEGES ON DATABASE user1_db3 TO user1_user1;
You can also give the user access to all databases by running the following SQL:
GRANT ALL PRIVILEGES ON ALL DATABASES TO user1_user1;
You can also give the user access to all tables in a database by running the following SQL:
GRANT ALL PRIVILEGES ON user1_db1.* TO user1_user1;
You can also give the user access to all tables in all databases by running the following SQL:
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO user1_user1;
You can also give the user access to all sequences in a database by running the following SQL:
GRANT ALL PRIVILEGES ON user1_db1 TO user1_user1;
You can also give the user access to all sequences in all databases by running the following SQL:
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO user1_user1;
You can also give the user access to all functions in a database by running the following SQL:
GRANT ALL PRIVILEGES ON user1_db1 TO user1_user1;
You can also give the user access to all functions in all databases by running the following SQL:
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO user1_user1;
You can also give the user access to all types in a database by running the following SQL:
GRANT ALL PRIVILEGES ON user1_db1 TO user1_user1;
You can also give the user access to all types in all databases by running the following SQL:
GRANT ALL PRIVILEGES ON ALL TYPES IN SCHEMA public TO user1_user1;
You can also give the user access to all operators in a database by running the following SQL:
GROMySQL: How to grant all privileges on all databases and tables to a user?
The best way to do this is to use the GRANT ALL PRIVILEGES ON . TO 'user'#'localhost' syntax.
GRANT ALL PRIVILEGES ON *.* TO 'user'#'localhost' IDENTIFIED BY 'password';
This will give the user all privileges on all databases and tables.
I finally made it work with the memberships :
postgres=# \du
List of roles
Role name | Attributes | Member of
-------------------+------------------------------------------------------------+---------------------
user1 | | {user1_pgsqluser}
user1_pgsqluser | | {}
This can be granted as follow :
psql -U postgres -c 'grant $dbuser to $user;'
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.
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;
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;
I'm having trouble granting privileges to another user in PostgreSQL 8.3. While the GRANT command gives me no error, the privileges do not show up. Do I need to "flush" them?
sirprize=# CREATE DATABASE testdb;
CREATE DATABASE
sirprize=# GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;
GRANT
sirprize=# \c testdb
You are now connected to database "testdb".
testdb=# \z
Access privileges for database "testdb"
Schema | Name | Type | Access privileges
--------+------+------+-------------------
(0 rows)
testdb=#
\z Shows your table, view, and sequence permissions, for the objects contained within the Database. It does not show permissions on the database itself. If you create a table or some other object within 'testdb', it will then show up in \z's output.
You can see which Databases exist on your system with \l (or \l+ for a bit more info).
See section 9.22. of the PostgreSQL 8.3 manual for information about how to programatically determine which permissions exist for a user on a given database.