0
votes

I have a table MYSCHEMA.TEST_SNOWFLAKE_ROLE_T in Snowflake created using the role CONSOLE_USER.

MYSCHEMA has a FUTURE GRANTS associated with it, which grants the following privileges to the role BATCH_USER for any table created under the schema MYSCHEMA - DELETE, INSERT, REFERENCES, SELECT, TRUNCATE, UPDATE.

The role BATCH_USER also has CREATE STAGE and USAGE privileges on the schema MYSCHEMA.

A second user belonging to the role BATCH_USER tries to insert data into the same table from a dataframe, using the following Spark SQL (Databricks), but fails with an insufficient privileges error message.

df.write.mode(op_mode)                   \ 
  .format("snowflake")                   \ 
  .options(**self.sfoptions)             \
  .option("dbtable", snowflake_tbl_name) \
  .option("truncate_table", "on")        \
  .save

The following error message appears:

Py4JJavaError: An error occurred while calling o908.save.
   : net.snowflake.client.jdbc.SnowflakeSQLException: SQL access control error
   : Insufficient privileges to operate on table 'TEST_SNOWFLAKE_ROLE_T')

The role CONSOLE_USER has ownership rights on the table, hence the role BATCH_USER would not be able to drop the table, but adding the option option("truncate_table", "on") should have prevented automatic overwrite of the Table schema.

I've gone through the available Snowflake and Databricks documentation several times, but can't seem to figure out what is causing the insufficient privilege issue.

Any help is much appreciated!

2

2 Answers

2
votes

I figured it out eventually.

The error occured because the table was created by the role CONSOLE_USER, which retained ownership privileges on the table.

The Spark connector for Snowflake uses a staging table for writing the data. If the data loading operation is successful, the original target table is dropped and the staging table is renamed to the original target table’s name.

Now, in order to rename a table or swap two tables, the role used to perform the operation must have OWNERSHIP privileges on the table(s). In the situation above, the ownership was never transferred to the role BATCH_USER, hence the error.

df.write.mode(op_mode)                   \ 
  .format("snowflake")                   \ 
  .options(**self.sfoptions)             \
  .option("dbtable", snowflake_tbl_name) \
  .option("truncate_table", "on")        \
  .option("usestagingtable", "off")      \
  .save

The solution was to avoid using a staging table altogether, although going by the documentation, Snowflake recommends using one, pretty strongly.

0
votes

This is a good reference for troubleshooting custom privileges: https://docs.snowflake.net/manuals/user-guide/security-access-control-overview.html#role-hierarchy-and-privilege-inheritance

  1. Is the second batch_user inheriting any privileges? Check on this by asking the user in their session to see what privileges they have on the table: https://docs.snowflake.net/manuals/sql-reference/sql/show-grants.html What are the grants listed for the Batch_user having access issues to the following:

SHOW GRANTS ON

SHOW GRANTS OF ROLE

SHOW FUTURE GRANTS IN SCHEMA { }

  1. Was a role specified for the second batch_user when they tried to write to "dbtable"?

3.Since you mentioned Future Grants were used on the objects created - FUTURE be ing limited to SECURITYADMIN via https://community.snowflake.com/s/question/0D50Z00009MDCBv/can-a-role-have-rights-to-grant-future-rights