Introduction
Setup
//============================================================================= // Description : This is a Demo sql for explaining secure views //============================================================================ //============================================================================= // Set context //============================================================================= USE ROLE sysadmin; USE WAREHOUSE Compute_WH; //============================================================================= // Create the Database and the Tables //============================================================================= CREATE OR REPLACE DATABASE SecureViews; --DROP DATABASE IF EXISTS SecureViews; USE DATABASE SecureViews; USE SCHEMA PUBLIC; CREATE OR REPLACE TABLE NETFLIX_SERIES ( ID NUMBER, TITLE STRING, MOVIECATEGORY STRING ); INSERT INTO NETFLIX_SERIES VALUES (0, 'Queens Gambit', 'Drama'), (1, 'Ozark', 'Thriller'), (2, 'The Crown', 'Drama'), (3, 'Mindhunter', 'Don''t know'), (4, 'The Haunting of Hill House', 'Horror'), (5, 'Tiger King', 'Hmmm'), (6, 'Stranger Things', 'Don''t know either');
Next, I created the User security table, with a Moviecategory and UserId as columns. For this demo I want to limit the access per user on certain movie categories. The user Hennie is allowed to see movies in the category "Drama" and Peter in the category "Thriller".
SELECT CURRENT_USER();
CREATE OR REPLACE TABLE USERSECURITY
(
MOVIECATEGORY STRING,
USERID STRING
);
INSERT INTO USERSECURITY(MOVIECATEGORY, USERID) VALUES ('Drama', 'HENNIE'), ('Thriller', 'PETER');
SELECT * FROM USERSECURITY;
And here is the result of the SELECT:
Create a secure view
The next step is creating the secure view with the keyword SECURE in CREATE SECURE VIEW. Here is the DDL for the view.
CREATE OR REPLACE SECURE VIEW NETFLIX_SERIES_Secure_view_v2
AS
SELECT
NS.ID,
NS.TITLE,
NS.MOVIECATEGORY,
US.USERID
FROM NETFLIX_SERIES NS
INNER JOIN USERSECURITY US ON NS.MOVIECATEGORY = US.MOVIECATEGORY
WHERE USERID = CURRENT_USER();
SELECT * FROM NETFLIX_SERIES_Secure_view_v2;
I executed this SELECT with user HENNIE and it is only showing the movies with category "Drama"
Next, I looked at SHOW VIEWS command
SHOW VIEWS;
And here you can see the definition of the view
Can I create this RLS on a normal View? Yes we can..
/=============================================================================
// Can I create the security without the SECURE key word?
//=============================================================================
CREATE OR REPLACE VIEW NETFLIX_SERIES_view
AS
SELECT
NS.ID,
NS.TITLE,
NS.MOVIECATEGORY,
US.USERID
FROM NETFLIX_SERIES NS
INNER JOIN USERSECURITY US ON NS.MOVIECATEGORY = US.MOVIECATEGORY
WHERE USERID = CURRENT_USER();
SELECT * FROM NETFLIX_SERIES_view;
One thing I tried was creating a materialized Secure view.
//=============================================================================
// Can I create a Secure materialized views?
//=============================================================================
CREATE OR REPLACE SECURE MATERIALIZED VIEW NETFLIX_SERIES_MATERIALIZED_SECURE_view
AS
SELECT
NS.ID,
NS.TITLE,
NS.MOVIECATEGORY,
US.USERID
FROM NETFLIX_SERIES NS
INNER JOIN USERSECURITY US ON NS.MOVIECATEGORY = US.MOVIECATEGORY
WHERE USERID = CURRENT_USER();
Now creating a materialized view isn't possible because of the reason that it's not possible to create a materialized view based on two tables.
SQL compilation error: error line 0 at position -1 Invalid materialized view definition. More than one table referenced in the view definition
Check the RLS views with another User
Now create another user "PETER" and what are results that Peter can see of the Netflix series and movies. Here are some scripts for creating the user PETER.
USE ROLE ACCOUNTADMIN;
CREATE ROLE IF NOT EXISTS SecureViews;
--GRANT USAGE ON WAREHOUSE COMPUTE_WH TO ROLE SecureViews;
GRANT USAGE ON DATABASE SecureViews TO ROLE SecureViews;
GRANT USAGE ON SCHEMA SecureViews.PUBLIC TO ROLE SecureViews;
GRANT SELECT ON ALL TABLES IN SCHEMA SecureViews.PUBLIC TO ROLE SecureViews;
GRANT SELECT ON ALL VIEWS IN SCHEMA SecureViews.PUBLIC TO ROLE SecureViews;
--Grant role to USER PETER
GRANT ROLE SecureViews TO USER PETER;
Next step is logging as user PETER and query the normal view.
SELECT * FROM NETFLIX_SERIES_view;
And here is the result of the query. Peter sees the Thriller category, only.
Can peter see the same with the SECURE view? Yes he can...
SELECT * FROM NETFLIX_SERIES_Secure_view_v2
SHOW VIEWS;
Final Thoughts
This blogpost is about Secure views and row level security.
Hennie
Geen opmerkingen:
Een reactie posten