Geliştirici için KVKK ve GDPR: Kişisel Veri, Özel Nitelikli Veri, Veri Sorumlusu/Veri İşleyen ve Kodu Etkileyen İlkeler
Kişisel veri, başka bir kayıtla kişiye bağlanabilen her bilgidir; bu yüzden hash'lenmiş e-posta, IP adresi ve cihaz kimliği de kişisel veridir. 6698 sayılı Kanun ve GDPR'ın tanımlarını, veri sorumlusu ile veri işleyen ayrımını, ilgili kişi haklarının endpoint karşılıklarını, 7499 ile 2024'te değişenleri ve KVKK–GDPR farklarını Bookstore üzerinde, çalıştırılmış kod ve birincil kaynaklarla anlatıyoruz; hukuki tavsiye değildir.
Sürüm notu: Bu yazıdaki kodlar .NET 10, ASP.NET Core 10, Entity Framework Core 10.0.15 (SQLite) ve xUnit 2.9 ile derlenip denenmiştir. Hukuki tarih, süre ve madde numaraları 15 Kasım 2026'da mevzuat.gov.tr, kvkk.gov.tr ve Resmî Gazete'den doğrulanmıştır.
Bu seri bir geliştiricinin bakışıdır, hukuki tavsiye değildir. Kanunu nasıl uygulayacağına, hangi verinin hangi hukuki sebebe dayandığına ve saklama sürelerine hukuk danışmanın karar verir; burada anlatılan, o kararların kodda neye dönüştüğüdür.
Önce Tahmin Et
Bookstore'un pazarlama ekibi, müşteri e-postalarını bir reklam platformuna yüklemek istiyor ama "kişisel veri göndermeyelim" diyor; çözüm olarak her adresin SHA (standart bir hash fonksiyonu ailesi) ailesinden SHA-256 özetini gönderiyorlar. Sence gönderilen dosya anonim veri mi, yoksa hâlâ kişisel veri mi? İkinci soru: müşterinin "verilerimi görmek istiyorum" talebine verdiğin cevapta oturum açtığı IP adresi ve cihaz kimliği de olmalı mı? Cevapları kodla birlikte aşağıda bulacaksın.
Kişisel Veri Nedir, Ne Değildir
Bu yazıda KVKK (6698 sayılı Kişisel Verilerin Korunması Kanunu) ile GDPR'ı (General Data Protection Regulation; Avrupa Birliği'nin 2016/679 sayılı Genel Veri Koruma Tüzüğü) yan yana okuyoruz. Kanun 7 Nisan 2016 tarihli ve 29677 sayılı Resmî Gazete'de yayımlandı; GDPR 25 Mayıs 2018'den beri uygulanıyor (Art. 99). Kanunun 3. maddesine göre kişisel veri, kimliği belirli veya belirlenebilir gerçek kişiye ilişkin her türlü bilgidir. Kritik kelime "belirlenebilir". Ad soyad ve e-posta açıkça kişisel veri; ama tek başına bir isim taşımayan müşteri numarası, sipariş geçmişi, teslimat adresi ya da bir cihaz kimliği de başka bir kayıtla birleştirilip kişiye ulaştırılabiliyorsa kişisel veridir. GDPR aynı tanımı Art. 4(1)'de veriyor ve "online identifier"ı açıkça sayıyor; Recital 30, IP adreslerini ve cookie identifier'ları kişiyi tanımlamaya yarayabilecek iz olarak anıyor. KVKK metni IP adresini ayrıca saymıyor; geliştirici olarak güvenli varsayım, IP adresini ve cihaz kimliğini kişisel veri olarak ele almak.
Özel nitelikli kişisel veri (GDPR'daki karşılığı special categories of personal data) ayrı bir sınıf. Kanunun 6. maddesi ırk, etnik köken, siyasi düşünce, felsefi inanç, din, mezhep, kılık ve kıyafet, dernek, vakıf ya da sendika üyeliği, sağlık, cinsel hayat, ceza mahkûmiyeti ve güvenlik tedbirleri ile biyometrik ve genetik verileri sayıyor. Bir kitapçı bunların hiçbirine ihtiyaç duymaz ve bu iyi bir şey: Bookstore'un tasarım kuralı, özel nitelikli veriyi hiç toplamamak. Dikkat edilmesi gereken nokta, T.C. kimlik numarasının bu listede olmaması; hassas ve korunması gereken bir veri ama Kanun anlamında özel nitelikli değil. Bu ayrım 03. yazıda şifreleme kararını verirken işimize yarayacak.
Anonim hâle getirme ise Kanunda şöyle tanımlanıyor: verinin, başka verilerle eşleştirilerek dahi hiçbir surette kimliği belirli veya belirlenebilir bir kişiyle ilişkilendirilemeyecek hâle getirilmesi (md. 3/1-b). Çıta yüksek. "Başka verilerle eşleştirilerek dahi" ifadesi, hash'lenmiş bir e-postanın neden anonim olmadığını açıklıyor. Kendi müşteri listesini elinde tutan biri için bunu denemek bir satır kod:
// "Anonim" analytics export'u: e-posta yerine e-postanın SHA-256 özeti.
string[] customerEmails = [.. FakePeople.All.Select((_, i) => FakePeople.ToCustomer(i, DateTime.UtcNow).Email)];
string[] exportedHashes = [Sha256Hex("grace.demoray@example.com"), Sha256Hex("linus.fakely@example.com")];
// Müşteri listesine sahip olan herkes satırları tek bir dictionary ile geri eşleştirir.
Dictionary<string, string> lookup = customerEmails.ToDictionary(Sha256Hex, e => e);
foreach (string hash in exportedHashes)
{
Console.WriteLine($"{hash[..16]}... -> {lookup.GetValueOrDefault(hash, "(unknown)")}");
}
// 11 haneli bir kimlik numarasının en fazla 900.000.000 geçerli değeri var (9 serbest hane + 2 kontrol hanesi).
const int sample = 2_000_000;
var sw = Stopwatch.StartNew();
for (int i = 0; i < sample; i++)
{
SHA256.HashData(Encoding.ASCII.GetBytes((100_000_000 + i).ToString(CultureInfo.InvariantCulture)));
}
sw.Stop();
double perSecond = sample / sw.Elapsed.TotalSeconds;
double minutes = 900_000_000 / perSecond / 60;
Console.WriteLine(string.Create(CultureInfo.InvariantCulture,
$"single core: {perSecond:N0} SHA-256/s, whole ID space: ~{minutes:N0} min"));
dotnet run --project tools/Bookstore.PrivacyLab -- hash-link
693cee2edc8c0bd0... -> grace.demoray@example.com
68203c30f2ed3faa... -> linus.fakely@example.com
single core: 5,408,153 SHA-256/s, whole ID space: ~3 min
Örnekteki kişiler uydurma, adresler example.com alan adında. İlk iki satır, elinde müşteri listesi olan birinin hash'ten kişiye nasıl döndüğünü gösteriyor. Üçüncü satır daha rahatsız edici: listen olmasa bile değer uzayı küçükse tamamını denemek mümkün. Kimlik numarası gibi 11 haneli bir değerin bütün olası değerlerini tek bir CPU çekirdeği birkaç dakikada hash'liyor. Hash, veriyi gizlemez; en fazla pseudonymization (takma adlandırma) sağlar. GDPR bu farkı açıkça koyuyor: Art. 4(5) pseudonymization'ı ek bilgi olmadan kişiye bağlanamayan işleme olarak tanımlıyor, Recital 26 da pseudonymization'dan geçmiş verinin hâlâ kişisel veri olduğunu söylüyor. KVKK'nın 3. maddesinde pseudonymization için ayrı bir tanım yok; bu yüzden pratikte tek soru, verinin anonim hâle getirme tanımını karşılayıp karşılamadığı. Hash'lenmiş e-posta karşılamıyor.
Veri Sorumlusu ve Veri İşleyen
Kanunun iki rolü kodu doğrudan etkiliyor. Veri sorumlusu (GDPR'daki karşılığı controller), kişisel verinin işleme amaçlarını ve vasıtalarını belirleyen ve veri kayıt sisteminin kurulmasından ve yönetilmesinden sorumlu kişidir. Veri işleyen (GDPR'daki karşılığı processor) ise veri sorumlusunun verdiği yetkiye dayanarak onun adına veri işleyen kişidir (md. 3/1-ğ ve 3/1-ı). İlgili kişi (GDPR'daki karşılığı data subject) verisi işlenen gerçek kişinin kendisi.
Sitedeki serilerin ortak örnek uygulaması Bookstore'u (bir online kitapçı) bu gözle okuyalım. Bireysel müşterinin hesabı, siparişi ve teslimat adresi için Bookstore veri sorumlusu: neyi, neden ve ne kadar süre tutacağına o karar veriyor. Siparişi teslim eden kargo şirketi ya da uygulamanın çalıştığı cloud sağlayıcısı, Bookstore adına iş yaptıkları ölçüde tipik veri işleyen adayları. Ödeme kuruluşu ise daha karmaşık bir örnek: Bookstore adına ödemeyi tahsil ediyor ama kendi mevzuatından gelen yükümlülükleri için aynı veriyi kendi amacıyla da işleyebilir. Rolü sözleşme ve fiili işleyiş belirler; bu kararı kod değil hukuk ekibi verir. Geliştirici için önemli olan sonuç şu: her dış servis entegrasyonu, envantere yazılması gereken bir veri aktarımıdır. Kanunun 12/2. maddesi, veri işleyen adına işlenen veride güvenlik tedbirlerinden veri sorumlusunu onunla birlikte müştereken sorumlu tutuyor.
Kurumsal Sipariş tarafında bir okul kendi personelini kullanıcı olarak eklediğinde, bu personelin verisi için okul mu veri sorumlusu, Bookstore mu? Bu soru da aşağıdaki listeye giriyor.
Genel İlkeler ve İşleme Şartları Kodda Neye Dönüşür
Kanunun 4. maddesi beş ilke sayıyor: hukuka ve dürüstlük kurallarına uygunluk; doğru ve gerektiğinde güncel olma; belirli, açık ve meşru amaçlar için işleme; amaçla bağlantılı, sınırlı ve ölçülü olma; ilgili mevzuatta öngörülen veya amaç için gerekli süre kadar muhafaza. GDPR'ın Art. 5(1)'i bunlara çok benzeyen altı ilke ve Art. 5(2)'de accountability (hesap verebilirlik; uyumu gösterebilme yükümlülüğü) içeriyor. 5. madde ise işleme şartlarını veriyor: kural açık rıza (GDPR'daki karşılığı consent), ama sözleşmenin kurulması veya ifası, hukuki yükümlülük, meşru menfaat gibi şartlardan biri varsa açık rıza aranmıyor. Bu şartlardan hangisinin hangi alana dayanak olduğunu hukuk ekibi belirler; senin işin, bu kararı kodda görünür ve test edilebilir kılmak.
| İlke (KVKK md. 4 / GDPR Art. 5) | Kodda karşılığı | Bu seride |
|---|---|---|
| Belirli ve meşru amaç / purpose limitation | Her alanın bir amaç etiketi; amaç dışı sorgu yok | 02 |
| Sınırlı ve ölçülü olma / data minimisation | Gereksiz alanı modele hiç almamak, doğum tarihi yerine yaş onayı | 02 |
| Doğru ve güncel olma / accuracy | Düzeltme endpoint'i, doğrulama | 01 |
| Gerekli süre kadar muhafaza / storage limitation | Retention alanları ve periyodik imha job'ı | 04 |
| Veri güvenliği (KVKK md. 12) / integrity and confidentiality | Şifreleme, maskeleme, erişim kısıtı | 03 |
| Hesap verebilirlik (GDPR Art. 5(2)) | Envanter, imha kaydı, audit log | 02 ve 04 |
İlgili Kişinin Hakları: Endpoint'ler ve Job'lar
Kanunun 11. maddesi ilgili kişiye bir hak listesi veriyor: verisinin işlenip işlenmediğini öğrenme, işlenmişse bilgi talep etme, amacını öğrenme, verinin aktarıldığı üçüncü kişileri bilme, eksik veya yanlış verinin düzeltilmesini isteme, 7. madde şartlarında silinmesini veya yok edilmesini isteme, bu işlemlerin aktarılan üçüncü kişilere bildirilmesini isteme, münhasıran otomatik analizle aleyhine çıkan sonuca itiraz etme ve zararın giderilmesini talep etme. 13. madde de cevabın en geç otuz gün içinde verilmesini istiyor; GDPR'da bu süre bir ay, gerekirse iki ay uzatılabiliyor (Art. 12(3)).
Bu listenin her maddesi ya bir endpoint, ya bir job, ya da envanterde bir satır demek. Bookstore API'sinin ilk hâli üç endpoint ile başlıyor:
RouteGroupBuilder me = app.MapGroup("/api/me").RequireAuthorization();
// KVKK md. 11/1-b, GDPR Art. 15: erişim hakkı
me.MapGet("/personal-data", async (ClaimsPrincipal user, DataSubjectRequests requests, CancellationToken ct) =>
await requests.ExportAsync(CustomerId(user), ct) is { } export ? Results.Ok(export) : Results.NotFound());
// KVKK md. 11/1-d, GDPR Art. 16: düzeltme hakkı
me.MapPatch("/profile", async (ProfileCorrection change, ClaimsPrincipal user, DataSubjectRequests requests, CancellationToken ct) =>
await requests.CorrectAsync(CustomerId(user), change, ct) ? Results.NoContent() : Results.NotFound());
// KVKK md. 7 ve 11/1-e, GDPR Art. 17: silme senkron bir DELETE değil, takip edilen bir taleptir
me.MapPost("/erasure-requests", async (ClaimsPrincipal user, DataSubjectRequests requests, CancellationToken ct) =>
{
ErasureRequest request = await requests.RequestErasureAsync(CustomerId(user), ct);
return Results.Accepted($"/api/me/erasure-requests/{request.Id}", new { request.Id, request.DueAtUtc });
});
Kimlik doğrulama bu yazının konusu değil. Örnek, yalnız Development ortamında çalışan ve müşteri numarasını bir header'dan okuyan bir demo handler kullanıyor; gerçek giriş akışını ve hesap silmenin Identity tarafını Authentication ve Authorization serisinin "ASP.NET Core Identity ile Hesap Yaşam Döngüsü: Kayıt, E-posta Onayı, Parola Sıfırlama, External Login ve Hesap Silme" yazısında anlattık. Erişim talebinin cevabı, kişinin profil verisiyle sınırlı kalmamalı:
curl -s -H "X-Demo-Customer-Id: 3" http://127.0.0.1:52801/api/me/personal-data
{
"profile": {
"fullName": "Grace Demoray",
"email": "grace.demoray@example.com",
"phone": "+90 000 000 00 03",
"birthDate": "1992-03-10",
"city": "Istanbul"
},
"orders": [
{
"orderId": 3,
"orderedAtUtc": "2026-03-13T09:00:00",
"total": 412.5,
"shippingAddress": "Example St. 3, Istanbul"
}
],
"sessions": [
{
"signedInAtUtc": "2026-03-13T08:55:00",
"ipAddress": "127.0.0.1",
"deviceId": "device-0003",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}
],
"exportedAtUtc": "2026-11-15T06:05:51.065062Z"
}
sessions bölümü, giriş sorusunun ikinci yarısının cevabı. Oturum tablosundaki IP adresi ve cihaz kimliği kişiye bağlı tutulan veri; export'a girmiyorsa ya kişisel veri saymadığın ya da var olduğunu unuttuğun bir tablo var demektir. Bunu bir test ile sabitledik:
[Fact]
public async Task Export_includes_ip_address_and_device_id()
{
using var testDb = new TestDb();
int id;
using (BookstoreContext db = testDb.CreateContext())
{
Customer c = FakePeople.ToCustomer(0, Now);
c.Sessions.Add(new CustomerSession { SignedInAtUtc = Now, IpAddress = "127.0.0.1", DeviceId = "device-0001", UserAgent = "test" });
db.Customers.Add(c);
await db.SaveChangesAsync();
id = c.Id;
}
using BookstoreContext read = testDb.CreateContext();
PersonalDataExport? export = await new DataSubjectRequests(read, new FixedClock(Now)).ExportAsync(id);
SessionExport session = Assert.Single(export!.Sessions);
Assert.Equal("127.0.0.1", session.IpAddress);
Assert.Equal("device-0001", session.DeviceId);
}
Silme talebi ise bilerek senkron değil. Kanun 7. maddede silme, yok etme ve anonim hâle getirmenin "işlenmesini gerektiren sebeplerin ortadan kalkması hâlinde" yapılacağını söylüyor; sipariş ve fatura kayıtlarında vergi ve ticaret mevzuatından gelen saklama yükümlülükleri sürüyor olabilir. Bu yüzden talep bir kayıt olarak açılıyor ve son tarihi 30 günlük cevap süresinden hesaplanıyor:
// KVKK md. 13/2: talepler en geç 30 gün içinde sonuçlandırılır.
public static readonly TimeSpan ResponseDeadline = TimeSpan.FromDays(30);
public async Task<ErasureRequest> RequestErasureAsync(int customerId, CancellationToken ct = default)
{
DateTime now = clock.GetUtcNow().UtcDateTime;
var request = new ErasureRequest
{
CustomerId = customerId,
RequestedAtUtc = now,
DueAtUtc = now + ResponseDeadline,
};
db.ErasureRequests.Add(request);
await db.SaveChangesAsync(ct);
return request;
}
curl -s -i -X POST -H "X-Demo-Customer-Id: 3" http://127.0.0.1:52801/api/me/erasure-requests
HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
Location: /api/me/erasure-requests/1
Transfer-Encoding: chunked
{"id":1,"dueAtUtc":"2026-12-15T06:05:51.083069Z"}
Talebi neyin silineceğine, neyin anonimleştirileceğine ve neyin yasal süre bitene kadar kısıtlı erişimle saklanacağına göre işleyen job 04. yazının konusu. Bugünden alınacak ders: "hesabımı sil" bir buton değil, son tarihi olan bir iş akışı. Aktarılan üçüncü kişileri bilme hakkı ve düzeltmenin onlara bildirilmesi için de aktarımların kaydı gerekiyor; alt işleyenler listesini 07. yazıda kuracağız.
KVKK ile GDPR Yan Yana
Bookstore Avrupa Birliği'nde yerleşik kişilere de satış yapıyorsa GDPR da gündeme gelebilir; bunun değerlendirmesi de hukuk ekibinde. Kod açısından fark eden noktaları tek tabloda topladım. İdari para cezası tutarlarını bilerek yazmıyorum: KVKK'nın 18. maddesi tutarları sayıyor, güncel değerleri Kurum'un sitesinden okumak gerekir.
| Konu | KVKK (6698) | GDPR (2016/679) |
|---|---|---|
| Özel nitelikli veri | md. 6; kılık kıyafet, dernek/vakıf üyeliği, ceza mahkûmiyeti de listede | Art. 9; mahkûmiyet verisi ayrı maddede (Art. 10) |
| Pseudonymization | Kanunda tanımı yok | Art. 4(5) tanımlı, Art. 25'te örnek tedbir |
| İlgili kişi talebine cevap | En geç 30 gün (md. 13/2) | Bir ay, gerekirse iki ay uzatma (Art. 12(3)) |
| Veri ihlali bildirimi | md. 12/5 "en kısa sürede"; Kurul 24.01.2019 tarih ve 2019/10 sayılı kararla 72 saat | Mümkünse 72 saat içinde (Art. 33(1)) |
| Kayıt yükümlülüğü | Veri Sorumluları Sicili (md. 16), VERBİS (Veri Sorumluları Sicil Bilgi Sistemi) üzerinden; istisnalar Kurul kararıyla | Records of processing activities (Art. 30) |
| Sorumlu kişi | Sicil yönetmeliğindeki irtibat kişisi | Belirli şartlarda DPO (veri koruma görevlisi) zorunlu (Art. 37) |
| Yurt dışına aktarım | md. 9 (7499 ile değişik): yeterlilik kararı, uygun güvenceler, arızi haller | Chapter V (Art. 44–49) |
| İdari para cezası | md. 18; güncel tutarlar kvkk.gov.tr'de | 10 milyon € veya %2 ya da 20 milyon € veya %4, hangisi yüksekse (Art. 83) |
DPO'nun KVKK'da birebir karşılığı yok; Veri Sorumluları Sicili Hakkında Yönetmelik (30 Aralık 2017 tarihli ve 30286 sayılı Resmî Gazete) sicil kaydında bir irtibat kişisi belirlenmesini istiyor. VERBİS kaydının kimin için zorunlu olduğu ve idari süreci bu serinin konusu değil; Kurum'un VERBİS sayfası tek doğru kaynak.
7499 sayılı Kanunla 2024'te neler değişti
7499 sayılı Kanun 12 Mart 2024 tarihli ve 32487 sayılı Resmî Gazete'de yayımlandı ve 6698'in 6., 9. ve 18. maddelerini 1 Haziran 2024'ten itibaren değiştirdi. 6. maddenin ikinci fıkrası yürürlükten kaldırıldı, üçüncü fıkrası yeniden yazıldı: özel nitelikli verinin işlenmesi kural olarak yasak, istisnalar artık tek bir listede (açık rıza, kanunlarda açıkça öngörülme, bir hakkın tesisi ve korunması, sağlık hizmetleri, istihdam ve sosyal güvenlik yükümlülükleri gibi; md. 6/3). Yurt dışına aktarım maddesi baştan yazıldı: yeterlilik kararı, yoksa standart sözleşme gibi uygun güvenceler, o da yoksa arızi haller. Standart sözleşmenin imzalanmasından itibaren beş iş günü içinde Kurum'a bildirilmesi şartı geldi (md. 9/5) ve bu bildirimi yapmamak için yeni bir idari para cezası bendi eklendi (md. 18/1-d). Kurul'un idari para cezalarına karşı dava yolu idare mahkemesi olarak belirlendi (md. 18/3); 1 Haziran 2024 itibarıyla sulh ceza hâkimliklerinde görülmekte olan başvurular orada sürüyor (geçici md. 3/2). Geçici 3. madde, eski 9. maddenin ilk fıkrasının 1 Eylül 2024'e kadar yeni hâliyle birlikte uygulanmasına izin verdi. Aktarım rejiminin teknik etkisini 07. yazıda konuşacağız.
Hukuk Ekibine Sorulacak Sorular
Kodu yazmadan önce cevabını hukuk ekibinden alman gereken sorular, geliştiricinin bakış açısından:
- Bu alan hangi amaç için ve hangi işleme şartına (md. 5 veya 6) dayanarak toplanıyor; açık rıza gerekiyor mu?
- Her veri kategorisi için saklama süresi nedir ve süre hangi olaydan itibaren başlar (sipariş tarihi, hesabın kapanması, son giriş)?
- Kargo, ödeme, e-posta ve cloud sağlayıcılarımızın rolü nedir (veri işleyen mi, ayrı veri sorumlusu mu) ve verinin yurt dışına çıktığı bir akış var mı?
- Kurumsal müşteri kullanıcılarının verisinde veri sorumlusu kim?
- Silme talebinde hangi kayıtlar yasal yükümlülük nedeniyle saklanmaya devam edecek, kimler erişebilecek?
- Bir veri ihlalinde 72 saatlik bildirim için kim karar verir ve teknik ekipten hangi bilgiyi hangi sürede ister?
Üretimde Dikkat
Erişim talebine verilen export, tek bir veritabanı sorgusuyla bitmiyor. Destek sistemindeki biletler, e-posta servisindeki gönderim geçmişi, analytics'teki kullanıcı kimliği de aynı kişiye ait. Hepsini otomatik toplayamasan bile hangi sistemlerin elle kontrol edileceğini bilmen gerekir; bu listenin adı veri envanteri ve bir sonraki yazının konusu. İkinci nokta, talebin kimden geldiğini doğrulamak: export endpoint'i kimliği doğrulanmamış bir isteğe başka birinin verisini döndürüyorsa, hakkı kullandırırken bir veri ihlali üretmiş olursun. Örnekteki 401 cevabı bu yüzden önemli. Üçüncüsü sürelerin takibi: DueAtUtc alanı bir dashboard'da ya da alert'te görünmüyorsa yalnızca bir sütundur.
Log'lar da bu resmin parçası. Erişim talebini işlerken export'un içeriğini log'a yazmak, kişisel veriyi bir kopyasıyla daha çoğaltmak demek. Log'da kişisel veriyi sınıflandırıp otomatik maskelemenin mekaniğini .NET'te Logging serisinin "Log'larda Hassas Veri: Redaction, Data Classification ve KVKK'ya Uygun Logging" yazısında gösterdik.
Sık Düşülen Tuzaklar
En yaygın tuzak, e-posta ya da telefon hash'ini anonim veri sanmak. Yukarıdaki çıktı, müşteri listesine sahip herkesin hash'i geri eşleştirebildiğini ve küçük değer uzaylarının dakikalar içinde tamamen denenebildiğini gösteriyor. Hash, salt ya da HMAC (anahtarlı hash) ile güçlendirilse bile anahtarı tutan için geri dönüştürülebilir; bu pseudonymization'dır ve veri kişisel veri olmaya devam eder.
İkinci tuzak, IP adresini, cihaz kimliğini ya da cookie değerlerini "teknik veri" diye kişisel verinin dışında saymak. Bu değerler oturum tablosunda bir müşteri numarasının yanında duruyorsa kişiye bağlıdır; erişim talebinde dönmeli, silme talebinde silinmeli, log ve analytics'te sınırlanmalı. Üçüncüsü, T.C. kimlik numarasını özel nitelikli veri sanmak ya da tersine sıradan bir alan gibi davranmak. Kanunun 6. maddesindeki listede yok, ama kimlik hırsızlığına en açık alanlardan biri; 03. yazıda şifreleyeceğiz. Dördüncüsü, bir tabloya "anonymized" adını Kanunun sorusunu sormadan vermek: başka verilerle eşleştirilerek dahi kişiye ulaşılabiliyor mu?
Bu Yazının Dayandığı Kaynaklar
Hukuki ifadelerin hepsi aşağıdaki birincil kaynaklara dayanıyor; erişim tarihi 15 Kasım 2026.
- 6698 sayılı Kişisel Verilerin Korunması Kanunu, güncel metin (md. 3, 4, 5, 6, 7, 11, 12, 13, 16, 18, geçici md. 3):
mevzuat.gov.tr/mevzuatmetin/1.5.6698.pdf - 7499 sayılı Kanun, 12 Mart 2024 tarihli ve 32487 sayılı Resmî Gazete:
resmigazete.gov.tr/eskiler/2024/03/20240312-1.htm - Kurul'un 24.01.2019 tarih ve 2019/10 sayılı kararı (veri ihlali bildirimi, 72 saat):
kvkk.gov.tr/Icerik/5362/Veri-Ihlali-Bildirimi - Veri Sorumluları Sicili Hakkında Yönetmelik, 30 Aralık 2017 tarihli ve 30286 sayılı Resmî Gazete:
kvkk.gov.tr/Icerik/5442/VERI-SORUMLULARI-SICILI-HAKKINDA-YONETMELIK - GDPR, Regulation (EU) 2016/679 (Art. 4, 5, 9, 12, 17, 25, 33, 37, 83, 99; Recital 26 ve 30):
eur-lex.europa.eu/eli/reg/2016/679/oj
Küçük Bir Deneme
★☆☆ hash-link komutunu kendi makinende çalıştır ve tek çekirdekte saniyede kaç hash hesaplandığına bak. Aynı hesabı 10 haneli bir telefon numarası uzayı için yap: hash'lenmiş telefon numarası listesi ne kadar sürede geri çözülür?
★★☆ DataSubjectRequests'e kişinin hangi üçüncü taraflarla paylaşıldığını döndüren bir GET /api/me/recipients endpoint'i ekle (md. 11/1-ç). Veriyi nereden okuyacağını düşün: kod içine gömülü bir liste mi, envanter mi?
★★★ Kimliği doğrulanmamış ya da başka bir müşterinin numarasıyla gelen isteğin export'a ulaşamadığını gösteren bir integration test yaz. Header'ı gönderilmemiş istek için 401 bekle; demo handler'ın production'da hiç kaydedilmediğini de test et.
Bir sonraki yazıda bu dağınık bilgiyi tek yerde topluyoruz: Bookstore'un kişisel veri envanterini kodun içinden çıkarıyor, alanları Microsoft.Extensions.Compliance attribute'larıyla sınıflandırıyor ve "ileride lazım olur" diye eklenen alanı derleme sonrası testte yakalıyoruz.