I have a table_aa created by ROLE_A under my_database.shema_1. Now, I have another ROLE_B, which has CREATE TABLE and USAGE privilege on my_database.shema_1, as well as SELECT on tables under my_database.shema_1. Then, is ROLE_B able to insert data into table_aa, which is owned and created by ROLE_A?
I understand since table_aa's ownership is ROLE_A, so ROLE_B can't drop table_aa. But could ROLE_B write into table_aa?
I'm new to the snowflake. Any ideas?
Your understanding is correct. ROLE_B can't drop/insert into table_aa since it is owned by ROLE_A.
I understand where your confusion lies. In your case, since ROLE_B has CREATE TABLE and USAGE SELECT on tables privilege on my_database.shema_1, it is not sufficient for this role to insert or drop tables owned by other roles. Now, since ROLE_B has the CREATE TABLE privilege, any new table created by this role, will be owned by ROLE_B and likewise, ROLE_A can't insert/drop the tables owned by this role unless specific permissions are given.
In your case, as suggested by #srinath you need to grant INSERT privilege to ROLE_B
grant insert on table my_database.shema_1.table_aa to role ROLE_B;
For an object owned by a role, the owner role has to grant necessary privileges to the objects in order to perform specific operations using another role.
To verify what all the privileges a role has, run show grants to role; similarly to check all the privileges a particular table has been assigned run show grants on table my_database.shema_1.table_name; This will show all the privileges the table has and assigned to which role.
Refer to snowflake-access-control-model and security-access-control-privileges for more clarifications
You will need to provide insert privilege to Role_B on table_aa to be able to write to it.
Related
I'm running the following code. As you can see I'm using a role called owner_bi_db to create a temporary table.
use database bi_db;
use schema [my_schema];
use role accountadmin;
drop table if exists _test;
use role owner_bi_db;
create temporary table _test as select 1 as t;
use role accountadmin;
show tables like '_test';
Even though owner_bi_db was the creator of the temporary table, the owner ends up being DEV_ROLE. How is that possible? I thought ownership was always granted to the creator of the object. This is the same whether I do it on a temporary or a regular table.
Ah! I found it. We had a future ownership grant on the schema for tables which was overriding the create grant. Interesting.
I want to execute code on user IDK:
CREATE OR REPLACE TRIGGER sal_trig
AFTER UPDATE OF status ON TAB1
FOR EACH ROW
WHEN (new.status = 'ZAK')
CALL log_sal(1, 5, 8);
I have following grants:
GRANT CREATE PROCEDURE TO IDK;
GRANT CREATE SEQUENCE TO IDK;
GRANT CREATE TABLE TO IDK;
GRANT CREATE TRIGGER TO IDK;
GRANT CREATE TYPE TO IDK;
GRANT UNLIMITED TABLESPACE TO IDK;
GRANT SELECT ON TAB1 TO IDK;
What grants i need more?
I won't get update/delete/insert on TAB1.
I am getting error: not sufficient privileges.
I created procedure from user IDK:
CREATE OR REPLACE PROCEDURE log_sal (
emp_id NUMBER,
old_sal NUMBER,
new_sal NUMBER
)
AS LANGUAGE JAVA
NAME 'CaseWatch.logSal(int, float, float)';
According to your comments the TAB1 table created by different User, so the table is in a different schema, this is the main key.
When you want to grant privileges to create a trigger on a table in different schema then you need to use:
GRANT CREATE ANY TRIGGER TO IDK;
CREATE TRIGGER => in fact giving permission to create a database trigger in the grantee's schema, in your case if TAB1 created by IDK then this privilege is enough.
Regarding the CREATE ANY TRIGGER here you can find some more interesting info:
https://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_9013.htm
Grant create any trigger vs grant create trigger
I'm attempting to use an application role with a specific default schema to facilitate using SQL commands without schema designations, i.e. unqualified names. I need to create and work with 4+ complete sets of tables+views+etc. (each 50-100 objects) that all should work exclusively within their own schema.
To test it, I've created an application role with a suitable default schema. I then use 'sp_setapprole' to attach this role, and 'sp_unsetapprole' to revert to my previous role. This seems to be working, as SCHEMA_NAME() returns the expected schema name (and 'dbo' before 'set' and after 'unset').
While in my approle, I attempt to drop and create a table, and then insert a record into the created table. The drop/creation works fine, but the insert fails, as it attempts to insert the record into a table with a similar name in the 'dbo' schema (which it hasn't been given permission to do).
Why is it, that my (purposedly) unqualified table reference suddenly reverts to 'dbo' even though my approle dictated default schema is another ?
It also fails when I do a 'select', which again defaults to 'dbo'.
I have granted all possible permissions for my approle to the designated schema, and only SELECT to dbo.
Any help is appreciated.
Cheers
Lars
This is tricky because the object resolution is based on the default schema active when the batch is parsed. So a batch like this:
DECLARE #cookie varbinary(8000);
exec sp_setapprole a_role,'P#ssword', #fCreateCookie = true, #cookie = #cookie output
--go
select * from t
Will reference dbo.t, even if a_role has a different default schema. If you break it into two batches, then t will resolve to a.t.
Either that or you're using static SQL in a stored procedure, which is resolved relative to the procedure's schema, rather than any user's default_schema.
Apart from that, I don't think Application Roles are the right approach. You can accomplish this more simply by using impersonation than using Application Roles. EG grant the application users the right to impersonate a user who has rights only in a specific schema. Something like:
create role app_users
create user a_user without login with default_schema=a
grant select, insert, update, delete, execute on schema::a to a_user
grant impersonate on user::a_user to app_users
go
execute as user='a_user'
select * from t --resolves to a.t
select * from dbo.t --fails
revert
I have a store procedure that have several selects for checking and balances in our order process, long story short, this store procedure reads (SELECT) about 20 tables with are spread in 3 databases.
CREATE USER [stageUsrOrder] FOR LOGIN [domain\[my user]]
GO
CREATE ROLE OrderSpecRole AUTHORIZATION [stageUsrOrder]
GO
GRANT EXECUTE on [orders].[ValidateOrderById] TO pmdSchedulerRole
GO
I thought that this statements would give me read access to all the tables inside the store procedure.
I have try
GRANT EXECUTE on [AVIS].[spReportValidationByLAN] TO pmdSchedulerRole WITH GRANT OPTION
GO
But it didn't work.
So, How do I grant execute access to the store procedure and SELECT to all the tables inside?
You don't. One of the value propositions of stored procedures is that you can restrict access to certain patterns. For example, if you want people to only search by ID, you give then a stored procedure that takes ID as a parameter.
But if you want to give them arbitrary select access to the underlying tables, you have to do that explicitly.
Every day in our datawarehouse (that will be dynamically changing) the tables are dropped and rebuilt. Also is it possible that some developer in our organisation will create more tables in that database.
Because of that I can not give permissions to the database that are persistent.
Question:
I want to make some kind of a job that runs every day, that lists all the table names (that are existing at that time) in a database like 'Select * FROM sys.tables'
Then I want the tables names as an input value to a script that runs trough all table names and places them in a script like :
GRANT SELECT TO [Tablename1] TO [ROLE_READALLTABLES Except 1 table],
GRANT SELECT TO [Tablenaam2] TO [ROLE_READALLTABLES Except 1 table]
and so go on in a loop until all existing tables are readable.
So all tables (except 1 table ) in the entire database should get the GRANT SELECT permission.
I have looked around all the related answers, but I cannot seem to get a good idea how to get this to work.
I hope someone can help me with this.
UPDATE
I use Microsoft SQL Server 2014, and I work through SQL Management Studio 2014
UPDATE 2 :
There is one exception. This table has schema [dbo]. like all other tables
You can use the db_datareader role to grant access to all tables generally, then a specific role with a DENY rule to exclude access to the one table that's the exception.
The steps would be roughly like this:
1) Create your "Read all except 1 role":
CREATE ROLE [ROLE_READALLEXCEPT1]
2) Create your "deny" role like so:
CREATE ROLE [ROLE_DENY]
GO
DENY SELECT, INSERT, UPDATE, DELETE ON myTable TO [ROLE_DENY]
GO
3) Then add your "except 1" role to it:
EXEC sp_addrolemember #rolename = 'ROLE_DENY', #membername = 'ROLE_READALLEXCEPT1'
4) Add your role to db_datareader:
EXEC sp_addrolemember #rolename = 'db_datareader', #membername = 'ROLE_READALLEXCEPT1'
The deny role should override db_datareader, and the net effect is that your role now has access to all tables (including new ones) except for those explicitly denied.
You can then add your users to "ROLE_READALLEXCEPT1" and they will have access to everything except the one exception table.
there is no information about the excluded table so i assume is always the same.I also assume that all the other tables are on the schema dbo; this is not a relevant constraint or limitation because the logic can be easily applied to more than one schema.
the easiest solution is granting permission at the schema level. move the single table on a separate schema with restricted permissions and grant full read on the whole schema where the user tables reside:
GRANT SELECT ON SCHEMA::dbo TO [relevant role/user];
now the developers can create all the table they feel like on the schema dbo and the permission are inherited by the schema.
should you need to grant access to more than one schema the permission are easily applied once and then every new table will get proper permission.
the huge pro of this solution is that it is fire and forget: once in place there is no maintenance, no jobs, no script to run daily/weekly/whatever.
this advantage is to be evaluated and weighted against the move of the excluded table (or the other way round: move the user tables): maybe is used by just a couple of internal applications so it is a quick patch or is used by a whole bunch of services accessible worldwide instead and that would be a nightmare.