5.7 Row-Level and Column-Level Security

Key Takeaways

  • Column-level security uses column masks to apply functions that transform column values based on the querying user's identity or group membership.
  • Row-level security uses row filters to restrict which rows a user can see based on their identity or group membership.
  • Dynamic views can implement row/column security using functions like current_user() and is_account_group_member() in WHERE and CASE WHEN clauses.
  • Column masks and row filters are defined at the table level and enforced automatically for all queries, regardless of access method.
  • These security features work with Unity Catalog and are enforced by the Databricks query engine — they cannot be bypassed by direct file access.
Last updated: March 2026

Row-Level and Column-Level Security

Quick Answer: Column masks transform sensitive column values (e.g., masking SSNs) based on user identity. Row filters restrict which rows users can see. Both are defined at the table level in Unity Catalog and enforced automatically for all queries.

Column Masks

Column masks apply transformation functions to column values based on the querying user:

-- Create a masking function
CREATE FUNCTION mask_ssn(ssn STRING)
RETURN CASE
    WHEN is_account_group_member('pii-admins') THEN ssn
    ELSE concat('***-**-', substring(ssn, 8, 4))
END;

-- Apply the mask to a column
ALTER TABLE customers ALTER COLUMN ssn SET MASK mask_ssn;

How Column Masks Work

  • PII admins see: 123-45-6789
  • Other users see: ***-**-6789
  • The mask is applied automatically on every query
  • Users cannot bypass the mask — it is enforced at the engine level

Common Masking Patterns

PatternUse CaseExample
Full redactionHide entire valueRETURN '***REDACTED***'
Partial maskingShow last 4 digitsconcat('***-**-', substring(ssn, 8, 4))
Role-basedFull access for adminsCASE WHEN is_group_member() THEN value ELSE 'REDACTED' END
HashingPreserve uniqueness without revealing valueRETURN sha2(email, 256)

Row Filters

Row filters restrict which rows a user can see:

-- Create a filter function
CREATE FUNCTION region_filter(region STRING)
RETURN (
    is_account_group_member('global-team')
    OR region = CASE
        WHEN is_account_group_member('us-team') THEN 'US'
        WHEN is_account_group_member('eu-team') THEN 'EU'
        ELSE 'NONE'
    END
);

-- Apply the row filter
ALTER TABLE orders SET ROW FILTER region_filter ON (region);

How Row Filters Work

  • Global team sees: all rows
  • US team sees: only rows where region = 'US'
  • EU team sees: only rows where region = 'EU'
  • Filters are applied transparently — users do not see the filter logic

Dynamic Views (Alternative Approach)

-- Create a dynamic view with embedded security
CREATE VIEW secure_customers AS
SELECT
    customer_id,
    name,
    CASE
        WHEN is_account_group_member('pii-admins') THEN email
        ELSE '***@***.***'
    END AS email,
    CASE
        WHEN is_account_group_member('pii-admins') THEN phone
        ELSE '***-***-****'
    END AS phone
FROM customers
WHERE (
    is_account_group_member('all-data')
    OR region = current_user_region()
);

Column Masks vs. Dynamic Views

FeatureColumn MasksDynamic Views
Applied toBase table directlySeparate view object
Bypass riskNone — enforced at table levelUsers could query base table if they have access
ManagementPer-column configurationSeparate view definition to maintain
PerformanceMinimal overheadAdditional view resolution
RecommendedFor production securityFor simpler cases or legacy environments

On the Exam: Know that column masks and row filters are applied at the table level and cannot be bypassed. Understand the functions is_account_group_member() and current_user() for identity-based security.

Test Your Knowledge

A data engineer needs to ensure that users in the "us-team" group can only see orders from the US region. Which Unity Catalog feature should they use?

A
B
C
D
Test Your Knowledge

How does a column mask differ from simply removing column access via REVOKE?

A
B
C
D
Test Your Knowledge

Can a user bypass a row filter or column mask by directly reading the underlying Parquet files in cloud storage?

A
B
C
D