All projects

KVKK Compliance Engine

Compliance shown by a program that can fail, not by a document.

  • TypeScript
  • Express
  • node:sqlite
  • Node crypto (AES)

Problem

Most systems that claim GDPR/KVKK compliance demonstrate it with a policy document. A document describes what someone intended, not what the code does — and the two drift apart.

For an HR system holding personal data the real questions are: when an erasure request arrives, is the data actually gone; when a retention period expires, does the record actually go; and can an unauthorised role actually not see unmasked data?

Solution

Compliance is written as an executable check. Field-level encryption (AES via a keyring), role-based access, PII masking and the retention job are each tested separately, and every access is written to an audit record.

Erasure works by destroying the key, not by blanking the row: the ciphertext may remain but can no longer be opened. A copy restored from backup stays unreadable too — precisely the case that row-deletion does not solve.

Outcome

188 tests. The compliance claim is written to a report file: if the run fails, the system says itself that it is not compliant.

One stack decision was deliberate: SQLite rather than PostgreSQL. The reasoning is in ADR-008 — the point of the project is that someone can clone it and run the compliance check on their own machine, and putting a database server between git clone and a green test run works against that.

Keys are managed through a keyring: the master key is supplied to the application from outside and per-record keys are wrapped with it. Erasure destroys the per-record key.

There is a rule about test data, and the reason is a real incident: an earlier version of the fixture file carried the author's own mobile number, put there while writing the test and invisible afterwards because a phone number in a fixture looks exactly like a phone number in a fixture. A pre-publication scan caught it. Every fixture value is now deliberately unusable: the name is historical, the national ID sequential, the phone in the 555 range no Turkish operator issues.

Source code

Comments are shown in the page language. Files in the repository carry both English and Turkish.

Project structure

README.md

103 lines · 9 KB

Loading…