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.
You are building consent management for a mobile app that several backend services depend on. Lay out what you would build: how consent is captured, stored, and checked, and how other services learn that a user changed their mind.
Sample Answer
Direct answer
Build one consent service as the system of record. Clients capture choices per purpose, the service stores them as an append-only history, other services check against it, and every change is published as an event so downstream services update without polling. Consent here means the user's recorded choice for a specific purpose.
Capture
- The app shows a notice with a version number and one toggle per purpose (analytics, personalised ads, and so on), none pre-set to yes.
- Each choice is sent with user identity (or an anonymous device ID before login, merged at login), purpose, decision, notice version and timestamp.
- Offline: the SDK (software development kit) queues the change and syncs later, with the device's local time stored next to the server's recorded time.
Store
An append-only event log (one row per grant or revocation, only ever added to, never edited) plus a "current state" view derived from it. This keeps history for proof and a fast read for checks.
Check
- Services call a check API (user, purpose, minimum notice version) or read a cached snapshot.
- Fail closed (when unsure, deny): if the service is down and the cached answer is too old, treat consent-dependent processing as not allowed. Essential processing that does not rely on consent keeps working.
Telling other services the user changed their mind
| Mechanism | Role |
|---|---|
| Publish a consent-changed event to a message topic (a named channel that services subscribe to), with a per-user sequence number (a counter that rises by one for each change that user makes) | Fast push to subscribers |
| Subscribers ignore any event whose sequence number is lower than the last one they applied, and applying the same event twice changes nothing (idempotent) | Safe under retries and reordering |
| Short cache lifetime as a backstop | Covers a missed event |
| Nightly reconciliation (a job that compares each subscriber's stored state with the service and reports differences) | Catches drift |
Worked case for ordering: a user switches personalised ads on at 10:00 (sequence 7) and off at 10:05 (sequence 8). The ad service receives sequence 8 first and records "off"; sequence 7 then arrives late. Because 7 is lower than the 8 already applied, it is ignored and ads stay off. Without the rule, the late grant would silently turn ads back on.
Revocation must be as easy as granting (GDPR Article 7(3)). Stopping future processing is immediate; what happens to data already collected is a per-purpose decision (delete, keep aggregated, keep under another lawful basis) that legal confirms. For example, on revoking ads: stop targeting immediately; delete the user's ad-click history; keep the invoice records that tax law requires.
Conflict rule
If two devices change the same purpose offline, the later effective time wins, and a tie goes to the more restrictive choice. Example: a phone, offline, records analytics off at 09:00; a tablet records analytics on at 09:30; both sync at 11:00. The 09:30 choice is later, so analytics is on. If both had been stamped 09:30, the result would be off. Two details keep this consistent with the ordering rule above: the per-user sequence number is assigned by the consent service when it records the resolved outcome, not by arrival order, so a late-arriving offline event that loses the conflict is kept in history but does not become the current state; and the effective time is the device time clamped to the server's receipt time (a device clock set in the future is not trusted), with the server's recorded time stored beside it as noted under capture.
Pitfall
Checking consent only in the app is not enough: the backend must enforce it, because clients can be out of date.
You are planning in-app analytics for a mobile app that must satisfy privacy regulations and still give the team enough signal for roadmap decisions. Which events, identifiers, sampling and retention would you choose, and what would you refuse to collect?
Sample Answer
Direct answer
I would start from the product questions the roadmap actually asks (where do users drop off, which feature is used, what crashes) and collect only the events that answer them. Events carry no free text or precise location. They are tied to a random, resettable per-install ID rather than an account, device or advertising identifier. Raw events are kept for a short, fixed period, and long-term trends live in aggregates. I would refuse anything that identifies a person but answers no roadmap question.
Events: derive them from decisions
Write each roadmap decision down first, then list the minimum event that informs it. Examples (a funnel is the sequence of steps users move through, such as install, onboarding, first purchase, and where they drop out): "Do users finish onboarding?" needs onboarding_step_completed with a step number. "Is the new search used?" needs search_used with a boolean for results shown. Each event gets an owner, a purpose and an expiry review date in a tracking plan (a reviewed schema file in the repo). An event with no decision attached is not added.
Identifiers
| Option | Choice |
|---|---|
| OS advertising ID, hardware ID, phone number, email | Refuse. Analytics does not need them |
| Account ID in events | Refuse. Keep analytics out of the join path to the user table |
| Per-install random ID (generated by the app, reset on reinstall) | Use. It is pseudonymous (a stable label that is not a name, but still personal data under GDPR if it can single someone out) |
| Random ID rotated every 30 days (the app generates a new one; the old one is discarded) | Use where analysis only needs events grouped within a month, such as a purchase funnel. The per-install ID lets you follow retention across months; the rotating one cannot, because events more than 30 days apart carry unrelated IDs |
Pseudonymization is not anonymization: a per-install ID is still personal data, so the opt-out, retention and deletion design below still applies. Deletion works by deleting that ID's rows when the user resets it or asks.
Sampling and pre-aggregation
High-volume, low-value events (scroll, tap-heatmap style signals) are sampled, for example 1 in 10 installs, decided once per install so that a user's session stays whole. In practice the app hashes its install ID and takes the remainder after dividing by 10: with int(hashlib.sha256(install_id.encode()).hexdigest(), 16) % 10 == 0 in Python the install sends these events, and the ID e4417d3a lands on 0 (sends) while b81f2c47 lands on 4 (does not). Because the install ID never changes, the same installs are always in or out, and across 200,000 installs about 20,000 send the sampled events. Rare, decision-critical events (purchase, onboarding completion) are never sampled, because sampling them destroys the small counts you need. Where only a total matters (daily active installs, or crash-free sessions, the share of app sessions that ended without a crash), count on the device or at the ingest edge (the first server that receives events, before they are stored) and send the counter, not the stream. Cohorts (groups of installs that share a trait) are defined by coarse buckets (app version, install week, country, not city), and reports suppress any bucket under a minimum size, for example 20 installs, so a small cohort cannot point at one person. For example, a bucket of version 4.2 in New Zealand with 14 installs is hidden from reports, while the same version in Germany with 3,800 installs is shown.
Retention
Raw event rows: 90 days (illustrative; pick the shortest window that covers one release cycle plus analysis lag). After that, only aggregates (counts per day, per version, per bucket) are kept. Retention is enforced by a table TTL (time to live: rows expire automatically after a set age), not by a to-do.
What I would refuse, with the leaky fields that usually slip in
- Free text: search queries, chat messages, form fields, since these routinely contain names and health or financial details.
- Precise location (use country or none), contact lists, clipboard contents, screen recordings or session replay of fields.
- Full URLs or deep links with tokens or emails in query strings, and error messages that echo user input. Log exception type and code, never the message body.
- Device fingerprints (model + OS + fonts + timezone combined).
- Anything about children's accounts without a separate review.
Schema pattern that prevents leaks
Define events as typed enums and bounded integers in a schema, validate at the SDK and at ingest, and reject unknown properties. A free-string property is a design smell: replace it with an enum or a bucket (query_length_bucket: 1-3, 4-10, 11+).
Worked variation: a mobile game
For a mobile game, the same plan applies: events such as level_completed and match_ended with minimal fields (level, duration bucket, result), a per-install pseudonymous player-analytics ID kept separate from the account and voice or chat content, and an in-game opt-out switch honoured at the SDK so no event is sent. Anti-cheat and fraud data are a different purpose with their own retention and are not mixed into product analytics.
Consent and regulation
Whether analytics needs opt-in consent (nothing is collected until the user says yes), or can run on a legitimate-interest basis with an opt-out (a legal basis, for example in GDPR Article 6(1)(f), that lets a company collect without asking first when its need is real and not overridden by the user's rights, while the user can object), depends on jurisdiction and on what the SDK reads from the device. That call belongs to privacy counsel. My engineering default is the safe one: ship opt-out controls in settings that are easy to find, and gate non-essential analytics on consent where counsel says it is required.
Trade-offs
You lose per-user journey analysis across reinstalls and fine-grained cohort slicing. Product gets most roadmap signal back through funnels, aggregates and a small opt-in research panel. What would change my call: a regulator or app-store rule requiring consent first (then default off until accepted), or a decision that truly needs user-level history (then I would ask for explicit opt-in research participation).
You're asked to remove a popular personalization feature implemented with on-device ML models because of privacy concerns, but it improves engagement by ~10%. Propose alternative architectures or design changes that preserve value while reducing privacy risk, and outline an evaluation plan to compare them.
Sample Answer
Direct answer. First find out what the privacy concern actually is, because on-device models already keep raw data off the server, so removal may be a heavier fix than the risk needs. Then offer a ladder of designs from least to most change, test them against both engagement and a privacy-risk score, and pick the option that keeps most of the value at the lowest risk. The decision rule is written before the test starts.
Step 1: pin down the concern. Typical causes: the model infers sensitive traits (health, finances), the data is retained too long, a sync to the cloud exists, other apps or people could read the on-device store, or the feature is switched on without a clear choice. Each leads to a different fix, so ask privacy and legal what the specific objection is.
Step 2: alternatives, from least to most change
- Keep the model, shrink the inputs: remove sensitive categories from features, use coarse categories rather than item-level history, shorten the window, add decay (older actions count for less each day, so old history fades instead of accumulating).
- Change the defaults and controls: opt-in or a clear first-run choice, a visible "why this" and a reset button. This addresses consent without touching the model.
- Contextual personalisation: rank by the current session and context (time, screen, query) with no stored history. Usually lowest value, lowest risk.
- Cohort model: the server trains on aggregated groups of similar users (cohorts) and the device picks the closest cohort, so no individual history is stored. Needs a minimum group size so no cohort identifies a person.
- Remove the feature: the baseline for comparison.
Step 3: evaluation plan. Illustrative numbers: engagement without personalisation is 20%, and the feature lifts that by about 10% relative (10% of 20% is 2 points), to 22%. Decision rule: adopt an alternative if it retains at least half the lift. Half of 2 points is 1 point, so the bar is 21%.
- Detecting 20% against 21% needs a sample size. Significance of 5% (two-sided) is the false-alarm rate you accept: a 1 in 20 chance of declaring a difference when there is none. Power of 80% is the chance the test catches a real difference of this size, so 1 in 5 real effects of this size are missed. The two-proportion formula is n = (1.96 * sqrt(2 * pbar * (1 - pbar)) + 0.8416 * sqrt(p1(1-p1) + p2(1-p2)))^2 / (p1 - p2)^2, where 1.96 and 0.8416 are the normal-curve values for 5% two-sided significance and 80% power, p1 = 0.20, p2 = 0.21 and pbar = 0.205. That gives n = (1.1190 + 0.4805)^2 / 0.0001 = 25,582.5, rounded up to 25,583 users per arm (computed in python). With four arms (no personalisation, current feature, two alternatives) that is 102,332 users.
- Run for whole weeks, at least two, so weekday patterns and a novelty effect (a short-lived jump in engagement because something is new) do not mislead.
- Compare each alternative with the no-personalisation arm (the 21% bar is judged against the 20% baseline) using a correction for several comparisons: each extra comparison is another chance for a fluke to look significant, so split the 5% budget. With two comparisons, test each at 2.5%, which raises the sample to about 30,980 per arm (about 123,920 across four arms) (computed in python, same formula with 2.2414 in place of 1.96, the normal-curve value for a 2.5% two-sided level, so 2.24 would give about 30,952). Comparing an alternative directly with the current feature (21% against 22%) is a different test with a smaller gap relative to the noise: it needs about 26,493 per arm at the 5% level and about 32,082 at 2.5% (computed in python), so size the arms for whichever comparison the decision rests on.
- Guardrails (metrics that must not get worse even if the main metric wins): opt-out rate, support complaints, session length, and a privacy-risk score computed per design. An illustrative scoring rule: 1 point per personal field retained, plus 5 if sensitive categories can be inferred, plus 1 per 30 days of retention (rounded up), plus 5 if anything leaves the device. The current feature retains 12 fields, allows sensitive inference and keeps data 180 days: 12 + 5 + 6 + 0 = 23. Alternative 1 (smaller inputs) retains 5 fields, no sensitive inference, 30 days: 5 + 0 + 1 + 0 = 6. If alternative 1 shows 21.4% engagement (1.4 of the 2 points, 70% of the lift) it clears the 21% bar at about a quarter of the risk score.
Step 4: who signs off. Product owns the engagement trade-off, privacy and legal own the residual risk, and security owns the on-device protection. If the "10%" is an absolute rather than a relative gain, redo the sample size.
Pitfalls. Judging only by engagement will favour the risky design. A test too small to see a 1 point difference will say "no difference" when there is one.
You must decide whether a heavy personalization model runs on the device or in the cloud. How would you frame the recommendation, what privacy and security benefits would you weigh, and what would you give up?
Sample Answer
Direct answer
I would frame it as a decision about where the data and the model should live, not a slogan. My default recommendation is a split: run a smaller personalization model on the device so raw behavioural data never leaves it, and keep heavy training and any non-personal model work in the cloud. I would put the heavy model fully in the cloud only if the device genuinely cannot run it at acceptable quality, and then minimize what is sent.
How I frame the recommendation
- What data does the model need (clicks, location, health, messages), and how sensitive is it?
- Who benefits from keeping it local, and who bears the cost (battery, storage, app size, device fragmentation)?
- What quality does the product need, and does a compressed model deliver it?
- Who owns the decision: product and the ML lead decide quality and cost, security and privacy sign off on data flows.
Privacy and security benefits of on-device
- Raw personal data stays on the phone, so there is less to breach, subpoena (a legal order forcing a company to hand over data it holds), over-retain or misuse for a new purpose later (data minimization).
- Smaller attack surface (fewer places an attacker can reach) on the server side, no per-user profile store to protect.
- Works offline and with lower latency.
- Simpler deletion: clearing app data clears the personalization state.
Benefits of cloud
- Larger, better models and quick updates, with central monitoring.
- Easier evaluation and abuse detection.
- Model and weights are protected from extraction by users, and keys are handled centrally.
What you give up with on-device
| Cost | Detail |
|---|---|
| Quality | A compressed model (shrunk by storing its numbers with fewer bits, or by training a small model to imitate a big one) is usually weaker than a full-size one |
| Device cost | Battery, memory, thermal limits, and older phones that cannot run it (device fragmentation: many phone models with different hardware) |
| Model security | The weights (the learned numbers that are the model) ship inside the app. An attacker can copy them out of the app package and reuse or resell them (extraction), edit them so the model behaves differently, for example always ranking one seller first (tampering), or send many inputs and study the outputs to rebuild the model or infer what it was trained on (probing) |
| Visibility | You cannot easily see failures or abuse |
| Update speed | Model rollouts depend on app and OS update cycles |
Worked example
A shopping app wants personalized rankings from browsing history. Option A sends the full browse history to the server each session. Option B keeps history on the device, scores 200 candidate items locally using a small model, and sends only the IDs of the items the user tapped, not the browsing history (the server can then count taps per item across users, but each session still uploads a short list). With illustrative numbers: Option A uploads about 300 browse events of roughly 100 bytes each, 30 KB per session, and ranks at a 6.0% click-through rate. Option B uploads 5 tapped item IDs, well under 1 KB, and a smaller model might reach 5.4%, a 10% relative drop (0.6 / 6.0), while scoring 200 items at about 5 ms each costs roughly 1 second of processor time per session (200 x 5 ms = 1,000 ms), which is the battery cost to measure. Option B loses some ranking quality and some insight into long-tail behaviour, but the server never holds the browse history. I would recommend B, with a cloud fallback for devices below a hardware threshold that sends only the minimum features and is opt-in.
Decision flips
If the model needs data from many users to work (collaborative signals) or needs frequent updates, I would move that part to the cloud (collaborative signals, such as "people who bought this also bought that", only exist when many users' data is combined) with pseudonymous, minimized inputs. If the data is highly sensitive (health), I lean on-device. If model theft is the bigger business risk, cloud wins.
A new feature needs precise, time-limited location access. How would you design it privacy-first: what runs on the device, what precision you really need, how consent is asked, and what is stored and for how long?
Sample Answer
Direct answer
Do as much as possible on the device, ask only for the precision the feature needs, request permission at the moment of use with a plain explanation, send the server coarse data (location rounded so it points to an area rather than a spot) where possible, and delete the precise data when the time-limited task ends. I would argue for coarsening by showing the risk of precise coordinates in concrete terms.
On the device
- Compute the feature locally when it can be (distance to a destination, or a geofence check, which asks whether the phone is inside a virtual boundary drawn around a place) and send only the result.
- Request location only while the feature is active, and stop updates when the window ends. Use the system's "while using the app" permission, not background access, unless the feature truly cannot work without it.
- Use the platform's approximate-location option as the starting request, and ask for precise only if needed.
What precision you really need
Coordinate decimal places map to distance (roughly 111 km per degree of latitude, computed):
| Decimals | About |
|---|---|
| 2 | 1.1 km |
| 3 | 110 m |
| 4 | 11 m |
| 5 | 1.1 m |
Coarsening means rounding the coordinate to fewer decimals (rounding the last kept digit, not just cutting digits off). A real coordinate such as 51.50735 becomes 51.507 at 3 decimals (about 110 m) and 51.51 at 2 decimals (about 1.1 km): the shorter number still says "central London" but no longer says which door. The table is for latitude; a degree of longitude is shorter away from the equator (about 69 km at London's latitude, 111.32 x cos 51.5 degrees), so the real grid cell is narrower east to west than north to south.
A "nearby stores" feature works at 2 to 3 decimals. A pickup meeting point may need 4 for the live period only. Product asks for high precision, so test with them: does accuracy at 110 m versus 11 m change the outcome they measure?
Measuring the privacy risk of precise coordinates
Ask what the coordinates reveal: a point at home overnight reveals the home address, repeat visits reveal workplace, a clinic or a place of worship reveals sensitive facts. A few precise points per person can single them out, so they are rarely anonymous. Score each use from 1 (low) to 3 (high) on sensitivity, precision, duration and who can see it, add the four, and use the total (4 to 12) to justify the coarser setting. Illustrative scores: nearby stores at 3 decimals, kept for the session, seen only by the app service scores 2+1+1+1 = 5, so it is fine. A pickup point at 4 decimals for 30 minutes scores 2+2+1+1 = 6, so it is acceptable for that window. Keeping a precise trace for 12 months where marketing can read it scores 2+3+3+3 = 11, so coarsen it, shorten it or drop it. Treat 9 or more as a stop-and-redesign line.
Consent
Ask in context ("to show drivers near you for the next 30 minutes"), explain what happens if the user declines, and make the feature degrade gracefully (keep working in a reduced form, for example by letting the person type an address). Do not bundle location with unrelated permissions.
Storage and retention
- Precise coordinates: held only for the session, deleted at session end.
- Coarse trace for the record (a rough path of where the person was, rounded to 3 decimals): kept a short fixed period, for example 24 hours, for support or fraud, then deleted.
- No joining to the advertising ID (the resettable identifier a phone gives to ad networks to track a person across apps). Access limited to the service that needs it, with logging.
The exact periods are illustrative and should follow the stated purpose and your counsel's advice.
Unlock Full Question Bank
Get access to all 12 Privacy by Design and Default interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.