Jay Taylor's notes

back to listing index

How do you create a read-only user in PostgreSQL - Stack Overflow

[web search]
Original source (stackoverflow.com)
Tags: postgres postgresql howto sql privileges read-only grants stackoverflow.com
Clipped on: 2013-09-05

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 DB are CREATE, CONNECT, TEMPORARY, and TEMP.

asked Apr 17 '09 at 12:26
Image (Asset 1/8) alt= 11.3k24102174
add comment
up vote 88 down vote accepted

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 either 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')

This should output the relevant GRANT commands to GRANT SELECT on all tables and views in public, for copy-n-paste love. Naturally, this will only be applied to tables that have already been created.

answered Apr 18 '09 at 0:39
Image (Asset 3/8) alt= 26.3k24563
12 upvote
 flag
You should put your edit concerning PG9 at the top of the post. – Danilo Bargen Dec 12 '11 at 9:36
  upvote
 flag
I've submitted an edit based on your request, Danilo. – André Terra Jun 28 at 17:11
add comment

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;
GRANT
answered Jun 19 '10 at 21:21
Image (Asset 4/8) alt= 9,44632749
add comment

You might find this blogpost helpful: http://www.depesz.com/index.php/2007/10/19/grantall/

answered Apr 17 '09 at 17:16
user80168
add comment

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.

answered Apr 17 '09 at 12:35
Image (Asset 5/8) alt= 62.2k396145
  upvote
 flag
This is exactly right. – Nicholas Kreidberg Apr 18 '09 at 0:40
add comment

"grant select" seems deprecated in Postgres 9.x. in deference to "grant connect"

However, it is still used in the 9.0 manual.

See http://wiki.glitchdata.com/index.php?title=PostgreSQL:_Grant_Privileges_to_a_user

answered Apr 29 at 6:24
Image (Asset 7/8) alt= 1
add comment

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.

answered Oct 27 '11 at 16:22
Image (Asset 8/8) alt= 720312
add comment

Your Answer

 
community wiki

Not the answer you're looking for? Browse other questions tagged or ask your own question.