Remove ability view/list all table from schema - amazon-redshift

Using a Amazon Redshift database. I have a schema called 'Public', and another schema called 'SchemaX'. I have created a user called 'User1'; and give him access to 'SchemaX'. I want to stop 'User1' from viewing or listing the available tables in my 'Public' schema. How does one go about doing this?

To disallow users from creating objects in the PUBLIC schema of a database, use the REVOKE command to remove that privilege.
REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | REFERENCES } [,...] | ALL [ PRIVILEGES ] }
ON { [ TABLE ] table_name [, ...] | ALL TABLES IN SCHEMA schema_name [, ...] }
FROM { username | GROUP group_name | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
SELECT
Revokes the privilege to select data from a table or a view using a SELECT statement.
INSERT
Revokes the privilege to load data into a table using an INSERT statement or a COPY statement.
UPDATE
Revokes the privilege to update a table column using an UPDATE statement.
DELETE
Revokes the privilege to delete a data row from a table.
REFERENCES
Revokes the privilege to create a foreign key constraint. You should revoke this privilege on both the referenced table and the referencing table.
ALL [ PRIVILEGES ]
Revokes all available privileges at once from the specified user or group. The PRIVILEGES keyword is optional.
ON [ TABLE ] table_name
Revokes the specified privileges on a table or a view. The TABLE keyword is optional.
ON ALL TABLES IN SCHEMA schema_name
Revokes the specified privileges on all tables in the referenced schema.
GROUP group_name
Revokes the privileges from the specified user group.
PUBLIC
Revokes the specified privileges from all users. PUBLIC represents a group that always includes all users. An individual user's privileges consist of the sum of privileges granted to PUBLIC, privileges granted to any groups that the user belongs to, and any privileges granted to the user individually.
CASCADE
If a user holds a privilege with grant option and has granted the privilege to other users, the privileges held by those other users are dependent privileges. If the privilege or the grant option held by the first user is being revoked and dependent privileges exist, those dependent privileges are also revoked if CASCADE is specified; otherwise, the revoke action fails.
For example, if user A has granted a privilege with grant option to user B, and user B has granted the privilege to user C, user A can revoke the grant option from user B and use the CASCADE option to in turn revoke the privilege from user C.
RESTRICT
Revokes only those privileges that the user directly granted. This behavior is the default.

Related

postgreSQL: How to use ROLE to allow full access to all users part of a given role (without using SET ROLE prior accessing a table for instance)

I'm coming to postgreSQL with a SQL Server background and was naively applying the same concepts to postgreSQL in order to allow different users to share 'by default' some objects within a database.
This is what I did:
CREATE DATABASE testdb;
CREATE ROLE testdb_role_full INHERIT;
GRANT ALL PRIVILEGES ON DATABASE testdb TO testdb_role_full;
CREATE USER user1 INHERIT;
GRANT testdb_role_full TO user1;
CREATE USER user2 INHERIT;
GRANT testdb_role_full TO user2;
Once done, I created a table t1 using the user1.
Then, I tried, as user2, to read the t1 table and I received a "permission denied error"... :-(
By reading the documentation, it seems that I have to issue a SET ROLE testdb_role_full first so as to act as the testdb_role_full.
However, this is not really that I want. I do not want the user to be aware of this.
So my question:
Is there any way to make this work?
Thanks a lot,
José
You've granted some privileges on the database, but that doesn't mean any user with the role testdb_role_full would have all privileges on all objects inside that database. To quote from the documentation:
When an object is created, it is assigned an owner. The owner is normally the role that executed the creation statement. For most kinds of objects, the initial state is that only the owner (or a superuser) can do anything with the object. To allow other roles to use it, privileges must be granted.
So after the user1 created the table t1, he is the owner and only he has the privileges on it. He would need to run
GRANT ALL PRIVILEGES ON TABLE t1 TO testdb_role_full;
then user2 would be able to access it as well (without having to switch any roles - that's only necessary when it has the NOINHERIT attribute on the role).
If you don't want your users to have to execute GRANT each time they create a new object in the database, you can alter the default privileges that will be applied whenever an object is created by user2:
ALTER DEFAULT PRIVILEGES FOR user2
GRANT ALL PRIVILEGES ON TABLES TO testdb_role_full;
Notice these specify the initial value only, and user2 could revoke the privileges on his tables if he wanted to prevent others from seeing them.

Create aws redshift user with access to given schema including drop tables

I would like to seperate access to two existing data schemas (with tables already created) in redshift by creating two new users and granting them access to their relevant schemas.
So user_1 should have access only to schema_1 and user_2 should have access only to schema_2.
By access I mean that the users should be able to SELECT, INSERT, UPDATE, DELETE, DROP from all current tables (no matter who created them) and to CREATE new tables on their schemas.
I have found the below statements to create a new user and to give them specific access types:
Create new user:
CREATE USER user_1 WITH PASSWORD 'password_1';
Grant usage to the given schema:
GRANT USAGE ON SCHEMA "schema_1" TO user_1;
Assign privileges:
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA "schema_1" TO user_1;
Alter Default Privileges to maintain the permissions on new tables
ALTER DEFAULT PRIVILEGES IN SCHEMA "schema_1" GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO user_1;
In the documentation it shows how to add all privileges required except for DROP tables. When testing this it errors with ERROR: must be owner of relation table_to_drop.
I alternatively have tried to grant all privileges as below...
GRANT ALL TABLES IN SCHEMA "schema_1" TO user_1;
...but this doesn't overwrite the requirement of it needing to be the owner of the table that drops is able to drop it.
So question is is it possible to restrict a user to a given schema with acccess to it as mentioned above?
Only the owner of the table, the schema owner, or a superuser can drop a table. So user_1 should be the owner of schema_1 and user_2 should be the owner of schema_2 if you want them to be able to drop tables in their respective schema.
I am assuming that user_1 and user_2 are not superusers or the question is moot.

How to change the privileges of a table in postgresql?

I try to grant specific privileges to my table "MEMBERS" in postgresql but nothing changes. More specifically I do this (through pgadmin console):
CREATE DATABASE login;
CREATE USER loginUser WITH PASSWORD 'xxxxxxxxxxxxx';
CREATE TABLE members (
id serial NOT NULL,
username varchar(30) NOT NULL
PRIMARY KEY(id)
)
ALTER USER loginuser WITH SUPERUSER;
ALTER TABLE members OWNER TO loginuser;
GRANT SELECT, UPDATE, INSERT, DELETE ON members TO loginuser;
The query is returned successfully but when I check the table's privileges through the pgadmin gui all of them are selected.
What am I missing?
By default, a table's owner has full privileges on it. If you want "loginuser" to have only select, update, insert, and delete privileges, you would normally revoke all privileges first, then grant just those four.
revoke all on members from loginuser;
grant select, update, insert, delete on members to loginuser;
This will appear to work for you, but it really won't. A database superuser can revoke privileges from a table's owner. But you've made "loginuser" a superuser. Whatever privileges you revoke, "loginuser" can just grant to herself.
You need to think more carefully about what you're trying to accomplish here.

Alter default privileges for a group role in PostgreSQL

I have created two group roles in Postgres 9.2: one is called admins and the other is called readers.
The idea is very simple: admins create tables and readers have read access to these tables.
After granting privileges to both group roles everything worked as expected for exisintg objects. But now what about new objects?
So after reading this post I altered the default privileges to grant SELECT privileges to readers for any new table that admins create:
ALTER DEFAULT PRIVILEGES FOR ROLE admins IN SCHEMA public GRANT SELECT ON TABLES TO readers;
ALTER DEFAULT PRIVILEGES FOR ROLE admins IN SCHEMA public GRANT SELECT ON SEQUENCES TO readers;
But apparently, ALTER DEFAULT PRIVILEGES only affects the role itself but not the members of the role. Let me show you.
If I login as userX (a member of admins) and create a new table, no default privileges are granted (and therefore, readers cannot access this table):
test=# CREATE TABLE table1 (name VARCHAR(10)); -- Creating table as userX
test=# \dp table1
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+--------+-------+-------------------+--------------------------
public | table1 | table | |
However, the default privileges are granted if I create the table as admins (readers can access this table):
test=# SET ROLE admins;
test=# CREATE TABLE table2 (name VARCHAR(10)); -- Creating table as admins
test=# \dp table2
Access privileges
Schema | Name | Type | Access privileges | Column access privileges
--------+--------+-------+-----------------------+--------------------------
public | table2 | table | readers=r/admins +|
| | | admins=arwdDxt/admins |
Is there a way to alter the default privileges for ALL members of a group role? Or should I just alter default privileges for each user?
UPDATE: In this PostgreSQL forum someone asked a very similar question and the answer was:
Unfortunately I can't see a way to achieve what you want without granting default privileges to everybody involved.
However this question was asked 2 years ago. Is there a solution now?
If a user creates a table then this user becomes the owner of the table. So in your case any default privileges for userX apply, not those of admins. the solution is to SET ROLE admins before creating your table:
SET ROLE admins;
CREATE TABLE ... -- This now applies default privileges of admins
;
RESET ROLE;
More in general, you would want to do this always: Create all tables and views through a group role or some other role not used in daily operations and grant access to the relations to another group role whose privileges are inherited by regular login roles (users). This greatly facilitates security management.
Cheers,
Patrick

Postgres create database user with grant access to schema only

I have a database with a template_schema.I cloned this template schema and created a database user with password. I need to provide access to cloned schema only, for the created user.
SELECT clone_schema('my_template_schema','john_smith_gmail_com');
CREATE USER john_smith_gmail_com WITH PASSWORD 'mypassword';
Upto this Ok. Then I need to grant access to this user for this cloned schema(john_smith_gmail_com) only
Method :1
I tried to revoke all privileges on all tables of cloned schema(john_smith_gmail_com) for the user and grant select to the user. But my question is, can this user get SELECT access on other schema tables?
REVOKE ALL ON ALL TABLES IN SCHEMA john_smith_gmail_com FROM john_smith_gmail_com;
GRANT SELECT ON ALL TABLES IN SCHEMA john_smith_gmail_com TO john_smith_gmail_com;
Method :2
Create a role with only SELECT access and assign or grant this role to newly created user. If I do this, for which schema I grant access,because I clone schema dynamically?
Which method is best one?
From postgresql version 9.0 and forward, the best way is probably to use ALTER DEFAULT PRIVILEGES.
...the default privileges for any object type normally grant all grantable permissions to the object owner, and may grant some privileges to PUBLIC as well. However, this behavior can be changed by altering the global default privileges with ALTER DEFAULT PRIVILEGES.
So if all users like "john_smith_gmail_com" should only have SELECT access to tables in "their own" schema, after creating the schema and user, you can run:
ALTER DEFAULT PRIVILEGES IN SCHEMA john_smith_gmail_com GRANT SELECT ON TABLES TO john_smith_gmail_com;