What is the difference between a user and a role? - postgresql

I know there are other threads that are similar, but I am not sure if they are relevant to Postgres.
I am reading the PostgreSQL documentation which it reads as follows:
Note: As explained in Chapter 20, PostgreSQL actually does privilege
management in terms of "roles". In this chapter, we consistently use
database user to mean "role with the LOGIN privilege".
Does this basically mean a role is a database user? Or is there a difference between a role and a user? Do users have the potential to not have full privileges while roles are users who always do have full privileges?

Previous versions of Postgres, and some other DB systems, have separate concepts of "groups" (which are granted access to database objects) and "users" (who can login, and are members of one or more groups).
In modern versions of Postgres, the two concepts have been merged: a "role" can have the ability to login, the ability to "inherit" from other roles (like a user being a member of a group, or a group being a member of another group), and access to database objects.
For convenience, many tools and manuals refer to any user with login permission as a "user" or "login role", and any without as a "group" or "group role", since it is useful and common practice to keep roughly to that structure. This is entirely a convention of terminology, and to understand the permissions, you need only understand the options available when creating roles and granting them access.
Again purely for convenience, Postgres still accepts commands using the old terminology, such as CREATE USER and CREATE GROUP which are both aliases for CREATE ROLE. If you write CREATE USER, the LOGIN permission will be added to the new role by default, to emulate the old behaviour when that was a separate command.

I found this link pretty useful.
The final goal is that some user/role can readwrite, some rule/user can be only read.

https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/#:~:text=Users%2C%20groups%2C%20and%20roles%20are,to%20log%20in%20by%20default.&text=The%20roles%20are%20used%20only,grant%20them%20all%20the%20permissions.
Users, groups, and roles
Users, groups, and roles are the same thing in PostgreSQL, with the only difference being that users have permission to log in by default. The CREATE USER and CREATE GROUP statements are actually aliases for the CREATE ROLE statement.
enter image description here
In other relational database management systems (RDBMS) like Oracle, users and roles are two different entities. In Oracle, a role cannot be used to log in to the database. The roles are used only to group grants and other roles. This role can then be assigned to one or more users to grant them all the permissions. For more details with a focus on how to migrate users, roles, and grants from Oracle to PostgreSQL, see the AWS blog post Use SQL to map users, roles, and grants from Oracle to PostgreSQL.

Related

What is the usage of a NOLOGIN user in the postgresql?

I'm trying to understand the initial steps of PostgREST tutorial.
In the mentioned tutorial, it is recommended to create two different roles named web_anon and authenticator as below:
create role web_anon nologin;
grant usage on schema api to web_anon;
grant select on api.todos to web_anon;
create role authenticator noinherit login password 'mysecretpassword';
grant web_anon to authenticator;
As far as I know, the the PostgREST server receives Rest API requests from the clients, without any information about the user (role). And also, as far as I know, nologin roles can't do login to database. (can they send queries?)
So the questions are:
why do we need two different roles? What is the role of web_anon and what is the role of authenticator?
What can a nologin role do in postgres?
When PostgREST receives a rest API query, which user does it use to send and execute that query to the database?
To question 1:
A NOLOGIN role can be seen as a user group. The idea is to attach all privileges to a group rather than to individual users, which has several advantages:
It is possible to drop the user, because it does not have any privileges.
It is less work to add a user to a group or remove a user from a group than to grant or revoke lots of permissions whenever you have to add a user or change its privileges.
There is no danger of having so many individual ACL entries attached to a single database object that it becomes impossible to add more permissions (the whole metadata row has to fit into a single 8kB block).
This whole exercise only makes sense if you have many users in the database, otherwise it is silly. But it is a good idea to have different users for different purposes.
To question 2:
A NOLOGIN role can either be a group that carries privileges that users can inherit.
Another use is that you can use SET ROLE to assume the identity of the role.
To question 3:
I guess whatever user you use in the PostgreSQL connect string.

How to use postgresql roles to connect a database?

We saw PostgreSQL roles in class this year. Our teacher told us that it is more secure to use different roles with custom rights for every table or even column if necessary.
We have a project in which we have to use PostgreSQL to build a website with restricted access for connected users, who can be of different types (admin, employee, client). To follow the teacher's recommendations, we created different roles with different rights (one for each type of user).
We decided to use Go for our back end (with token auth) but I can't figure it out how to use our roles, which are more groups than users. I read in the doc that you "open" the connection to the DB once for all but to do so you have to give a PostgreSQL role. I didn't find a way to change the connected role without closing and reopening the DB. If I run the application without changing connected roles, how can PostgreSQL control if a user has the right to access tables he needs for the requests.
You can change roles on the fly in PostgreSQL. If you are logged in as nobody, and nobody is a member of role cleve, you can become role admins with
SET ROLE cleve;
But using that during authentication is problematic, because there is nothing that keeps the user from running the statement
RESET ROLE;
to become nobody again and then impersonating somebody else.
Typically, there are two ways how you can use the role system to leverage database permissions:
You have a personalized database user for every user of the application.
That is of course only feasible if the set of users is fairly constant and limited.
Then the individual users have no permissions at all, and there are certain roles like admin, reader, accountant and so on. The login roles are assigned permissions by becoming members of one or more of these roles, and they inherit their permissions.
You don't have personalized database users.
Then you only have one login role per set of permissions, say accountant, admin, viewer and so on.
The application has to decide as which user it should connect before establishing the database connection. If you need database queries for this decision, you perform those as a nobody database user with very limited permissions. For example, it may call a function that verifies a user-supplied password.
You can use the set role command to change the role while the session is open.

Firebird user has all access rights on a single database except cannot create new db and no access to other database

I have a server that will manage multiple Firebird databases. My users are allowed to have full access on all the objects for a single database but they are not allowed to create new database and no access to other databases in the same server. How do I configure for this scenario?
Since Firebird 3, users need to have an explicit privilege to create databases (Database DDL Privileges). So as long as you don't grant that privilege to a user, they cannot create a database (unless they have and apply the RDB$ADMIN role).
Giving a user access to everything in a database is harder to do. You'll need to define the access for each database object individually. The preferred way to do that, is to grant the necessary access to a role, and grant that role to the user. See SQL Privileges for details.
In Firebird 3 and earlier, users do not assume the rights of a role unless they explicitly specify that role on connect. Firebird 4 will introduce default roles, which will always be applied. It might be possible to use Firebird 3 privilege mapping to define a default role as well, but I'm not sure if that works.
Firebird does not provide a way to disallow a user to connect to a database: almost all rights are stored per database, so a user has to connect before the server knows which rights they have. If you want to disallow users to connect, you will need to create a custom ON CONNECT trigger to raises an exception for users that shouldn't be allowed to connect.

Creating super user in MongoDB 3.2

Previously in Mongo 2.6 was possible to create super user that will access all databases. However in the documentation of MongoDB 3.2 I don't see this option. My question is, how can I add a user in MongoDB 3.2 that will have access to all databases?
The roles are well documented for MongoDB 3.2
The superuser roles do provide access to all databases, either directly or implicit. However it is bad practice to do the bread and butter CRUD work with a superuser. You should always apply the Principle of least privilege.
If you only want the user to be able to read all databases, that would be the readAnyDatabase role. If the user should be able to modify all databases, that would translate to the readWriteAnyDatabase role.
In MongoDB 3.2 you have a bunch of built in roles. You can see them here :
https://docs.mongodb.org/manual/reference/built-in-roles/
Unfortunatly there is no "super user" role. You have to give several roles to your user.
Personally my super users have these roles :
userAdmin or userAdminAnyDatabase : allow him to create users
clusterAdmin : this role allow me to shutdown databases and manage my cluster
readWriteAnyDatabase : I think you can guess what it does
But you can add other roles to fit your user to your needs.

Two owners of the same PostgreSQL database

Is it possible with Postgresql to create a database which has 2 users which act like owners to the database?
I can create a group role and add both users to that group, and then make the group the owner of the database, but this requires both users to be have to manually set their role on every connection to make any tables they have created accessible to the other user. Is there any way to make the group be the default role for a user each time they log in or any other way to achieve the same thing?
No, each database can only have one owner. As stated previously you can have more than one superuser, or you can grant permissions specifically to group roles that are then inherited.
You might want to look at http://blog.hagander.net/archives/70-Faking-the-dbo-role.html, for a way to fake something similar to what you're asking for. It's not perfect, but it might be good enough for you. It should be able to solve the object-ownership problem at least.
Ah, found it: PostgreSQL Docs: Chapter 20. Database Roles and Privileges
"member roles that have the INHERIT attribute automatically have use of privileges of roles they are members of."
CREATE ROLE joe LOGIN INHERIT;
CREATE ROLE admin NOINHERIT;
GRANT admin TO joe;
"Immediately after connecting as role joe, a database session will have use of privileges granted directly to joe plus any privileges granted to admin, because joe "inherits" admin's privileges."