Our Security group is asking for us to have Snowflake audit records ingested into our on prem SIEM by the end of the quarter. I've found the information_schema.login_history records but I'm struggling to find anything else that the SIEM might want (privilege usage, etc). Any tips on relevant views or functions would be appreciated.
some tables can be used to understand query & login attempts by Snowflake users along with various dimensions. For details take a look at:
https://docs.snowflake.net/manuals/sql-reference/functions/login_history.html
https://docs.snowflake.net/manuals/sql-reference/functions/query_history.html
Here are some of the SNOWFLAKE ACCOUNT_USAGE SCHEMA QUERIES that may come handy.
Access_History ,Query_History will help to find out who and How the Snowflake DB is been accessed and Query History will show the queries executed ,Role ,Warehouse,start time ,end time etc.
Also try to login to Snowsight get the full lineage of a specific Role.
--TO FIND THE ACTIVE USERS IN THE ACCOUNT--
SELECT FIRST_NAME,LAST_NAME,DISPLAY_NAME from "SNOWFLAKE"."ACCOUNT_USAGE"."USERS"
WHERE DELETED_ON IS NULL GROUP BY FIRST_NAME,LAST_NAME,DISPLAY_NAME
ORDER BY FIRST_NAME DESC;
--TO FIND THE ACTIVE USERS AND ROLES IN THE ACCOUNT--
SELECT ROLE,GRANTEE_NAME,GRANTED_BY FROM "SNOWFLAKE"."ACCOUNT_USAGE"."GRANTS_TO_USERS"
WHERE DELETED_ON IS NULL
GROUP BY ROLE,GRANTEE_NAME,GRANTED_BY
ORDER BY GRANTEE_NAME DESC;
--TO FIND THE ACTIVE GRANTS ON ROLES TO OBJECTS--
SELECT PRIVILEGE,TABLE_CATALOG,GRANTEE_NAME,GRANTED_BY FROM "SNOWFLAKE"."ACCOUNT_USAGE"."GRANTS_TO_ROLES"
WHERE DELETED_ON IS NULL
GROUP BY PRIVILEGE,TABLE_CATALOG,GRANTEE_NAME,GRANTED_BY
ORDER BY TABLE_CATALOG;
Related
SQL Query to get total number of tables available in Snowflake account(including all DB and schemas)
You can query account_usage.tables or information_schema.tables views to find the total number of tables:
select count(*) from information_schema.tables;
https://docs.snowflake.com/en/sql-reference/info-schema/tables.html
select count(*) from snowflake.account_usage.tables;
https://docs.snowflake.com/en/sql-reference/account-usage/tables.html
There are three ways:
You can query the view INFORMATION_SCHEMA.TABLES to find all tables of your current database. So: You have to write a SELECT COUNT(*) FROM [database].INFORMATION_SCHEMA.TABLES for each of your databases, do a UNION ALL afterwards and SUM() your results per database to get the whole number of tables in all databases.
You can query the view ACCOUNT_USAGE.TABLES to find all tables and views of your account. One row represents one table. As ACCOUNT_USAGE.TABLES also contains views, you have to add a WHERE-Klause for the attribute TABLE_TYPE. Here you also have to keep in mind that you may have a latency of 90 minutes.
Run SHOW TABLES IN ACCOUNT; to see all tables
More infos about INFORMATION_SCHEMA.TABLES: https://docs.snowflake.com/en/sql-reference/info-schema/tables.html
More infos about ACCOUNT_USAGE.TABLES: https://docs.snowflake.com/en/sql-reference/account-usage/tables.html
More infos about SHOW TABLES: https://docs.snowflake.com/en/sql-reference/sql/show-tables.html
Note: For all three ways you can only see objects for which your current role has access privileges.
There is a situation where I need to clean up my database in snowflake.
we have around 40 database and each database has more than 100 table. Some are getting loaded everyday and some are not, but used everyday.
However, There has been lots of table added for testing and other purpose (by lots of developer and user).
Now we are working on cleaning up un-used table.
We have query_history table which gives us the information of query run in past, however it has field such as database, warehouse, User etc. but not table.
I was wondering is there is any way we can write a query which give us table name not used (DDL and DML b0th) in last 10 days.
select obj.value:objectName::string objName
, max(query_start_time) as QUERY_DATE_TIME
from snowflake.account_usage.access_history
, table(flatten(direct_objects_accessed)) obj
group by 1
order by QUERY_DATE_TIME desc;
The information schema has a tables view and in that you have a last altered column, will that work with you? It will not give you the last accessed table but will give the last altered table. Other than this, there are no easy way to get this information from snowflake at this time. I also needed this feature, I think we should request for this feature.
select table_schema,
table_name,
last_altered
from information_schema.tables
where table_type = 'BASE TABLE'
and last_altered < dateadd( 'DAY', -10, current_timestamp() )
order by table_schema,
table_name;
I looked up the SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY table but the information it provides is the database name. Is there a way in snowflake to get the table names a query is accessing ? I am not looking for a solution which involves parsing the query string, as that is really complicated.
To see what tables an historical query accessed, you can go to the History tab, click on the query ID for the query, and then click on the profile. For queries that you are about to run, you can see what table(s) it will access by typing "explain" before the query. That will produce a metadata result set with a list of tables the query will read from in addition to other information.
Edit: If the explain produces a very long result set and you want to filter it down to just the affected tables, you can do something like this:
-- Generate the explain metadata reult set
explain select * from MY_VIEW;
-- Filter to just affected tables
select distinct "objects" as TABLE_NAME
from table(result_scan(last_query_id()))
where "operation" ilike '%table%' and "objects" is not null;
How to find the users and corresponding no.of queries executed by the user for all users in snowflake account.
I like to see output some thing like this for all the users.
username no.of queries executed by user
XXXXXXX 50
The below query helps in getting the details of queries executed by single user.
select query_text,
warehouse_name,
database_name,
schema_name,
user_name,
role_name,
execution_status,
error_code,
error_message,
start_time,
end_time
from table(information_schema.QUERY_HISTORY_BY_USER('USERNAME')) -- put username here
order by start_time desc;
Let me know for nay details required.
You can use the Query_history view in the account_usage schema though there will be a little delay in propagating the latest details. You can group by the user_name column.
https://docs.snowflake.com/en/sql-reference/account-usage/query_history.html#query-history-view
Good day. Trying to create a view in MS SQL that retrieves user data MS Dynamics CRM. I just need to extract the name of the employee and to correlate it with the identifier of one particular group. But the problem is that I can not find a relation with the security roles. Please give an example.
The table you are looking for is SystemUserRoles
select systemuser.firstname, systemuser.lastname, role.name, role.*
from systemuser
join SystemUserRoles on systemuser.systemuserid = systemuserroles.SystemUserId
join [role] on systemuserroles.roleid = [role].roleid