Privacy by Design and Default Questions
Designing privacy into products, architectures and the software development lifecycle instead of bolting it on afterward. Covers the privacy-by-design principles and privacy-protective defaults, data minimization and purpose limitation at design time, personal-data flow mapping and PII inventory for a feature, consent and preference design including consent storage, enforcement across web and mobile and region-specific consent flows, retention and deletion design including legal holds, deletion across backups and immutable logs, provable deletion, and data-subject access, export and erasure flows, PII-safe logging, telemetry and session replay, on-device processing to limit data exposure, privacy-versus-personalization trade-offs, privacy in ML training data, feature stores and erasure from trained models, and privacy review gates, checklists, CI/CD checks, release readiness and requirements traceability inside engineering workflows. Includes designing privacy-first features, reference architectures, remediating privacy design flaws and rollout programs across product teams, and working with product, legal and security partners. Cryptographic and statistical privacy techniques, formal impact assessments, data-protection law, cross-border transfer rules, vendor risk, and encryption or access-control mechanics are covered elsewhere.
Design an export/data portability feature that allows users to download their data in a machine-readable format. Specify format choices, authentication and authorization checks, throttling, and how to avoid including other users' PII indirectly (e.g., comments with mentions).
Sample Answer
Direct answer. Build the export as an asynchronous job run by a dedicated export service. It re-authenticates the user, collects only data tied to that user through per-dataset exporters (one small piece of code per dataset that names the exact fields it writes, so a new table is never exported by accident, unlike a generic "select everything" query), writes JSON plus CSV files into a ZIP with a manifest (an index file listing what the ZIP contains), and delivers it through a short-lived, single-use download link. Data about other people is stripped or replaced with placeholders before anything is written.
What the law asks for. GDPR (General Data Protection Regulation) Article 20 gives people the right to receive personal data they provided, "in a structured, commonly used and machine-readable format", when processing is based on consent or contract and is automated. Article 20(4) says the right must not adversely affect the rights and freedoms of others, which is the source of the third-party PII (personally identifiable information) problem. Article 12(3) sets a response deadline of one month, extendable by two further months for complex or numerous requests. Which of your datasets count as "provided by" the user, and when repeated requests become excessive, is a call for counsel. The product can export more than the legal minimum.
Format choices
- JSON for nested data (profile, settings, posts), one file per entity type, with a
schema_versionfield and amanifest.jsonlisting files, row counts and field descriptions. An illustrative manifest:{"schema_version":"1.0","generated_at":"2026-03-13T09:30:00Z","files":[{"name":"profile.json","rows":1},{"name":"posts.json","rows":212},{"name":"orders.csv","rows":37}]}. - CSV for flat, tabular data (orders, activity history) so non-engineers can open it in a spreadsheet.
- Media in its original format. No PDF-only exports, because PDF is readable but not machine-readable.
- Stable field names and ISO 8601 timestamps (the international date format, like
2026-03-14T09:30:00Z) so another service can import it.
Authentication and authorization
- Step-up authentication (asking the user to prove who they are again, even though they are logged in, before a sensitive action): require a fresh login or second factor within the last 10 minutes (illustrative window), because an export is the highest-value payload in the account.
- The request creates a job keyed to the authenticated
subject_id. The subject comes from the session, never from a request parameter. - Each exporter has an allowlist of fields (the only fields it may write; everything else is excluded by default). A new column is excluded until someone classifies it.
- Email the account owner when a request is made and when the file is ready. Deliver via a signed link bound to the account, valid 24 hours (illustrative), single use, over HTTPS. A signed link carries an expiry time, the account ID and a signature computed with a secret only the server holds, for example
/dl/9c1e?acct=1042&exp=1773480600&sig=4cfcdc722238f1b2; changing the account or the expiry makes the signature fail, and the server also marks the link used after the first download. Encrypt the stored archive and delete it after expiry.
Throttling. Allow one active export job per user and queue the rest. Rate-limit the request endpoint per account and per IP, run workers off-peak with a size cap per part (split large exports into several ZIP parts), and limit download attempts per link. Throttling protects the system and stops an attacker with a stolen session from draining data repeatedly. It must not become a way to make the legitimate request hard, since the deadline in Article 12(3) still runs.
Keeping other users' PII out
| Item | Export treatment |
|---|---|
| The user's own posts and comments | Include the text |
| An @mention token inside the user's comment | Replace with [another user], drop the handle and ID (the comment "Thanks @dana_k, see you Friday" is exported as "Thanks [another user], see you Friday") |
| Replies written by others | Exclude, or include only a placeholder reference |
| Group chat messages from others | Exclude |
| Shared documents with co-owners | Include the user's own edits, mask co-owner names |
| Free-text that names a third party | Cannot be fully detected: keep the user's own words, since they are the author, and have counsel confirm this rule |
Enforce it with a field classification (subject, other, shared) in the exporter schema, and a test: seed two users who mention and reply to each other, run user A's export, and assert user B's ID, email and display name appear nowhere in any file.
Trade-offs. Stripping mentions makes threads less readable, so the placeholders should be consistent inside one export. Generous formats cost engineering time, so start with JSON plus CSV for the core entities.
You are designing the privacy settings screen for a mobile app. Which controls would you expose, how would you explain the trade-offs to users in plain language, and how do you make sure what the screen says matches what the system does?
Sample Answer
Direct answer
Expose a small set of real choices, grouped by what they affect, with privacy-protective starting values. Describe each in one plain sentence about what the app does and what you give up. Then make the screen true by wiring every toggle to an enforced check in the system and testing it.
Controls to expose
- Analytics and diagnostics (on or off): off unless the user opts in where possible.
- Personalization (use my activity to tailor suggestions).
- Location (never, while using, precise or approximate), linking to the system permission.
- Marketing messages and ad personalization, separate from account emails.
- Contacts, photos and microphone access, each separate.
- Data actions: download my data, delete my account, clear history.
- Sharing and visibility of the profile.
Fewer, meaningful toggles beat thirty vague ones. Keep legal terms out of the labels.
Plain-language explanations
Say what happens either way. Example: "Personalized suggestions: we use what you watch to suggest more. If off, you still get suggestions, but they are the same for everyone." Do not use guilt wording (labels that shame the person for saying no, such as "No thanks, I don't care about my privacy") or hide the off option behind extra taps; these are called dark patterns.
Making the screen match the system
- Store each choice as one preference record (one row per user and setting, such as
user 52, analytics = off, changed 3 May), and have services read it through a single check, not copies. In code that is one shared function,is_allowed(user, "analytics"), that every service calls, instead of each service keeping its own copy of the flag. - Enforce server-side as well as in the app, since a client toggle alone can be ignored by a backend job.
- Test: an automated test turns each toggle off, then asserts that the matching events, requests or jobs stop (for example, no analytics calls fire).
- Review: privacy sign-off whenever a new data use is added, so a new use gets a toggle or a notice.
- Propagate changes to downstream systems (the other services and data pipelines that use this data) within a stated time, for example 24 hours, by publishing a change event they consume. An app that was offline keeps the old value locally, so it syncs the stored preference at next launch before sending anything, and the server rejects events from users whose record says off.
Worked example
A user switches "Analytics" off. The next app launch makes no requests to the analytics endpoint (a test confirms this), the server stops processing queued events for that user, and the screen shows when the change took effect.
Litigation just placed a legal hold on customer transaction records that your retention job is about to purge. How do you design storage and access so the hold is honored, nothing else is kept longer than it should be, and normal deletion resumes afterward?
Sample Answer
Direct answer. Pause deletion for the held records only, by tagging them with a hold flag that the retention job must respect. Keep them in restricted, access-logged storage, continue normal deletion for everything else, and when legal releases the hold, clear the flag so the next retention run deletes what is due. A legal hold is a lawyer's instruction to preserve records that may be evidence in a dispute or investigation, overriding the normal retention schedule. Counsel decides what is covered and when the hold ends; engineering makes it precise and provable.
Immediate steps (the same day).
- Get a written scope from legal: which custodians (the people or teams whose records are relevant, such as the account manager and billing team), systems, date range, record types, and the case ID. Over-scoping keeps more personal data than necessary; under-scoping risks destroying evidence.
- Suspend the purge for that scope before the next scheduled run. The safest quick stop is to disable the job, then replace it with a filtered job once the flag exists, so other data is not kept by accident.
- Snapshot the scope if records could change, and record hashes (a fingerprint of each file: if it later produces the same fingerprint, it has not changed) so integrity can be shown later.
Design.
- Hold registry: a table of holds (ID, case, scope query or record list, requested by, date, expected review date, status). A record is held if it matches any active hold.
- Deletion job rule: delete only when
retention_expired AND NOT held. The check happens at delete time, against the registry, not from a stale copy, so a hold created while the job runs still applies. Make the deletion fail closed: if the registry cannot be read, delete nothing. - Storage: held records move or stay in a restricted store with a separate access role (legal and a small named group), reading is logged, and no new use is allowed. The hold preserves data; it does not permit the business to start using it. Bucket-level "object lock" features (storage settings that make an object unmodifiable and undeletable for a set period, also called write-once-read-many or WORM) can enforce immutability but do not change retention rules by themselves.
- Copies: apply the hold to replicas (copies kept for reliability), exports, search indexes (derived copies built for fast lookup) and backups that contain the scope, or document why a backup is not affected.
- Minimize collateral: hold only matching records, not the whole database. Tag held records with hold ID so they can be located.
Release. Legal confirms the hold is lifted in writing; the registry marks it released; if a record has no other active hold, its normal expiry already passed, so the next run deletes it. Do a reconciliation: list records that were held, confirm each was deleted or has another reason to remain, and keep evidence (counts, job logs, approval).
Worked example. A retention rule deletes transactions after 7 years. Litigation covers 2,000 transactions from one merchant, 2016 to 2019. The registry row is {hold_id: H-2031, case: "Acme v. Orbit", scope: "merchant_id = 'M-5521' AND txn_date BETWEEN '2016-01-01' AND '2019-12-31'", requested_by: "Legal", opened: "2025-11-03", review_by: "2026-05-03", status: "active"} and the job's delete query becomes DELETE FROM transactions WHERE expires_at < now() AND NOT EXISTS (SELECT 1 FROM holds h WHERE h.status = 'active' AND matches(transactions, h.scope)), so the filter excludes those 2,000 IDs. The other 40,000 expired records are still deleted on schedule. Two years later the hold is lifted; the next run removes the 2,000.
Pitfalls. Holds that are never reviewed turn into permanent retention; a hold flag that lives in one system while a replica job ignores it; and engineers deleting held data "by mistake" because the hold was a spreadsheet. Set a periodic review reminder for each hold.
You are designing telemetry for a browser used by 500 million people. It needs consent choices, sampling, low client overhead and extra care for sensitive events. How would you architect collection and processing so privacy holds at that scale?
Sample Answer
Direct answer. Enforce privacy in the client and in automation, because at 500 million people no human review can keep up. The client checks consent before anything is queued, decides sampling locally, and can only send events declared in a schema. The server strips network identifiers at the edge, splits data by sensitivity, aggregates early, and refuses to show small groups.
Data tiers
- Essential diagnostics (crash counts, version, performance): minimal, no identifiers, collected under a legal basis (the lawful reason for processing, such as consent or a legitimate need) that counsel signs off.
- Optional usage (feature use): needs the user's choice, off if they decline.
- Sensitive events (anything related to browsing, search or content): not collected by default. If a question demands it, measure on-device and send only a coarse result. For example, the browser classifies pages locally and uploads a weekly count per category such as
{news: 41, shopping: 12}, never the URLs. A per-install count is still a small browsing profile, so add noise on the device before upload (local differential privacy: each client randomly flips or perturbs its answer, so any one report is deniable but the population totals can still be recovered), and send each report under a fresh random token rather than the install ID described below, because reports sharing one install ID could be chained together for as long as that ID lasts (30 days in the example).
Client design
- Consent: the choice is stored locally and checked before an event is queued, so "no" means nothing is created, not "created and dropped on the server".
- Sampling: the client decides once per metric per period using a local random draw. At 1% that is 5 million reporting clients (500,000,000 x 0.01). At an illustrative 20 events per day, that is 100 million events per day, around 20 GB per day at 200 bytes each. Of those 5,000,000 sampled clients, a feature used by 0.1% of users still shows up on 5,000 (5,000,000 x 0.001), enough to read, which is why 1% can be enough.
- Overhead: batch events, cap queue size and daily upload bytes, upload on idle and on unmetered networks (Wi-Fi rather than a capped mobile plan), and compress.
- Identity: a random install ID, created at install, replaced by a fresh random value on a schedule (say every 30 days, illustrative) with no link kept between old and new, and deleted on opt-out, never a cross-product account ID.
Schema as the enforcement point. Every event and field is declared in a registry with data category, purpose, retention, and owner. CI fails a change that adds an undeclared field, and the ingest service rejects unknown fields. This is how privacy scales across hundreds of engineers.
Server side
- Edge (the first servers that receive uploads, before anything reaches storage): drop IP addresses before logs (keeping only coarse country) and truncate the user agent (the browser's self-description string) to browser and major version.
- Separate stores per tier with different retention (raw 30 days, aggregates longer, illustrative) and access.
- Aggregate early, publish a cell (one row of a result table, such as one country plus browser version) only if it covers a minimum number of distinct clients (say 50, illustrative). A cell with 2 clients identifies them: if you know your colleague is one of the two, the cell's "visited a health site" count tells you about them.
- Automation: automatic expiry (TTL, time-to-live), access audit and an anomaly alert on large exports.
Trade-offs. Sampling reduces rare-event visibility, so use higher rates for crashes and low-volume features and say so in the schema. Rotating IDs break long-term retention analysis, which is the price of unlinkability.
What would change my call. Strict regional rules may require region-specific consent flows and storage location, which counsel decides. A measurement need that cannot be met with coarse data should go to a privacy review before collection, not after.
A team is starting discovery on a payment feature that collects billing addresses. What privacy questions do you want answered before design starts, and who needs to be in the room?
Sample Answer
Direct answer
Before design starts I want the following answered: why we collect a billing address at all, what exactly we collect, where it goes and who can see it, how long we keep it, and what the user can do with it. The people in the room are the product manager, the engineer who will build it, a security or privacy reviewer, someone from the payments or finance side, a support lead (who will need access in practice), and (if the answers raise risk) legal. Asking early keeps the cheapest design option, which is collecting less.
Questions to answer
- Purpose and necessity. Why do we need the billing address? Common real reasons: the card network's address check (address verification: the card issuer compares the street number and postal code you typed with the address it holds for the card, to catch stolen cards), tax calculation, invoices. Does the payment provider already collect it, so we do not need to store a copy?
- Minimization (collect only what the purpose needs). Do we need the full address or only postal code and country? Do we need it on every purchase, or only for some regions?
- Data flow. Does the address go to our servers or straight to the payment provider (hosted fields: input boxes served by the provider and shown inside our page, so the typed value goes to the provider and never touches our servers)? Which services, logs and analytics tools would see it?
- Storage and retention. Where is it stored, for how long, and why that long (tax or accounting rules can set a minimum, which counsel or finance confirms)? What is deleted when a user closes their account?
- Access. Who can view it (support, finance, engineers), and is access logged?
- User rights. How will a user see, correct and delete it, and how does a deletion request reach every copy?
- Third parties. Which provider receives it and what do we know about their handling?
- Shared with other uses. Will marketing or analytics ever use it? If so, that is a separate purpose needing its own decision.
Who needs to be in the room
| Person | Why |
|---|---|
| Product manager | Owns the purpose and what the feature really needs |
| Engineer or tech lead | Knows where data will flow and be logged |
| Security or privacy reviewer | Raises risks and checks minimization |
| Payments or finance owner | Knows tax, invoice and fraud-check requirements |
| Support lead | Knows who will need access in practice |
| Legal or counsel | Joins when retention, cross-border (data stored or processed in a different country from the customer's) or unusual uses come up |
Worked example
Team says "we need the full address". Questions reveal the fraud check needs only street number and postal code, tax needs country and postal code (in many places the rate depends on where the buyer is, and finance confirms what each jurisdiction needs), and invoices are generated by the payment provider. Result: collect through the provider's hosted form (the provider's own input form embedded in our page), store only country and postal code (tax record) with a defined retention, and keep the full address out of our database and logs.
Handling unknowns
Purpose and minimization decide the design, and unknowns (such as retention minimums) get an owner and a date.
Unlock Full Question Bank
Get access to all 47 Privacy by Design and Default interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.