Show grants on all schemas in a Snowflake database - snowflake-cloud-data-platform

I am trying to list all grants of all schemas in a specific database.
I found that only SHOW GRANTS ON SCHEMA "TEST_DB"."TEST_SCHEMA" do the trick for one schema, but unfortunately I cannot be done for all schemas.
I believe I would need to do a combination of SHOW and result_scan, but I wanted to know if there is a more straightforward solution
I came up with :
show grants on schema "DB"."SCHEMA_A";
show grants on schema "DB"."SCHEMA_B";
select * from table(result_scan(last_query_id())) union all select * from table(result_scan(last_query_id(-2)));
But it quite dirty, and very cumbersome

Each database you create in Snowflake has an information_schema schema which you can use to get metadata about objects. You can see what grants have been assigned to a schema in your database with:
select *
from your_db_name.information_schema.object_privileges
where object_type = 'SCHEMA';
This will show you which roles (the "grantee") have been granted access to the schemas in that database but keep in mind that it won't show how the permissions are pushed down the role hierarchy to child roles.
Information schema documentation: https://docs.snowflake.com/en/sql-reference/info-schema.html

Related

What is the complete list of privileges a role needs in order to create a table in a schema?

I have granted USAGE on the schemas and database.
I have granted select on all tables.
Using that role, I can read data from all tables within any schema.
I then grant the permission to create tables in all schemas within that database
GRANT CREATE TABLE ON ALL SCHEMAS IN DATABASE TEST1_CONTROL TO DEVELOPERS;
Yet, when I issue this command (while using DEVELOPERS role), I get an error
CREATE TABLE PDS.ERIC_TEST_TABLE(COUCOU STRING NULL);
What am I missing?
Works fine for me (script below). Going to go with what Lukasz commented and that your schema was created later.
use role accountadmin;
create database TEST1_CONTROL;
create schema PDS;
create role DEVELOPERS;
grant role DEVELOPERS to user <your_username>;
GRANT USAGE ON DATABASE TEST1_CONTROL TO DEVELOPERS;
GRANT USAGE ON ALL SCHEMAS IN DATABASE TEST1_CONTROL TO DEVELOPERS;
GRANT CREATE TABLE ON ALL SCHEMAS IN DATABASE TEST1_CONTROL TO DEVELOPERS;
use role DEVELOPERS;
CREATE TABLE PDS.ERIC_TEST_TABLE(COUCOU STRING NULL);
Snowflake does offer future grants if you want a role to have access to any new schemas that would be created in the future.

CI Temporary Schema Not Deleting

I've recently enabled the CI feature on dbt Cloud. Their documentation mentions that
Once the PR is closed, dbt Cloud will delete the temporary schema.
But it seems like these schemas aren't actually deleting once I've closed the PR.
Anyone know what's happening here?
Does your dbt executing user on snowflake (Example snowflake_dbt) have all permissions for all schemas on that DB?
I'd start by checking something like the following and then check for what privileges are enabled for all schemas on that database:
SHOW GRANTS TO USER <dbt_user>
SHOW GRANTS OF ROLE <dbt_service_role>
SHOW GRANTS ON SCHEMA <ci_schema>
SHOW GRANTS ON DATABASE <ci_database>
Reminder, dbt is creating the schema on the fly so pre-existing schema privileges won't apply. This is a privilege that will have to be given to all schemas on that database for either that user or role.

Revoke access from PostgreSQL User to see other tables

I have a PostgreSQL DB user "limited_user" and want to give SELECT permission on one table ONLY.
GRANT CONNECT ON DATABASE "db1" TO limited_user;
GRANT SELECT ON TABLE users to limited_user;
What happens is that when I try \dt , the user can see all the other tables in this db1, while he can perform SELECT operation to table "user" as I gave permission. How can I revoke access access to the user so that he can not see other tables and just one table?
You can't, at least not in any straightforward way that I am aware of.
Tables exist within the schema namespace, and schemas exist within the database. To give access to a user on a particular table means you must also give that user the USAGE permission on the schema to which the table belongs. USAGE does not grant permissions on the tables themselves, only the the schema in question. But table definitions are part of the schema, so USAGE does allow the user to see table names (and the columns too).
But if there are other tables in the same schema, the user will not be able to SELECT from those tables unless you also GRANT SELECT on those tables, even though they will be able to see that they exist.
This answer gives a pretty clear explanation of the permission system.
Edit to add:
One way to achieve a similar outcome would be like this (using psql):
sec_schema=# REVOKE ALL ON ALL TABLES IN SCHEMA sec_schema FROM restricted_user;
REVOKE
sec_schema=# REVOKE USAGE ON SCHEMA sec_schema FROM restricted_user;
REVOKE
sec_schema=# CREATE SCHEMA new_schema;
CREATE SCHEMA
sec_schema=# GRANT USAGE ON new_schema TO restricted_user;
GRANT
sec_schema=# CREATE VIEW new_schema.secret_view AS SELECT * from sec_schema.secret_table;
CREATE VIEW
sec_schema=# GRANT SELECT ON new_schema.secret_view TO restricted_user;
GRANT
This will remove all access to the schema sec_schema for user restricted_user, but then creates new_schema and new_schema.secret_view which is a cover view over sec_schema.secret_table. After the GRANT SELECT, the user will be able to read the data from table sec_schema.secret_table through the view, but they will not be able to see any objects in sec_schema.

Grant SELECT permission on a view in reporting schema, but not on underlying objects in different schemas

I am preparing set of views which users can use to prepare their own reports. The views query tables from other schemas including dbo.
The views are created in a separate REPORTING schema. I have configured following user which will be used to access the data by end users:
CREATE ROLE report AUTHORIZATION db_securityadmin;
GRANT SELECT, EXECUTE ON SCHEMA :: reporting TO report
CREATE LOGIN reporting_login WITH PASSWORD = 'SomePassword'
CREATE USER reporting_usr FOR LOGIN reporting_login
EXEC sp_addrolemember N'report', reporting_usr'
When tried to query my view I got an error saying that: 'The SELECT permission was denied on the object XXX schema dbo'. So following this topic: Grant Select on a view not base table when base table is in a different database (clarification: I have all of my tables and views in the same database)
I changed the ownership of the views to dbo user(ALTER AUTHORIZATION ON reporting.[vCounters] TO dbo) , which worked well for views that only used dbo tables, but when I started using other schemas I started getting permission denied errors again on those tables.
All schemas used by views are owned by same ApplicationAdmin user, dbo schema is obviously owned by dbo.
How can I apply ownership chain properly to allow reporting_usr to query from views in reporting schema but not underlying tables in other schemas.
How can I apply ownership chain properly to allow reporting_usr to query from views in reporting schema but not underlying tables in other schemas.
The views and tables must have the same owner. If your reporting users have no rights to create objects in the reporting schema, then just change its owner to dbo.

SNOWFLAKE.INFORMATION_SCHEMA does not showing any record

I am trying the below query against SNOWFLAKE.INFORMATION_SCHEMA from account admin but it returning an error.
Query:
Select
'databases' as category,
count(*) as found,
'3' as expected
from SNOWFLAKE.INFORMATION_SCHEMA.DATABASES
where DATABASE_NAME IN ('USDA_NUTRIENT_STDREF','LIBRARY_CARD_CATALOG','SOCIAL_MEDIA_FLOODGATES')
Error:
SQL compilation error: Database 'SNOWFLAKE' does not exist or not authorized.
Checked SNOWFLAKE database exists but it does not have any schema including INFORMATION_SCHEMA
Databases live under your account. Account is the top level object in the Snowflake object hierarchy. Databases live under account. See this link, and find the text where it says, "The top-most container is the customer account...". It's got a nice little graphic there.
When you query information_schema on the Snowflake database, you're getting the information_schema of just the snowflake database, not of your entire account. Snowflake.information_schema is kinda useless b/c it just shows the information schema of a database (Snowflake) that you have no control over - Snowflake controls it.
If you want to see all the databases in your account, you can do the following:
use role accountadmin;
show databases;
select count(*) from table(result_scan(last_query_id())) where "name" in ('USDA_NUTRIENT_STDREF','LIBRARY_CARD_CATALOG','SOCIAL_MEDIA_FLOODGATES');
Now, separately, if you're concerned about the error you're getting - that you don't have access to the snowflake database, then I'd say you're either not using the accountadmin role, or you're not using a role that has the right privileges. If you'd like to give a role privileges to the Snowlfake database, you can run the following:
GRANT IMPORTED PRIVILEGES
ON DATABASE SNOWFLAKE TO ROLE {SOME_ROLE_OF_YOURS};
Good luck!

Resources