Grants
Access to Snowflake objects is an integral part of the DataOps ecosystem. DataOps pipelines cannot (and will not) run successfully without being able to read from and write to Snowflake objects. Therefore, it is imperative that unauthorized users do not gain access to an organization's data for multiple reasons, including:
- To prevent data loss through theft
- To prevent data from being held hostage as part of ransomware attacks
- To maintain confidentiality
- To protect data integrity
How does DataOps manage access to the organization's Snowflake objects?
The straightforward answer is via the Snowflake Object Lifecycle Engine (SOLE).
We've designed SOLE's access management to control access to all Snowflake objects. In other words, SOLE manages the rules around access control by implementing Snowflake's access control rules.
What is access control?
The Snowflake Access Control webpage has the following to say to answer this question:
Access control privileges determine who can access and perform operations on specific objects in Snowflake.
This access control model image describes the SOLE access control model:
Source: https://docs.snowflake.com/en/user-guide/security-access-control-overview.html
Role hierarchy
It is essential to understand the Snowflake role hierarchy implemented by SOLE.
Snowflake describes roles as follows:
Roles are the entities to which privileges on securable objects can be granted and revoked. Roles are assigned to users to allow them to perform actions required for business functions.
You can also grant roles to other roles, thereby creating a hierarchy of roles, as the following image shows:
Source: https://docs.snowflake.com/en/user-guide/security-access-control-overview.html
The ACCOUNTADMIN
, SECURITYADMIN
, SYSADMIN
, USERADMIN
, and PUBLIC
roles are Snowflake system-defined roles. These roles inherit from each other.
For instance, The ACCOUNTADMIN
role inherits all the privileges from the SECURITYADMIN
and USERADMIN
roles. Another way to describe this functionality is that the ACCOUNTADMIN
role can create the SECURITYADMIN
and USERADMIN
roles and grant them the privileges they need to function. The SECURITYADMIN
role also inherits all the USERADMIN
privileges because it is higher than USERADMIN
in the role hierarchy.
The last point to note when looking at this image is that the system-defined role SYSADMIN
is responsible for creating several custom roles and that several of these roles inherit from each other.
Grants
You can grant one or more access privileges on objects to roles in the Snowflake object configuration files. Based on these configurations, SOLE generates all Snowflake object grants and revokes. As SOLE follows a declarative method for defining Snowflake objects, it checks the configuration and updates objects accordingly.
When your pipeline runs, SOLE applies the grants you define in the configuration and removes any other existing grants, no matter where they are defined, and regardless of the value of manage mode. Therefore, only the access privileges you specify in the configuration are granted to their related roles.
When your pipeline runs:
-
SOLE applies the grants you define in the configuration and removes any other existing grants, no matter where they are defined, and regardless of the value of manage mode. Only the access privileges you specify in the configuration are granted to their related roles.
-
SOLE creates a
revoke
to remove all privileges not specified in the configuration file or those defined with an empty list[]
.
The implicit revoke is initiated if you use the keyword grants
in the object configuration.
If you want to define access to Snowflake objects outside SOLE, for example, don't define the keyword grants
in any configuration and at any level. When no grants are specified anywhere, SOLE manages only the object properties.
The example below shows how the MODIFY
privilege to role ROLE_1
is specified in the grants
section in the DATABASE_1
configuration. Because it is in the configuration, SOLE will manage this MODIFY
grant. And as no grants
section is defined for database_2
, SOLE will not manage any grants for this object.
databases:
DATABASE_1:
comment: "database 1"
grants:
MODIFY:
- ROLE_1
DATABASE_2:
comment: "database 2"
DATABASE_3:
comment: "database 3"
grants:
MODIFY: []
Also, based on this configuration:
- SOLE generates revokes on the privileges
MONITOR
,USAGE
,CREATE SCHEMA
, andIMPORTED PRIVILEGES
for the databaseDATABASE_1
. - SOLE does not perform any revokes for
DATABASE_2
as nogrants
section is defined in its configuration. - SOLE generates revokes on the privilege
MODIFY
forDATABASE_3
as it is defined with an empty list. SOLE will also create revokes for the database's other missing privileges (MONITOR
,USAGE
,CREATE SCHEMA
, andIMPORTED PRIVILEGES
).
See Supported database grants to roles for the list of supported grants.
Enabling roles to grant privileges to other roles
It is possible to allow specific roles to grant the same privileges to other roles by setting with_grant_option
to true
, which is set to false
by default.
In the following example:
ROLE_1
can grantUSAGE
to other roles aswith_grant_option
is set totrue
.ROLE_2
,ROLE_3
, andROLE_4
cannot grantUSAGE
to other roles aswith_grant_option
is set tofalse
explicitly or by default.ROLE_5
can grant the privilegesMODIFY
,MONITOR
,USAGE
,CREATE SCHEMA
, andIMPORTED PRIVILEGES
to other roles aswith_grant_option
is set totrue
.
databases:
DATABASE_3:
comment: DATABASE 3
grants:
USAGE:
- ROLE_1:
with_grant_option: true # the role can grant the privilege to other roles
- ROLE_2:
with_grant_option: false # the role can not grant the privilege to other roles
- ROLE_3: # the role can not grant the privilege to other roles
- ROLE_4: # the role can not grant the privilege to other roles
ALL PRIVILEGES:
- ROLE_5: # the role can grant all the privileges to other roles
with_grant_option: true
Revoking all privileges
To manage revokes on all the privileges of a Snowflake object, use an empty grants
in the Snowflake object's configuration, as the following example shows:
databases:
DATABASE_3:
comment: DATABASE 3
grants:
In this scenario, SOLE generates revokes for all the privileges (MONITOR
, USAGE
, CREATE SCHEMA
, IMPORTED PRIVILEGES
, and MODIFY
) on DATABASE_3
.
Revoking privileges on objects shared in multiple environments
If a managed resource is shared between environments (no environment-specific suffix added, see namespacing), then grants on the object would be reset in each pipeline as per the environment.
roles:
ROLE_1:
namespacing: suffix
comment: Role 1
warehouses:
WAREHOUSE_1:
comment: Warehouse 1
size: MEDIUM
namespacing: prefix
grants:
MONITOR:
- ROLE_1
In the above example, one role and one warehouse are managed by SOLE.
The role ROLE_1
is created in each environment, whereas the warehouse WAREHOUSE_1
is created once and shared between environments.
If the pipeline runs in the PROD environment, then MONITOR
on WAREHOUSE_1
would be granted to ROLE_1_PROD
.
When the same pipeline runs in the QA environment, the grant to ROLE_1_PROD
is revoked and MONITOR
is granted to ROLE_1_QA
.
Implicit grant of USAGE
privilege on parent objects
If you grant a privilege to a role on a database object, such as a schema, table, or view, but USAGE
is not granted on its parent objects, the role can't access this database object. You must manually grant USAGE
on the parent object for the role to access its child object.
To reduce the number of configurations you must manage, SOLE implicitly grants USAGE
on the parent, and grandparent, objects for such roles.
The following example shows this principle:
SELECT
is granted to rolesROLE_1
,ROLE_2
andSYSADMIN
, andINSERT
is granted toROLE_2
onTABLE_1
,- As
USAGE
is not granted to any of the roles in the schemaSCHEMA_1
and the databaseDATABASE_5
, these roles cannot accessTABLE_1
.
However, because SOLE implicitly grants USAGE
to ROLE_1
, ROLE_2
and SYSADMIN
on both SCHEMA_1
and DATABASE_5
, these roles can access TABLE_1
.
databases:
DATABASE_5:
comment: Database 5
grants:
MODIFY:
- ROLE_1
MONITOR:
- ROLE_1
- ROLE_2
schemas:
SCHEMA_1:
comment: Hello
grants:
MODIFY:
- ROLE_1
tables:
TABLE_1:
grants:
SELECT:
- ROLE_1
- ROLE_2
- SYSADMIN
INSERT:
- ROLE_2
comment: Hello Table_1
COLUMNS:
COLUMN_1:
type: VARCHAR(16777216)
Preventing implicit grant of USAGE
To prevent SOLE from implicitly granting USAGE
privilege on parent objects, set the DATAOPS_SOLE_DISABLE_IMPLICIT_GRANTS
variable to any value. The variable is set to false
by default.
Handling ALL PRIVILEGES
privilege in SOLE
By assigning specific privileges to roles within SOLE, you control who can access and perform operations on objects in Snowflake. However, it's important to note that managing the ALL PRIVILEGES
privilege in SOLE varies from its handling in Snowflake.
When you grant ALL PRIVILEGES
to a role on a Snowflake object, such as a database, function, masking policy, etc., SOLE does not grant the supported privileges for the specified object all at once as it is the case in Snowflake.
SOLE converts ALL PRIVILEGES
into individual privilege grants before resolving them in Snowflake. This approach enhances effective management of revokes and tracking of granted privileges to roles.
The privilege conversion before execution means that the privileges applied by Snowflake and those applied by SOLE may differ depending on the privileges known to SOLE at the time through the configuration files.
SOLE grant management
SOLE grant management provides a complete alternative to the Terraform Snowflake Provider for inspecting, comparing, and executing operations. SOLE grant management is enabled by default, and it:
- Inspects the existing grants that are part of the organization's Snowflake infrastructure during SOLE's PLAN lifecycle action.
- Compares the grants defined in the configuration file with what's in Snowflake and determines what privilege and role grants must be added or revoked. Because this inspection is a run-time inspection, unlike the Terraform provider, no local state is required.
However, if you want to deactivate SOLE grant management and revert to using the Terraform provider to manage all object grants, set the variable DONT_USE_SOLE_GRANT_MANAGEMENT
to any value.
This is evaluated as true
and results in Terraform provider managing object grants.
The following two sections only apply if DONT_USE_SOLE_GRANT_MANAGEMENT
is either:
- Not set - this variable is not set by default, which indicates SOLE grant management is enabled
- Set to
0
- evaluated asfalse
, which indicates SOLE grant management is enabled
DATAOPS_SOLE_WAREHOUSE
SOLE grant management requires a Snowflake warehouse to perform object inspection. This warehouse must be assigned to the user used to connect to Snowflake and can either be specified in the variable DATAOPS_SOLE_WAREHOUSE
or can be saved in the DataOps Vault path SNOWFLAKE.SOLE.WAREHOUSE
.
If no warehouse is defined, SOLE grant management assumes a default warehouse is set for the user. You can run the following query in Snowflake to set a default warehouse for the user:
ALTER USER <SOLE_USER> SET DEFAULT_WAREHOUSE = <WAREHOUSE_NAME>
Limiting the roles and users operated on
By default, SOLE grant management applies and revokes privileges on all environment (DEV, QA, and PROD) roles as per the YAML configuration. Apart from this functionality, it can also revoke all privileges.
For some use cases, you might want to limit SOLE Grant Management's scope to a well-known set of roles and users. These roles and users can be defined using the top-level keys specified_roles
and specified_users
, respectively. If present in the configuration, SOLE Grant Management only manages the roles and users that match the specified values. Privileges for roles and users that do not match the patterns will not be altered. In other words, they are expressly not revoked but also not granted to an object.
You can use the roles, user names, or regular expressions in the specified_roles
and specified_users
keys.
For instance:
specified_roles:
- DATAOPS_ADMIN
- DATAOPS_*
specified_users:
- SOLEADMIN
- DATAOPS_*
With the above configuration, SOLE grant management will only grant or revoke privileges if the role is either DATAOPS_ADMIN
or matches the DATAOPS_*
regex value. Similarly, a role is only granted or revoked if the role is either DATAOPS_ADMIN
or matches regex DATAOPS_*
, or the user is either SOLEADMIN
or matches regex DATAOPS_*
.