What you will be able to do
- Write the minimum set of grants a role needs to query a table, and know when to add WITH GRANT OPTION
- Explain how direct user grants interact with secondary roles and how to switch them off
- Use future grants correctly, including schema-over-database precedence and behaviour on clone
- Automate role and grant management with the Snowflake Python API
- Set up SCIM so IdP groups provision and maintain Snowflake roles and their membership
1.Granting privileges: containers, roles and users
Building a custom role has four steps. Create the role. Grant privileges to it. Grant it to the users who need it. Grant it to a parent role so it joins the hierarchy. The last step is optional, but Snowflake strongly recommends it. Only USERADMIN or higher, or a role with CREATE ROLE, can create roles, and SECURITYADMIN can grant privileges and roles.
Checkpoint 1 of 7· Put it in order
Put the steps for setting up a custom role in the order Snowflake recommends
- 1.Grant a set of privileges to the role
- 2.Create the custom role
- 3.Grant the role to the users who need those privileges
- 4.Grant the role to another role to create or extend a role hierarchy
The role is created, given privileges, assigned to users, and finally attached to a parent role so administrators above it inherit its privileges.
“Grant the role to another role to create or add to a role hierarchy.”Source: docs.snowflake.com
Database objects always sit inside a schema, and the schema sits inside a database. A privilege on a table is useless without USAGE (or some other privilege) on the database and schema that contain it. A role that runs queries also needs USAGE on a warehouse to supply the compute. A read-only role for one schema therefore needs four grants.
GRANT USAGE
ON DATABASE d1
TO ROLE read_only;
GRANT USAGE
ON SCHEMA d1.s1
TO ROLE read_only;
GRANT SELECT
ON ALL TABLES IN SCHEMA d1.s1
TO ROLE read_only;
GRANT USAGE
ON WAREHOUSE w1
TO ROLE read_only;When you grant one role to another, the recipient inherits the granted role's privileges whether or not you add WITH GRANT OPTION. The option only adds the right to pass the granted role on to other roles. Privileges can also go directly to users, which is UBAC. Those grants only take effect when the user has all secondary roles enabled. An account that doesn't want direct user grants can turn them off with an account parameter.
ALTER ACCOUNT SET DISABLE_USER_PRIVILEGE_GRANTS = TRUE;Checkpoint 2 of 7· Exam question
Which statement about database roles in Snowflake is accurate?
Correct answer: D — A database role cannot be activated in a session; it must be granted to an account role, and users exercise its privileges through that role.
- A. Database roles cannot be activated in a session at all, so USE ROLE cannot select one. USAGE on the database does not change this restriction.
- B. Database roles can be granted to account roles, other database roles in the same database, or shares, but not directly to users. Users always reach them through an account role.
- C. The direction is reversed: account roles can be granted database roles, but account roles cannot be granted to database roles. A database role stays scoped to its database.
- D. Database roles are scoped to one database and are not selectable with USE ROLE. Their privileges become usable only after the database role is granted to an account role.
Checkpoint 3 of 7· Check yourself
Role R holds SELECT on mydb.myschema.mytable and USAGE on a warehouse, but its queries on the table fail. What is the most likely missing grant?
Object privileges only work when the role also has a privilege on the containing database and schema.
“users must be granted USAGE or any other privilege on the container database and schema.”Source: docs.snowflake.com
Sources1
2.Future grants for objects that don't exist yet
The ON ALL TABLES grant in the read-only example only covers tables that exist when it runs. Tables created later aren't included. Future grants fill that gap. You define privileges on a type of object in a database or schema, and Snowflake grants them automatically to the chosen role whenever a new object of that type is created. They only set the starting privileges, so you can still grant more or revoke some on each object afterwards.
Checkpoint 4 of 7· Fill the gap
Which keyword makes the read_only role receive SELECT on tables created later in d1.s1?
GRANT SELECT ON ? TABLES IN SCHEMA d1.s1 TO ROLE read_only;ON FUTURE TABLES applies to tables created afterwards. ON ALL TABLES only covers tables that already exist.
Source: docs.snowflake.comDatabase-level future grants apply in managed access schemas as well as regular ones. You add them with GRANT … ON FUTURE and remove them with REVOKE … ON FUTURE, and in Snowsight that means running SQL in a worksheet. Cloning a database or schema copies its future grants to the clone. Cloning a single object inside a schema applies that schema's future grants to the clone, unless you specify COPY GRANTS. In that case the clone keeps the original object's privileges and doesn't pick up the future grants.
Sources1
3.Automating RBAC with the Snowflake Python API
The grants above can all be scripted. The Snowflake Python API represents account roles with Role and RoleResource, and database roles with DatabaseRole and DatabaseRoleResource. Through RoleResource you can grant and revoke privileges, privileges on all objects, future privileges and roles. Following the advice for automated scripts, run these under a role other than ACCOUNTADMIN.
from snowflake.core.role import Securable
root.roles['my_role'].grant_role(role_type="ROLE", role=Securable(name='my_role_1'))Database roles are created inside a specific database collection, which matches the fact that a database role is a database-level object. The API can also clone a database role into another database. That helps when every domain database needs the same set of access roles.
Checkpoint 5 of 7· Fill the gap
Which method makes my_role receive SELECT and INSERT on tables created later in my_db.my_schema?
from snowflake.core.role import ContainingScope
root.roles['my_role']. ? (
privileges=["SELECT", "INSERT"],
securable_type="TABLE",
containing_scope=ContainingScope(database='my_db', schema='my_schema'),
)grant_future_privileges is the API version of GRANT … ON FUTURE. grant_privileges_on_all only covers objects that already exist.
Source: docs.snowflake.com4.Driving role membership from the IdP with SCIM
SCIM 2.0 lets an identity provider push users and groups into Snowflake. Each IdP group becomes a Snowflake role, with a one-to-one mapping, and group members become users who hold that role. When someone's group changes in the IdP, their Snowflake access changes with it. You set this up with a SCIM security integration whose RUN_AS_ROLE owns everything the IdP imports. Creating the integration requires CREATE INTEGRATION, which only ACCOUNTADMIN has by default.
| Identity provider | SCIM_CLIENT | RUN_AS_ROLE |
|---|---|---|
| Okta | OKTA | OKTA_PROVISIONER |
| Microsoft Entra ID | AZURE | AAD_PROVISIONER |
| Custom IdP | GENERIC | GENERIC_SCIM_PROVISIONER |
use role accountadmin;
create role if not exists generic_scim_provisioner;
grant create user on account to role generic_scim_provisioner;
grant create role on account to role generic_scim_provisioner;
grant role generic_scim_provisioner to role accountadmin;
create or replace security integration generic_scim_provisioning
type=scim
scim_client='generic'
run_as_role='GENERIC_SCIM_PROVISIONER';Ownership is what makes syncing work. If a role was created by hand, or ownership was moved away from the provisioner, IdP updates to it stop reaching Snowflake. Granting the provisioner MONITOR ROLE on the account lets it see every group, not just those it owns. If you'd rather use something less privileged than ACCOUNTADMIN for setup, use a role with global MANAGE GRANTS, or a custom role that owns all the roles SCIM will manage. For hierarchies, keep in mind that a custom SCIM integration may not support nested groups, so confirm that with your IdP first.
Checkpoint 6 of 7· Exam question
A security lead wants a new DBA team to create and manage custom roles and grant them to users, but the team must not be able to create databases or warehouses and must not hold the privilege to modify arbitrary grants. Which system-defined role should anchor this delegation?
Correct answer: B — Grant USERADMIN to the team, because it holds CREATE USER and CREATE ROLE on the account but has no privilege to create databases or warehouses.
- A. SYSADMIN creates and manages warehouses, databases and objects. It is not the role for creating users and roles, and it would give the team the object creation rights they must not have.
- B. USERADMIN is purpose-built for user and role administration. It lacks MANAGE GRANTS and the object-creation privileges held by SYSADMIN, so it fits the least-privilege requirement.
- C. ACCOUNTADMIN encapsulates SYSADMIN and SECURITYADMIN, so it can create databases and warehouses. A session policy governs session behavior and cannot strip role privileges.
- D. SECURITYADMIN holds MANAGE GRANTS globally, not only for roles it owns. That lets the team modify any grant, which the requirement explicitly rules out.
Checkpoint 7 of 7· Check yourself
SECURITYADMIN created role FINANCE_ANALYSTS by hand, and an Okta group with the same name now pushes membership changes through SCIM. The changes never appear in Snowflake. What is the cause?
The SCIM role has to own the roles it manages. Otherwise IdP updates aren't synced.
“SCIM roles in Snowflake must own any users or roles that are imported from the identity provider.”Source: docs.snowflake.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.GRANT SELECT ON ALL TABLES IN SCHEMA also covers tables created later.Why is that wrong?
ON ALL only covers objects that exist when the grant runs. New tables need a separate ON FUTURE grant.
2.Database-level and schema-level future grants on the same object type add together.Why is that wrong?
The schema-level future grants win and the database-level ones are ignored for that schema, even when they target a different role.
3.Once SCIM is set up, any Snowflake role with a matching name follows IdP group changes.Why is that wrong?
Only roles owned by the SCIM provisioner role are kept in sync. Roles owned by other roles won't receive IdP updates.
Practise it for real
Build a least-privilege read-only role for schema d1.s1 that also covers future tables and sits in the SYSADMIN hierarchy
1.As USERADMIN, run CREATE ROLE r1 COMMENT = 'This role has all privileges on schema_1'; (or name it read_only)
Why: Only USERADMIN or higher, or a role with CREATE ROLE, can create roles
You should see: The role exists but isn't granted to any user or role yet
2.Grant USAGE on database d1, schema d1.s1 and warehouse w1, then GRANT SELECT ON ALL TABLES IN SCHEMA d1.s1 to the role
Why: Table privileges only work with USAGE on the containers, and a warehouse is needed to run queries
You should see: The role can query every table that currently exists in d1.s1
3.Run GRANT SELECT ON FUTURE TABLES IN SCHEMA d1.s1 TO ROLE read_only;
Why: ON ALL doesn't cover tables created later
You should see: Tables created in d1.s1 from now on are readable by the role without further grants
4.Run GRANT ROLE r1 TO ROLE sysadmin; using the role you created
Why: Puts the role in the hierarchy so SYSADMIN inherits its privileges and can manage what it owns
You should see: The Snowsight roles graph shows the role as a child of SYSADMIN
5.Run GRANT ROLE r1 TO USER smith; and optionally ALTER USER smith SET DEFAULT_ROLE = r1;
Why: Users only get a role's privileges once the role is granted to them
You should see: smith can activate the role and query d1.s1, but can't modify data or create objects
Stuck? Get a nudge
If the user's queries fail with a missing-object error, check the container USAGE grants before the table grant.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“A role granted without WITH GRANT OPTION still inherits the granted role’s privileges.”
↩︎ Granting privileges: containers, roles and users“Privileges assigned directly to users are only effective when the user has all secondary roles enabled.”
↩︎ Granting privileges: containers, roles and users“As new objects are created in the database or schema, the defined privileges are automatically granted to a specified role.”
↩︎ Future grants for objects that don't exist yet“Database level future grants apply to both regular and managed access schemas.”
↩︎ Future grants for objects that don't exist yet“When a database or schema is cloned, future grants are copied to its clone.”
↩︎ Future grants for objects that don't exist yet“grants the SELECT privilege on all existing tables only”
↩︎ Exam trap 1“This behavior applies to privileges on future objects granted to one role or different roles.”
↩︎ Exam trap 2“Grant the role to another role to create or add to a role hierarchy.”
↩︎ Checkpoint“the schema-level grants take precedence over the database level grants, and the database level grants are ignored.”
↩︎ Prediction - 2.https://docs.snowflake.com/en/developer-guide/snowflake-python-api/snowflake-python-managing-user-rolesOfficial docs
“manage access privileges on a securable Snowflake object to an account role, database role, or user”
↩︎ Automating RBAC with the Snowflake Python API“A database role is a database-level object.”
↩︎ Automating RBAC with the Snowflake Python API - 3.
“Snowflake recommends using a role other than ACCOUNTADMIN for automated scripts.”
↩︎ Automating RBAC with the Snowflake Python API“users must be granted USAGE or any other privilege on the container database and schema.”
↩︎ Checkpoint - 4.https://docs.snowflake.com/en/user-guide/scim-introOfficial docs
“Role management is a one-to-one mapping from the identity provider to Snowflake.”
↩︎ Driving role membership from the IdP with SCIM“updates in the identity provider will not be synced to Snowflake”
↩︎ Exam trap 3“SCIM roles in Snowflake must own any users or roles that are imported from the identity provider.”
↩︎ Checkpoint - 5.
“As the user’s role changes in the identity provider, their access to Snowflake automatically changes”
↩︎ Driving role membership from the IdP with SCIM“the SCIM provisioner can see all groups in a Snowflake account”
↩︎ Driving role membership from the IdP with SCIM - 6.
“Only the ACCOUNTADMIN role has this privilege by default.”
↩︎ Driving role membership from the IdP with SCIM - 7.https://docs.snowflake.com/en/user-guide/scim-customOfficial docs
“A custom SCIM integration may or may not allow the provisioning and management of nested groups.”
↩︎ Driving role membership from the IdP with SCIM