Row Level Security In SQL Server

SQL Server Row Level Security

Row-level security (RLS) is a feature added as of SQL Server 2016. Instead of encrypting or decrypting a database’s table data, it restricts and filters a table’s row-level data in accordance with security policies defined by the user. This enables the database engine to limit the number of exposed data rows. This is a simple and powerful SQL Server security control that is transparent to both clients and user applications.

Permissions

Creating, altering, or dropping security policies requires the ALTER ANY SECURITY POLICY permission. Creating or dropping a security policy requires ALTER permission on the schema.

Additionally, the following permissions are required for each predicate that is added:

·        SELECT and REFERENCES permissions on the function being used as a predicate.

·        REFERENCES permission on the target table being bound to the policy.

·        REFERENCES permission on every column from the target table used as arguments.

 

-- Create databas RLS

CREATE DATABASE RLS

GO

-- Create schema

CREATE SCHEMA Sales

GO


-- Create table

CREATE TABLE Sales.Orders

    ( 

    OrderID int, 

    SalesRep nvarchar(50), 

    Product nvarchar(50), 

    Quantity smallint 

    );

-- Insert records into table

INSERT INTO Sales.Orders  VALUES (1, 'SalesRep1', 'Valve', 5);

INSERT INTO Sales.Orders  VALUES (2, 'SalesRep1', 'Wheel', 2);

INSERT INTO Sales.Orders  VALUES (3, 'SalesRep1', 'Valve', 4);

INSERT INTO Sales.Orders  VALUES (4, 'SalesRep2', 'Bracket', 2);

INSERT INTO Sales.Orders  VALUES (5, 'SalesRep2', 'Wheel', 5);

INSERT INTO Sales.Orders  VALUES (6, 'SalesRep2', 'Seat', 5);

 

-- View the  rows in the table 

SELECT * FROM Sales.Orders;

-- Create users

CREATE USER Manager WITHOUT LOGIN; 

CREATE USER SalesRep1 WITHOUT LOGIN; 

CREATE USER SalesRep2 WITHOUT LOGIN;

GO


-- Before granting read access to users

-- Grant read access on the table to each of the users.

GRANT SELECT ON Sales.Orders TO Manager; 

GRANT SELECT ON Sales.Orders TO SalesRep1; 

GRANT SELECT ON Sales.Orders TO SalesRep2;


Create a new schema, and an inline table-valued function. The function returns 1 when a row in the SalesRep column is the same as the user executing the query (@SalesRep = USER_NAME()) or if the user executing the query is the Manager user (USER_NAME() = 'Manager').

-- Create new schema as Security

CREATE SCHEMA Security; 

GO 


-- Create inline function

CREATE FUNCTION Security.tvf_securitypredicate(@SalesRep AS nvarchar(50)) 

    RETURNS TABLE 

WITH SCHEMABINDING 

AS 

    RETURN SELECT 1 AS tvf_securitypredicate_result

WHERE @SalesRep = USER_NAME() OR USER_NAME() = 'Manager'; 

GO


Create a security policy adding the function as a filter predicate. The state must be set to ON to enable the policy.

-- Create a security policy

CREATE SECURITY POLICY SalesFilter 

ADD FILTER PREDICATE Security.tvf_securitypredicate(SalesRep)

ON Sales.Orders

WITH (STATE = ON); 

GO


-- Allow SELECT permissions to the fn_securitypredicate function

GRANT SELECT ON Security.tvf_securitypredicate TO Manager; 

GRANT SELECT ON Security.tvf_securitypredicate TO SalesRep1; 

GRANT SELECT ON Security.tvf_securitypredicate TO SalesRep2; 

-- Now test the filtering predicate, by selected from the Sales table as each user

EXECUTE AS USER = 'SalesRep1'; 

SELECT * FROM Sales.Orders;

REVERT; 

EXECUTE AS USER = 'SalesRep2'; 

SELECT * FROM Sales.Orders;

REVERT; 

EXECUTE AS USER = 'Manager'; 

SELECT * FROM Sales.Orders;

REVERT;

-- Disable the policy

ALTER SECURITY POLICY SalesFilter 

WITH (STATE = OFF);


Now Sales1 and Sales2 users can see all six rows.

EXECUTE AS USER = 'SalesRep1'; 

SELECT * FROM Sales.Orders;

REVERT;


EXECUTE AS USER = 'SalesRep2'; 

SELECT * FROM Sales.Orders;

REVERT;


-- Connect to the SQL database to clean up resources

DROP USER SalesRep1;

DROP USER SalesRep2;

DROP USER Manager;

DROP SECURITY POLICY SalesFilter;

DROP TABLE Sales.Orders;

DROP FUNCTION Security.tvf_securitypredicate;

DROP SCHEMA Security;

DROP SCHEMA Sales;

Comments

Post a Comment

Hi User,
Thanks for visiting My Blog and please provide your valuable feedback and subscribe for more updates. Please don't post any spam content or comments.
Thank You

Popular Posts

Failed to execute the package or element. Build errors were encountered

Restore of database 'DataBase_Name' failed. (Microsoft.SqlServer.Management.RelationalEngineTasks)

Cannot convert "Column" between a unicode and a non-unicode string data types in SSIS