Gatekeeper
Decides requests for EU health data in seconds, without exposing a single patient.
October 2026Code
The problem
Every request for health data lands on someone's desk.
The European Health Data Space lets researchers, public bodies and companies reuse health data from across the EU. Each country has an access body that decides every request: someone reads it, checks the purpose against the law, turns “type 2 diabetes” into medical codes, writes the queries and checks every number before it leaves.
Reading the brief, the slowness wasn't what stayed with me. It was how much depends on that one careful person never slipping.
- SlowSomeone reads every request, turns plain words into medical codes and writes the queries by hand. Weeks, sometimes months.
- FragileEvery answer can look safe on its own and still point at one real patient when you put two of them together.
- Easy to misuseInsurers, employers and advertisers are banned outright, and none of them say so in their request.
The solution
Let the AI read. Never let it count.
With one night to build, the easy move was to hand everything to a language model. We did the opposite. The model reads the request and nothing else. Anything that touches patient data is plain code that does the same thing every time and can be tested like any other code.
01Read
A language model reads the request text, and only that, and fills in a typed plan. Three readings run in parallel and vote.
02Decide
The purpose is checked against what the regulation allows and forbids. The answer cites its articles, in English or German.
03Compute
Plain code turns the plan into SQL. Opted-out patients are gone before any query runs; groups under ten are hidden.
04Release
Statistics go out at once. Records wait for a case officer to sign the permit, in a workspace with no download button.
- Request
JSON, English or German
- Decision letter
plain language, citing the EHDS articles it relies on
- AI readings
request text and medical code list
purpose ×3terms ×3 - Majority vote
a split takes the stricter outcome
2 of 3 agree
- Decision ladder
refuse, statistics or records
Art. 53/54 rules - Compiler
typed plan → SQL
same plan, same SQL - Patient database
views without opted-out patients
DuckDB - Statistics
counts, percentages, means
small-cell rule: <10 - Release checks
ledger stops answers being subtracted
privacy firewall - Secure workspace
a database per data permit, locked until staff sign it
no downloadsairlock: groups ≥ 10
- Access-body staff
review queue and audit log: every reading, plan, SQL query and privacy check
sign permitswithdraw grantsreopen refusals
Refusal, statistics 1, record access 2
Request → AI readings → Majority vote → Decision ladder
Three readings of the purpose and three of the terms run in parallel and the majority wins. Fixed rules then make the decision. The AI sees the request text and a list of medical codes, never patient data, and never writes SQL.
Decision ladder → Decision letter
A refusal under Art. 54 (prohibited use) or Art. 53 (no allowed purpose) goes out at once, without waiting for a plan.
- 1
Compiler → Patient database → Statistics → Release checks → Decision letter
Code turns the plan into SQL over views that already leave out opted-out patients. Counts under 10 are hidden, and the ledger withholds any number that, subtracted from an earlier one, would reveal fewer than 10 patients.
- 2
Decision ladder → Secure workspace
Approved record access copies only the selected patients into a database per data permit. It stays locked until staff sign the permit; nothing can be downloaded, and only grouped results of 10 or more leave through the airlock.
Majority vote → Access-body staff
Staff see every reading, plan, query and privacy check, and are alerted to permits to sign, appeals and cases the AI was unsure about.
- request or data
- 1statistics
- 2record access
The trick most tools miss
Two safe answers can still give someone away.
The usual rule hides any group smaller than ten. That sounds airtight until you ask two questions in a row:
Q1Adults with type 2 diabetes in Burgenland
33
Q2The same, aged 40 or older
32
33 − 32 = 1 patient over 40 would be exposed. Both counts pass the small-cell rule, so the rule alone lets this through.
So Gatekeeper keeps a ledger of everything it has ever released, to anyone, and refuses the one answer that would finish the subtraction. It's the part I keep coming back to, because each answer on its own looks completely harmless.
AI reads the request. Code computes the answer.
Vienna, 29–30 October
From the brief to second place in a day and a half.
Four of us at IBM's office in Vienna, a track brief on Thursday afternoon and a pitch on Friday evening. The first working version ran before midnight. Then we spent the night writing requests meant to fool it, fixing whatever they broke, and teaching it German.



What I'd build next
It won a prize. It isn't finished.
- Real sign-in. Right now a switch separates the applicant view from the access body, which is fine for a demo and nothing else.
- The official wording of every article, not my plain-language summaries.
- Catching requests that contradict themselves, so a confused applicant gets a question back instead of a number.