Snowflake roles are not able to see newly created Privileged database? - database

I created a new Database (DB_COMMON) using ACCOUNTADMIN role and I grant ALL PRIVILEGES to other roles but I am not able to see newly created Database (DB_COMMON) using those roles. Am I missing something? Please guide.
Here is the complete code:
USE DATABASE ACCOUNTADMIN;
-- DATABASE CREATION
CREATE DATABASE IF NOT EXISTS DB_COMMON;
-- PERMISSION TO ALL THE FUTURE SCHEMAS
GRANT ALL PRIVILEGES ON FUTURE SCHEMAS IN DATABASE DB_COMMON TO ROLE DEVADMIN;
GRANT ALL PRIVILEGES ON FUTURE SCHEMAS IN DATABASE DB_COMMON TO ROLE QAADMIN;
GRANT ALL PRIVILEGES ON FUTURE SCHEMAS IN DATABASE DB_COMMON TO ROLE UATADMIN;
GRANT ALL PRIVILEGES ON FUTURE SCHEMAS IN DATABASE DB_COMMON TO ROLE PRODADMIN;
-- PERMISSION TO ALL THE FUTURE TABLES
GRANT ALL PRIVILEGES ON FUTURE TABLES IN DATABASE DB_COMMON TO ROLE DEVADMIN;
GRANT ALL PRIVILEGES ON FUTURE TABLES IN DATABASE DB_COMMON TO ROLE QAADMIN;
GRANT ALL PRIVILEGES ON FUTURE TABLES IN DATABASE DB_COMMON TO ROLE UATADMIN;
GRANT ALL PRIVILEGES ON FUTURE TABLES IN DATABASE DB_COMMON TO ROLE PRODADMIN;
-- CREATION OF SCHEMA
USE DATABASE DB_COMMON;
CREATE SCHEMA IF NOT EXISTS COMMON;
After these commands, if I switch to these roles (DEVADMIN, QAADMIN, etc) I am not able to see DB_COMMON Database. Am I missing something? Please guide.

It is not recommeded to use ACCOUNTADMIN role as owner of user-defined databases:
Avoid Using the ACCOUNTADMIN Role to Create Objects:
The ACCOUNTADMIN role is intended for performing initial setup tasks in the system and managing account-level objects and tasks on a day-to-day basis. As such, it should not be used to create objects in your account, unless you absolutely need these objects to have the highest level of secure access. If you create objects with the ACCOUNTADMIN role and you want users to have access to these objects, you must explicitly grant privileges on the objects to the roles for these users.
Instead, we recommend creating a hierarchy of roles aligned with business functions in your organization and ultimately assigning these roles to the SYSADMIN role. For more information, see Aligning Object Access with Business Functions in this topic.
Second the USAGE permission on the database needs to be granted.
GRANT USAGE ON DATABASE ... TO ROLE ...;
Database Privileges:
USAGE
Enables using a database, including returning the database details in the SHOW DATABASES command output. Additional privileges are required to view or take actions on objects in a database.

Related

How do I grant all privileges for a database to a role in Snowflake

I am trying to grant all privileges for a database to a role in snowflake
This includes all ability to read, create, update and delete schemas, stages, storage integrations, tables and so on.
Also should include any future objects created in the database.
grant all on database test to developer;
This only grants view of the database and not the schema or any other objects within the database
Unfortunately in Snowflake, there is no as such command to grant all access via a single command.
Even with all privileges command, you have to grant one usage privilege against the object to be effective.
It's mentioned in the documentation on Schema Privileges as well.
For future grants, you can try following commands at schema and database level
SCHEMA LEVEL
grant usage on database SAMPLEDATABASE1 to role testrole12;
grant usage on schema SAMPLEDATABASE1.TEST to role testrole12;
grant select on future tables in schema SAMPLEDATABASE1.TEST to role testrole12;
grant role testrole12 to user SUJANT3;
DATABASE LEVEL
grant usage on database SAMPLEDATABASE1 to role testrole12;
grant usage on future schemas in database SAMPLEDATABASE1 to role testrole12;
grant select on future tables in database SAMPLEDATABASE1 to role testrole12;
grant role testrole12 to user SUJANT3;
There is no one single command to affect all the objects under the database, but you can run these set of SQL's per object:
GRANT ALL ON ALL schemas in database <DB> TO ROLE <role>;
GRANT ALL ON ALL TABLES IN SCHEMA <db.schema> TO ROLE <role>;
similarly for future grants:
grant all on future schemas in database <DB> TO ROLE <role>;
grant all on future tables in schema <db.schema> to ROLE <role>;
This can be extended to views and other objects too.
It sounds like you want to grant ownership? There can only be 1 owner per object, so I recommend you use this only when appropriate:
GRANT OWNERSHIP ON DATABASE TEST
TO DEVELOPER
COPY CURRENT GRANTS
;
Note: Copying current grants retains the current privileges, except ownership is transferred. Otherwise, all existing privileges will be dropped.

Create database overwrote my data from recently copied data from s3 bucket

CREATE OR REPLACE DATABASE "Orders";
I did not set any permissions on this database. Another person at my company ran the SQL above and replaced the data. How can I prevent this from happening in the future using the permissions in Snowflake?
TL;DR: The global privilege CREATE DATABASE in Snowflake permits a user/role to run such a statement. Removing it requires designing a role based access system and revoking administrative level rights from existing users.
At the very minimum, severely restrict the users who are allowed to run statements as ACCOUNTADMIN, SECURITYADMIN or SYSADMIN roles. Revoke these privileges from the set of users you want to prevent from performing DATABASE level operations:
REVOKE accountadmin FROM USER other_user1;
REVOKE securityadmin FROM USER other_user1;
REVOKE sysadmin FROM USER other_user1;
REVOKE accountadmin FROM USER other_user2;
REVOKE securityadmin FROM USER other_user2;
REVOKE sysadmin FROM USER other_user2;
(… repeat for all users that need to be limited …)
Next, design custom roles and define a desired level of accesses over them. Also decide which usernames will belong to each role depending on their function in your organization.
The following is a very generic and basic example just for illustrative purposes that divides all "Orders" database users into two levels of access. Specific needs will vary depending on your organization's unique situation.
CREATE ROLE orders_read_and_write;
CREATE ROLE orders_read_only;
-- Snowflake recommends you create a hierarchy of roles so you can allow any
-- SYSADMIN-allowed users to manage these newly created roles instead of
-- requiring an ACCOUNTADMIN level user to do so in future
GRANT ROLE orders_read_and_write TO ROLE sysadmin;
GRANT ROLE orders_read_only TO ROLE sysadmin;
The two roles orders_read_and_write and orders_read_only created above can then be granted privileges appropriately to control their level of access for schema and tables under the "Orders" database. Continuing the example:
-- Allow both these roles to access schema and tables under "Orders" DB
-- This does not allow them to perform any DB-level operations
-- such as replacing/overwriting it
GRANT USAGE ON DATABASE "Orders" TO ROLE orders_read_and_write;
GRANT USAGE ON DATABASE "Orders" TO ROLE orders_read_only;
-- Allow read and write access appropriately to schema under the DB
-- Note the difference on using ALL vs. USAGE in the privilege granted
-- to each role here:
GRANT ALL ON SCHEMA "Orders"."SCHEMA-NAME" TO ROLE orders_read_and_write;
GRANT USAGE ON SCHEMA "Orders"."SCHEMA-NAME" TO ROLE orders_read_only;
GRANT SELECT
ON ALL TABLES IN SCHEMA "Orders"."SCHEMA-NAME"
TO ROLE orders_read_only;
Finally, grant the roles to their respective username(s).
GRANT ROLE orders_read_and_write TO USER other_user_1;
GRANT ROLE orders_read_only TO USER other_user_2;
(…)
Any role lacking the CREATE DATABASE level privilege will no longer be able to perform a statement such as CREATE OR REPLACE DATABASE "Orders";.
In the above example, both roles only receive USAGE level access on the Orders database, which does not permit them to run such statements anymore.
If you ever need to permit such a privilege to a role, you can GRANT it explicitly to the role of choice that has trusted users under it:
GRANT CREATE DATABASE TO ROLE role_name;
I highly recommend going over Snowflake's Access Controls feature section a few times to get acclimated to the terminology. This makes it easier to implement and manage effective access controls in your organization.
Note: Introducing access control is a wide-impacting change and will require communication and coordination within your organization to be truly effective. It is always difficult to remove freedoms as this may be ingrained into scripts and programs already in use.

Why does a FUTURE grant in Snowflake require AccountAdmin by default?

I've set up the following scenario:
The Demo_DB is owned by the sysadmin role. The Demo_Schema was created and is owned by Demo_Developer role. All the objects in Demo_Schema are owned and have been created by the Demo_Developer role.
AccountAdmin created a new role called Demo_Analyst, which the intent is to set up as a read-only user of the Demo_Schema tables. Demo_Developer successfully executed the following grant (assuming because it is the owner of all the tables in the Demo_Schema):
use role Demo_Developer;
grant select on all tables in schema Demo_DB.Demo_Schema to role Demo_Analyst;
However, neither Demo_Developer or event SysAdmin (which belongs to the Demo_Developer role) can execute the following:
use role sysadmin;
grant select on FUTURE tables in schema Demo_DB.Demo_Schema to role Demo_Analyst;
However, the above will execute using the AccountAdmin role. This seemed strange to me at first, but then I reasoned that maybe we won't know which future tables will be created by which owners, so we need an AccountAdmin to grant FUTURE. Is that correct?
I did some more testing and changed ownership of one of the tables in Demo_Schema to a completely different role that Demo_Developer isn't a part of. Then I tried to grant select on all tables using that Demo_Developer again (first statement above), and this time it didn't grant to all tables, but just to the tables Demo_Developer was the owner of.
So I wonder why the attempted grant on FUTURE tables doesn't work the same way - i.e. grant select on future tables owned by the grantor of the future grant.
So my question is: Why do I need an AccountAdmin to grant select on Future tables, but I can use the owner role (Demo_Developer) to grant select on all current tables?
Did you see this in the usage notes?
The MANAGE GRANTS global privilege is required to grant or revoke privileges on future objects at the database level. By default, only the SECURITYADMIN and ACCOUNTADMIN roles have the MANAGE GRANTS privilege.

How should I set up a power user role for a Snowflake database?

Fundamentally I want
my "DBA" user; the original account which has the SYSADMIN and ACCOUNTADMIN roles, to be able to see any object in the database as well as its data. It seems that at least at the level of ACCOUNTADMIN I should be able to do this.
a "power" user; via a role (dr_uce_role) I can assign at a database level where the user can do virtually everything within a database.
I thought I had made the power user role with the following code:
--grant power to engineer
grant all privileges on database dr_ev to dr_uce_role;
grant all privileges on all schemas in database dr_ev to dr_uce_role;
grant all privileges on all tables in schema dr_ev.public to dr_uce_role;
grant all privileges on all views in schema dr_ev.public to dr_uce_role;
grant select on future tables in schema dr_ev.public to dr_uce_role;
grant select on future views in schema dr_ev.public to dr_uce_role;
grant all privileges on all tables in schema dr_ev.stg to dr_uce_role;
grant all privileges on all views in schema dr_ev.stg to dr_uce_role;
grant select on future tables in schema dr_ev.stg to dr_uce_role;
grant select on future views in schema dr_ev.stg to dr_uce_role;
This user then created objects in the schemas. However my "DBA" user at SYSADMIN could not see the objects at all. With role ACCOUNTADMIN the user can see the objects, but not query them. My understanding is that ACCOUNTADMIN is the top level account, and can take ownership of these objects anyway, so if this is supposed to be a security feature I don't really understand how it is providing much protection as it can always steal ownership?
I tried changing ownership of an object as ACCOUNTADMIN to SYSADMIN, to find it had a blocking privilege;
grant ownership on dr_ev.stg.load_opportunity to sysadmin;
SQL execution error: Dependent grant of privilege 'DELETE' on securable 'DR_EV.STG.LOAD_OPPORTUNITY' to role 'DR_UCE_ROLE' exists. It must be revoked first. More than one dependent grant may exist: use 'SHOW GRANTS' command to view them. To revoke all dependent grants while transferring object ownership, use convenience command 'GRANT OWNERSHIP ON TO REVOKE CURRENT GRANTS'.`
I tried taking ownership with
grant ownership on all tables in schema dr_ev.stg to sysadmin revoke current grants;
which did work - although it left my power user unable to see the objects. So I granted them back with
grant all privileges on all tables in schema dr_ev.stg to dr_uce_role;
However I want my power user to be able to create or replace this table. I believe this requires the DROP TABLE privilege, although apparently my power user grants do not provide it, and I am unclear on how I should be providing it?
I will not say I have the greatest understanding of Snowflake privileges and am wondering if the statements above like grant all privileges on all tables in schema do not live at the schema level to blanket apply to all tables, but actually sets object level permissions and my original approach has simply been too granular as I do not actually wish to manage anything at object level. That being said, I am unclear in the doc how to manage at a higher level than object anyway if the statement is actually just a shortcut to set many object privileges. How can I accomplish my original goals?
The best practice for a situation like this is to grant all of your custom roles to the SYSADMIN role. This allows the sysadmin to do everything a SYSADMIN can do plus everything that all of the other roles can do. You have a lot of questions in your post, but I think this resolves many of them.
The way I did was to create a super role 'superole' and granted sysadmin, securityadmin and accountadmin to that role. I then attached the superrole to whoever I wanted to be my DBA...

how can I grant usage on all Snowflake databases (inlcuding future) to a role?

I would like to create a role that would have permissions to clone any database, present and future.
Something like
GRANT CREATE DATABASE ON ACCOUNT TO ROLE CLONE_ADMIN;
Followed by
GRANT USAGE ON FUTURE DATABASES TO ROLE CLONE_ADMIN;
Is it possible?
Future grants can only be applied to schema objects.
From the documentation"When a database is cloned, the schemas in the cloned database copy the future privileges from the source schemas. This maintains consistency with the regular object grants, in which the grants of the source object (i.e. database) are not copied to the clone, but the grants on all the children objects (i.e. schemas in the database) are copied to the clones."
Future grants cannot be applied to databases.
USE ROLE ACCOUNTADMIN;
USE DATABASE ANALYTICS;
CREATE OR REPLACE ROLE DATA;
GRANT USAGE ON DATABASE ANALYTICS TO DATA;
GRANT CREATE DATABASE ON ACCOUNT TO ROLE DATA;
GRANT ROLE DATA TO USER NEW_USER1;
USE ROLE DATA;
CREATE DATABASE Z_NEW_USER1_TEST CLONE ANALYTICS;
The feature of future grant at database level is in the roadmap. It is currently in private preview with selected customers to gather feedback from early users.
Stay tune from update from Snowflake when this feature will become accessible to wider audience.

Resources