Snowflake - Grant permissions by username - snowflake-cloud-data-platform

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.

Related

new role which can query snowflake account usage, without account admin role

I would like a new role which can query snowflake account usage. Currently only Account Admin have this privilege and don’t want to assign Account Admin for required users.
The IMPORTED PRIVILEGES grant would allow a non-admin role access to the SNOWFLAKE.ACCOUNT_USAGE schemas (docs). There is also a MONITOR USAGE global grant which allows similar billing and usage monitoring but through information_schema functions instead. See the documentation here -- particularly the table is helpful to explain the differences between these two options.
These are some of the more common built-in grant options for a billing-monitoring role, but if you need a more custom solution, you can always create some custom SQL (perhaps stored procedure and task for maintenance) that copies only the desired admin results from ACCOUNT_USAGE to a custom table/view. Then you can grant access to that custom object to your non-admins.

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.

How do I show all grants to all roles in Snowflake?

In Snowflake, I know I can show roles:
show roles
I know I can show grants on specific roles and access those via query:
show grants to role dev_role;
select * from table(RESULT_SCAN (LAST_QUERY_ID()));
I'd like to show ALL grants for ALL roles in one table. My best guess would be to write a procedure that iterates through all the role names, executes the above code, and outputs the result to a table.
Is there a better way of doing this?
Do you have access to the shared database called snowflake? If not then you may need to ask an accountadmin to provide you the IMPORTED PRIVILEGES grant as explained here.
Anyway if you have access to this database then I think you should be able to get the info you need from the GRANTS_TO_ROLES view:
select *
from snowflake.account_usage.grants_to_roles;
Unfortunately there is not currently a better way to accumulate the grant information. My current solution is exactly what you've described.

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