3

Is it possible in PostgreSQL to create a user that can only access a single schema?

Here is what I tried:

REVOKE ALL ON DATABASE testdb FROM public;
GRANT CONNECT ON DATABASE testdb TO testuser;

When I connect as testuser indeed I cannot access the actual data:

> SELECT * FROM some_table;
ERROR:  permission denied for relation some_table

However, I can still list all the tables, etc. in all the other schemas:

SELECT * FROM pg_tables;
     schemaname     |                 tablename                 | tableowner | tablespace | hasindexes | hasrules | hastriggers | rowsecurity
--------------------+-------------------------------------------+------------+------------+------------+----------+-------------+-------------
 test2              | foo                                       | postgres   |            | t          | f        | f           | f
 test2              | bar                                       | postgres   |            | t          | f        | f           | f
...
AndreKR
  • 32,613
  • 18
  • 106
  • 168
  • Possible duplicate of [PostgreSQL Revoking Permissions from pg\_catalog tables](http://stackoverflow.com/questions/20554771/postgresql-revoking-permissions-from-pg-catalog-tables) – Burhan Khalid Aug 22 '16 at 02:38
  • @BurhanKhalid That's not a duplicate. I absolutely want the user to read pg_tables, but only see his own objects of course. – AndreKR Aug 22 '16 at 02:42
  • Then you need to revoke access to all schemas except his own (as detailed in the answer to that question). – Burhan Khalid Aug 22 '16 at 02:44
  • I thought I already did that, how can I check? – AndreKR Aug 22 '16 at 02:46
  • @Abelisto I wanted to let different users share one database, so a user with sufficient permissions can still join data between the schemas, but regular user cannot. – AndreKR Aug 22 '16 at 02:53
  • Sorry I was not clear. The problem you described that the user able to list the tables from any schemes even it have no right to select data from those tables. Right? In othe words: I can see the box but I can not see the box content. Is it a problem? – Abelisto Aug 22 '16 at 02:58
  • Of course that is a huge problem if the "users" are actually different users (= persons; or compromised applications). Table and (even more so) column names are very sensitive information for any application that isn't open source. – AndreKR Aug 22 '16 at 03:05
  • If you are shame about table/column names... If seriously there are no DBMS provides such restriction (**as I know!**) Oracle tries to do something but (**as I know!** again) there is a several hacks for it. Probably (sorry for self-advertisement) it helps: [PostgreSQL 9.5: Permission to deny functions body](http://dba.stackexchange.com/a/134963/88191) – Abelisto Aug 22 '16 at 03:20
  • @Abelisto Thanks for the self-advertisement, it's actually quite helpful. :) – AndreKR Aug 22 '16 at 03:26

2 Answers2

5

It is impossible to configure PostgreSQL so that a user can only see those objects in the system catalogs for which he or she has permissions.

If you need such a setup, you should create a database per user.

Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
  • 1
    It is not a criticism, but what is "database per user." and how it helps? – Abelisto Aug 22 '16 at 03:34
  • Maybe I was too concise. From the comments it is clear that @AndreKR wants several users to use one database, each has its own schema, and nobody should be able to see objects owned by other people. Which you cannot have. So it is best just to use a database per user. – Laurenz Albe Aug 22 '16 at 03:41
0

I was able to do this like so:

GRANT USAGE ON SCHEMA schema_name TO user_name;
ALTER USER user_name SET search_path = schema_name;

The ALTER USER statement like this is a way of permanently setting the search path for schemas the way you would set the schema search path of an individual sessions with

SET SEARCH_PATH= schema_name_1, schema_name_2;
  • 3
    Have you tried running `SELECT * FROM pg_tables` as user_name afterwards and checked that he cannot see any other schema? – AndreKR Mar 09 '17 at 03:16