Data Governance, Contracts, and Classification Questions
Governing data at scale: data contracts between producers and consumers, schema evolution/compatibility, data classification and sensitivity tagging, access control, and lineage/cataloging. Covers policy, ownership, and compliance-driven controls over data. The governance layer over the technical stack.
Design a data governance and access-control architecture for an analytics platform operating across multiple regions with different privacy regimes (say, the EU and the US), covering product analytics, ML feature stores, and customer records. Cover data classification, PII detection and masking, role-based access control, lineage, audit trails, and how you'd structure a governance decision-making body, while keeping ML feature freshness and developer agility workable.
Sample Answer
Build one governance model with region-aware enforcement rather than two separate governance systems for the EU (European Union) and the US: a shared classification taxonomy and shared access-control mechanism, with region-specific rules (residency, retention, consent basis) expressed as policy parameters rather than as forked infrastructure, spanning product analytics, the ML (machine learning) feature store, and customer records.
Data classification
A single four- or five-tier classification (public, internal, confidential, restricted, and, given the regulatory scope here, a distinct regulated-PII sub-tier for data covered by GDPR (the EU's General Data Protection Regulation) or CCPA (the California Consumer Privacy Act) style rules) applies globally, with a region tag attached alongside the sensitivity tag. A customer record's sensitivity tier doesn't change between the EU and the US, but its region tag determines which residency and retention rules apply to it.
PII detection and masking
Automated PII (personally identifiable information) detection runs across all three domains, product analytics events, ML feature store inputs, and customer records, using a combination of schema-level tagging (known PII fields declared at ingestion) and pattern-based scanning (catching PII that lands in free-text or unexpected fields). Masking defaults follow the classification tier: confidential and restricted fields are masked by default in any cross-team or cross-region view, unmasked only for roles with an approved, region-appropriate business need.
Role-based access control
RBAC (role-based access control) roles are defined once, globally (analyst, ML engineer, finance, compliance), with region as an additional attribute checked alongside the role, effectively a lightweight attribute-based layer on top of RBAC rather than a fully separate ABAC (attribute-based access control) system: an EU-based analyst role and a US-based analyst role have the same permissions structure, but an EU analyst's access to EU customer records is subject to the residency rule that data doesn't leave the EU region's processing boundary, even for another employee with the same job title based in the US.
Lineage and audit trails
End-to-end lineage tracking (capturing how a customer record or an ML feature traces back to its source and forward to every derived dataset or model that consumes it) is essential here specifically because a right-to-erasure or data-subject-access request under GDPR requires being able to answer "everywhere this person's data went," not just where it started. Audit trails record every access, transformation, and cross-region data movement, since cross-region movement is itself a regulated event under most residency regimes, not just another access to log.
SOC 2 and consent-management framing
Beyond the GDPR/CCPA distinction, this architecture should also be evaluated against SOC 2 (System and Organization Controls 2, an audit standard for how a service organization manages customer data) trust-service criteria, since access control, change management, and monitoring requirements from a SOC 2 audit map directly onto the same RBAC, audit-logging, and lineage components described above; building governance to satisfy GDPR/CCPA residency rules largely satisfies SOC 2's security and confidentiality criteria as a byproduct, but SOC 2 additionally expects documented, tested incident-response and change-management processes around this infrastructure, which should be built explicitly rather than assumed.
Consent management is the piece that ties classification to actual legal basis: a customer's consent state (what they've agreed their data can be used for, which can differ between EU and US customers under different regimes) is stored as its own governed record linked to the customer's identifier, and the access-control layer checks consent state, not just role and region, before allowing a customer record into an ML feature pipeline. A pseudonymization/tokenization architecture variant supports this concretely: customer records feeding the ML feature store are pseudonymized (the raw identifier replaced by a stable token) at ingestion, with the reversible mapping held in a separate, tightly-restricted vault, so a consent withdrawal can be enforced by revoking or expiring that customer's token without needing to hunt down every derived feature-store row that used the raw identifier.
Governance decision-making body
A standing governance council, not a single owner, since region-specific legal obligations and cross-functional trade-offs (ML freshness versus residency, self-service speed versus compliance) need multiple perspectives represented:
- Chair: a data governance or privacy lead, owning the overall policy and cadence.
- Legal/privacy counsel for each covered region (EU and US), since the specific obligations differ.
- A security lead, owning encryption, key management, and the SOC 2 control set.
- An ML engineering representative, owning the feature-freshness and pseudonymization trade-offs.
- A product/business representative, ensuring policy decisions account for actual business need, not compliance in a vacuum.
This body meets on a regular cadence (for example monthly, with an expedited path for urgent decisions like a new region's regulatory change) to approve new classification categories, review flagged cross-region data movements, and adjudicate exception requests.
flowchart TB
subgraph EU[EU processing boundary]
EUDATA[EU customer records + features]
end
subgraph US[US processing boundary]
USDATA[US customer records + features]
end
EUDATA -->|pseudonymized token only, consent-checked| SHARED[Shared aggregate / model artifacts]
USDATA -->|pseudonymized token only, consent-checked| SHARED
CONSENT[(Consent record store)] --> RBAC[Region-aware RBAC layer]
RBAC --> EUDATA
RBAC --> USDATA
GOV[Governance council] -->|policy + exception review| RBAC
GOV --> CONSENT
Keeping ML feature freshness and developer agility workable
The residency and consent checks above add a lookup on the path from raw customer record to a live feature, which risks slowing feature-store updates if done naively. Keep it workable by:
- Checking consent and residency at write-time into the feature store (when a feature is computed), not at read-time on every serving request, so the low-latency serving path stays a simple key lookup with no per-request policy evaluation.
- Giving developers a self-service, pre-approved pattern (a feature-engineering template that already routes through pseudonymization and consent checks correctly) for the common case, so most new features don't require a governance council review individually, only genuinely new data sources or use cases do.
Trade-offs & pitfalls
The biggest risk in this design is a fast, informal "just this once" cross-region data copy for an urgent business need that bypasses the residency boundary; because the architecture makes the compliant path only slightly slower than the non-compliant one (pre-approved templates, write-time checks), there should be little practical incentive to skip it, but the governance council needs visibility into attempted or actual cross-region movements specifically to catch the cases where someone tries anyway.
Design a schema registry and CI enforcement setup for a streaming or event-driven platform: how do you register schemas, run compatibility checks before a producer's change ships, and alert on or block a breaking change? Discuss how this differs for a Kafka/Avro event stream versus a batch warehouse table, and what a schema registry buys you beyond just documentation.
Sample Answer
A schema registry is a centralized, versioned store of the schemas producers and consumers agree on, keyed by subject (typically the topic name), that a serializer or deserializer consults at write and read time, and that CI (continuous integration) can query to check whether a proposed schema change is compatible with what is already registered. The design has three parts: a registration and versioning API, a CI-time compatibility gate, and a runtime alerting or blocking mechanism. The same idea applies to a batch warehouse table, but the enforcement points differ because there is no per-message serializer to intercept.
Core components
- Registry service: stores schemas per subject, with a version history and a compatibility mode (backward, forward, or full) configured per subject.
- Producer-side serializer: before writing, looks up or registers the schema for the topic; the registry rejects registration if it violates the subject's compatibility mode.
- Consumer-side deserializer: looks up the writer's schema, identified by a small ID embedded in each message, and resolves it against the reader's own schema.
Registering schemas
On first deploy, the producer registers its Avro (a data serialization format commonly used for streaming events), Protobuf (Google's binary serialization format), or JSON Schema definition against a subject name, commonly <topic>-value. Every subsequent message carries that schema ID rather than the whole schema, keeping the wire format compact; the consumer fetches the corresponding schema from the registry by ID and caches it locally.
CI enforcement before a producer's change ships
The registration step is the gate: a CI job on the producer's pull request (PR) calls the registry's compatibility-check endpoint with the new schema before merge, using the subject's configured mode. An incompatible change fails the CI job, so it never reaches deploy.
Alerting on and blocking breaking changes
Two layers matter. First, the registry itself blocks a genuinely incompatible schema from being registered at all when enforcement is strict, so a bad change cannot land even if someone tries to bypass CI locally. Second, for cases a schema-level check does not fully cover (someone bypasses the registered serializer, or a batch job silently changes a table without going through a registry), a monitoring layer should watch for shape drift at runtime, comparing incoming data's actual shape against the last known-good schema, and alert or quarantine to a dead-letter path rather than let malformed records flow downstream silently.
Kafka/Avro streaming versus a batch warehouse table
For a Kafka (a distributed event-streaming platform) topic using Avro, enforcement is naturally per-message and synchronous: the serializer-registry interaction happens on every write, so a breaking change is caught within the first bad message, before it is even durably written. For a batch warehouse table, there is no per-row serializer in the loop, so the equivalent controls have to live earlier and later in the pipeline: earlier as a CI check against the table's DDL or dbt (a SQL-based data transformation tool) model definition before the pipeline deploys, and later as a data-quality check on the loaded output (row counts, null rates, a schema diff against the prior run) that alerts before downstream consumers query a broken table. The batch case also has to deal with older and newer partitions or files coexisting under different schema versions, which a streaming registry mostly avoids because each message is evaluated individually against the current subject schema.
What a schema registry buys beyond documentation
A written schema document can go stale the moment someone changes the producer's code. A registry makes the schema the mechanism the pipeline actually runs on: the producer cannot write a message the registry considers incompatible when enforcement is on, so the schema and the guarantee are the same artifact, not a document describing a guarantee nobody checks. It also provides a machine-readable version history, a stable schema ID on the wire (cheaper than repeating field names on every message), and a query surface other tools, like data catalogs and lineage systems, can read from instead of re-deriving structure by sampling data.
flowchart LR
Dev[Developer PR: new schema] --> CI[CI: compatibility check]
CI -->|compatible| Registry[(Schema Registry)]
CI -->|incompatible| Block[Build fails, PR blocked]
Registry --> Producer[Producer serializer]
Producer -->|schema ID + payload| Topic[(Kafka topic)]
Topic --> Consumer[Consumer deserializer]
Consumer --> Registry
Worked example
A payments.charge_created Avro schema is registered under subject payments.charge_created-value in BACKWARD mode. A developer opens a PR that renames amount to amount_cents. CI calls the registry's compatibility endpoint for that subject with the new schema; the registry evaluates whether a reader on the new schema can parse data written with the old one, finds no field named amount and no alias pointing to it, and returns is_compatible: false. CI fails the build. The developer adds "aliases": ["amount"] to amount_cents, so a new-schema reader can resolve data written under the old field name; CI re-runs, the check passes, and the PR can merge.
Trade-offs and pitfalls
Strict enforcement is safest but slows down producers who need a genuine breaking change (a rename with no clean alias, a field split); the correct escape hatch is a new subject or version, not disabling the check, otherwise the registry stops being trustworthy. A registry only enforces what serializers actually call into: if a team writes raw JSON to a topic without going through the registered serializer, the guarantee is a fiction for that topic. And a registry proves structural compatibility, not semantic correctness; it will not catch a field that keeps its type but silently changes meaning.
Data governance practices like access controls, lineage, and PII handling are often the first things deprioritized under deadline pressure. How would you make the case for investing in them anyway, and what's one low-friction first step you'd implement to start building the habit without asking for a big upfront commitment? If you've led an effort like this before, walk through what you actually did and what stuck.
Sample Answer
Direct answer
Make the case in terms the deadline-driven decision already respects: frame access controls, lineage, and personally identifiable information (PII) handling as risk-reduction with a cost that grows the longer you wait, not as a nice-to-have quality investment competing with the feature. Then pick a first step that piggybacks on work already happening (tagging sensitivity on tables as they get touched during a planned migration, for instance) rather than asking for a dedicated project, so the habit starts without needing a big upfront commitment.
Structured elaboration
Making the case. Governance work is usually deprioritized because its cost is immediate and visible while its payoff is deferred and probabilistic (an incident that might happen). Reframe it concretely: an access-control gap is a specific future incident-response cost (who has access to what, discovered under pressure during an actual incident, is much more expensive than knowing it in advance); missing lineage is a specific future debugging cost (a bad number surfaces and nobody can say quickly where it came from); ungoverned PII is a specific future compliance and trust cost. The pitch is not "governance is good practice," it is "here is the bill we will pay later, and here is the much smaller bill we can pay now instead."
Picking a low-friction first step. The step that works is one that attaches to something already scheduled rather than requesting new headcount or a dedicated sprint: tagging sensitivity classification on tables as part of a migration that is happening anyway, adding an owner field to the catalog entry every time a new dataset gets created (a one-line addition to an existing creation checklist), or capturing lineage automatically as a side effect of adopting a transformation tool the team is already evaluating. The common thread is that it rides on existing momentum instead of asking for new momentum.
What tends to stick versus what does not. A rule enforced by tooling (a required field in a dataset-creation template, a check that blocks a merge if a new table has no declared owner) tends to persist, because it does not depend on anyone remembering. A rule that depends on a person remembering to do an extra step by hand, however well-intentioned at rollout, tends to decay within a quarter once the person who championed it moves to a different priority.
Worked example
A realistic version of this: a team is migrating a set of tables from one warehouse to another anyway. Instead of treating that as a pure lift-and-shift, the migration script is extended to require a sensitivity tag and an owner field before a table is allowed to land in the new warehouse, using values the team already knows (they are moving the table, so they know what it contains and who owns it). No separate governance project gets proposed or approved; the tagging happens as an unavoidable step of work that was already scheduled. Six months later, new tables created after the migration still carry the tag, not because anyone is manually enforcing it, but because the creation template that grew out of the migration script still requires the field. What stuck was the tooling requirement, not a one-time cleanup effort or a policy document asking people to remember.
Trade-offs & pitfalls
The main risk of the "piggyback on existing work" approach is scope creep in the wrong direction: if the governance addition meaningfully slows down the work it is attached to, it becomes the reason the underlying project gets deprioritized instead of quietly succeeding alongside it, so the addition has to be genuinely small. Making the risk-based case too abstract ("this could cause an incident someday") is easy to deprioritize against a concrete deadline; it needs a specific enough scenario to be memorable, without inventing a specific incident that did not happen. And a first step that only touches new work leaves the existing backlog of undocumented, untagged data untouched, so it needs to be paired, eventually, with a plan for the backlog, even if that plan starts smaller and later.
You're asked to stand up a data-stewardship program from scratch across a few product or business domains. How would you identify and recruit the first stewards, what would their actual day-to-day responsibilities be, how would you onboard them over the first couple of months, and what KPIs would tell you the program is working rather than just existing on paper?
Sample Answer
Direct answer. Start by identifying the domains with the highest data-quality pain or highest business criticality, recruit stewards from within those domains rather than hiring new people, give them a small, concrete set of recurring responsibilities instead of an open-ended mandate, run a structured onboarding over the first couple of months, and track KPIs (key performance indicators) that measure actual behavior change, issues resolved, datasets documented, rather than just program existence, stewards named, kickoff held.
Identifying and recruiting the first stewards
- Prioritize domains by a combination of business criticality and current pain: datasets feeding executive reporting or revenue-critical pipelines with a history of quality incidents are strong first candidates, since success there is visible and the need is already felt.
- Recruit from people already doing informal stewardship: the analyst everyone already asks about a table's quirks, or the engineer who already fields "why does this number look wrong," is usually the right person, since the program formalizes and supports existing behavior instead of assigning it cold.
- Get their manager's explicit buy-in on time allocation before asking the individual; stewardship without a manager-sanctioned time carve-out becomes something done only when nothing else is on fire.
Day-to-day responsibilities
- Triage and respond to data-quality alerts for datasets in their domain within a defined response window.
- Review and approve schema or definition changes proposed by producing teams in their domain.
- Maintain documentation, field definitions, known caveats, freshness expectations, for their domain's key datasets.
- Serve as the point of contact for access requests and use-case questions specific to their domain's data.
Onboarding over the first couple of months
- Weeks 1-2: kickoff and role definition. The steward gets a written charter (scope, authority, time commitment), access to the catalog and monitoring tooling, and a walkthrough of their domain's current dataset inventory and known issues.
- Weeks 3-6: shadowing and paired work. The steward handles their first few quality alerts and access requests with support, building confidence before going solo.
- Weeks 7-8: independent operation with a check-in cadence, for example a biweekly sync to surface blockers, plus an initial documentation pass on the domain's top datasets.
- End of month 2: a baseline review comparing the domain's state, documentation coverage, open quality issues, against the pre-program baseline captured at kickoff, so the KPI trend has a real starting point.
KPIs that show the program is working, not just existing on paper
- Documentation coverage: percentage of the domain's key datasets with an owner, a steward, and a current field-level description, tracked as a trend, not a one-time snapshot.
- Time-to-acknowledge and time-to-resolve for data-quality alerts in the domain, compared against the pre-program baseline.
- Steward-initiated actions, definition changes approved, access requests handled, as a count over time, which distinguishes an active steward from a named-but-inactive one.
- A specifically easy-to-fake leading indicator worth watching: attendance at steward syncs and charter sign-off are necessary but not sufficient. If those are the only things tracked, the program can look healthy, stewards named, meetings held, while the metrics above stay flat, which is exactly the "existing on paper" failure mode.
Trade-offs and pitfalls
- Recruiting stewards without securing manager-sanctioned time is the single most common way these programs quietly fail; the role gets a title and no bandwidth, and the first fire in someone's actual job displaces it.
- Choosing KPIs that measure program activity instead of program outcome is exactly how a program can look successful in a status update while doing nothing.
- Standing up too many domains at once dilutes the support available to each new steward during onboarding; starting with one or two high-value domains and expanding once the model is proven is more durable than a simultaneous organization-wide rollout.
Design a practical, org-wide strategy to detect and mask PII across all your streaming and batch pipelines, not just the ones someone remembered to flag, covering both raw lake data and curated warehouse tables. What detection approaches would you combine (schema tagging, regex pattern matching, ML-based classifiers), what masking or redaction strategy follows once something is found, and how would you handle the inevitable false positives and legitimate exceptions?
Sample Answer
Detect PII (personally identifiable information) as a mandatory, automated stage every pipeline passes through, not an opt-in step someone has to remember to add, by combining schema tagging, pattern-based rules, and machine learning (ML) classifiers so no single blind spot in one method leaves a gap, and pair detection with a masking strategy that defaults to safe while giving legitimate exceptions a documented, reviewed path.
Detection approaches, combined
No single technique catches everything on its own, so the three are layered rather than treated as alternatives:
- Schema tagging. Fields already known to be PII (declared at table or event-schema creation,
email,ssn,date_of_birth) are tagged in the schema registry at the point of definition. This is the cheapest and most reliable method, but it only catches PII that someone remembered to declare; it says nothing about a new field added later or a free-text field that happens to contain PII incidentally. - Regex and pattern matching. Deterministic patterns (an email format, a national ID number's digit structure, a credit card number's format) run against both structured columns and free-text fields, catching PII that landed somewhere undeclared, for example a support-ticket comment field containing a customer's phone number typed in by an agent.
- ML-based classifiers. Named-entity recognition or a trained classifier scans less-structured content (chat logs, free-text notes) for PII patterns too varied for a fixed regex to catch reliably, a person's name embedded in a sentence, an address written in an unstructured format. This is the most expensive method computationally and the one most prone to false positives, so it's best applied selectively rather than on every record in a high-volume stream.
Running all three, with schema tagging as the free first pass, regex as a cheap second pass, and ML classification reserved for content the first two can't confidently clear, keeps overall detection cost proportional to how much genuinely needs the expensive method.
Covering both raw lake data and curated warehouse tables
The same three-method detection runs at two different points, not just once:
- At the raw lake ingestion point, detection tags incoming data as it lands, before anyone builds a curated table on top of it, so a downstream table doesn't inherit an undetected PII field from an upstream source that was never scanned.
- At the curated warehouse layer, detection re-runs against derived and joined tables specifically because a join or transformation can combine otherwise-innocuous columns into a newly PII-bearing result (a table joining a customer ID with a separately-innocuous demographic table becomes identifying once joined), which a source-only scan would miss entirely.
Covering both streaming and batch pipelines
- Streaming (for example Kafka, Flink, or Kinesis). Schema tagging and regex matching run inline, on the hot path, since they're cheap enough not to meaningfully add latency; ML classification, being more expensive, runs asynchronously on a side path (writing flagged content to a review queue) rather than blocking the main stream, so a slow classifier doesn't become a throughput bottleneck for the whole pipeline.
- Batch (for example Spark or a scheduled warehouse job). All three methods can run inline as part of the batch job itself, since batch jobs already tolerate longer per-record processing time; this is also where full re-scans of existing tables (not just new data) happen periodically, catching PII in data that landed before detection was in place.
flowchart TB
subgraph Streaming
SIN[Streaming ingestion] --> SSCHEMA[Schema tag check, inline]
SSCHEMA --> SREGEX[Regex check, inline]
SREGEX --> SML[ML classifier, async side path]
end
subgraph Batch
BIN[Batch ingestion / scheduled scan] --> BALL[Schema + regex + ML, inline]
end
SSCHEMA --> POLICY[Policy engine]
SREGEX --> POLICY
SML --> POLICY
BALL --> POLICY
POLICY --> MASK[Masking / redaction applied]
POLICY --> LAKE[(Raw lake, tagged)]
POLICY --> WH[(Curated warehouse, tagged)]
Masking or redaction strategy once something is found
The action taken depends on the field's classification tier and its downstream use, not a single blanket rule:
- Confirmed structured PII (a tagged or high-confidence regex match on a known field type): masked by default in any view accessible outside the field's originating team, using the same tiered masking approach used elsewhere in the platform (partial mask, full redaction, or tokenization depending on sensitivity).
- PII detected in free text by the ML classifier: redacted (the specific span replaced with a placeholder like
[NAME]or[PHONE]) rather than the whole record being dropped, preserving the non-sensitive content around it for analysis. - Low-confidence ML detections: routed to a review queue rather than auto-masked or auto-ignored, since ML detections carry meaningfully more uncertainty than a schema tag or a regex match.
Handling false positives and legitimate exceptions
- False positives (a regex matching a numeric ID that happens to look like a phone number, or an ML classifier flagging a business name as a person's name): a lightweight review workflow lets a data owner mark a flagged field as a confirmed false positive, which suppresses future flags for that specific field or pattern rather than requiring a manual override on every occurrence.
- Legitimate exceptions (a field that is technically PII-shaped but has an approved, narrow business use, for example a fraud-detection model that genuinely needs raw device identifiers): handled through the same exception-request process used for other restricted-data access elsewhere in governance, an explicit, time-boxed, logged approval, not a permanent bypass flag quietly set once and forgotten.
- Feedback loop. Confirmed false positives and approved exceptions feed back into tuning the regex patterns and retraining or recalibrating the ML classifier's confidence thresholds over time, so the false-positive rate should trend down as the system accumulates review history, rather than staying static.
Trade-offs & pitfalls
The most common mistake is running detection only at ingestion and treating a table as permanently cleared once scanned, which misses both new PII introduced by later joins/transformations and PII in data that existed before detection was deployed. Periodic re-scanning of curated tables, not just one-time ingestion-point scanning, is what catches both gaps, at the cost of ongoing compute spent re-checking data that, most of the time, hasn't changed in its PII profile since the last scan.
Unlock Full Question Bank
Get access to all 31 Data Governance, Contracts, and Classification interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.