How to create a read-only user in postgres for all schema? - postgresql

I am wondering if anyone knows a command to create a read-only user for all schemas and tables in a postgres DB. I have found ways to do it for specific tables and specific schemas but not across the board (we have many schemas and I would rather not run the command 60+ times). Thanks in advance

There is no simple way to do that in PostgreSQL.
What you should do is create a role that has read access to all tables (and yes, you'll have to run at least one GRANT statement per schema) and grant that role to all login users that need read access.
That way you have to do the work only once, and dropping the user becomes so much easier.

Related

very confused about permissions in postgres

I have multiple databases and each of them have multiple schemas.
I have a set of apps that connect to these databases. Each app has it own user and, depending on their function, the apps can:
read / write all schemas and tables of a specific db, set functions/notifications
read only all schemas and tables of a specific db
The schemas and tables can be created at any time, so the permissions need to be set with ALTER DEFAULT.
My understanding is that the ALTER DEFAULT has to be done by the user that will create the future tables. Is that correct?
Since I can have scenarios where User 1 can RO db A, but RW db B, while User 2 can only RO db B, etc.. using roles doesn't seem to be of any help here.
So I'm a bit confused how to set that up.
Then comes the next complication:
I can assign permissions as either SELECT (RO), or SELECT, INSERT, UPDATE, DELETE (RW), but:
what about sequences? I don't want a RW user to be able to alter the sequences, but they need to be able to use them
then how does it work with functions? the RW users need to be able to set/update their own functions
Any example of this setup would be greatly appreciated because going through the doc didn't help me much and most of the questions / answers on SO seems to be very similar yet never exactly the same, so it's quite confusing :)
Edit, following 'a_horse_with_no_name''s suggestion in the comments, I did this:
here is my init.sql:
CREATE DATABASE accounts;
CREATE DATABASE analysis;
CREATE DATABASE exchange;
GRANT CONNECT ON DATABASE exchange TO capture, analyzer, sunny, viewer;
GRANT CONNECT ON DATABASE analysis TO analyzer, sunny, viewer;
GRANT CONNECT ON DATABASE accounts TO sunny;
then I log in as admin to db exchange and do:
GRANT pg_write_all_data TO capture;
GRANT pg_read_all_data TO analyzer, sunny, viewer;
and I create a table called instruments there
then I log in as capture to to db exchange and do an insert, and I get:
42501: permission denied for table instruments
so using the capture user on the exchange db, I should have the pg_write_all_data property; why do I get the error?
It looks like I have to grant usage of instruments to capture.. which defeats the purpose of the pg_write_all_data. If I do the grant, then it works. So it looks like adding the role doesn't work.
Since your users shall have different permissions in different databases, define read-only and read-write roles for each database.
For example, db1_ro has read-only permissions in db1, and db2_rw has read-write permissions in db2. Then you can grant them both to a user, and the user will have different permissions in different databases.
Using a sequence typically means to call nextval(). So you should give that user the USAGE privilege. To use setval(), the user would need UPDATE. Nobody except the owner can ALTER an object anyway.
Functions cannot be set or updated, only executed, for which there is the EXECUTE privilege, which is granted to PUBLIC by default.

Postgres DB USER Creation

I am new to Postgres and want to know if there is a way to CREATE a DB USER in such a way that it will have access to ALL the SCHEMA's including those which are not created yet, I mean access to all the current and future schema's.I have multiple Schema's in my Postgres DB which have the same Tables.If the above is possible I want this user to have SELECT,INSERT,UPDATE on only 2 Tables in the existing and future created Schemas.
You can use ALTER DEFAULT PRIVILEGES to give a user permissions on future schemas and tables, but you cannot restrict that to certain table names.
You may be able to do that with an event trigger.
Personally, I would put GRANT statements into the code that creates the tables.

PostgreSQL: Only allow users to execute procedures, but avoid access to any other resources such as tables?

I want to limit the type and scope of all operations that a user can make in order to protect the database.
How can I tell PostgreSQL that a given user is only allowed the execution of stored procedures, and not to read or write tables directly?
If there are better ways to do this I am also opened to suggestions :)
Thanks!

Multi tenancy with Schemas and RLS in PostgreSQL

I am new to Postgres/databases and am thinking of how to design a multi tenant application. I read some of the basic stuff such as schemas supported by Postgres and Row Level Security which is added since Postgres 9.5. So in my case a tenant can have many users. Two different tenants can have users with same name ( Kind of like a hierarchy). So at the top level, I can have a schema for each tenant. And then within each there is a RLS policy for users. Can this be done in Postgres and is this a good option ? With RLS, I will need a role for each user. This will probably blow up since my understanding is that roles are global across schemas.
Or other thing I can think of is that I keep everything in same tables but have policies which honor the user as well as tenant columns in the table. Is this possible in Postgres ? For example, when I add a policy with current_users = "column_name" ,can I add another condition where I add a check that the top level tenant name matches. But where and how is this set, similar to SET ROLE "user"
Bit confused about the right approach to use.
I would go with tenant per database. This is a little easier to backup (per tenant) and a little more secure by default. And a little easier to manage w pgAdmin.
You don't need a db user for each application user to use RLS, but it's probably a good idea.
Set db_user_namespace=true in postgresql.conf to allow per-db usernames. See http://www.postgresql.org/docs/9.5/static/runtime-config-connection.html for caveats

How to prevent a user from being able to see other databases and the tables from other databases?

I want to create a postgres user that can access only one database on the postgres server at all.
Currently my flow is:
create database database1;
create user user1 with password 'pass';
grant all privileges on database database1 to user1;
but user1 can still see a list of dbs, users, tables etc. Is there a way to prevent that user from seeing that info? The user needs to be able to write to and read from that db.
Thanks a lot.
Each user can see other databases and roles listed, but should not be able to see tables in other databases, ever.
If you revoke CONNECT privilege on all databases except the allotted one, the user will not be able to access the contents of other databases.
Roles and database names are global, and not readily blockable. You can try Frank Heikens suggestion of selective revocations on the system tables, but you take risks to do that. PostgreSQL developers on the usenet mailing lists have discouraged tampering with access to the system catalogs.
Psql, among other tools, assumes they will be available and functions poorly without them.
Why is knowing the names of other databases and roles so bad?
REVOKE the SELECT permissions on the information_schema and some sections in the system catalog.
By default any objects you create are created in the public schema. Also, any users that you create have CREATE and USAGE privileges on the public schema. You should revoke CREATE and USAGE to the public schema for this user, or you should change the default access level. You'll also need to move the database to which this user has access into the user's schema, or a schema accessible to the user. See DDL Schemas in the Postgres manual.