CertSafari
    Snowflake SnowPro Advanced: Security Engineer (SEA-C01)· Lessons

    Domain 1 · Lesson 1/21

    Managing Snowflake privilege grants, future grants and SCIM-provisioned roles

    Design and implement access control strategies.

    12 min read
    5.5% of exam
    7 sources
    Published 5 Oct 2026
    Docs as of 4 Oct 2026

    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. 1.Grant a set of privileges to the role
    2. 2.Create the custom role
    3. 3.Grant the role to the users who need those privileges
    4. 4.Grant the role to another role to create or extend a role hierarchy

    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.

    Minimum grants for a read-only role on schema d1.s1sql
    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.

    Turning off user-based privilege grants for the accountsql
    ALTER ACCOUNT SET DISABLE_USER_PRIVILEGE_GRANTS = TRUE;

    Checkpoint 2 of 7· Exam question

    Which statement about database roles in Snowflake is accurate?

    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?

    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;

    Database-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.

    Building the hierarchy in code: granting my_role_1 to my_rolepython
    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'),
    )

    Sources23

    4.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.

    SCIM_CLIENT and default RUN_AS_ROLE by identity provider
    Identity providerSCIM_CLIENTRUN_AS_ROLE
    OktaOKTAOKTA_PROVISIONER
    Microsoft Entra IDAZUREAAD_PROVISIONER
    Custom IdPGENERICGENERIC_SCIM_PROVISIONER
    Custom SCIM setup: a provisioner role with CREATE USER and CREATE ROLE, then the integrationsql
    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?

    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?

    Sources4567

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 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.

      Covered in Future grants for objects that don't exist yet

    2. 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.

      Covered in Future grants for objects that don't exist yet

    3. 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.

      Covered in Driving role membership from the IdP with SCIM

    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. 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. 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. 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. 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. 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. 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. 2.
      “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. 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. 4.
      “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. 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. 7.
      “A custom SCIM integration may or may not allow the provisioning and management of nested groups.”
      ↩︎ Driving role membership from the IdP with SCIM

    Ready to test yourself?

    Practise the 20 questions on this subdomain.

    Spotted a mistake, or was something unclear? Tell us.