I wonder if there is a possibility to hide tables from a certain user, not just revoking access to them.
Basically what needs to be done is to grant a user read-only access to the DB, but hide some tables from him.
I tried to revoke all privileges from schema public but to no avail.
So far you can not hide Postgres System Catalogs. Meaning you can not hide metadata.
The user can still see the structure, but can not access them if not granted access.
If you want to grant specific permissions to specific users you can use VIEWS.
https://www.tutorialspoint.com/postgresql/postgresql_views.htm
Related
We create many shares with accountadmin.
Now we granted 'create shares' to sysadmin, how can i change the ownership of previous shares to sysadmin without drop and recreate the share?
I think currently
The ACCOUNTADMIN role has the privileges to create a share.
You can also grant CREATE SHARE and IMPORT SHARE to other roles, enabling the tasks to be delegated to other users in the account. For more information, see Enabling non-ACCOUNTADMIN Roles to Perform Data Sharing Tasks.
Also Ownership of a share cannot be transferred to another role
Ownership of a share, as well as the objects in the share, may be either through a direct grant to the role or inherited from a lower-level role in the role hierarchy. For more details, see Role Hierarchy and Privilege Inheritance.
Also, it’s possible for the same role to own a share and the objects in the share.
The only option will be to drop and recreate the share
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.
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.
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.
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."