PostgreSQL Permissions – Why Can a New User Select from Any Table

access-controlpermissionspostgresqlpostgresql-9.1

When I create a user in Postgres,

create user test with password 'test';

The user ends up being able to connect to every database in the instance. The user can also select from any table:

# psql -h localhost testdb test
Password for user test: *****
psql (8.4.20, server 9.1.13)
WARNING: psql version 8.4, server version 9.1.
         Some psql features might not work.
Type "help" for help.

testdb=> select * from testtable;
 id
------------
      1
(1 row)

The \l database listing shows that testdb has empty Access privileges. So why can a newly created user connect to that database?

The newly created "test" user can also select data from tables. Why can he do so without a grant of select privileges?

I'd like to create a user that can only connect to one database and only read from certain views. How can I prevent a user from reading directly from tables?

Best Answer

To address the question of why test can SELECT from tables without a GRANT, it is because you have not explicitly run REVOKE for the ability to connect to your database(s) from PUBLIC, and then explicitly run GRANT for your test user:

REVOKE connect ON DATABASE testdb FROM PUBLIC;
GRANT connect ON DATABASE testdb TO test;

Once that is done, you would REVOKE SELECT for your user within that database your tables and other items you wish to prevent the user from accessing, and then explicitly GRANT SELECT for the views.

Note that user here could also be role, which multiple users could then be added to.