Mert Özen Her Satırda Daha İleri
Güvenlik Veri Gizliliği ve KVKK (geliştirici için) — #07

Yurt Dışına Aktarım ve Veri İhlali Hazırlığı: Cloud Region, LLM Sağlayıcıları, Standart Sözleşme ve 72 Saatlik Bildirim

Mert Özen 15 Kas 2026 11 dk 6 görüntülenme
Yurt Dışına Aktarım ve Veri İhlali Hazırlığı: Cloud Region, LLM Sağlayıcıları, Standart Sözleşme ve 72 Saatlik Bildirim

Yurt dışına aktarım yalnız sunucunun yeri değildir; log, backup, e-posta, analytics ve LLM prompt'ları da aktarımdır ve 2024'ten beri yeterlilik kararı, standart sözleşme gibi uygun güvenceler ya da arızi hâllerden birine dayanmalıdır. Bookstore'da alt işleyen envanterini kodda tutuyor, standart sözleşmenin beş iş günlük bildirimini başlangıçta kontrol ediyor, erişim kaydıyla bir ihlalin kapsamını ve 72 saatlik bildirimin son anını ilk saatte çıkarıyoruz.

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 ve süreler 15 Kasım 2026'da mevzuat.gov.tr, Resmî Gazete ve kvkk.gov.tr'den doğrulanmıştır.

Bu seri bir geliştiricinin bakışıdır, hukuki tavsiye değildir. Hangi aktarımın hangi mekanizmaya dayanacağına, standart sözleşmenin türüne ve bir olayın veri ihlali sayılıp sayılmadığına hukuk danışmanın karar verir; bu yazıdaki tarihler ve sözleşme türleri örnektir.

Önce Tahmin Et

Sitedeki serilerin ortak örnek uygulaması Bookstore'un (bir online kitapçı) toplantısında biri "yurt dışına aktarımımız yok, sunucularımız Türkiye'de" diyor. API'nin appsettings.json'unda ise telemetry, e-posta, analytics ve yeni eklenen kitap önerisi için bir LLM servisinin adresleri duruyor. Kaç tane yurt dışına aktarım var? İkinci soru: cuma gecesi, saat 01.00'i geçerken bir destek hesabının şifresi çalınıyor ve hesap müşteri kayıtlarını dışarı aktarıyor. Olay cumartesi sabahı 09.30'da fark ediliyor. Kurul'a bildirimin son anı ne zaman ve "kimler etkilendi" sorusunu bir saat içinde cevaplayabilir misin?

1 Haziran 2024'ten Sonra Aktarım Rejimi

KVKK'nın (6698 sayılı Kişisel Verilerin Korunması Kanunu) 9. maddesi 7499 sayılı Kanunla baştan yazıldı ve 1 Haziran 2024'te yürürlüğe girdi (01. yazıda değişikliğin tamamını konuştuk). Usul, Kişisel Verilerin Yurt Dışına Aktarılmasına İlişkin Usul ve Esaslar Hakkında Yönetmelik'te; Yönetmelik 10 Temmuz 2024 tarihli ve 32598 sayılı Resmî Gazete'de yayımlandı ve yayımı tarihinde yürürlüğe girdi. Yapı üç basamaklı:

  • Yeterlilik kararı: Kurul bir ülke, ülkedeki bir sektör ya da uluslararası bir kuruluş için yeterli koruma olduğuna karar verebilir; karar Resmî Gazete'de ve Kurum'un sitesinde yayımlanır, en geç dört yılda bir yeniden değerlendirilir (Yönetmelik md. 8, 9).
  • Uygun güvenceler, yeterlilik kararı yoksa ve ilgili kişinin aktarımın yapıldığı ülkede de haklarını kullanabilmesi kaydıyla: kamu kurumları arasında uluslararası sözleşme niteliğinde olmayan anlaşma, bağlayıcı şirket kuralları, standart sözleşme ya da yazılı taahhütname (md. 10). Standart sözleşme dışındakiler Kurul'un izin ya da onayını gerektiriyor.
  • Arızi aktarım, ilk ikisi yoksa: ilgili kişinin riskler hakkında bilgilendirilerek açık rıza vermesi, sözleşmenin ifası gibi sayılı hâller. Yönetmelik arızi olanı düzenli olmayan, tek veya birkaç sefer gerçekleşen, süreklilik arz etmeyen ve olağan faaliyet akışı içinde bulunmayan aktarım olarak tanımlıyor (md. 16).

Geliştiriciyi en çok ilgilendiren cümle tanımda: Yönetmelik md. 4/1-e'ye göre aktarım, verinin yurt dışındaki bir veri sorumlusu ya da veri işleyene iletilmesi ya da başka bir suretle erişilebilir hâle getirilmesi. Yani veri Türkiye'deki bir veritabanında dursa bile, yurt dışındaki bir destek ekibinin o veritabanına uzaktan erişimi de bir aktarım sorusu doğuruyor.

Standart sözleşmeleri Kurul 4 Haziran 2024 tarihli ve 2024/959 sayılı kararla kabul etti ve Kurum 10 Temmuz 2024'te dört türü ilan etti: veri sorumlusundan veri sorumlusuna, veri sorumlusundan veri işleyene, veri işleyenden veri işleyene ve veri işleyenden veri sorumlusuna. Koda dönüşecek kurallar Yönetmelik'in 14. maddesinde: metin değiştirilmeden kullanılır; imzaların tamamlanmasından itibaren beş iş günü içinde fiziki olarak, KEP (kayıtlı elektronik posta) ile ya da Kurul'un belirlediği başka yöntemle Kurum'a bildirilir; taraflar bildirimi kimin yapacağını belirlemediyse veri aktaran yapar; taraflarda ya da içerikte değişiklik ve sözleşmenin sona ermesi de aynı usulle bildirilir. Beş iş günü Kanun'un 9/5 fıkrasında da var ve bildirmemek için ayrı bir idari para cezası bendi eklendi (md. 18/1-d); tutarları Kurum'un sitesinden takip et. GDPR (Avrupa Birliği Genel Veri Koruma Tüzüğü) tarafında karşılığı Art. 46(2)(c)'deki, Komisyon'un kabul ettiği standard data protection clauses; Art. 46(2) bunları denetim makamından ayrıca izin gerektirmeyen güvenceler arasında sayıyor.

Teknik Etki: Veri Nereye Gidiyor

"Sunucu nerede" sorusu, verinin gittiği yerlerin yalnız biri. Bookstore'da bir müşteri kaydının dokunduğu servisler ve her birinin konumu:

07-transfer-map-tr.png

Cloud tarafında region seçimi uygulamanın ve veritabanının yerini belirliyor; ama geo-redundant backup ikinci bir region'a, managed servislerin log'ları sağlayıcının seçtiği yere gidebiliyor. Region ve availability zone kavramlarını Cloud Temelleri serisinin "Cloud Nedir? IaaS, PaaS, SaaS, Serverless, Shared Responsibility, Region ve Availability Zone" yazısında, managed veritabanlarının backup seçeneklerini aynı serinin 08. yazısında anlattık. Telemetry backend'i, e-posta ve SMS (kısa mesaj) sağlayıcısı, CDN (içerik dağıtım ağı) ve WAF (web uygulama güvenlik duvarı) ayrı birer alt işleyen. Analytics ise özel bir durum: veri Bookstore'un sunucusuna hiç uğramadan ziyaretçinin tarayıcısından doğrudan sağlayıcıya gidiyor; 06. yazıdaki rıza bu aktarımı ortadan kaldırmıyor, yalnızca ne zaman başlayacağını belirliyor.

Alt İşleyen Envanteri Kodda

01. yazıda alt işleyenler listesini bu yazıya bırakmıştık. Listeyi bir Excel dosyası yerine kodda tutmanın sebebi 02. yazıdakiyle aynı: kodla birlikte değişsin ve testle doğrulansın.

// Kanun md. 9 ve 2024 aktarım yönetmeliğindeki mekanizmalar.
public enum TransferMechanism { Domestic, AdequacyDecision, StandardContract, BindingCorporateRules, WrittenUndertaking, Occasional }

public sealed record SubProcessor(
    string Key,
    string Role,
    string Location,
    bool Abroad,
    string[] DataCategories,
    TransferMechanism Mechanism,
    string? ContractType = null,
    DateOnly? SignedOn = null,
    DateOnly? NotifiedOn = null);

API başlarken TransferInventoryCheck üç şeye bakıyor: konfigürasyondaki her dış servis envanterde mi; yurt dışındaki her kayıt geçerli bir mekanizmaya dayanıyor mu; standart sözleşme beş iş günü içinde bildirilmiş mi:

case TransferMechanism.StandardContract:
    DateOnly due = BusinessDays.Add(s.SignedOn!.Value, NotificationBusinessDays, holidays.Days);
    if (s.NotifiedOn is not { } notified || notified > due)
    {
        problems.Add($"{s.Key}: standard contract signed {s.SignedOn:yyyy-MM-dd}, notification due {due:yyyy-MM-dd}, notified {s.NotifiedOn?.ToString("yyyy-MM-dd") ?? "never"}");
    }
    break;

Kitap önerisi özelliğini geliştiren ekip appsettings.json'a ExternalServices:Llm:Endpoint ekledi ama envantere dokunmadı. API başlamadı (yol kısaltıldı):

Unhandled exception. System.InvalidOperationException: Transfer inventory: Llm: configured (https://llm.example.net) but not in the sub-processor inventory
   at Program.<Main>$(String[] args) in .../src/Bookstore.Api/Program.cs:line 40

Başlangıçta kırılmak sert görünebilir ama aktarım, koddaki ilk istekle başlıyor; sözleşme ve bildirim ondan önce yapılmalı. Envantere kayıt eklendikten sonra API açıldı. Lab komutu envanterin özetini veriyor:

cd tools/Bookstore.PrivacyLab
dotnet run -- transfers
cloud-hosting     abroad    StandardContract  customer-profile, order-billing, sign-in-session, payment, consent
telemetry         abroad    StandardContract  telemetry
email             abroad    StandardContract  customer-profile
analytics         abroad    StandardContract  analytics-events
llm               abroad    StandardContract  purchase-history-titles
payment-provider  domestic  Domestic          payment
iys               domestic  Domestic          commercial-message

Testler bildirim süresini ve mekanizmayı da kontrol ediyor. 1 Ekim 2026 perşembe imzalanan bir sözleşmenin beş iş günü 8 Ekim'de doluyor; 9 Ekim'de yapılan bildirim test çıktısında sms: standard contract signed 2026-10-01, notification due 2026-10-08, notified 2026-10-09 olarak raporlanıyor. Resmî tatiller 06. yazıdaki gibi konfigürasyondan geliyor. Envanterdeki tarihler örnek; gerçek tarihlerin sahibi hukuk ekibi.

LLM Sağlayıcılarına Giden Prompt'lar

Bir LLM API'sine giden her prompt, içindeki kişisel veriyle birlikte bir aktarım. Bookstore'un öneri özelliği prompt'a yalnız müşterinin satın aldığı kitapların adlarını koyuyor; ad, e-posta ve adres yok. Envanterdeki kategori de bu yüzden purchase-history-titles. Prompt'a ne girdiğini, system prompt ve RAG (dış kaynaktan getirilen bağlamla cevap üretme) context'inden sızan veriyi LLM Uygulama Güvenliği serisinin "Hassas Veri ve Hidden Context İfşası: System Prompt, RAG Context'i ve Sağlayıcıya Giden Veri" yazısında anlattık; 05. yazıdaki canary testi prompt builder'a da uygulanabilir. Sözleşmede bakılacaklar: sağlayıcının prompt'ları ne kadar sakladığı, modeli eğitmek için kullanıp kullanmadığı ve işlemenin hangi region'da yapıldığı.

Burada sık görülen bir kestirme "arada bir istek atıyoruz, arızi aktarım sayılır" demek. Her öneri isteğinde çalışan bir özellik olağan faaliyet akışının parçası; Yönetmelik'in tanımına göre arızi değil. Envanterde Occasional olarak işaretlenen sürekli bir servis testte a running service cannot rely on an occasional transfer hatası veriyor.

Veri İhlali: 72 Saat ve İlgili Kişiler

Kanun md. 12/5, kişisel verilerin kanuni olmayan yollarla başkaları tarafından elde edilmesi hâlinde veri sorumlusunun bunu en kısa sürede ilgilisine ve Kurul'a bildirmesini istiyor. Kurul 24 Ocak 2019 tarihli ve 2019/10 sayılı kararla "en kısa süre"yi 72 saat olarak yorumladı. Kararın koda ve runbook'a dönüşen hükümleri şunlar.

Süre, veri sorumlusunun ihlali öğrendiği andan başlıyor; bildirim gecikmeksizin ve en geç 72 saat içinde Kurul'un Kişisel Veri İhlal Bildirim Formu ile yapılıyor. Haklı bir gerekçeyle geç kalınırsa gecikmenin nedeni de açıklanıyor; bilgilerin hepsi aynı anda yoksa aşamalı veriliyor.

Etkilenen kişiler belirlendikten sonra onlara makul en kısa sürede, iletişim adresi biliniyorsa doğrudan, bilinmiyorsa veri sorumlusunun sitesinde yayımlamak gibi yollarla bildirim yapılıyor.

Veri işleyen, kendi tarafındaki ihlali gecikmeksizin veri sorumlusuna bildiriyor. İhlallerin bilgisi, etkileri ve alınan önlemler kayıt altına alınıyor ve bir veri ihlali müdahale planı hazırlanıp belirli aralıklarla gözden geçiriliyor.

İlgili kişiye yapılacak bildirimin asgari içeriğini Kurul 18 Eylül 2019 tarihli ve 2019/271 sayılı kararla belirledi: açık ve sade bir dille ihlalin ne zaman gerçekleştiği, kişisel veri ve özel nitelikli kişisel veri ayrımı yapılarak hangi verilerin etkilendiği, olası sonuçları, olumsuz etkileri azaltmak için alınan ya da önerilen tedbirler ve bilgi almak için irtibat kişisi ya da iletişim yolları. GDPR'da Art. 33 denetim makamına 72 saat içinde bildirimi istiyor ama ihlalin kişiler için risk oluşturması muhtemel değilse bildirimi gerektirmiyor; Art. 34 ilgili kişilere bildirimi yüksek risk durumuna bağlıyor. KVKK md. 12/5'te böyle bir eşik yazmıyor; hangi olayın bildirilecek bir ihlal olduğu hukuk ekibinin kararı, ama kod her iki durumda da aynı soruları hızlı cevaplayabilmeli.

Hazırlık Kodda: Erişim Kaydı, Etki Sorgusu, Bildirim Taslağı

"Kimler etkilendi" sorusunun cevabı ihlalden sonra yazılamaz; ihlalden önce tutulmuş bir kayıt gerekiyor. Destek, export ve back office endpoint'leri kişisel veriye her erişimde bir satır yazıyor:

// Kim, kimin hangi kategorideki verisini okudu. Destek, export ve back office endpoint'leri yazar.
[DataCategory("access-audit")]
public sealed class PersonalDataAccess
{
    [NoDataClassification]
    public long Id { get; set; }

    [PersonalData(InformationType = "Staff ID")]
    public required string ActorId { get; set; }

    [PersonalData(InformationType = "Customer ID")]
    public int CustomerId { get; set; }

    [NoDataClassification]
    public required string DataCategory { get; set; }

    [NoDataClassification]
    public required string Action { get; set; }

    [NoDataClassification]
    public DateTime AtUtc { get; set; }
}

BreachScope bir hesap ve zaman aralığı için etkilenen müşterileri kategorileriyle çıkarıyor, Kurul'a bildirimin son anını hesaplıyor ve kategorileri 2019/271'in istediği gibi kişisel ve özel nitelikli olarak ayırıyor. Bookstore'un hiçbir kategorisi Kanun md. 6 anlamında özel nitelikli değil, ama ayrım bildirim taslağında açıkça yazılıyor. Lab komutu giriş sorusundaki senaryoyu kuruyor: staff-17 hesabı gece 01.10 ile 01.40 arasında üç müşterinin profilini dışarı aktarıyor, ikisinin fatura bilgisine bakıyor; olay 09.30'da fark ediliyor:

dotnet run -- breach
detected:           2026-11-14 09:30 UTC
notify Authority by 2026-11-17 09:30 UTC
affected customers: 3
  customer 1: customer-profile
  customer 3: customer-profile, order-billing
  customer 4: customer-profile, order-billing
reachable by e-mail: 3

When: between 2026-11-14 01:10 and 2026-11-14 01:40 UTC
Personal data affected: customer-profile, order-billing
Special category data affected: none
Possible consequences: [legal team]
Measures taken and recommended: [security and legal team]
Contact: kvkk@example.com

Giriş sorusunun cevabı: 72 saat hafta sonunu beklemiyor; cumartesi 09.30'da öğrenilen ihlalin son anı salı 09.30. Taslağın açık satırlarını kod dolduramaz; olası sonuçlar ve tedbirler bir değerlendirme gerektiriyor. Kodun işi, o değerlendirmeyi yapacak kişilere ilk saatte doğru listeyi ve süreyi vermek. Erişim kaydı olmasaydı tek dürüst cevap "destek hesabının erişebildiği bütün müşteriler" olurdu.

Üretimde Dikkat

Erişim kaydı, saldırganın da hedefi: destek hesabını ele geçiren kişi kendi izini silmeye çalışabilir. Kaydı uygulamanın yazabildiği ama silemediği ayrı bir depoya yaz (append-only tablo, ayrı yetkili bir log hesabı ya da değiştirilemez storage) ve saatleri UTC (eşgüdümlü evrensel zaman) olarak tut. Kaydın kendisi de kişisel veri; envanterde access-audit olarak duruyor ve saklama süresi var. Olay müdahale sürecinin tamamını (tespit, kapsam, kanıtı korumak, iletişim) Threat Modeling ve Güvenli Geliştirme Süreci serisinde anlatacağız; bu yazının parçası, sürecin ilk saatinde ihtiyaç duyulan sorguların hazır olması. Bildirim formu, müşteriye gidecek metin şablonu ve irtibat bilgisi önceden hazır olmalı ve yılda en az bir kez masa başı tatbikatla denenmeli. Alt işleyen envanteri de ihlal hazırlığının parçası: veri işleyenin ihlali size gecikmeksizin bildirmesi sözleşmede yazmalı ve envanterde hangi sağlayıcının hangi kategoriyi tuttuğu görünmeli.

Sık Düşülen Tuzaklar

En yaygını, "sunucu Türkiye'de" denirken log'un, backup'ın, e-posta servisinin ya da analytics'in yurt dışında olması. İkincisi, geo-redundant backup'ın başka bir ülkedeki region'a kopyalandığını fark etmemek. Üçüncüsü, standart sözleşmeyi imzalayıp beş iş günü içinde bildirmeyi unutmak ya da metninde değişiklik yapmak. Dördüncüsü, sürekli çalışan bir entegrasyonu arızi aktarıma dayandırmak. Beşincisi, erişim kaydı tutmamak ve ihlal anında kapsamı daraltamamak. Altıncısı, 72 saati yanlış andan, ör. inceleme bittiğinde ya da pazartesi mesai başladığında saymaya başlamak.

Bu Yazının Dayandığı Kaynaklar

Erişim tarihi 15 Kasım 2026.

  • 6698 sayılı Kanun md. 9, 12 ve 18: mevzuat.gov.tr/mevzuatmetin/1.5.6698.pdf; Yurt dışına aktarım yönetmeliği: resmigazete.gov.tr/eskiler/2024/07/20240710-2.htm ve mevzuat.gov.tr/MevzuatMetin/yonetmelik/7.5.40863.pdf
  • Kurul 2024/959 ve standart sözleşmeler: kvkk.gov.tr/Icerik/7938; yurt dışına aktarım sayfası: kvkk.gov.tr/Icerik/2053
  • Kurul 2019/10 ve ihlal bildirim formu: kvkk.gov.tr/Icerik/5362; Kurul 2019/271: kvkk.gov.tr/Icerik/5547
  • GDPR Art. 33, 34 ve 46: eur-lex.europa.eu/eli/reg/2016/679/oj

Küçük Bir Deneme

★☆☆ Envanterdeki email kaydının bildirim tarihini imza tarihinden altı iş günü sonraya al ve hem testin hem API başlangıcının hangi mesajla kırıldığını gör. Sonra 29 Ekim'i tatil listesine ekleyip aynı denemeyi o haftaya taşı.

★★☆ Destek ekibinin müşteri görüntüleme endpoint'ine (03. yazıdaki maskeli görünüm) PersonalDataAccess yazan bir filter ekle ve kaydın, isteğin kendisi başarısız olsa bile yazıldığını test et.

★★★ BreachScope'a ikinci bir mod ekle: hesap yerine bir veritabanı backup dosyasının çalındığı senaryo. Backup'ın alındığı andaki müşterileri ve kategorileri 04. yazıdaki erasure ledger'ı da hesaba katarak çıkar; backup'tan sonra silinmiş müşterilerin de etkilenenler listesinde kalması gerektiğini test et.

Seri burada bitiyor. Yedi yazıda KVKK ve GDPR'ın koda dönüşen kısmını Bookstore üzerinde kurduk: kişisel veriyi tanımak ve envanterlemek, alanları sınıflandırıp minimizasyonu testle korumak, hassas alanları uygulama seviyesinde şifrelemek, saklama süresi dolanı silmek ve anonimleştirmek, log ve telemetry'ye sızdırmamak, rızayı ispat edilebilir biçimde almak ve verinin nereye gittiğini bilip bir ihlalde ilk saatte doğru soruları cevaplayabilmek. Hepsinin ortak noktası, hukuk ekibinin kararlarının kodda bir yerde yazılı ve bir testle korunuyor olması.