future grants on a snowflake database - permissions

Any insight on why the below grant statements are not providing future grants on tables in database db_prod for role analyst_legacy_test? Below grants do give select to views and tables, but not to future views or tables...(when a new table is created by another role, analyst_legacy_test role cannot see it or view it)
use role securityadmin;
grant usage on database db_prod to role analyst_legacy_test;
grant usage on all schemas in database db_prod to role analyst_legacy_test;
grant select on all tables in database db_prod to role analyst_legacy_test;
grant select on all views in database db_prod to role analyst_legacy_test;
grant usage on future schemas in database db_prod to role ANALYST_LEGACY_TEST;
grant select on future tables in database db_prod to role analyst_legacy_test;
grant select on future views in database db_prod to role ANALYST_LEGACY_TEST;
I've read multiple pieces of documentation and pulled these statements from there.
https://community.snowflake.com/s/article/How-to-grant-select-on-all-future-tables-in-a-schema-and-database-level
I've also read about the potential issue with future grant precedence (that if you designate schema level future grants the datbase level grants will be ignored). I don't believe my statements apply to this scenario
https://community.snowflake.com/s/article/Precedence-rule-for-future-grants
UPDATE/SOLUTION: The issue was that another role had schema level future grants. From the documentation it was not clear to me the future grants precedence issue spanned across roles. To resolve issue, I had to check every role in database for schema level grants (and remove them) or grant schema level grants on this role.

One plausible scenario is existence of another future grants that are assigned on schema level to different role. In such situation future grants assigned on the database level are ignored.
Considerations
When future grants are defined on the same object type for a database and a schema in the same database, the schema-level grants take precedence over the database level grants, and the database level grants are ignored. This behavior applies to privileges on future objects granted to one role or different roles.
Reproducible example:
USE ROLE SYSADMIN;
CREATE OR REPLACE DATABASE DB_PROD;
USE ROLE SECURITYADMIN;
CREATE OR REPLACE ROLE analyst_legacy_test;
grant usage on database db_prod to role analyst_legacy_test;
grant usage on all schemas in database db_prod to role analyst_legacy_test;
grant select on all tables in database db_prod to role analyst_legacy_test;
grant select on all views in database db_prod to role analyst_legacy_test;
grant usage on future schemas in database db_prod to role ANALYST_LEGACY_TEST;
grant select on future tables in database db_prod to role analyst_legacy_test;
grant select on future views in database db_prod to role ANALYST_LEGACY_TEST;
grant role ANALYST_LEGACY_TEST TO USER <user_name_here>;
USE ROLE SYSADMIN;
CREATE OR REPLACE SCHEMA TEST;
CREATE OR REPLACE VIEW TEST_VW AS SELECT 1 AS c;
-- no schema level future grants, the view is accessible
USE ROLE analyst_legacy_test;
SELECT * FROM TEST.TEST_VW;
-- 1
-- adding future grants to different role on schema level
USE ROLE SECURITYADMIN;
grant select on future views in schema DB_PROD.TEST to role sysadmin;
-- TEST_VW still works
USE ROLE analyst_legacy_test;
SELECT * FROM TEST.TEST_VW;
-- 1
-- new view
USE ROLE SYSADMIN;
CREATE OR REPLACE VIEW TEST.TEST_VW_NEW AS SELECT 2 AS c;
USE ROLE analyst_legacy_test;
SELECT * FROM TEST.TEST_VW_NEW;
-- Object 'DB_PROD.TEST.TEST_VW_NEW' does not exist or not authorized.

Related

In dbt cloud, using snowflake what is a good standard to create a "dbt transformer" role used by DBT RUN - mine does not work

The only way I can get dbt run to work is by connecting as an accountadmin (bad). Any other role gives me "insufficient privileges on table xxx" when executing dbt models. I am using DBT cloud connecting to snowflake. I have created the following with a role that I wanted to use, but it seems that my grants do not work, to allow running my models with this new role.
my dbt cloud "dev" target profile connects as dbt_user, and creates objects in analytics.dbt_ddumas
Below is my grant script, run by an accountadmin:
There must be an easier way than this below, which is not even working :(
Dave
use role accountadmin;
CREATE ROLE dbt_role
GRANT ROLE dbt_role TO ROLE sysadmin
GRANT USAGE ON WAREHOUSE transform_wh TO ROLE dbt_role
GRANT ALL ON database analytics TO ROLE dbt_role
grant ALL ON ALL schemas in database analytics to role dbt_role;
grant ALL ON future schemas in database analytics to role dbt_role;
grant ALL ON ALL tables in SCHEMA analytics.dbt_ddumas to role dbt_role;
grant ALL ON future tables in SCHEMA analytics.dbt_ddumas to role dbt_role;
grant ALL ON ALL views in SCHEMA analytics.dbt_ddumas to role dbt_role;
grant ALL ON future views in SCHEMA analytics.dbt_ddumas to role dbt_role;
CREATE USER dbt_user PASSWORD = 'Password123' MUST_CHANGE_PASSWORD = FALSE;
GRANT ROLE dbt_role TO USER dbt_user;
For anyone who is new to DBT with snowflake, here is what you need to do to setup a dbt role to run models, test, etc with dbt run, dbt test, etc
After much frustration, and a willingness to save others the pain I went through...
This is for a lower environment . Ex dev or test
Step 0: Login as an accountadmin, or have an accountadmin do this:
Step 1: create a warehouse . Ex. transform_wh
Step 2: create a database Ex. Analytics
Run this below, substituting the proper password for dbt_user:
NOTE: DO NOT CREATE ANY SCHEMAS AS ACCOUNTADMIN. That was my main problem, so do not make that mistake. The reply from the user who replied to this message did not know that, and his reply would work also. The dbt_loader_dev role will do this as you execute dbt_run. If you do, dbt_loader_dev will get "insufficient privileges" errors when trying to create schemas, tables, and views.
USE ROLE accountadmin;
-- this role is used to load all models in the dev (lower environments) when you do a dbt run, dbt test, etc
CREATE ROLE dbt_loader_dev;
-- custom roles should be granted to sysadmin
grant ROLE dbt_loader_dev TO ROLE sysadmin;
-- these grant are all you need to run so that dbt_loader_dev can do all that it needs to for any dbt run, dbt test, etc
GRANT USAGE ON WAREHOUSE transform_wh TO ROLE dbt_loader_dev;
GRANT all ON database analytics TO ROLE dbt_loader_dev;
GRANT usage ON ALL SCHEMAS IN DATABASE analytics TO dbt_loader_dev;
GRANT usage ON future SCHEMAS IN DATABASE analytics TO dbt_loader_dev;
GRANT Monitor ON ALL SCHEMAS IN database analytics TO dbt_loader_dev;
GRANT Monitor ON future SCHEMAS IN database analytics TO dbt_loader_dev;
GRANT MODIFY ON ALL SCHEMAS IN DATABASE analytics TO dbt_loader_dev;
GRANT MODIFY ON future SCHEMAs IN DATABASE analytics TO dbt_loader_dev;
-- create a user and grant the role
CREATE USER dbt_user PASSWORD = 'Password123' MUST_CHANGE_PASSWORD = FALSE;
GRANT ROLE dbt_loader_dev TO USER dbt_user;
That's it! Enjoy!
Dave (edited)
I recommend following the excellent article by Claire on the dbt Discourse that covers this exact topic.
It would be helpful to know exactly what table, schema, or database you are unable to read from. You say my dbt cloud "dev" target profile connects as dbt_user, and creates objects in analytics.dbt_ddumas, but what databases and schemas is it reading from? (Where are your sources located)? Most of your grants will be oriented to reading existing data, since dbt Cloud will create your dbt_ddumas schema, and therefore own it and every other relation that it creates.
Assuming your raw data is located in a database called raw, then I would change your script to:
use role accountadmin;
CREATE ROLE dbt_role
GRANT ROLE dbt_role TO ROLE sysadmin
GRANT USAGE ON WAREHOUSE transform_wh TO ROLE dbt_role
grant usage on database raw to role dbt_role;
grant usage on future schemas in database raw to role dbt_role;
grant select on future tables in database raw to role dbt_role;
grant select on future views in database raw to role dbt_role;
grant usage on all schemas in database raw to role dbt_role;
grant select on all tables in database raw to role dbt_role;
grant select on all views in database raw to role dbt_role;
grant usage ON database analytics TO ROLE dbt_role;
grant create schema ON database analytics TO ROLE dbt_role;
CREATE USER dbt_user PASSWORD = 'Password123' MUST_CHANGE_PASSWORD = FALSE;
GRANT ROLE dbt_role TO USER dbt_user;

Grant select on future views snowflake

How can I grant select on all future views in a schema or database.
This works fine but I want the role to have access to all future views too:
grant select on view <schema>.<view> to role <role>;
Any ideas?
Grant on future objects like this (using ACCOUNTADMIN role):
Make sure USAGE is granted on database and schema:
GRANT USAGE ON DATABASE <database> TO ROLE <role>;
GRANT USAGE ON SCHEMA <database>.<schema> TO ROLE <role>;
Grant select on future objects:
grant select on future tables [views] in schema <database>.<schema> to role <role>;
grant select on future views in schema <database>.<schema> to role <role>;

Create user with access to view in redshift

I’m pulling data from mysql ec2 instances, to s3 buckets, then creating views in redshift. I want to create database users who can only query and see certain views created specifically for them in Redshift. I have example code below that I use to create the user, view, and grant access. The issue I have is that I also have to grant access to the underlying schema the view is created from, which means the user can see and query tables in that schema. Also the user can see other schemas in the database, even ones they can’t query. Is there a way to only grant users to specific views, and make it so they can’t see other schemas they don’t have access to?
Code:
--create schema
create schema tst_user_schema;
--create view in schema
create view tst_user_schema.inventory_report_customer as (
select * from user341.inventory_report_customer
)
with no schema binding;
--creating user
CREATE USER tstuser PASSWORD 'tstPassword';
--grant access
GRANT USAGE ON SCHEMA tst_user_schema TO tstuser;
--grant read access to all tables in schema
GRANT SELECT ON ALL TABLES IN SCHEMA tst_user_schema TO tstuser;
--grant access
GRANT USAGE ON SCHEMA user341 TO tstuser;
--grant read access to all tables in schema
GRANT SELECT ON ALL TABLES IN SCHEMA user341 TO tstuser;
--grant access
GRANT USAGE ON SCHEMA tst_user_schema TO tstuser;
--grant read access to all tables in schema
GRANT SELECT ON ALL TABLES IN SCHEMA tst_user_schema TO tstuser;
to recap:
schema user341 - contains source tables, user should not be able to select from tables in this schema. You also want to hide it form the user
tst_user_schema - contains views user is supposed to be able to select from.
Looking at your GRANT statements, you're granting user unnecessarily SELECT permission on ALL TABLES IN SCHEMA user341. For views to work you only need to GRANT USAGE on that schema.
So REVOKE those permissions, and user should not be able to select.
REVOKE SELECT ON ALL TABLES IN SCHEMA user341 FROM tstuser;
Tip: to easily test permissions, you can start a session as tstuser using SET SESSION AUTHORIZATION directive and then test which statements are allowed and which not.
SET SESSION AUTHORIZATION tstuser
Regarding schema visibility - unfortunately there's no way to hide or forbid user from seening all tables and columns in all schemas. One can only restrict access to data.

PostgreSQL: Give all permissions to a user on a PostgreSQL database

I would like to give a user all the permissions on a database without making it an admin.
The reason why I want to do that is that at the moment DEV and PROD are different DBs on the same cluster so I don't want a user to be able to change production objects but it must be able to change objects on DEV.
I tried:
grant ALL on database MY_DB to group MY_GROUP;
but it doesn't seem to give any permission.
Then I tried:
grant all privileges on schema MY_SCHEMA to group MY_GROUP;
and it seems to give me permission to create objects but not to query\delete objects on that schema that belong to other users
I could go on by giving USAGE permission to the user on MY_SCHEMA but then it would complain about not having permissions on the table ...
So I guess my question is: is there any easy way of giving all the permissions to a user on a DB?
I'm working on PostgreSQL 8.1.23.
All commands must be executed while connected to the right database cluster. Make sure of it.
Roles are objects of the database cluster. All databases of the same cluster share the set of defined roles. Privileges are granted / revoked per database / schema / table etc.
A role needs access to the database, obviously. That's granted to PUBLIC by default. Else:
GRANT CONNECT ON DATABASE my_db TO my_user;
Basic privileges for Postgres 14 or later
Postgres 14 adds the predefined, non-login roles pg_read_all_data / pg_write_all_data.
They have SELECT / INSERT, UPDATE, DELETE privileges for all tables, views, and sequences. Plus USAGE on schemas. We can GRANT membership in these roles:
GRANT pg_read_all_data TO my_user;
GRANT pg_write_all_data TO my_user;
This covers all basic DML commands (but not DDL, and not some special commands like TRUNCATE or the EXECUTE privilege for functions!). The manual:
pg_read_all_data
Read all data (tables, views, sequences), as if having SELECT rights
on those objects, and USAGE rights on all schemas, even without
having it explicitly. This role does not have the role attribute
BYPASSRLS set. If RLS is being used, an administrator may wish to
set BYPASSRLS on roles which this role is GRANTed to.
pg_write_all_data
Write all data (tables, views, sequences), as if having INSERT,
UPDATE, and DELETE rights on those objects, and USAGE rights on
all schemas, even without having it explicitly. This role does not
have the role attribute BYPASSRLS set. If RLS is being used, an
administrator may wish to set BYPASSRLS on roles which this role is
GRANTed to.
All privileges without using predefined roles (any Postgres version)
Commands must be executed while connected to the right database. Make sure of it.
The role needs (at least) the USAGE privilege on the schema. Again, if that's granted to PUBLIC, you are covered. Else:
GRANT USAGE ON SCHEMA public TO my_user;
Or grant USAGE on all custom schemas:
DO
$$
BEGIN
-- RAISE NOTICE '%', ( -- use instead of EXECUTE to see generated commands
EXECUTE (
SELECT string_agg(format('GRANT USAGE ON SCHEMA %I TO my_user', nspname), '; ')
FROM pg_namespace
WHERE nspname <> 'information_schema' -- exclude information schema and ...
AND nspname NOT LIKE 'pg\_%' -- ... system schemas
);
END
$$;
Then, all permissions for all tables (requires Postgres 9.0 or later).
And don't forget sequences (if any):
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO my_user;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO my_user;
Alternatively, you could use the "Grant Wizard" of pgAdmin 4 to work with a GUI.
This covers privileges for existing objects. To also cover future objects, set DEFAULT PRIVILEGES. See:
Grant privileges for a particular database in PostgreSQL
How to manage DEFAULT PRIVILEGES for USERs on a DATABASE vs SCHEMA?
There are some other objects, the manual for GRANT has the complete list. As of Postgres 14:
privileges on a database object (table, column, view, foreign table, sequence, database, foreign-data wrapper, foreign server, function, procedure, procedural language, schema, or tablespace)
But the rest is rarely needed. More details:
Grant privileges for a particular database in PostgreSQL
How to grant all privileges on views to arbitrary user
Consider upgrading to a current version.
GRANT ALL PRIVILEGES ON DATABASE "my_db" to my_user;
In PostgreSQL 9.0+ you would do the following:
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA MY_SCHEMA TO MY_GROUP;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA MY_SCHEMA TO MY_GROUP;
If you want to enable this for newly created relations too, then set the default permissions:
ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
GRANT ALL PRIVILEGES ON TABLES TO MY_GROUP;
ALTER DEFAULT PRIVILEGES IN SCHEMA MY_SCHEMA
GRANT ALL PRIVILEGES ON SEQUENCES TO MY_GROUP;
However, seeing that you use 8.1 you have to code it yourself:
CREATE FUNCTION grant_all_in_schema (schname name, grant_to name) RETURNS integer AS $$
DECLARE
rel RECORD;
BEGIN
FOR rel IN
SELECT c.relname
FROM pg_class c
JOIN pg_namespace s ON c.namespace = s.oid
WHERE s.nspname = schname
LOOP
EXECUTE 'GRANT ALL PRIVILEGES ON ' || quote_ident(schname) || '.' || rel.relname || ' TO ' || quote_ident(grant_to);
END LOOP;
RETURN 1;
END; $$ LANGUAGE plpgsql STRICT;
REVOKE ALL ON FUNCTION grant_all_in_schema(name, name) FROM PUBLIC;
This will set the privileges on all relations: tables, views, indexes, sequences, etc. If you want to restrict that, filter on pg_class.relkind. See the pg_class docs for details.
You should run this function as superuser and as regular as your application requires. An option would be to package this in a cron job that executes every day or every hour.
I did the following to add a role 'eSumit' on PostgreSQL 9.4.15 database and provide all permission to this role :
CREATE ROLE eSumit;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO eSumit;
GRANT ALL PRIVILEGES ON DATABASE "postgres" to eSumit;
ALTER USER eSumit WITH SUPERUSER;
Also checked the pg_table enteries via :
select * from pg_roles;
Database queries snapshot :
In PostgreSQL 12 and later, it is possible to grant all privileges of a table in a database to a role/user/account.
The syntax is:
GRANT ALL ON table_name TO role_name;
If you want to grant it to all tables in the database then the syntax will be:
GRANT ALL ON ALL TABLES TO role_name;
If you want to grant it to all tables of a schema in the database then the syntax will be:
GRANT ALL ON ALL TABLES IN SCHEMA schema_name TO role_name;
Note: Remember you will need to select the database before you can grant its privileges to a user.
Resources: PostgreSQL GRANT
That's all
I hope this helps
GRANT USAGE ON SCHEMA schema_name TO user;
GRANT ALL ON SCHEMA schema_name TO user_name;
Give all permissions to a user on a PostgreSQL database:
Command:
grant all privileges on database [database_name] to [database_user_name];
Example:
grant all privileges on database studentdb to shaifullah;
OR
GRANT ALL PRIVILEGES ON DATABASE studentdb TO shaifullah;

Vertica role grant not working

I am trying to setup a new role for making the access rights granting easier. I was wondering if there is an easier way to give select on all tables (newly created tables should be accessible automatically) under a schema to selected users. I ran following queries for the same. But still my user is not able to access the specific table.
CREATE ROLE myrole;
GRANT SELECT ON myschema.mytable TO myrole;
GRANT usage ON schema myschema TO myrole;
CREATE USER mytest1 identified BY '***';
GRANT myrole TO mytest1;
After this, when I login with mytest1 user and trying to run select on myschema.mytable it is asking me to grant usage on schema to user. After I grant usage on schema to user directly it is failing with permission denied for that table.
Please help with the same. I am running on vertica 5.0
Update:
I find that u also have to make that role default or explicitely set that role as default for user session for making the role's effect take place.
ALTER USER mytest1 DEFAULT ROLE myrole;
But still, my another question of how to make all tables under a schema accessible to specific users remains.
As per the Vertica SQL Reference Manual.pdf (page 725) (doc version 5.0 - for page numbers)
GRANT (Schema)
...
USAGE
Allows the user access to the objects contained within the
schema. This allows the user to look up objects within the
schema. Note that the user must also be granted access to the
individual objects. See the GRANT TABLE (page 727) ... .
The the user must also be granted access to the individual objects means that you need to also GRANT table.
The two I use is GRANT SELECT and GRANT REFERENCES which allows the user to run queries and join (reference) tables in the query.
Example:
GRANT SELECT ON TABLE [schema].[Table1] TO myUser;
GRANT SELECT ON TABLE [schema].[Table2] TO myUser;
GRANT REFERENCES ON TABLE [schema].[Table1] TO myUser;
GRANT REFERENCES ON TABLE [schema].[Table2] TO myUser;
...
6.0 doc reference GRANT SCHEMA (page 808) and GRANT TABLE (page 813).