Not Every Team Can See Every Row

A hard Pipeline Design interview practice problem on DataDriven. Design the pipeline on the canvas: sources, transforms, storage and checks, then get feedback on it.

Domain
Pipeline Design
Difficulty
hard
Seniority
L7

Problem

A security reviewer found that an engineer had copied confidential HR files straight out of our S3 bucket, a read the query layer never saw. Design the warehouse we build on that S3 data, about 2 TB a day read by 300 analysts, so confidential data reaches only the groups allowed to see it.

Everyone can see the bucket. Not everyone should.

Business requirements

Worked solution and explanation

The trap

This is defense in depth dressed up as a warehouse build. The real skill is holding two access boundaries at the same time: file isolation in storage and column visibility in the engine. Anyone can draw object storage feeding a warehouse. What separates candidates is refusing to let the query engine be the only lock. If all governance lives in warehouse views, one direct GetObject call against the bucket returns the confidential file and the engine never hears about it.

Walk the requirements

Step 1: Classify at write time

The classification step tags each record from a rule, a column match or an upstream tag, and routes it on that tag. If you reclassify after landing, confidential rows sit in the wrong prefix long enough for someone to download them.

Step 2: Enforce at the storage layer

The public, restricted and confidential zones are separate prefixes or buckets. The restricted and confidential zones each carry their own bucket policy that grants read only to their groups' roles. A direct API call from the wrong role fails at storage, whichever query path it came from. This is why the design needs a cold-storage tier at all.

Step 3: Mask columns on mixed tables

An employee table holds name and department next to salary. The column masking policy in front of the governed warehouse shows analysts only the public columns and shows HR all of them, from one table. Hiding columns in the BI tool fails the moment someone queries the base table, so the masking policy sits between the warehouse and every reader group.

Step 4: Keep an audit trail you can query

Query history and storage access logs from every zone land in the audit archive, held in an open table format and retained for the regulatory window. Then 'who read this last March' is a SQL query, not a forensic project.

The shape that fits

Records are classified once, then routed into per-sensitivity zones. The restricted and confidential zones each carry a bucket policy. Column masking in front of the warehouse gives analysts only the public columns and gives HR all of them. Query logs and file-access logs both land in the audit archive.
  • data sources (source, Kafka)
  • classification step (transform, Spark)
  • public zone (storage, object storage)
  • restricted zone bucket policy (storage, object storage)
  • confidential zone bucket policy (storage, object storage)
  • governed warehouse (storage, warehouse)
  • column masking policy (quality gate, custom)
  • audit archive (storage, Iceberg)
  • analysts public columns only (consumer, dashboard)
  • hr all columns (consumer, dashboard)
  • compliance (consumer, dashboard)
  • data sources -> classification step
  • classification step -> public zone
  • classification step -> restricted zone bucket policy
  • classification step -> confidential zone bucket policy
  • public zone -> governed warehouse
  • restricted zone bucket policy -> governed warehouse
  • confidential zone bucket policy -> governed warehouse
  • governed warehouse -> column masking policy
  • column masking policy -> analysts public columns only
  • column masking policy -> hr all columns
  • governed warehouse -> audit archive
  • public zone -> audit archive
  • restricted zone bucket policy -> audit archive
  • confidential zone bucket policy -> audit archive
  • audit archive -> compliance
Engine-only governance
One prefix with secure views. Access holds only while every request goes through the warehouse, and a direct bucket read skips the whole policy.
Storage plus engine
Bucket policies per zone block direct reads, and column masking in front of the warehouse handles mixed tables. Each layer covers the other's blind spot.

Common follow-up questions