Security in Snowflake is quite different to what's implemented in SQL Server.
In SQL Server, objects have owners that can either be specific people, or as occurs when a dbo person creates an object, it is owned by the dbo role. In Snowflake, objects in the database also have owners, but the owners can't be users, they are always roles.
When you create a database, there are four pre-defined roles:
The ACCOUNTADMIN role is the closest to what we have in SQL Server with the sysadmin role. The SYSADMIN role in Snowflake is much more limited. For example, if a user in the SALESPERSON role creates a table, a SYSADMIN role member cannot even see that table, unless the SYSADMIN role is added to the SALESPERSON role.
Now it's recommended that the SYSADMIN role is added to all other roles, to avoid this issue but there's no concept of a DDL trigger that would allow you to enforce that.
One at a time
Another very curious concept is that your security context can only be in one role at a time. That's quite unlike Windows, and SQL Server where you can do whatever any of the roles that you are in can do.
There is a USE Database like we have in SQL Server but there is also USE WAREHOUSE to decide which virtual warehouse will be used for compute costs, and USE ROLE to decide which role you are operating in. So commands that you execute are always in a context of:
- Which database
- Which warehouse
- Which role
DDL commands look odd
While the concept of granting a permission to a role is familiar, and works much the same way, they also use the words GRANT and REVOKE for role membership.
I find that really odd. In my mind, roles are things that have members, and the DDL should relate to adding and removing members from roles. Roles can be nested, and so if, for example, you want to add the role SALESPEOPLE to the role EMPLOYEES, you say:
GRANT EMPLOYEES to SALESPEOPLE;
So I can't say that I like the way that they've implemented the DDL commands for roles. I think there should be separate DDL for granting and revoking permissions from roles, and for adding and removing members of roles.
Schemas are also a bit odd
Another thing that I find odd is that when you grant a role permission to SELECT on a schema, it only applies that to objects that are currently in the schema. So that's just like a shortcut way to avoid granting to every object in the schema. Normally when I grant permissions at the schema level, it's for all items currently in the schema, and all objects that will ever be in the schema.
Curiously, Snowflake has an extra permission for that, where you need to separately tell it "oh, and all future objects too".
To transfer ownership of an object, you need to:
- Remove all permission grants
- Change ownership
- Re-establish all permission grants
If you delete a role, the role that you are currently executing in when you execute the delete, becomes the owning role for all the objects in the deleted role.
Checking current grants
You can check the grants that have been made by:
SHOW GRANTS TO ROLE
SHOW GRANTS TO USER