Revoke access from PostgreSQL User to see other tables - database

I have a PostgreSQL DB user "limited_user" and want to give SELECT permission on one table ONLY.
GRANT CONNECT ON DATABASE "db1" TO limited_user;
GRANT SELECT ON TABLE users to limited_user;
What happens is that when I try \dt , the user can see all the other tables in this db1, while he can perform SELECT operation to table "user" as I gave permission. How can I revoke access access to the user so that he can not see other tables and just one table?

You can't, at least not in any straightforward way that I am aware of.
Tables exist within the schema namespace, and schemas exist within the database. To give access to a user on a particular table means you must also give that user the USAGE permission on the schema to which the table belongs. USAGE does not grant permissions on the tables themselves, only the the schema in question. But table definitions are part of the schema, so USAGE does allow the user to see table names (and the columns too).
But if there are other tables in the same schema, the user will not be able to SELECT from those tables unless you also GRANT SELECT on those tables, even though they will be able to see that they exist.
This answer gives a pretty clear explanation of the permission system.
Edit to add:
One way to achieve a similar outcome would be like this (using psql):
sec_schema=# REVOKE ALL ON ALL TABLES IN SCHEMA sec_schema FROM restricted_user;
REVOKE
sec_schema=# REVOKE USAGE ON SCHEMA sec_schema FROM restricted_user;
REVOKE
sec_schema=# CREATE SCHEMA new_schema;
CREATE SCHEMA
sec_schema=# GRANT USAGE ON new_schema TO restricted_user;
GRANT
sec_schema=# CREATE VIEW new_schema.secret_view AS SELECT * from sec_schema.secret_table;
CREATE VIEW
sec_schema=# GRANT SELECT ON new_schema.secret_view TO restricted_user;
GRANT
This will remove all access to the schema sec_schema for user restricted_user, but then creates new_schema and new_schema.secret_view which is a cover view over sec_schema.secret_table. After the GRANT SELECT, the user will be able to read the data from table sec_schema.secret_table through the view, but they will not be able to see any objects in sec_schema.

Related

snowflake role: not giving select access to tables moved into the schema from another schema

In snowflake i have a role given select access to all the tables inside a schema SCHEMA1
GRANT USAGE ON DATABASE DB1 TO test_role;
GRANT USAGE ON SCHEMA DB1.SCHEMA1 TO test_role;
GRANT SELECT ON ALL TABLES IN SCHEMA DB1.SCHEMA1 TO ROLE test_role;
I have three tables inside them
but when I a move a table into this schema from another schema its not getting the select access
alter table if exists "DB1"."SCHEMA2"."table1" RENAME TO "DB1"."SCHEMA1"."table4";
i am expecting all tables to have select access inside this schema "SCHEMA1".
Also i observed those created inside the schema directly are having select access, but those which have been moved using alter are not getting the select access.
i am expecting all tables to have select access inside this schema
"SCHEMA1".
Also i observed those created inside the schema directly are having
select access, but those which have been moved using alter are not
getting the select access.
When you create a table, it doesn't come with additional grants (such as SELECT) except ownership. You said that the tables created inside the schema have SELECT access, so I suspect FUTURE GRANTS are applied for that schema.
The rename operation doesn't trigger "future grants":
https://docs.snowflake.com/en/sql-reference/sql/grant-privilege.html#restrictions-limitations
In this case, you need to grant the required SELECT permissions.

Exclusive User ownership on sql server tables

Requirement: User who created tables in a particular schema, should own the tables, other users who got access to that schema should not able to perform any action on that table(including read).
Example:
Tables created by ‘User1’ in ‘Schema1’ should be exclusive to the User1 only with (SELECT, CREATE, UPDATE and DELETE)
Other Users who got access to ‘Schema1’, should not able to perform any actions on the tables created by ‘User1’
This requirement is expected to be available for users who have access to the 'schema1', so the tables they create is accessible only for them and not for other users.
For the sake of the discussion let's CREATE new LOGIN, new SCHEMA, and new USER.
use master
GO
CREATE LOGIN SO_Login WITH PASSWORD = 'Dont1Use2This3In4Production'
GO
Use AdventureWorks2019
GO
CREATE SCHEMA SO_Schema
GO
CREATE USER SO_User FOR LOGIN SO_Login;
GO
In theory, you could get what you are looking for, by simply have a rule which allows CREATE TABLE on specific schema. Something like: GRANT CREATE TABLE ON SCHEMA::SO_Schema TO public;
In this case we could give everyone the option to CREATE TABLE on the schema and use simple DDL trigger on CREATE TABLE in order to add permissions like SELECT,DELETE,INSERT,UPDATE for the user that created the table.
unfortunately, GRANT CREATE TABLE ON SCHEMA is not supported.
To CREATE TABLE you Required to have CREATE TABLE permission in the database and ALTER permission on the SCHEMA in which the table is being created.
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver15#permissions-1
This makes the task more complex and probably not recommended in most cases since you will need to provide more permissions than what you really want the USER to have...
If you still want to get this work (against the recommendation) then you will need to GRANT ALTER ON SCHEMA and GRANT CREATE TABLE on database to all - all means "public"
use AdventureWorks2019
GO
GRANT ALTER ON SCHEMA::SO_Schema TO public;
GO
GRANT CREATE TABLE TO public;
GO
next, you will need to DENY the unwonted permission since the above will give all USERs a lot more power than you want to!
This can be done by CREATE DDL TRIGGER on the DATABASE for any DDL_DATABASE_LEVEL_EVENTS
https://learn.microsoft.com/en-us/sql/relational-databases/triggers/ddl-event-groups?view=sql-server-ver15
inside the TRIGGER you should check what was the event. If it was something else than CREATE_SCHEMA or the USER that executed the event should not CREATE SCHEMA then you ROLLBACK TRANSACTION;.
Note! Since you do not want to change the trigger each time a new USER need to CREATE TABLE and add the USER name to the hard coded list of users which can CREATE TABLE, it is best to CREATE new ROLE and simply add each USER you need to this ROLE
CREATE ROLE ModifyTable;
GO
In this case that you based on a ROLE like above ModifyTable, you can GRANT ALTER ON SCHEMA and GRANT CREATE TABLE only to the ROLE ModifyTable instead of to public
In addition, in the same TRIGGER if the USER is one of these that should be able to CREATE the table then you should GRAND him permission to INSERT, DELETE, UPDATE, SELECT on the table which he just created.
Remember that if you forget to DENY a permission from this USER or all the rest then you might have a security issue - which is why this is not recommended procedure.
Your best option is to re-0design the system so you will not need this exact recruitment. So... you can do it as I explained here, but it is not recommended for most cases.
A much better approach is NOT to permit USERs to CREATE TABLEs except for these you can trust with all tables. You should CREATE THE TABLEs for your users directly or using application which you control, and give them the permission to use the specific table which they need. ALTER SCHEMA is not recommended permission to give to simple users!
A user with ALTER permission on a schema can create procedures, synonyms, and views that are owned by the schema's owner. Those objects will have access (via ownership chaining) to information in other schemas owned by the schema's owner. When possible, you should avoid granting ALTER permission on a schema if the schema's owner also owns other schemas.
https://learn.microsoft.com/en-us/sql/t-sql/statements/grant-schema-permissions-transact-sql?view=sql-server-ver15

What is the complete list of privileges a role needs in order to create a table in a schema?

I have granted USAGE on the schemas and database.
I have granted select on all tables.
Using that role, I can read data from all tables within any schema.
I then grant the permission to create tables in all schemas within that database
GRANT CREATE TABLE ON ALL SCHEMAS IN DATABASE TEST1_CONTROL TO DEVELOPERS;
Yet, when I issue this command (while using DEVELOPERS role), I get an error
CREATE TABLE PDS.ERIC_TEST_TABLE(COUCOU STRING NULL);
What am I missing?
Works fine for me (script below). Going to go with what Lukasz commented and that your schema was created later.
use role accountadmin;
create database TEST1_CONTROL;
create schema PDS;
create role DEVELOPERS;
grant role DEVELOPERS to user <your_username>;
GRANT USAGE ON DATABASE TEST1_CONTROL TO DEVELOPERS;
GRANT USAGE ON ALL SCHEMAS IN DATABASE TEST1_CONTROL TO DEVELOPERS;
GRANT CREATE TABLE ON ALL SCHEMAS IN DATABASE TEST1_CONTROL TO DEVELOPERS;
use role DEVELOPERS;
CREATE TABLE PDS.ERIC_TEST_TABLE(COUCOU STRING NULL);
Snowflake does offer future grants if you want a role to have access to any new schemas that would be created in the future.

Can I prevent update or delete on an Oracle DB?

I have to implement a financial application. One of the acceptance criteria is:
"The data may never change."
Therefore I need to prevent update and delete operations on the database, because it will be deployed on machines owned and administrated by the customer.
Is this even possible? Maybe with triggers? If not, are there any other databases that can prevent update and delete?
The easiest way is via roles, such as a query role. Grant select on the list of tables to that role, and grant that role to the user of your application. You can of course create others such as an admin role with update and delete privileges, to be granted later on when needed.
Example:
CREATE ROLE FIN_APP_INS_SEL_ROLE;
GRANT INSERT, SELECT on <table1> to FIN_APP_INS_SEL_ROLE;
GRANT INSERT, SELECT on <table2> to FIN_APP_INS_SEL_ROLE;
GRANT CONNECT, FIN_APP_INS_SEL_ROLE to <app_user>;
You can also make tablespaces read only,
ALTER TABLESPACE <name> READ ONLY;
or the entire database read only.
ALTER DATABASE OPEN READ ONLY;
It turns out to be impossible.
There is no way to grant an INSERT privilege without allowing to UPDATE. As I understand it, the INSERT privilege is interpreted as may alter data of that table.

Which permission need to grant to access sys.dba_systems

I am working on the application which works on Oracle. For some kind of logic I need to get the list of tables from the given db user with the specified schema. In my case, I have a user which have granted access of the given schema. So when my code creates connection using the given credential and tries to fetch the tables from the following query, its return table list.
SELECT * FROM dba_objects where owner ='schema' and object_type = 'TABLE'
The above query was working with user having grant all privileges
but when I did try with limited permission, it is throwing error msg.
ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
For the secondary user, from which our code is creating connection has granted permissions by following query
create user johnsmith identified by Passw0rd;;
grant connect to johnsmith ;
grant select any table to johnsmith ;
grant UPDATE any table to johnsmith ;
grant DELETE any table to johnsmith ;
grant INSERT any table to johnsmith ;
Which permission should I grant to user to have access on the following system tables...?
dba_objects
user_constraints
user_cons_columns
USER_TABLES
all_tab_cols
and also allow to access dbms_metadata.get_dependent_ddl() method
With the O7_DICTIONARY_ACCESSIBILITY initialisation parameter set to false, which is the default, then:
System privileges that provide access to objects in other schemas do not give other users access to objects in the SYS schema. For example, the SELECT ANY TABLE privilege allows users to access views and tables in other schemas, but does not enable them to select dictionary objects (base tables of dynamic performance views, regular views, packages, and synonyms). You can, however, grant these users explicit object privileges to access objects in the SYS schema.
So you can either grant select privileges on the specific views you need:
grant select on sys.dba_objects to johnsmith;
and the same for other views; or if you need them to have wider access to the SYS schema objects you can give them that with a role:
grant select_catalog_role to johnsmith;
though the principle of least privilege should always apply, so this may be overkill and potentially expose things you don't want that user to be able to see.
You don't need to grant anything for the user to be able to query user_* views. If you meant the DBA equivalents of those - e.g. dba_tables - then grant them as for dba_objects above; or they woudl be included in select_catalog_role. But again, only grant what is actually needed.
Either way, for dbms_metadata you can just grant privileges on that package too (you can't grant privileges on individual procedures in a package):
grant execute on dbms_metadata to johnsmith;
or - again probably much more than actually needed, and potentially much more dangerous that the select role:
grant execute_catalog_role to johnsmith

Resources