cancel
Showing results for 
Search instead for 
Did you mean: 
Data Engineering
Join discussions on data engineering best practices, architectures, and optimization strategies within the Databricks Community. Exchange insights and solutions with fellow data engineers.
cancel
Showing results for 
Search instead for 
Did you mean: 

How to apply Column masking and RLS on Views in Databricks

TejeshS
New Contributor III

Hello Databricks Community,

We are working on a use case where we need to apply column masking and row-level filtering on top of existing views or while creating new views dynamically.

Currently, we know that Delta tables support column masking and row-level filtering via Alter commands. However, we are wondering if there is a way to achieve similar functionality for views

Can anyone provide guidance on how to achieve this for views in Databricks?

Any suggestions, workarounds, or examples would be much appreciated!

Thank you!

2 REPLIES 2

Akshay_Petkar
Contributor III

Hello @TejeshS ,

We cannot directly mask a view since we cannot alter it or add data to it. However, we can apply column masking at the view level using Databricks Dynamic Views. This allows us to control access to specific columns based on the user's role.
For example, we can create a view where the Salary column is only visible to ab***@gmail.com and xy****@gmail.com while all other users see a masked value like "Masked".This is achieved using a Case When condition that checks the current user.

Sample Query :

CREATE OR REPLACE VIEW masked_employees AS
SELECT
Name,
Department,
CASE
WHEN current_user() IN ('ab***@gmail.com', 'xy***@gmail.com') THEN Salary
ELSE 'MASKED'
END AS Salary
FROM employees;

MadhuB
Contributor III

@TejeshS  You can alternatively use, mask function instead of hardcoding with value 'Masked'.

CREATE OR REPLACE VIEW masked_employees AS
SELECT
Name,
Department,
CASE
WHEN current_user() IN ('ab***@gmail.com', 'xy***@gmail.com') THEN Salary
ELSE mask(cast(Salary as string))
END AS Salary
FROM employees;

Else create custom functions like code, which is more dynamic for maintenance purposes.

 

-- First create a group for users who can see unmasked data
CREATE GROUP IF NOT EXISTS sensitive_data_viewers;

-- Create masking functions with role-based logic
CREATE OR REPLACE FUNCTION mask_functions.conditional_mask_email(email STRING)
RETURNS STRING
RETURN CASE 
    WHEN IS_MEMBER('sensitive_data_viewers') THEN email
    WHEN email IS NULL THEN NULL
    ELSE CONCAT(
        LEFT(SPLIT(email, '@')[0], 2),
        REPEAT('*', LENGTH(SPLIT(email, '@')[0]) - 2),
        '@',
        SPLIT(email, '@')[1]
    )
END;


-- Create view with conditional masking
CREATE OR REPLACE VIEW customer_data_masked AS
SELECT 
    customer_id,
    full_name,
    mask_functions.conditional_mask_email(email) as email,
    phone_number,
    -- Non-sensitive fields shown to everyone
    city,
    country,
    registration_date
FROM customer_table;

-- Grant access to the view for all users
GRANT SELECT ON VIEW customer_data_masked TO role_analyst;
GRANT SELECT ON VIEW customer_data_masked TO role_developer;

-- Add specific users to the sensitive data viewers group
ALTER GROUP sensitive_data_viewers ADD USER user1@company.com;
ALTER GROUP sensitive_data_viewers ADD USER user2@company.com;

 

Join Us as a Local Community Builder!

Passionate about hosting events and connecting people? Help us grow a vibrant local community—sign up today to get started!

Sign Up Now