A sum is not anonymization. Whether a number over special-category personal data (Art. 9 GDPR) says something about one person does not depend on its shape but on the population behind it. If fewer than k people stand behind a number, the aggregate is a single-person disclosure in table form.
A worked example with invented numbers
An HR department analyses union membership. The minimum group size is 5.
| Query A | Query B | Difference | |
|---|---|---|---|
| Question | How many in purchasing are organised? | Same question, hired before 2026 | |
| Population | 24 employees | 23 employees | 1 person |
| Result | 6 | 5 | 1 |
Both queries pass the threshold on their own. Their difference says that the one person who joined purchasing in 2026 is a union member. The numbers are synthetic and come from no real system.
Two consequences
First, a rule attached to the query shape ("grouped queries need at least k rows") can be bypassed with a filter that shrinks the population to one person. A rule attached to the counted population cannot. Second, k-anonymity is a minimum condition, not a solution.
How we handle it in Nowl
Nowl is a self-hosted semantic access layer for existing business software. For grouped queries, the check adds a group-size condition to the query plan automatically. For ungrouped queries, the population is counted before execution and the main query is not run if the count is below k. The rejection reveals nothing about the data, not even a substitute like "fewer than 5". k is set per project (2 to 10,000, k=1 is not accepted), and every request including rejections is logged.
What this does not do
- It does not stop differencing across several queries. That needs a query budget per recipient, which is not built.
- It gives no l-diversity guarantee.
- It says nothing about whether every sensitive field was classified in the first place.
Status: in pilot, tested on synthetic data, not yet proven on a live customer dataset.
Eight questions to ask any vendor
Before an AI returns aggregates over sensitive data:
- Who decided which fields are special categories, and is that confirmed by a human?
- Does the row set itself carry the sensitive statement?
- Does the threshold hang on the query shape or on the population?
- Who set k, and can it be set to a value that disables the check?
- Does it count people or joined rows?
- What happens when the check itself fails?
- Does the rejection leak anything?
- Is there bookkeeping across queries, or is that gap named?
The full article in German, with sources (Art. 9 GDPR, Recital 26, WP 216, Sweeney 2002): k-Anonymität: wann ein Aggregat wirklich anonym ist
Top comments (0)