Skip to content

Commit dc0152a

Browse files
committed
Cleaned up readme
1 parent 9714983 commit dc0152a

1 file changed

Lines changed: 21 additions & 5 deletions

File tree

README.md

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,9 @@ Each PII field gets `#[ITKDev\EntityBundle\Privacy\Attribute\Anonymize(strategy:
355355
than `--older-than` (based on `createdAt`) AND scrubs audit rows older than the configured retention
356356
(`itk_dev_entity.audit.retention`, default `P1Y`, with per-entity overrides). Idempotent.
357357

358-
The mechanism is law-neutral; the same machinery applies to GDPR, CCPA, LGPD, PIPEDA, etc.
358+
The mechanism is regime-neutral and applies to most privacy laws that recognise a right to erasure.
359359

360-
### GDPR semantics of strategies
360+
### Anonymization vs. pseudonymization
361361

362362
Not every strategy produces anonymous data. Pick deliberately:
363363

@@ -366,9 +366,25 @@ Not every strategy produces anonymous data. Pick deliberately:
366366
resulting column is no longer personal data.
367367
- `Pseudonymize` — **pseudonymization.** Output is a deterministic short token derived from the cleartext and
368368
`kernel.secret`, so rows that shared a value still collide post-scrubbing. Use this when you need to preserve
369-
referential equality (e.g. correlating activity across tables) without retaining the cleartext. Under GDPR
370-
Recital 26 the result is **still personal data** — apply the same access controls as you would to the cleartext, and
371-
do not export it as "anonymized."
369+
referential equality (e.g. correlating activity across tables) without retaining the cleartext. Under most privacy
370+
regimes the result is **still personal data** — apply the same access controls as you would to the cleartext, and do
371+
not export it as "anonymized."
372+
373+
### Limitation: free-text fields containing PII
374+
375+
Strategies operate on the **whole value** of an annotated property — they rewrite a column, not substrings inside it.
376+
If a host app stores the subject's name, email, or other identifier inside a free-text column (`notes`, `description`,
377+
`comment`, …), that text is still personal data and is in scope for erasure under most privacy regimes, regardless of
378+
which column it sits in. The bundle does **not** scan free text for embedded subject identifiers, so consumers face a
379+
coarse choice:
380+
381+
- Annotate the whole free-text column with `#[Anonymize(strategy: Strategy::Redact)]` or `Strategy::NullValue` — safe,
382+
but destroys the entire note (over-removal).
383+
- Leave it unannotated — under-removal; document the residual risk and handle it out-of-band (manual review, a
384+
host-app-specific cleanup task, …).
385+
386+
A finer-grained strategy that scans free text for the subject's known identifiers at scrub time and rewrites only those
387+
substrings is not currently shipped — host apps that need it have to implement it themselves.
372388

373389
## Configuration
374390

0 commit comments

Comments
 (0)