Implementing Row-Level Security (RLS) and Column-Level Security (CLS) on a Mirrored database in Microsoft Fabric
When working with Mirrored Databases in Microsoft Fabric, you may notice that the security pane for Row-Level Security (RLS) and Column-Level Security (CLS) is grayed out and read-only.
Why is the OneLake Security UI Disabled?
This is not a bug or a missing
feature; it is centered on Schema Integrity:
- Source
Control: For Mirrored Databases, the source system is the "Source of
Truth." The schema, column definitions, and overall structure are
defined at the origin.
- Preventing
Drift: Fabric is engineered to prevent source and security drift. By
locking the UI, Fabric ensures that the mirrored item remains a faithful
reflection of the source without conflicting security logic being applied
mid-stream.
The "Permission" Misconception
A common question I get is around the role of Workspace permissions. The critical point here is, having Fabric Admin or Contributor permissions will not enable the RLS/CLS UI. The interface is disabled based on the Item Type (Mirrored Database), not the user's permission level.
Can You Still Implement RLS and CLS?
Yes, you can do that, and I will walk you through the process in this blog post.
Instead of using the UI designer, you must use alternative mechanisms (T-SQL Security) to enforce security boundaries while maintaining the integrity of the mirrored link.
|
Security
Type |
Fabric
OneLake Security UI editable? |
How to
implement? |
|
Row
Level Security (RLS) |
No |
T-SQL
pattern Security policy |
|
Column
Level Security (CLS) |
No |
T-SQL
GRANT/DENY |
Where does the Security live?
The most important takeaway is that security for mirrored data is decentralized from the main Fabric UI. Because you cannot use the OneLake Security designer, you must use the SQL Analytics Endpoint and the security logic is stored within the Fabric SQL Database layer itself.
Applying Column Level Security:
Column Level Security can be applied via T-SQL GRANT/DENY statements.
If you want to DENY access to a specific columns lets says COLUMN A, for all Developers,
here is what you need to do.
- Create a DEVELOPER Role (DEVROLE) and Add
Members (individual Email ids) to that Role.
- Run the SQL DENY – DENY SELECT ON SCHEMA_NAME.TABLE_A (COLUMN A) to DEVROLE
- SQL DENY ensure that all members in the role DEVROLE will be denied access to the column “COLUMN A” in the table TABLE_A.
Applying Row Level Security:
Step 1 – Mirror a Database in Fabric. As of this
writing date, Fabric supports database mirroring for SQL Server, Snowflake, Azure
Cosmos DB and many more including Oracle, Google Big Query in public preview.
Step 2 – For this blog, lets have a Security requirement: Users
must not see rows in the CUSTOMER table where StatusCode = 1
Tip: Fabric does not support SHOW TABLE or DESC TABLE. Use the
T-SQL construct instead. If you want to list all columns and their data types,
use
SELECT
COLUMN_NAME,
DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH,
NUMERIC_PRECISION,
NUMERIC_SCALE,
IS_NULLABLE
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA =
'MIRRORSCHEMA'
AND TABLE_NAME
= 'CUSTOMER '
ORDER
BY ORDINAL_POSITION;
Step 3: Open the Mirrored database and select the SQL
Analytics Endpoint. Next open a New Query. This is where you will define the RLS
for mirrored data.
Step 4: Create
Roles and add members to that role –
- CREATE ROLE RLSTEST;
- ALTER ROLE RLSTEST
- ADD MEMBER [someone@example.com];
Step 5: Create a function with the definition to apply the RLS –
CREATE FUNCTION
dbo.fn_BlockSensitiveRows (@STATUSCODE decimal)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT 1
AS fn_result
WHERE @STATUSCODE
<> 1
);
Step 6: Create a Security Policy and
then attach this function to the table that was mirrored into Fabric.
CREATE SECURITY POLICY
SensitiveDataRLS
ADD FILTER PREDICATE
dbo.fn_BlockSensitiveRows(STATUSCODE)
ON MIRRORSCHEMA.CUSTOMER
WITH (STATE = ON);
Step 7: Grant access to your table to your users.
GRANT SELECT ON MIRRORSCHEMA.CUSTOMER TO RLSTEST
Once you have run these steps, if you query the table, you should ONLY see rows with where STATUSCODE is not equal to 1.
Run a test –
SELECT * FROM MIRRORSCHEMA.CUSTOMER
with STATUSCODE = 1. Does not show anything even though there is
data for STATUSCODE = 1 in the table.
Remember –
·
Object Level Security is for Table and/or Columns
while RLS is for Rows.
·
Both RLS and OLS, only applies to viewers in
a workspace. Workspace members assigned as Admin, Member, or Contributor have
edit permissions for the semantic model, and therefore, OLS doesn’t apply to
them. This means that admin members will still have access to the secured
tables or columns, as they have the necessary permissions to edit the model.
·
You cannot apply OLS to a TABLE which is
in middle of a relationship. If you have 3 tables Product -> Category
-> SubCategory. You cannot apply OLS only to Category table. However, you
can apply OLS to columns in tables which are in middle of
relationship but NOT for Key columns. Only Non-Key columns in tables middle of
relationship.
Step 8: Additional information: Steps to Change/Alter an existing RLS
condition
If you want to alter the RLS condition
(Instead of STATUSCODE <> 1, make
it STATUSCODE = 1), you must first DISABLE or DROP
the security policy.
Step 8A: ALTER SECURITY POLICY
SensitiveDataRLS WITH (STATE = OFF); OR
DROP
SECURITY POLICY SensitiveDataRLS
Step 8B: Now ALTER or CREATE (if you dropped) function –
CREATE OR ALTER
FUNCTION dbo.fn_BlockSensitiveRows (@STATUSCODE decimal)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT 1
AS fn_result
WHERE @STATUSCODE
=1
);
Step 8C: If you dropped the Security policy earlier, create a new security policy and attach it to the table as explained in Step 6.
~Narendra V Joshi
Comments
Post a Comment