Ranger Masking Breaks a Join, and a Column Is About to Be Dropped
A bank's CDP cluster governs a customers table with columns customer_id, ssn, email, and segment. A Ranger masking policy of type 'redact' (replaces the value with xxxx) is attached to the analyst_bi role on ssn, and a row filter restricts those analysts to segment = 'retail'. A BI dashboard that previously joined customers to a transactions table on ssn now returns zero rows, and its 'unique customers' KPI fell from 1.8M to 12K. The data steward also plans to drop the legacy tax_id column next sprint and wants to know which dashboards and Hive views depend on it. Two new columns, device_id and ip_address, were just added by an upstream team and are currently unmasked.
1. Diagnose which policy produced the zero rows and the KPI collapse, and choose a masking strategy that keeps the join working.
Read the worked answer
Two policies are active, and they have different signatures.
- Redact on ssn replaces every value with the constant
xxxx. Joining that totransactions.ssn, which still holds real values, matches nothing - hence zero rows, and a KPI that collapses to near-noise. A constant also destroys cardinality, so anyCOUNT(DISTINCT ssn)becomes 1, not 12K. - Row filter segment = 'retail' reduces the customer population (perhaps 1.8M to ~1.2M) but never to zero rows.
Confirm before changing anything: check Ranger audit logs for the denied/masked evaluation, then run the join as a user in analyst_bi with the ssn column selected and compare to a user without the policy. A quick test - SELECT COUNT(DISTINCT ssn) FROM customers - returning 1 proves redaction.
Choose a hash mask (for example SHA-256 with a cluster-managed salt) for any column used as a join key or distinct count: it is deterministic, so equality joins and distinct counts still work, and it is not reversible in practice. Keep redact or nullify for display-only columns where no downstream computation is needed. Critically, apply the same policy to every table carrying ssn - including transactions - otherwise the two sides are transformed differently and the join fails again. The KPI definition should also be reconciled with the row filter, since analysts can only ever see retail customers.
2. device_id and ip_address are unmasked. Design a governance approach that does not depend on someone noticing next time.
Read the worked answer
Resource-based policies are per-table and per-column; a newly added column simply is not covered, and the default is to allow. That is the structural gap.
Layered fix:
- Classify in Atlas. Tag
device_id,ip_address, and the existing PII columns with a PII classification. Atlas lineage and classification propagate to derived columns where the hooks support it. - Enforce with a Ranger tag-based policy. A tag policy that masks any column tagged PII for
analyst_bicovers new columns automatically once tagged, without a new resource policy per table. This requires Atlas–Ranger tag sync to be enabled and healthy; verify the sync interval. - Default-deny for the analyst role at the database level, with explicit allow on curated, masked views. New columns are then invisible until someone deliberately exposes them, which inverts the failure mode from 'leak until noticed' to 'blocked until approved'.
- Detection, not just prevention: monitor Atlas for new column entities on sensitive databases and alert the steward; add a pre-release check to the ingest pipeline that new columns are classified before the table is exposed.
Validate as a real analyst_bi member (not an admin), reading each column and confirming masked output, and re-test after any tag-sync change. A policy that is only tested by admins is untested.
3. Before dropping tax_id, what do you do with Atlas lineage, and in what order? What are the limits of relying on lineage alone?
Read the worked answer
Use lineage as the impact map, not as a guarantee.
- In Atlas, search the
tax_idcolumn entity and walk downstream lineage to find dependent Hive tables, views, Spark jobs, and any registered BI assets. Capture the owners. - Supplement it, because lineage has blind spots: Impala and Hive process lineage is captured via hooks, but external exports, ad-hoc SQL saved in a BI tool, and Python reading Parquet directly may not appear. Also grep
SHOW CREATE TABLEoutput for all views (SHOW TABLE EXTENDED ... LIKEor queryINFORMATION_SCHEMA/Atlas) fortax_id, and ask the dashboard owners directly. - Sequence the removal: (a) provide a replacement view or renamed column, (b) tag the column
deprecatedin Atlas and notify every downstream owner with a deadline, (c) stop populating it for one release cycle so consumers surface breakage while data still exists, (d) drop it, then re-check lineage to confirm no active process still references it. - Keep a rollback: retain the underlying files/partition for one retention window, and document the recreation SQL.
Lineage is only as complete as the hooks deployed. Treat the Atlas graph as strong evidence for Hive/Impala/Spark paths and weak evidence for everything else - the steward's sign-off should rest on both the graph and a manual sweep of views and BI assets.