Limited access for postgreSQL user - postgresql

is it possible to create PostgreSQL user so that he can connect and see only one specific database? So that he could only see one database (he couldn't see the others). Ideally, I could also set the visibility of the tables in the database.
I create user like this:
create user user with encrypted password 'password';
GRANT CONNECT ON DATABASE db TO user;
although I have given the user connect privilege to only one database, he can see all other databases :(

By default the connect privilege to every database is granted to the role public, so you need to run:
revoke connect on database ... from public;
for all other databases. Make sure you grant connect back to existing users.
Another option is to restrict connections for this specific user through pg_hba.conf

Related

How to set or change role upon login automatically in postgres?

I have an existing postgres 11 database called host_db and we have an existing application called host_app that has been using this database for a long time. This service uses superuser host_app_user to connect to database and do all the transactions. Hence, all the database objects are owned by this database superuser.
Now, we want to create db_admin superuser role too in our database whose credentials will be maintained by Vault. But to not mix up database ownership, I was thinking that whenever db_admin logs in to the database, it assumes the role of host_app_user. That way whatever changes the logged admin does will all be done as host_app_user.
My question is: Is there a way I can automatically set the role of logged in user in postgres at the time of logging in?
Use:
alter role db_admin set role host_app_user;
db_admin's role will be set to host_app_user on login.
Note though that db_admin must be a member of host_app_user.
I think the answer is no. But you could do this:
grant db_admin to host_app_user;
Then host_app_user will have all the permissions that db_admin has.

Basic configuration of database permissions

I'm learning databases and I have a question how to prepare the rules and groups configuration for the following assumptions:
I have two databases:
databaseA
databaseB
Each database will have several users connecting using the connectionString (server, port, database, username, password). So I have 3 users to each database:
userA1, userA2, userA3
userB1, userB2, userB3
How to create groups and roles and how to grant permission so that users A can only connect to database A and users B to database B. Can I make A users not see database B, have not seen users assigned to database B?
Probably it is a simple question, but I would like to see an example of how to do it - for now I have A and B database and the postgres user.
There is no point in trying to keep others from seeing a database's or user's metadata, don't try. PostgreSQL does not support that.
You create a user (a “login role”) with
CREATE ROLE user1a LOGIN;
As to the permissions, you first have to remove the default privilege that allows everyone to connect to the database:
REVOKE CONNECT, TEMP ON DATABASE databasea FROM PUBLIC;
Then you have to specifically allow the required users in:
GRANT CONNECT ON DATABASE databasea TO usera1, usera2, usera3;
If you have many users, or the users change frequently, it is better to use a group (a “nologin role”) that has the CONNECTprivilege, and you add the users to the group.
You have to configure pg_hba. conf so that the users are allowed to authenticate, see the documentation.

Create user with grant privileges on only one database

I want to grant read/write privileges to new user only to one database, so he can't access other databases.
After I created new user with:
sudo -u postgres createuser <username> What privileges this user get?
Is this all I need:
GRANT ALL PRIVILEGES ON my_db TO new_user; to get access to only one database?
What is the best way to do this?
Using PostgreSQL 10
By default, PUBLIC (everyone) is allowed to connect to all databases. So you'd have to revoke that privilege and hand out CONNECT more judiciously.
In addition to that, you'd have to make sure that every user has CREATE on all schemas in “his” database and the necessary privileges on all tables, because privileges on the database itself are not enough to access the objects in the database.
It could be the simplest solution to use REASSIGN OWNED to give the user ownership of all objects in “his” database.

Postgres ACL for Schemas

I'm not a DBA and I have got some questions around access controls for schemas. Let's say I have a Postgres server running a several databases. The admin user is postgres. I have another user tmpUser with which I could log in to the remote server using pgadmin3 client.
I now create a database called myDatabase which is by default owned by the postgres user. I then use my admin client to remotely log in to this myDatabase using the tmpUser account.
I now create a new schema inside this myDatabase called myDbSchema. I created a new role called myDbRole and did a grant usage, grant all on myDatabase, myDbSchema to the myDbRole.
The question now is how should I control access to this myDatabase. I tried to log in to the remote server using the tmpUser and when I tried to execute select * from myTable where myTable is a table in myDatabase, it came back with a permission denied sql message. So I changed the owner of the table to the tmpUser which I really do not want to!
Is there a guide or something on how I should go about creating and organizing roles with schemas in postgres?
It is not entirely clear what your problem is (for instance, what is role "myDbRole" for, is that a group role (NOLOGIN) or a user role (LOGIN)?) but in general you could follow this pattern of permission management:
Create a specific role to own a database and all or most of the objects in it. This should be a group role (NOLOGIN) for security reasons. Do not use the postgres user; if you need to login as that role often to do regular database work, you are doing something wrong. Any superuser (or other user role that has that role granted to it) can "impersonate" that owner role using SET SESSION AUTHORIZATION to do necessary maintenance. In a production environment this should be hardly ever necessary; during development you might want to consider making the role with LOGIN permission for ease of use.
The owner creates all the schemas, tables, views, functions, etc. that you need for your application. By default, all of those objects are only available to the database owner, with the exception of functions.
Define a number of group role profiles, each having specific requirements of the database. You could have, for instance sales_staff, product_managers, accounting and senior_management for a company, or web_user, web_admin, app_developer and app_manager for a web site. The database owner then GRANTs access to the database (CONNECT), schemas (USAGE), tables, views and functions (EXECUTE), as needed. I usually REVOKE ALL ON FUNCTION x() TO public, for security reasons.
Assign group role membership to user roles, as needed: GRANT sales_staff TO jane. The user roles should have LOGIN INHERIT such that they can log in and inherit the permission of group roles that they are a member of. That includes the permission to connect to a database and usage rights on schemas. Note that a single user role can have membership in multiple group roles.
Lastly, update your pg_hba.conf file to enable remote access to the database.

Database named "postgres"

I've just set up Postgres for use by different users on my network. Every user has his own username/password/database, but when I connect to Pg I can also see a 'postgres' database (and even create tables etc). I tried to REVOKE access to that database from public but then it won't let me connect. What exactly is the postgres database and why is it needed? Can I disable it so that users only see the database(s) I've created for them?
The postgres database is created by default when you run initdb.
Quote from the manual:
Creating a database cluster consists of creating the directories in which the database data will live (...) creating the template1 and postgres databases. When you later create a new database, everything in the template1 database is copied. (...) The postgres database is a default database meant for use by users, utilities and third party applications.
There is nothing special about it, and if you don't need it, you can drop it:
drop database postgres;
You need to do that as a superuser of course. The only downside of this is that when you run psql as the postgres operating system user, you need to explicitly provide a database name to connect to
If you drop the postgres database you'll find a few things to be confusing. Most tools default to using it as the default database to connect to, for one thing. Also, anything run under the postgres user will by default expect to connect to the postgres database.
Rather than dropping it, REVOKE the default connect right to it.
REVOKE connect ON DATABASE postgres FROM public;
The superuser (usually postgres), and any users you explicitly grant rights to access the database can still use it as a convenience DB to connect to. But others can't.
To grant connect rights to a user, simply:
GRANT connect ON DATABASE postgres TO myuser;