Row Level Security (RLS) - get more control over your data
Published Mar 01 2020 04:52 AM 6,410 Views

We are excited to announce a new Azure Data Explorer (Kusto) feature: Row Level Security (RLS) policy, which gives you fine control over who can access data inside your tables. You can now prevent specific users from viewing certain rows in a table, and you can also mask the data they see. For example, you can set an RLS policy that masks personally identifiable information (PII), enabling developers to query production environments for troubleshooting purposes without violating compliance regulations.


Here are some other scenarios where RLS shines:

  • In a table named Sales, each row contains details about a sale. One of the columns contains the name of the sales person. Instead of giving your sales people access to all records in Sales, you can enable a Row Level Security policy on this table to only return records where the sales person is the current user.
  • If you have an AAD group that contains the managers of the sales people, you might want them to have access to all rows in the Sales table
  • If you have multiple AAD groups, and you want the members of each group to see a different subset of data, RLS lets you achieve this
  • A hospital can set an RLS policy that allows nurses to view data rows for their patients only
  • A bank can set an RLS policy to restrict access to financial data rows based on an employee's business division or role
  • A multi-tenant application can store data from many tenants in a single tableset (which is very efficient). They would use an RLS policy to enforce a logical separation of each tenant's data rows from every other tenant's rows, so each tenant can see only its own data.

There are only two simple steps to enable RLS on a table. Here’s how it works:


Suppose we have a table called Customers. When support representatives view it, we don’t want them to see the credit card numbers. So we create a Row Level Security policy to achieve that.




The first step is to create a function that will do the masking:


.create-or-alter function with () MaskCreditCardDataForSupportReps() {
let InSupportRep = current_principal_is_member_of('');
let AllData = Customers | where InSupportRep != true;
let PartialData = Customers | where InSupportRep | extend CreditCardNumber = strcat("****-****-****-", substring(CreditCardNumber, strlen(CreditCardNumber)-4, 4)), Expiration = "**/**";
union AllData, PartialData

The second step is to enable the policy on the table:


.alter table Customers policy row_level_security enable "MaskCreditCardDataForSupportReps"


Now, when users access the Customers table, they’ll actually get the results of the MaskCreditCardDataForSupportReps function, which returns:

  • AllData: The full contents of Customers table, if the user is not a member of the AAD Group
  • PartialData:  All rows from Customers table, with masked credit card details, if the user is a member of the AAD Group



Row Level Security policy is now available for Public Preview. Find out more about it here:


UPDATE: Row Level Security policy is going to be Generally Available on Oct 14th, 2020.

Version history
Last update:
‎Sep 29 2020 12:54 AM
Updated by: