Privacy Engineering & Data Protection
GDPR gives an organization one month — extendable, but rarely in good faith — to answer someone who asks what personal data it holds on them, and the same clock to erase it everywhere if they ask for that instead. Most organizations can't actually answer either question quickly, not because the law is unreasonable but because nothing in their pipeline tracks where personal data lives, what it's tagged as, or when it's supposed to disappear. This page is about building the engineering underneath a privacy program instead of treating privacy as a legal review that happens once, right before launch — the same late gate this course's very first lesson already dismantled for security: data classification and tagging a pipeline actually enforces, PII detection tuned for the two places it reliably escapes to anyway — logs and object storage — and data minimization treated as a design constraint that shrinks how much every other control in this course has to protect in the first place.
Building a house with the wiring already inside the walls is different from building the house and then trying to fish wires through the plaster afterward — one was designed for it from the first blueprint, the other is a renovation that never quite closes every gap. Privacy by design is wiring personal-data protection into the blueprint: deciding what to collect, how to label it, and when to throw it away, before a single line of code exists — instead of bolting scanners and redaction onto a system that was never built to make either one easy.
Privacy engineering vs. privacy as a compliance checkbox
☺ Like you're 10: Asking a lawyer "is this okay?" the week before launch is exactly the late security gate this course already replaced — it's just privacy's turn to move earlier.
Every DevSecOps team in this course already learned why a security review scheduled for the week before release fails: the finding lands on an engineer who's moved on, the fix competes with a ship date, and the review only ever sees the last version of the design, never the fifteen decisions that shaped it. What is DevSecOps? called this the traditional model, and the fix was shifting left — threat modeling at design, scanning at every commit, a policy the pipeline enforces instead of a person remembering to. Privacy, in most organizations, still runs on the model security abandoned. A legal or privacy team reviews a feature's data handling once, usually from a design document instead of the actual schema, usually in the weeks before launch, and usually with authority to say no but no seat in the sprint where the schema got decided. The review isn't wrong to exist — GDPR, CCPA/CPRA, and a dozen sector-specific laws genuinely require someone to sign off on lawful basis and purpose — but a once-per-feature legal gate scales the same way a once-per-release security gate did: badly, and later than it should.
Privacy by Design, the framework Ontario's then-Information and Privacy Commissioner Ann Cavoukian formalized in the 1990s, states the alternative as seven principles: be proactive, not reactive; make privacy the default setting, not an opt-in; embed it into the design itself rather than bolt it on; insist on full functionality — a positive-sum trade, not privacy versus features; protect data end-to-end, across its entire lifecycle, not just at collection; keep the system visible and transparent; and stay user-centric throughout. Those seven principles motivated GDPR Article 25, "data protection by design and by default," which turns the same idea into an enforceable legal requirement: technical and organizational measures — pseudonymization and data minimization are the two the article names explicitly — have to be built in from the moment processing is designed, not retrofitted once a regulator or a breach forces the question. Compliance & governance already covers what GDPR requires as a regulation; this page covers what building to Article 25 actually looks like in a pipeline.
NIST's Privacy Framework (version 1.0, January 2020) gives the discipline the same shape NIST's Cybersecurity Framework gave security: a small set of core functions a team can organize work around instead of a checklist to march through once a year. Its five functions — Identify-P (inventory what personal data you process and why), Govern-P (establish policy and assign accountability), Control-P (give the organization the ability to act on data — disclose it, restrict it, delete it), Communicate-P (build organizational transparency), and Protect-P (apply the security controls this course already teaches) — deliberately mirror Identify/Protect/Detect/Respond/Recover without forcing every privacy risk into a security-shaped box. The rest of this page is essentially Control-P and part of Identify-P, made concrete: classification tags a pipeline enforces, detection tuned for where personal data actually leaks, and minimization as a constraint on the data model itself.
Security as code turned a policy into something the pipeline literally can't skip. Privacy as code is the identical move applied to Article 25: a classification tag, a minimization rule, or a residency constraint that lives in version control and runs on every commit is worth more than a privacy policy a reviewer reads once and everyone else forgets.
Data classification and tagging a pipeline can enforce automatically
☺ Like you're 10: A label on a box tells the mover which room it goes in without them opening it to check — a classification tag on a column does the same job for every system that touches your data afterward.
Classification starts with a taxonomy simple enough that an engineer tags a column correctly without asking legal first. A common four-tier shape — Public, Internal, Confidential, Restricted — covers most data, but personal data needs a second, orthogonal axis GDPR draws for you: ordinary personal data (a name, an email, an IP address) versus special category data under Article 9 — racial or ethnic origin, political opinion, religious belief, trade union membership, genetic data, biometric data used for identification, health data, and data concerning sex life or sexual orientation — which needs a stricter lawful basis (explicit consent, or one of Article 9(2)'s narrow exceptions) than ordinary processing does. A column holding a health condition and a column holding a shipping address are both "PII" in casual conversation, but they don't carry the same regulatory weight, and a classification scheme that collapses them into one tag has thrown away exactly the information that should decide what access control and retention rule the column needs.
The tag has to live somewhere a pipeline can read it, and three places are common in practice. Inline schema annotations — a SQL COMMENT on the column, a Protobuf field option, an OpenAPI x-classification extension — travel with the definition itself, so the tag can't drift out of sync with a renamed or dropped field the way a spreadsheet inventory reliably does. Metadata catalogs — DataHub, OpenMetadata, Amundsen, or a managed equivalent like AWS Glue Data Catalog paired with Lake Formation's tag-based access control, or Snowflake's native column tagging with masking policies attached — centralize the tag across every table that references the same logical field, so "email" gets classified once and every downstream table that copies it inherits the classification instead of re-deriving it. Commercial data-classification and DSPM platforms — Microsoft Purview's sensitivity labels, or the DSPM vendors CNAPP & the unified cloud security stack already covers (BigID, Cyera, Dig Security) — add automated discovery on top of any of the above: a classifier that scans a data store's actual contents and proposes tags for columns nobody remembered to annotate, which matters because the columns most likely to leak sensitive data are exactly the ones nobody thought to tag in the first place.
The enforcement step is what makes a tag a control instead of documentation. A CI check running against every migration diff — conceptually the same shape as policy as code checking a Terraform plan, just pointed at a schema instead of infrastructure — scans new and modified column definitions for PII-shaped heuristics, then fails the build if a match has no accompanying classification tag.
# ci/check_column_classification.py — run against every migration diff in CI.
# Fails the build if a PII-shaped column has no classification tag attached.
import re
PII_NAME_PATTERNS = [
r"email", r"e_?mail", r"ssn", r"social_security", r"tax_id",
r"date_of_birth", r"\bdob\b", r"phone", r"mobile", r"address",
r"passport", r"national_id", r"health", r"diagnosis", r"biometric",
]
ALLOWED_TAGS = {"public", "internal", "confidential", "restricted"}
def check_migration(added_columns):
failures = []
for col in added_columns:
looks_like_pii = any(re.search(p, col.name, re.I) for p in PII_NAME_PATTERNS)
if looks_like_pii and col.classification_tag not in ALLOWED_TAGS:
failures.append(
f"{col.table}.{col.name} looks PII-shaped but carries no "
f"'-- classification: <tag>' comment on the migration"
)
return failures
# CI step: fail the build if check_migration() returns anything at all.A column-name heuristic only catches PII that announces itself in the name. A notes free-text field, a metadata JSONB blob, or a column literally named contact_info holding an email address all sail through a name-based check completely untagged — which is exactly the gap the next section is about. Classification at the schema level is necessary; it is not sufficient on its own.
Finding PII where it actually leaks: logs and object storage
☺ Like you're 10: A label on the front door doesn't stop someone from leaving a spare key under the mat around back — logs and storage buckets are the back doors a classification tag doesn't automatically cover.
Column-level classification governs the database schema. It says nothing about the two places personal data most reliably ends up anyway: application logs, where a stack trace or a debug statement captures a full request payload including whatever a user typed into a form; and object storage, where a one-off CSV export, a support-ticket attachment, a database backup, or a data-warehouse dump lands in a bucket that was never modeled as "the PII table" and so never got a tag from the previous section's pipeline at all. Both are genuinely common exposure paths, not hypothetical ones — Secure by design & threat intel already walked through Equifax from the asset-inventory angle: the same breach exposed roughly 147 million Social Security numbers that were sitting in a system nobody had specifically classified as sensitive the day the vulnerability was actually exploited.
For logs, the most reliable control isn't detection at all — it's never emitting the field in the first place. Structured logging with an explicit allow-list of fields (log user_id, never the full request body; log order_total, never the shipping address that came with it) beats scrubbing after the fact, because a deny-list of regex patterns only ever catches the shapes someone thought to write a pattern for. Where free text can't be avoided — an exception message, a third-party webhook payload, a support tool's debug dump — an inline PII analyzer sitting between the application and the log sink is the next-best control. Microsoft Presidio, open source, pairs spaCy-based named-entity recognition with roughly thirty built-in regex and checksum-validated recognizers (EMAIL_ADDRESS, US_SSN, CREDIT_CARD, PERSON, PHONE_NUMBER, and more, extensible with custom recognizers for anything internal like an employee-ID scheme) and returns both the finding and a confidence score; its companion anonymizer then redacts, masks, hashes, or encrypts each match before the line ever reaches Splunk, Datadog, or an ELK stack.
For object storage, detection has to be a scheduled scan rather than an inline check, because the data isn't flowing through a pipeline you control the way a log line is — it's already sitting there. AWS Macie runs managed data identifiers (plus custom regex-based identifiers you add) against S3 buckets on a schedule, scores each finding by severity, and reports through Security Hub the same way a SAST or SCA finding would. Google Cloud's DLP API (rebranded Sensitive Data Protection) offers a broader catalog of over 150 built-in infoType detectors and can scan Cloud Storage, BigQuery, and streaming Dataflow pipelines with the same inspection templates. Both tools sample rather than exhaustively scan a multi-petabyte estate for cost reasons — CNAPP & the unified cloud security stack covers this exact tradeoff in its DSPM section, and the same caution applies here: a clean scan result is a probabilistic statement about what the sample found, not a guarantee about what the bucket actually contains.
A detector only finds what it was built to recognize. Presidio's default US_SSN recognizer and Macie's SSN identifier are both tuned for the US format and validate the checksum — neither one will flag a UK National Insurance number, an Aadhaar number, or an internal employee ID that looks sensitive to a human but not to a regex. NER-based person-name detection has the opposite failure mode: it will happily flag "Jordan" as a name in a sentence that's actually about the country. Treat every scanner's default ruleset as a starting point, add custom recognizers for anything specific to your own data model, and budget time to tune the false-positive rate down before anyone trusts the finding queue enough to act on it automatically.
Install Presidio locally (pip install presidio-analyzer presidio-anonymizer), feed it a handful of made-up log lines mixing a real-looking email, a US SSN, and an ordinary sentence containing a person's name, and look at the confidence score it returns for each. Then drop one recognizer's confidence threshold to something absurdly low and rerun it — watch the false-positive rate on ordinary text spike. That's the tuning tradeoff every DLP tool in this section is quietly making on your behalf, made visible.
Data minimization as a design constraint, not a virtue
☺ Like you're 10: The safest data to protect is the data you never collected — an empty drawer can't be broken into.
Data minimization is GDPR Article 5(1)(c): personal data must be "adequate, relevant and limited to what is necessary" for the purpose it was collected for. Read as a compliance clause, that sentence is vague. Read as an engineering constraint, it's specific: if a feature only needs to know whether a user is over eighteen, the schema should hold a boolean, not a date of birth; if a shipping flow only needs a delivery address for the duration of a shipment, the schema shouldn't hold it indefinitely once the package has arrived. Every field this course's other controls have to protect — encrypted, access-controlled, tagged, scanned for in logs — is a field that had to be collected and retained in the first place. Minimization is the one control in this course that shrinks the blast radius of every other one — secrets management, encryption, access control, even the detection tooling from the last section — instead of adding another layer around a problem that stays exactly the same size no matter how well the layer works.
Minimization has a second half beyond collection: retention. A field collected for a legitimate purpose becomes a liability the moment that purpose ends and nobody deletes it — which is precisely how forgotten data-warehouse exports and five-year-old snapshots end up as the "unknown unknowns" DSPM tooling exists to find. The fix ties directly back to the classification tags from earlier in this page: attach a retention period to the classification, not to the individual table, so "restricted, 90-day retention" is a rule that travels with every column tagged that way instead of a policy someone has to remember to apply table by table. In practice that's an S3 Lifecycle rule keyed to a bucket's classification tag, a BigQuery table's expiration_timestamp, or a scheduled job that queries for rows past their tag's retention window and removes them — the same "reconcile toward a declared state" instinct policy as code applies to infrastructure, applied to data age instead of a Terraform plan.
Three terms get used almost interchangeably in casual conversation and mean structurally different things under GDPR. Pseudonymization (Article 4(5)) replaces an identifying value with a token or key, reversibly, using information held separately — a customer ID swapped for a random UUID, recoverable only via a lookup table kept apart from the dataset. Pseudonymized data is still personal data under GDPR, because re-identification remains possible; the regulation treats it as a risk-reducing measure, not an exemption. Anonymization is irreversible by design — done correctly, the result is no longer personal data at all and falls outside GDPR's scope entirely — but "done correctly" is a genuinely hard bar to clear. Latanya Sweeney's widely cited 2000 study found that ZIP code, birth date, and sex alone uniquely identify roughly 87% of the US population, and Narayanan and Shmatikov's 2008 de-anonymization of the Netflix Prize dataset, cross-referencing it against public IMDb reviews, is the canonical demonstration that "we removed the names" is not the same claim as "this is anonymous." Tokenization — common in the PCI-DSS context this course's compliance & governance page already introduced — substitutes a format-preserving surrogate value for the original, typically via a vault the token maps back through, and is really pseudonymization wearing a payments-industry name.
| Reversible? | Still "personal data" under GDPR? | Typical mechanism | |
|---|---|---|---|
| Pseudonymization | Yes, via a separately held key or lookup | Yes | Token/UUID substitution, format-preserving encryption |
| Anonymization | No, by design | No — if actually achieved | Aggregation, k-anonymity, differential-privacy noise |
| Tokenization | Yes, via a token vault | Yes | Vault-backed surrogate value, common in PCI-DSS scope reduction |
For fields too sensitive to pseudonymize away — a health condition, a government ID number, anything under Article 9 — field-level encryption is the remaining tool: encrypt the value at the application layer with its own data encryption key before it ever reaches the database, so a database administrator, a backup, or a replica sees ciphertext rather than plaintext, and decryption requires a separate, audited call to a KMS rather than merely having read access to the table. Cryptography & key management covers the envelope-encryption mechanics in full; the piece worth restating here is what it buys specifically toward an erasure obligation: issue one key per tenant or per data subject, wrap it under a KMS-held key-encryption key, and "delete this person's data" becomes "destroy this one key" — crypto-shredding — rather than a distributed hunt through every backup, replica, and cold-storage copy a DELETE statement can't reach. A backup restored from six months ago still holds the ciphertext; once the key is gone, it holds nothing anyone can read.
Mapping data flows and gating features with a DPIA
☺ Like you're 10: Before you build a maze, you draw the map first — a data flow diagram is that map, showing exactly where a piece of personal data enters, where it rests, and every door it could walk out of.
GDPR Article 35 requires a Data Protection Impact Assessment (DPIA) before starting any processing "likely to result in a high risk" to individuals — large-scale processing of special category data, systematic and extensive profiling, and systematic monitoring of a publicly accessible area are the three examples the regulation names explicitly, though most organizations run a lightweight triage question on every feature rather than reserving DPIAs for the obvious cases. A DPIA that happens on paper, disconnected from the actual data model, produces the same value a design document produces without an architecture review attached to it: a description of what the team intended, not a check on what actually got built.
The engineering version of a DPIA starts with a data flow diagram: where does a given piece of personal data enter the system (a form field, a webhook, a third-party API response), where does it come to rest (which table, which cache, which bucket), what reads it on the way (which internal services, which third-party processors, which analytics pipeline), and where does it leave (an export, an API response, a support tool, a log line). Threat modeling already taught STRIDE for security threats against a system like this one; LINDDUN is the structurally equivalent framework for privacy threats specifically, and it's worth knowing by name even in outline: Linkability (can two pieces of data be tied to the same person who shouldn't be linkable), Identifiability (can a supposedly anonymous record be traced back to a person), Non-repudiation (can a user be tied to an action they'd have a legitimate reason to deny, like reading a specific article), Detectability (can an attacker tell whether a given person's data exists in a dataset at all, even without reading it), Disclosure of information (does data reach a party it shouldn't), Unawareness (does the user actually understand what's happening to their data), and Non-compliance (does the design violate a stated privacy policy or a regulation). Running LINDDUN over the same data flow diagram STRIDE already produced for the security threat model is often the fastest way to do both — the diagram is the expensive part to build accurately, and it's reusable across both frameworks.
The gate that makes any of this durable is structural, not procedural: a feature whose data flow diagram shows personal data — especially special category data — crossing a new boundary doesn't proceed from design to build without a completed DPIA attached to the pull request, the same way secure SDLC gates stop a build that hasn't cleared its SAST or SCA gate. The owner is different — a privacy gate is jointly held by engineering and whoever holds the DPO or privacy-counsel role, not engineering alone — but the mechanism is identical: block progress on a missing artifact instead of trusting that everyone remembered to write one.
Privacy as code: policy gates in CI/CD and IaC
☺ Like you're 10: The same trick that makes a security rule impossible to forget — writing it as code the pipeline checks automatically — works exactly as well for a privacy rule.
Every mechanism earlier on this page — the classification tag, the retention rule, the residency requirement a dataset carries — is only as strong as its enforcement, and the CI check from earlier in this page (a migration blocked for carrying an untagged, PII-shaped column) is one instance of a broader pattern: privacy as code, the same discipline security as code already established for this course, pointed at data-protection rules specifically instead of vulnerability findings.
Infrastructure as code is the other place these rules belong, because a dataset's classification tag should constrain where it's allowed to be provisioned, not just who can read it. A Rego policy evaluated against a Terraform plan — the same terraform show -json input IaC security & policy as code already covers — can deny a plan that provisions a storage resource tagged for EU-resident data outside an approved EU region, or one tagged restricted without encryption in place:
package terraform.privacy
import future.keywords.in
approved_eu_regions := {"eu-west-1", "eu-central-1"}
# Deny a bucket tagged for EU-resident data if it's provisioned outside the EU.
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
tags := resource.change.after.tags
tags.data_residency == "eu"
not resource.change.after.region in approved_eu_regions
msg := sprintf(
"resource %q: tagged data_residency=eu but region %q is not an approved EU region",
[resource.address, resource.change.after.region],
)
}
# Deny a bucket tagged "restricted" if it lacks default encryption.
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_s3_bucket"
resource.change.after.tags.classification == "restricted"
not resource.change.after.server_side_encryption_configuration
msg := sprintf(
"resource %q: tagged classification=restricted but has no default server-side encryption",
[resource.address],
)
}Access control is the third enforcement surface, and it works differently from a static IAM grant. Attribute-based access control (ABAC) — the model tools like Immuta and Privacera build around — computes an access decision at query time from three things: the requester's role, the data's classification tag, and the stated purpose of the request, instead of a standing grant decided once and left to go stale. A support engineer's role might be allowed to read a customer's confidential-tagged shipping address to resolve a ticket, but the same role reading the same column tagged restricted for a bulk export requires a different, explicitly purpose-scoped grant — the same least-privilege instinct workload identity & pipeline IAM applies to a CI job's cloud credentials, applied here to a person's query instead of a pipeline's API call.
Cross-border transfers, residency, and subject rights at scale
☺ Like you're 10: Some countries have rules about which other countries a piece of mail is even allowed to be shipped to — personal data has the same restriction, and someone has to actually enforce it, not just write it in a policy.
Moving personal data across a border is its own regulated act under GDPR, and the mechanism for doing it lawfully has been genuinely unstable for years. The Schrems II ruling (Court of Justice of the EU, July 2020) invalidated the EU-US Privacy Shield, leaving Standard Contractual Clauses (SCCs) as the primary transfer mechanism — but paired with a requirement to run a transfer impact assessment confirming the destination country's surveillance laws don't undermine the SCCs' protections in practice, not just on paper. The EU-US Data Privacy Framework, which the European Commission adopted an adequacy decision for in July 2023, currently provides a more direct path for transfers to certified US organizations, but this area has a documented history of being challenged and struck down — Privacy Shield was the second framework the CJEU invalidated, after Safe Harbor in 2015. Verify the current adequacy status and your organization's own legal position before treating any of this as a fixed, permanent mechanism rather than the current state of an ongoing legal fight.
Whatever the legal mechanism, the engineering obligation is the same one the previous section's IaC policy already enforces: a dataset tagged for EU residency needs to actually be provisioned, replicated, and backed up inside an approved region, not just documented as intended to be. That's the classification tag from earlier in this page doing a third job — access control, retention, and now region placement, all keyed off the same attribute, instead of three separate systems each tracking their own copy of "which datasets are EU data" and inevitably drifting out of sync with each other.
Every mechanism on this page converges on one operational test: can the organization actually answer a Data Subject Access Request (DSAR) — "show me everything you hold about me," or its counterpart, "delete everything about me" — inside the legal window, which is one month under GDPR Article 12(3) (extendable by two further months for genuinely complex requests) or 45 days under CCPA/CPRA (extendable once, to 90). Answering that by hand, with an engineer grepping across however many microservices and data stores the organization has accumulated, doesn't scale past a company's first few dozen requests. It scales when the classification tags from earlier in this page double as a queryable registry of where a given category of personal data lives — the same inventory CNAPP & the unified cloud security stack's DSPM section already pointed toward — so a DSAR orchestrator can fan a request out to every tagged store automatically, and "delete everything about this person" can invoke the crypto-shredding pattern from earlier instead of a distributed, error-prone hunt through backups nobody can fully enumerate under deadline pressure.
Put together, this page is one argument told four ways: a classification tag decided once and enforced everywhere beats a policy re-derived by hand at every layer; detection tuned for where data actually leaks beats trusting the schema alone; a smaller dataset beats a better-guarded large one; and every legal deadline on this page — the DPIA gate, the transfer assessment, the DSAR clock — gets easier to meet in direct proportion to how much of the above was already automated before the request arrived, not built in response to it. If you're aiming at a certification that weights this specifically, IAPP's CIPT (Certified Information Privacy Technologist) is the engineering-facing credential in this space, distinct from the legal-and-governance-focused CIPP/E; ISC2's CSSLP, already part of this course's certification track, folds privacy requirements into its secure-software-lifecycle domains as well. As always, verify current exam content and pricing on the vendor's own page before planning study time around either one.
Benny the Beaver: Pushed the migration — just a new contact_info column on the support-ticket table. Nothing dramatic.
Nutty the Squirrel: "Nothing dramatic" is exactly the kind of column I go looking for. Is it tagged?
Benny the Beaver: It's just a free-text field. It didn't trip the classifier — the name didn't match anything on the list.
Sol the Sloth: I scanned the bucket where support tickets get exported for the analytics team last week. That "free-text field" has phone numbers, home addresses, one medical note. Untagged, unencrypted, sitting in a bucket nobody's reviewed since it was created.
Timmy the Turtle: Then the gate has a gap. A name-based check can't see what's actually written inside a free-text field — that's not the kind of scan I run.
Ellie the Elephant: If it has to stay free text, at least let me hold it — one key per ticket, field-level encrypted. When someone asks us to delete their data, I destroy the key instead of you two hunting through every export that's ever copied it.
Professor Owl: And that's the whole page in one exchange: Sol finds where it actually lives, Nutty tags what it is, Timmy blocks what isn't tagged, Ellie makes the thing worth stealing worthless the moment someone asks us to forget it. None of it works if the field never should have been free text in the first place — which is Nutty's next question for the schema review.
1. What's the practical difference between how a once-per-feature legal review scales and how a shift-left, tag-enforced pipeline scales, and which GDPR article codifies the alternative? 2. Why does a column-name heuristic for PII classification need a second, independent detection layer for logs and object storage — give one concrete example of data it would miss. 3. Under GDPR, what's the difference between pseudonymization and anonymization, and why does that difference matter for whether a dataset still counts as "personal data"? 4. What does crypto-shredding actually destroy, and why does that make it useful against data replicated across backups nobody can fully enumerate? 5. Name LINDDUN's seven categories in outline and explain how it relates to STRIDE. 6. Why does tying retention, access control, and data residency all to the same classification tag matter more than treating each as a separate policy?
Check your answers
- A once-per-feature legal review is a single late manual gate, structurally identical to the pre-shift-left security review this course already retired — it doesn't scale past a handful of concurrent feature teams and catches design flaws only after the schema is already fixed. GDPR Article 25, "data protection by design and by default," codifies the alternative: build minimization and pseudonymization in from the moment processing is designed, enforced continuously rather than reviewed once.
- A name-based heuristic only flags columns whose name matches a known PII pattern; it can't see PII hiding inside a free-text field (a
notescolumn with a phone number typed into it), a JSONB blob, an application log line, or a one-off CSV export sitting in object storage that was never part of the schema review at all. Detecting those requires inline log analyzers (Presidio-style NER/regex) and periodic object-storage scans (Macie, Cloud DLP), not just a schema-level check. - Pseudonymization (Article 4(5)) replaces an identifier with a token that's reversible via a separately held key — GDPR still treats the result as personal data, because re-identification remains possible. Anonymization is irreversible by design; done correctly, the result falls outside GDPR's scope entirely. The difference matters because it determines whether every other GDPR obligation on this page (DPIA, subject rights, breach notification) still applies to the dataset at all.
- Crypto-shredding destroys the encryption key (the KEK, or a per-tenant/per-subject key) that wraps a piece of data — not the ciphertext itself. Because destroying one key makes every copy of the data it ever protected permanently unreadable everywhere at once, it turns "delete this person's data" into "destroy one key" instead of a manual, error-prone hunt through every backup, replica, and cold-storage copy that might hold a plaintext-recoverable copy a
DELETEstatement can't reach. - Linkability, Identifiability, Non-repudiation, Detectability, Disclosure of information, Unawareness, and Non-compliance. It's the privacy-specific counterpart to STRIDE — the same structured, per-data-flow threat-elicitation exercise, run against the same data flow diagram, just asking privacy-shaped questions instead of security-shaped ones.
- A single tag driving retention, access control, and residency means changing the rule once (e.g., raising the retention window for
restricteddata) updates every system that reads the tag automatically. Three separate policies each independently tracking the same "is this EU data" fact will drift out of sync the first time one gets updated and the others don't — exactly the kind of silent gap a DSPM scan or an auditor eventually finds the hard way.