Is it a good practice to separate roles with 'usage' permissions on data warehouse compute from other roles which provide access to databases? - snowflake-cloud-data-platform

With the ability to allow secondary roles, is it a good practice to separate roles with 'usage' permissions on data warehouse compute from other roles which provide access to databases, schemas. tables? As example, I create a role called 'USE_DEV_DW". This role is granted usage to the DEV data warehouse compute. In parallel, I create a role that has usage on a specific set of databases and schemas. I then grant both roles to a user so that they can query the provided database tables using the separately provided compute (data warehouse). This way I can control what compute users have access to separate from what objects they can query. I don't see this being possible without the ability to provide for secondary roles? Looking to see if others have done something like this.

Even though there is no guidelines from Snowflake how to create the roles, the way you described makes sense.
When you have two layers of roles, let's call them database and functional,
it will be easier to create role hierarchies and assign them to users.
For illustration purposes assuming you have DEVELOPERS and ANALYSTS as your groups and you have SALES and PRODUCTS databases
You can create your roles and role hierarchies like this
Database Roles
R_DB_SALES_READ_WRITE
R_DB_SALES_READ
R_DB_PRODUCTS_READ_WRITE
R_DB_PRODUCTS_READ
Functional Roles
R_DEVELOPER
R_ANALYSTS
Role Hiercharchy
R_DEVELOPER
R_DB_SALES_READ_WRITE
R_DB_PRODUCTS_READ_WRITE
R_ANALYSTS
R_DB_SALES_READ
R_DB_PRODUCTS_READ
With this you only need to assign functional roles to users

Related

Snowflake role redesigning

I need to structure the roles in snowflake and need advise for it.
Currently, there are two databases: basedb and computedb. basedb is the database where we load the data and the data is not transformed. more like a landing zone.
computedb is where the transformation happens and there are dozens of functional teams and each would have a schema like content team has content schema and there could a schema which can be shared across multiple teams.
all the teams/ schema inside computedb can read from basedb but there are teams that are reading from transform schema of other teams and that is where I need assistance.
all custom roles are under sysadmin and we have a read and write role per schema.
Now analytics schema wants to read from sales and marketing schema as well.
should just give the read access of sales and marketing to analytics? like shown in picture (issue is that the teams might need to access more schemas in future from other schemas in transform)
or should we create a new role for all the schema in computedb which needs access to other schemas of computedb?
Open to more suggestions.
A role hierarchy is the easiest to build and maintain, whilst giving you flexibility.
Create role(s) that give you the required access to each schema.
Create a role for each team and assign to it the appropriate roles to give them access to the schemas they need

Snowflake Role based Access control hierarchy

I am looking for your suggestions on Snowflake Role based Access control hierarchy which I created for a Snowflake data warehousing project.
Basically, we need to maintain different client data with different databases. This database creation process is automated with a script including create databases(DEV, QA and PROD), roles etc.. for a specific client. Here I have created a hierarchy with 3 different default roles for a database.
ADMIN_{ENV}_{CLIENT_ID}
READ_WRITE_{ENV}_{CLIENT_ID}
READ_{ENV}_{CLIENT_ID}
Then I created a set of roles which have access to all databases like..
ADMIN_{ENV}_ALL
READ_WRITE_{ENV}_ALL
READ_{ENV}_ALL
Hope below image illustrates that..
My questions are:
Is this right approach to continue?
When creating database objects, which role should I use? SYSADMIN? For example: for creating database objects in CLIENT_1_DEV_DB database, should I use ADMIN_DEV_CLIENT_1 role or SYSADMIN?
ADMIN_DEV_CLIENT_1 role should be able to create new users and grant the privileges. In that case should I use USERADMIN or SECURITYADMIN? Are there any methods to restrict that to database level?
There is a use case to clone a schema in a database if any issue occurred. In that case How to manage the grants? When we clone a schema, the roles are not retained to the cloned schema. In that case what is the best approach to copy the grants. having another role with MANAGE GRANTS privileges and use that?
Hope you suggestions on these. Thanks
A couple of RBAC approaches articles to help you fine-tune yours:
https://servian.dev/snowflake-role-based-access-control-simplified-41a3ddf34729
https://medium.com/snowflake/a-functional-approach-for-snowflakes-role-based-access-controls-5f0e84e80146
https://www.analytics.today/blog/introducing-snowflake-rbac

Granular access control for shared databases in Snowflake

When using shared databases in Snowflake (as a data consumer), there seems to be no other way to control the access than granting IMPORTED PRIVILEGES on the DB, which effectively grants read-only access to the entire DB and all its schemas & objects.
Is there no way to grant more granular access to the schemas & objects inside a shared database? My goal would be to create roles that have access to only limited portions of the share (specific schemas or objects, like I can with a regular database).
For example, let's say I want to share a database with 10 schemas in it (as a data provider), and would like to restrict/control the access to each of these schemas on the consumer side... would there be no other option than to create 10 shares (one for each schema) on the data provider side? And so on to restrict/control access for specific tables & views?
This is assuming I have access to both accounts (the provider and the consumer), or that I can negotiate the implementation details with the provider/consumer.
Is there no way to grant more granular access to the schemas & objects inside a shared database?
Currently, there is not.
For example, let's say I want to share a database with 10 schemas in it (as a data provider), and would like to restrict/control the access to each of these schemas on the consumer side... would there be no other option than to create 10 shares (one for each schema) on the data provider side? And so on to restrict/control access for specific tables & views?
That's how you would have to do it currently.
Edit: Actually, following up on Robert's answer, if the inbound side of the share is a full account rather than a reader account, you could sort of restrict access by creating a view that filters out rows based on current_role(). It wouldn't be like a privilege, more like row level security based on role.
One approach to this problem is to block access to certain objects in the share for those roles which you don't want to allow access. If your role owns the share then you can block access by revoking privileges on the objects from the share. If your role does not own the share, but owns the objects in the share, you can block access by revoking the USAGE or SELECT privileges with CASCADE on the objects from the share owner.
Alternatively, depending on all the details, it may be easier just to create as many seperate shares as are needed.

SQL Server permissions and views

I'm curious if there is a way for a user to use a view in database A (they have permission to database A) that accesses tables in database B (and/or additional databases they don't have permission to) without the user having access to database B?
My scenario:
We currently have a database (database A) where most of the views are housed. Most users across the team also have access to database A. We are wanting to split out our data tables from database A into their own databases (on the same server). When we do this, of course, the views will break because the tables they access will now be in database B. Since there are so many views, I'm looking for an easier way. My thought was to use database A as the hub for the views and as the views are accessed, permissions are granted to the various databases for the user(s) - without giving them direct access to the other databases.
Thank you in advance.
I think a database role would be better than a database as the container for view access.
It might be easier to delete objects than to move them. A backup-restore can create a copy of the database. Then delete the tables and views that don't belong in each database.
Cutting corners on security or integration can come back to bite. If the tables are distinctly part of different systems, then the views should go with the tables. Security and integration between systems by cross database references will tie all those systems to the same server. (Linked servers would be a performance and DTC nightmare.) We have several "separate" justice applications (e.g., DA, Public Defender, Probation, etc.) that do this. Security is still detailed via the use of database roles for each use. The integration is great, but it's a nightmare to migrate because it's all at once and together. If done correctly (e.g., connections strings to each database), we would be able to move one database at a time and update and test one system at a time. As it is now, it takes a lot of project management and a long time to get everybody ready.
If the tables are part of the same system, then schemas could be an option to segregate them if database roles are to tedious to manage. Is it more work to segregate the objects into databases or schemas than to manage a role?
Also, if you use SSDT db projects, then those cross database references (circular?) can be a pain.
For security, I would suggest a database role for each group that needs access. There is no "magic" database level container just for views. The best you can do is SELECT which includes tables and views. For just views, a script is not hard to create to grant a db role select access to all views in the db. I would not ever use grant select and then a DENY on tables because it can prevent access to table for users that should have access. If one or more schemas are used for the views, a role can be granted SELECT access to the schema. This might be the best option. If the view schema and the objects accessed by the view have the same owner, the ownership chain should allow access via the view to tables. For example, if the "view" schema is owned by "dbo", views in the "view" schema should be able to access tables in the "dbo" schema without the user being granted access to those tables. (I have not tried it.)
It would be nice if there was a second flavor of INSERT, UPDATE, etc. permissions that applied to views only, but there isn't.

How do I fo back and deduct the role hiearchy of my trial account?

Apologies for the new question, but I am having trouble understanding the best practices for understanding the recommended role set up for my account. I am auditing what I have created to backwards engineer and correct it on a new warehouse.
So here is the situation:
I granted all permissions on all warehouses modify AND usage to the sysadmin.
When running worksheets and ./snowsql in parallel, I used the ACCOUNTADMIN for all of the sessions in snowsql.
When I use the Sysadmin to modify the tables that copied the data staged in the warehouse sometimes I have permissions and other times I don't.
I have been sifting through account history with the ACCOUNTADMIN role to view all the grants with the recommended query from the documentation below:
select *
from table(information_schema.query_history())
order by start_time;
I filtered then by the database and query_id to include grant
select *
from table(information_schema.query_history())
where database_name = 'temp_db'
and query_id like '%grant%'
order by start_time;
I did this to see if there were any differences in the grants I did between databases in the warehouse. I only set up two warehouses so it was easy to see.
Going forward, Accountadmin is used to create roles, warehouses, and databases.
To prevent the need to do an audit when switching between roles, I want to set future grants on Sysadmin to specific databases in a warehouse for modification and usage, how do I do that?
Permissions to warehouses, database, and all other objects are separate things. Granting permissions to a warehouse let's that role use or modify a warehouse, but that has nothing at all to do with creating, updating, etc. other objects like databases, schemas, tables, and views. Also, only the role that OWNS a table can drop or alter a table. So, you might want to check on the ownership of the tables between SYSADMIN and ACCOUNTADMIN. As a best practice, ACCOUNTADMIN shouldn't own anything.
It would take quite a bit more information to give you a full rundown of RBAC in Snowflake. If you are struggling with it, you might want to contact Professional Services at Snowflake and get them to come in and do an overview (QuickStart or Security package) to get you straightened out.

Resources