Getting Started
Compliance
KVKK (Türkiye)

KVKK (Türkiye)

Under Türkiye's Personal Data Protection Law no. 6698 (KVKK), Lunixi normally acts as a data processor; your organisation is the data controller. The privacy notice, explicit-consent management, VERBİS registration and the final answer to a data-subject request remain your responsibility.

This page offers no legal interpretation. It describes what the platform actually does today: which fields are encrypted, which are not, how long data is retained, and how an erasure request is executed technically.

⚠️

Pending legal confirmation. The article references and retention periods on this page are derived from configuration values and developer notes in the codebase. The interpretation of the law, the rationale for each period and the final compliance assessment have not been confirmed by legal counsel. Do not use this page as evidence of compliance without verifying it with your own lawyers.

Who does what

TopicData controller (you)Data processor (Lunixi)
Determining the lawful basis✅—
Privacy notice and explicit consent✅—
VERBİS registration✅—
Answering a data-subject request✅Technical support: export and erasure endpoints
Technical and organisational measures✅ (in your environment)✅ (on the platform)
Defining the retention and destruction policy✅Executing the policy technically

Encryption

Field-level encryption

Identity verification data is encrypted per field with AES-256-GCM. Encryption uses authenticated additional data (AAD) in the form tenantId:columnName, so a ciphertext from one tenant cannot be transplanted into another tenant or another column — decryption fails authentication if it is.

Each tenant has its own data encryption key (DEK). DEKs are never stored in the clear: they are wrapped with a key encryption key (KEK) and only the wrapped form is persisted. DEK rotation defaults to 90 days.

The KEK provider is configurable: local key, cloud KMS or HSM. Which one your installation uses is a configuration decision — if you require hardware-backed key management, request it at installation. The default installation uses the local key provider.

Which fields are encrypted — and which are not

To be straightforward: we do not claim "all personal data is encrypted", because it would not be true. The current position:

Encrypted (identity verification customer record):

FieldForm
First name, last nameAES-256-GCM envelope
EmailAES-256-GCM envelope
PhoneAES-256-GCM envelope
Turkish national ID (TCKN)AES-256-GCM envelope
Date of birth (full)AES-256-GCM envelope
Address, company addressAES-256-GCM envelope
Trade registry numberAES-256-GCM envelope
Declared customer profileAES-256-GCM envelope
Identity document imagesAES-256-GCM (binary)

For search and de-duplication we additionally keep blind indexes (peppered hashes) for email, phone, TCKN and registry number. A blind index is not plaintext — the original value cannot be recovered from it; only equality comparison is possible.

Stored in plaintext:

FieldWhyNote
Birth year (year only)Operational filteringThe full date of birth is separately encrypted
Residency country, address countryRouting and rule selection
Company nameRead in invoicing, panel and search pathsFor a sole trader this may be a natural person's name
The organisation's legal name (legal_name)Invoicing, panel, searchPersonal data for a sole trader. Masked in the audit snapshot; the live column is plaintext
Cardholder nameStored-card displayThe card number itself is HSM-encrypted — see PCI DSS
Free-form extra fieldsIntegration flexibilityPersonal data written here is not encrypted — do not put it there
⚠️

legal_name and the cardholder name are plaintext today. This is an open hardening item and it is recorded as such in the code. Both are prevented from reaching logs and error traces (see below), but that is not encryption at rest. We write this down deliberately so you can size your own risk correctly.

Document images and object storage

Identity documents and selfie images are encrypted at the application layer — a per-tenant AES-256-GCM envelope — before they are written to object storage. This is not an option but a boot condition: if server-side encryption is not configured on the storage side, the service refuses to start unless application-layer encryption is enabled. There is no configuration in which an unencrypted document object can be written.

Phone numbers in the wallet

On the wallet side a phone number is never stored in plaintext. Two derivatives are produced at write time:

  • A peppered HMAC-SHA256 — for matching and uniqueness; the raw number cannot be recovered
  • A mask — for display (leading digits + last two)

The pepper comes from environment configuration and has no insecure default: if it is not set, the service fails to start.

Beneficiary IBANs

For bank dispatches the beneficiary IBAN is encrypted with AES-256-GCM, alongside a masked display value and an HMAC fingerprint. If the encryption key is absent the service will not start — there is no fallback to plaintext.

Redaction in logs and error traces

A shared redaction layer runs across the platform and it is actually wired — into the central log pipeline, the error-tracking (Sentry) pipeline, and inter-service error filters.

It works on two axes:

  • Field-name axis — fields whose key contains fragments such as tckn, tcKimlik, nationalId, passport, taxNumber, cardholder, firstName, dateOfBirth are masked
  • Content axis — 13–19 digit runs in free text are validated with the Luhn algorithm, and 11 digit runs with the TCKN check-digit algorithm. Only values that pass validation are masked, so arbitrary order numbers are left intact

Redaction is log hygiene, not encryption at rest. A field being masked in logs does not mean that field is encrypted in the database.

Retention and destruction

This section covers the identity verification (KYC) and identity/device signal side. Retention windows, end-of-window behaviour and legal-hold rules for the other products live on their own pages: fraud prevention and wallet.

Retention is resolved per jurisdiction:

ScopeDefault period
Global default1825 days (5 years)
Türkiye2920 days (8 years)
Biometric images (Türkiye ruleset)90 days

Periods are overridable per installation via environment configuration.

⚠️

Automatic destruction is off by default. Destruction jobs are planned and queued, but actually deleting data must be explicitly enabled per installation. Confirm whether it is enabled in your own installation — if it is not, expired records are not deleted, only flagged as due for destruction.

The destruction engine is saga-based:

  1. Every artifact to be destroyed is written to an immutable manifest before any deletion occurs
  2. Execution proceeds through progress checkpoints — after a crash it resumes where it stopped rather than restarting
  3. On completion a signed destruction certificate is produced (digest + signature + key id) and attached to the destruction record

Biometric images have a separate scheduler with a hard seven-day floor enforced in code — configuration cannot go below it.

Erasure and data-subject requests

The endpoints below are operator endpoints — they require authentication and pass through role-based authorisation.

OperationEndpointRequired permission
Start an erasure requestPOST /kyc/admin/sessions/:sessionId/erasurekyc:document_delete
Data-subject exportGET /kyc/admin/sessions/:sessionId/dsar-exportkyc:view_reports
List erasure requestsGET /kyc/admin/erasure-requestskyc:view_reports
Withdraw consentPOST /kyc/admin/sessions/:sessionId/consent/withdrawkyc:document_delete
⚠️

There is no self-service erasure endpoint for the data subject. You receive the request, assess it in your own process, and apply the outcome through these operator endpoints. Lunixi does not assess the request on your behalf.

The export itself is written to the audit trail — so "whose data, when, exported by whom" is on record.

Proof of erasure

  • On the identity verification side, proof consists of the signed destruction certificate plus a hash-chained audit log: each row's digest is derived from its own content and the previous row's digest, so insertion of a record or re-linking of the chain is detectable.
  • On the identity/device signals side there is additionally an append-only erasure event table; rows cannot be updated or deleted, and this is enforced at database level. That table holds no raw personal data — only pseudonymised selector digests.

Cross-border transfers

Data generated in Türkiye is hosted on our own infrastructure. The storage target and key management are determined by installation configuration, and a region-specific separate installation can be provisioned. For a hosting and transfer statement specific to your installation, request written confirmation from [email protected].

⚠️

If a cross-border transfer is required, establishing the legal ground — an undertaking, binding corporate rules or Board authorisation — is your responsibility as data controller. This page does not make that assessment.

Related pages

  • GDPR — processing model and DPA for EU personal data
  • MASAK — anti-money-laundering obligations in Türkiye
  • PCI DSS — how card data is handled

For the Data Processing Agreement and an installation-specific list of technical measures, email [email protected].