I am trying to implement RLS on a Table (fin.RLS_Data
) with following Function. I have another table stg.UserAccess
to control who can access the Data Table (RLS_Data
).
I am testing this on
Microsoft SQL Server 2022 (RTM-CU5) (KB5026806) - 16.0.4045.3 (X64)
May 26 2023 12:52:08
Copyright (C) 2022 Microsoft Corporation
Developer Edition (64-bit) on Linux (Ubuntu 20.04.6 LTS) <X64>
UserAccess :
RLS_Data :
Following function works perfectly for readonly access users.
CREATE FUNCTION rls.fn_Data_Predicate
(@DataProviderID AS INT, @TableName sysname)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT 1 as Result
FROM [fin].[RLS_Data] d
INNER JOIN [stg].[UserAccess] e ON e.DataProviderId = d.DataProviderID
WHERE d.DataProviderID = @DataProviderID
AND e.[User Email] = CURRENT_USER
AND e.TableName = @TableName
AND e.isAuthorized = 1
);
I want to have some exception where admin user (isAdmin
) can have full access to the Data Table (RLS_Data
).
user2 who is admin user should have full access to Data Table (RLS_Data
), but user1 need to have access to data for DataProviderId
= 10 in Data Table (RLS_Data
)
I tried following
SELECT 1 as Result
FROM [fin].[RLS_Data] d
INNER JOIN [stg].[UserAccess] e ON e.DataProviderId = d.DataProviderID
WHERE e.[User Email] = CURRENT_USER
AND ( e.isAdmin = 1
OR (d.DataProviderID = @DataProviderID
AND e.TableName = @TableName
AND e.isAuthorized = 1
)
)
This still isn't returning data for all DataProviderID
if user has isAdmin
set to true because of INNER JOIN [stg].[UserAccess] e ON e.DataProviderId = d.DataProviderID
I am open to solution where I have to hardcode the admin users inside function. Looking for a function which can do following , nut not sure how to implement this in function
IF CURRENT_USER IN ('dbo', 'DBENTPBIPROD')
SELECT 1 as Result
FROM [fin].[RLS_Data] d
ELSE
SELECT 1 as Result
FROM [fin].[RLS_Data] d
INNER JOIN [stg].[UserAccess] e ON e.DataProviderId = d.DataProviderId
WHERE d. DataProviderID = e.DataProviderId
AND e.[User Email] = CURRENT_USER
AND e.TableName = 'RLS_Data'
AND e.isAuthorized = 1
Any better way to do this ?