Snowflake Row Access Policy privileges - snowflake-cloud-data-platform

I am unable to find the list of privilege's that are required -
1.) For a Role to create Row Access Policy
2.) Grant Usage on the Policy to a different Role
3.) Grant Modify on the Policy to a different Role
Need simple step by step example starting from DBADMIN.

Snowflake supports adding and dropping row access policies in a single SQL statement.
For a given resource (i.e. table or view), to ADD or DROP a row access policy you must have either the APPLY ROW ACCESS POLICY privilege on the schema, or the OWNERSHIP privilege on the resource and the APPLY privilege on the row access policy resource.
The APPLY privilege allows ADD and DROP operations for the Row Access Policies on a table or view, and executing the DESCRIBE operation on tables and views.
The OWNERSHIP privilege allows full control over the row access policy. This is required to alter most properties of a row access policy. Only a single role can hold this privilege on a specific object at a time.
USAGE privilege on the parent database and schema are also required.
Row Access Policy Privileges

Related

Snowflake - Grant permissions by username

I'm trying to restrict read permissions on some entities to a specific user.
In Oracle I'd simply do
GRANT SELECT ON sensitive_schema.my_table1 TO error_2646;
GRANT SELECT ON sensitive_schema.my_table2 TO error_2646;
GRANT SELECT ON sensitive_schema.my_tableN TO error_2646;
or ideally at schema level
GRANT SELECT ON sensitive_schema TO error_2646;
Can I do this in Snowflake? In the documentation it looks like permissions are managed by role in Snowflake and I'd rather not change this person's role.
https://docs.snowflake.com/en/sql-reference/sql/grant-privilege.html
As Snowflake's approch for permission is Role-based Access Control (RBAC) you will not be able to give GRANTS to a specific user.
If you absolutly don't want to work on role for this, maybe you can have a look on Dynamic Data Masking. You will be able to mask data to a specific user using current_user(). But you will have to create a masking policy for every field type you want to mask and apply this policy to every field in your table so i would not recommend this compared to role approach.

How to create a table in Snowflake, but prevent dropping it under the same role?

We have build a streaming pipeline that has the rights to create new tables in snowflake when they are created in the source system. (running under the role PROD_EL_ROLE)
Even though we have time travel enabled 'for backup', I want to prevent the PROD_EL_ROLE itself from being able to 'accidentally' DROP tables. AFAIK, this cannot be done directly as the creator of a table in snowflake is also the owner, and thus, is also allowed to drop the table
What I tried in addition, is to transfer the owner to another role higher in our RBAC hierarchy (PROD_SYSADMIN_ROLE) . This unfortunately only works by using REVOKE GRANTS, which is not what we want as with the creating of a table under PROD_EL_ROLE various privileges are auto-created by various FUTURE GRANTS. And we obviously don't want to remove them.
If I use COPY GRANTS, it does not work due to the PROD_EL_ROLE not having the MANAGE GRANTS right. Which is a grant we obviously do not want to give to PROD_EL_ROLE...
I only want to prevent table dropping by PROD_EL_ROLE
Any idea how to solve this?
To follow the DAC concept, you own the object created then you can customise grants to it, so no way to prevent dropping it unless a higher role in same RBAC hierarchy claims ownership, and grant back some or ALL privileges of the object to that role.
So, for your requirement here another separate process/user need use PROD_SYSADMIN_ROLE to claim objects ownership and grant back ALL PRIVILEGES on that object to role PROD_EL_ROLE
USE ROLE PROD_SYSADMIN_ROLE;
grant ownership on ALL TABLES in SCHEMA TESTDB.TESTSCHEMA
TO ROLE PROD_SYSADMIN_ROLE;
grant ALL PRIVILEGES on ALL TABLES in SCHEMA TESTDB.TESTSCHEMA
TO ROLE PROD_EL_ROLE;
Now the role PROD_EL_ROLE can do all DML operations but no DDL operations on it again (dropping/modifying the definition of the object).

Can we grant select or insert to a user on table with out creating a role in snowflake?

Can we grant direct select or insert access( with out creating a role ) to a user on a table ?
No, you cannot. Snowflake uses Role-based Access Control (RBAC):
https://docs.snowflake.com/en/user-guide/security-access-control-overview.html#access-control-framework
Therefore, all access on a table should be granted through a role.
https://docs.snowflake.com/en/sql-reference/ddl-user-security.html#access-control-management
Of course you can use "existing roles" instead of "creating a new one".
The short answer is NO - you can only grant access to a ROLE - never directly to a USER.
In Snowflake, everything is accessed via a ROLE. See this diagram:
RBAC: USERS, ROLES and SECURABLE OBJECTS
From this article: https://www.analytics.today/blog/introducing-snowflake-rbac
In summary:
USERS are granted one or more ROLES
A ROLE is granted PRIVILEGES (for example, insert, update, delete) on SECURABLE OBJECTS (for example a TABLE or VIEW)
Even the concept of OWNERSHIP is different in Snowflake. Every USER with the same ROLE shares access to the OBJECTS. This has some unusual results.
For example:
If a USER creates a TABLE - everyone with the same ROLE has OWNERSHIP on the table.
You can read more about Snowflake RBAC on this article - which also links to another two which explain best practices on how to deploy. https://www.analytics.today/blog/introducing-snowflake-rbac

Create database overwrote my data from recently copied data from s3 bucket

CREATE OR REPLACE DATABASE "Orders";
I did not set any permissions on this database. Another person at my company ran the SQL above and replaced the data. How can I prevent this from happening in the future using the permissions in Snowflake?
TL;DR: The global privilege CREATE DATABASE in Snowflake permits a user/role to run such a statement. Removing it requires designing a role based access system and revoking administrative level rights from existing users.
At the very minimum, severely restrict the users who are allowed to run statements as ACCOUNTADMIN, SECURITYADMIN or SYSADMIN roles. Revoke these privileges from the set of users you want to prevent from performing DATABASE level operations:
REVOKE accountadmin FROM USER other_user1;
REVOKE securityadmin FROM USER other_user1;
REVOKE sysadmin FROM USER other_user1;
REVOKE accountadmin FROM USER other_user2;
REVOKE securityadmin FROM USER other_user2;
REVOKE sysadmin FROM USER other_user2;
(… repeat for all users that need to be limited …)
Next, design custom roles and define a desired level of accesses over them. Also decide which usernames will belong to each role depending on their function in your organization.
The following is a very generic and basic example just for illustrative purposes that divides all "Orders" database users into two levels of access. Specific needs will vary depending on your organization's unique situation.
CREATE ROLE orders_read_and_write;
CREATE ROLE orders_read_only;
-- Snowflake recommends you create a hierarchy of roles so you can allow any
-- SYSADMIN-allowed users to manage these newly created roles instead of
-- requiring an ACCOUNTADMIN level user to do so in future
GRANT ROLE orders_read_and_write TO ROLE sysadmin;
GRANT ROLE orders_read_only TO ROLE sysadmin;
The two roles orders_read_and_write and orders_read_only created above can then be granted privileges appropriately to control their level of access for schema and tables under the "Orders" database. Continuing the example:
-- Allow both these roles to access schema and tables under "Orders" DB
-- This does not allow them to perform any DB-level operations
-- such as replacing/overwriting it
GRANT USAGE ON DATABASE "Orders" TO ROLE orders_read_and_write;
GRANT USAGE ON DATABASE "Orders" TO ROLE orders_read_only;
-- Allow read and write access appropriately to schema under the DB
-- Note the difference on using ALL vs. USAGE in the privilege granted
-- to each role here:
GRANT ALL ON SCHEMA "Orders"."SCHEMA-NAME" TO ROLE orders_read_and_write;
GRANT USAGE ON SCHEMA "Orders"."SCHEMA-NAME" TO ROLE orders_read_only;
GRANT SELECT
ON ALL TABLES IN SCHEMA "Orders"."SCHEMA-NAME"
TO ROLE orders_read_only;
Finally, grant the roles to their respective username(s).
GRANT ROLE orders_read_and_write TO USER other_user_1;
GRANT ROLE orders_read_only TO USER other_user_2;
(…)
Any role lacking the CREATE DATABASE level privilege will no longer be able to perform a statement such as CREATE OR REPLACE DATABASE "Orders";.
In the above example, both roles only receive USAGE level access on the Orders database, which does not permit them to run such statements anymore.
If you ever need to permit such a privilege to a role, you can GRANT it explicitly to the role of choice that has trusted users under it:
GRANT CREATE DATABASE TO ROLE role_name;
I highly recommend going over Snowflake's Access Controls feature section a few times to get acclimated to the terminology. This makes it easier to implement and manage effective access controls in your organization.
Note: Introducing access control is a wide-impacting change and will require communication and coordination within your organization to be truly effective. It is always difficult to remove freedoms as this may be ingrained into scripts and programs already in use.

Grant user DDL permissions on specific schema

Using SQL Server (2008), is it possible to grant a specific user full control of the objects under a specific schema? This includes create/drop/alert table. Its important that this user isn't not given db_ddladmin role because that would give him access to other tables.
You can create a role in the database, assign all appropriate permissions(SELECT, UPDATE, DELETE, EXECUTE, etc.) to the role, and then assign the user to that role.

Resources