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

Aydınlatma, Açık Rıza ve Çerezler: Consent Kaydı, Çerez Banner'ı, Consent Mode ve Ticari İleti İzinleri (İYS)

Mert Özen 15 Kas 2026 13 dk 6 görüntülenme
Aydınlatma, Açık Rıza ve Çerezler: Consent Kaydı, Çerez Banner'ı, Consent Mode ve Ticari İleti İzinleri (İYS)

Aydınlatma her veri işlemede yapılır, açık rıza ise yalnız rızaya dayanan işlemede ve ayrıca alınır; rıza da ispat edilebilir, sürümlü ve geri alınabilir olmalıdır. Bookstore'da append-only ConsentRecord'u, Kurum'un çerez rehberine göre eşit butonlu bir Angular banner'ını, varsayılanı denied olan Google Consent Mode'u, bunları doğrulayan Playwright testlerini ve ticari e-posta izinlerinin üç iş günü içinde İYS'ye bildirilmesini kuruyoruz.

Sürüm notu: Bu yazıdaki kodlar .NET 10, ASP.NET Core 10, Entity Framework Core 10.0.15 (SQLite), xUnit 2.9, Angular 22.2 (TypeScript 6.0) ve Playwright 1.65 ile derlenip denenmiştir. Hukuki ifadeler 15 Kasım 2026'da kvkk.gov.tr, mevzuat.gov.tr ve iys.org.tr'den, Google Consent Mode developers.google.com'dan doğrulanmıştır.

Bu seri bir geliştiricinin bakışıdır, hukuki tavsiye değildir. Hangi çerezin açık rızaya tabi olduğuna, aydınlatma metnine ve ticari ileti izninin nasıl alınacağına hukuk danışmanın karar verir; burada anlatılan, o kararların kodda neye dönüştüğüdür.

Önce Tahmin Et

Sitedeki serilerin ortak örnek uygulaması Bookstore'un (bir online kitapçı) ilk çerez banner'ı şöyleydi: sayfanın altında "Siteyi kullanmaya devam ederek çerezleri kabul etmiş olursunuz" yazısı ve tek bir "Tamam" butonu; analytics script'i index.html'de, sayfayla birlikte yükleniyor. Kurum'un çerez rehberine göre bu tasarım kaç noktada sorunlu? Cevabı yazının sonunda Playwright testleri veriyor.

Aydınlatma Başka, Açık Rıza Başka

KVKK (6698 sayılı Kişisel Verilerin Korunması Kanunu) iki ayrı yükümlülük koyuyor ve kodda ikisi sık sık karışıyor. Aydınlatma (md. 10), hukuki sebep ne olursa olsun veri elde edilirken yapılan bilgilendirme: veri sorumlusunun kimliği, amaç, kimlere aktarıldığı, toplama yöntemi ve hukuki sebep, ilgili kişinin hakları. Açık rıza ise işleme şartlarından yalnızca biri; Kanun md. 3/1-a onu "Belirli bir konuya ilişkin, bilgilendirilmeye dayanan ve özgür iradeyle açıklanan" rıza olarak tanımlıyor. Sipariş için adres işlemek sözleşmeye dayanır ve açık rıza gerektirmez ama aydınlatma yine gerekir.

Usul, Aydınlatma Yükümlülüğünün Yerine Getirilmesinde Uyulacak Usul ve Esaslar Hakkında Tebliğ'de (10 Mart 2018 tarihli ve 30356 sayılı Resmî Gazete, 28 Nisan 2019'da değişik). Tebliğ'in 5. maddesinden koda dönüşenler: aydınlatma her işlemede yapılır ve ilgili kişinin talebine bağlı değildir; amaç değişirse işlemeden önce yeniden yapılır; yapıldığını ispat yükü veri sorumlusundadır; işleme açık rızaya dayanıyorsa aydınlatma ile rızanın alınması ayrı ayrı yapılır. Geliştirici için anlamı: aydınlatma metninin bir sürümü olmalı, her rıza kaydı hangi sürümü gösterdiğini tutmalı ve rıza kutusu aydınlatma metninin içine gömülmemeli. GDPR (Avrupa Birliği Genel Veri Koruma Tüzüğü) da benzer bir çizgide: Art. 7(1) veri sorumlusunun rızayı ispat edebilmesini, Art. 7(3) rızanın her an geri alınabilmesini ve geri almanın vermek kadar kolay olmasını istiyor.

ConsentRecord: Rızanın Sürümü, Zamanı ve Geri Alınması

Bookstore'da her karar yeni bir satır; satır güncellenmiyor. Geri alma da bir karar olduğu için o da yeni bir satır. Böylece "bu kişi 13 Kasım'da hangi metni görüp neye evet dedi, ne zaman vazgeçti" sorusunun cevabı tablonun kendisi:

// Append-only: her karar (onay ya da geri alma) yeni bir satır; güncel durum amaç başına son satır.
[DataCategory("consent")]
public sealed class ConsentRecord
{
    [NoDataClassification]
    public long Id { get; set; }

    // Giriş yapmış müşteri ya da yalnız çerezdeki rastgele ID ile bilinen anonim ziyaretçi.
    [PersonalData(InformationType = "Customer ID")]
    public int? CustomerId { get; set; }

    [PersonalData(InformationType = "Device ID")]
    public Guid? VisitorId { get; set; }

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

    [NoDataClassification]
    public bool Granted { get; set; }

    // Kişinin gördüğü aydınlatma metni ve cevapladığı rıza metni.
    [NoDataClassification]
    public required string NoticeVersion { get; set; }

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

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

Güncel durum amaç başına son satır; hiç satır yoksa cevap "rıza yok":

// Amaç başına son satır kazanır; satır yoksa rıza da yok.
public async Task<bool> HasConsentAsync(int customerId, string purpose, CancellationToken ct = default) =>
    await db.Set<ConsentRecord>()
        .Where(r => r.CustomerId == customerId && r.Purpose == purpose)
        .OrderByDescending(r => r.RecordedAtUtc).ThenByDescending(r => r.Id)
        .Select(r => (bool?)r.Granted)
        .FirstOrDefaultAsync(ct) ?? false;

Kayıt API'si eski bir bildirim sürümüyle gelen kararı 409 Conflict ile reddediyor; aydınlatma metni değiştiğinde banner yeniden soruyor. Tabloya IP adresi ve user agent yazmıyoruz: ispat için hangi metne, ne zaman, hangi kanaldan cevap verildiği yeterli ve fazlası 02. yazıdaki minimizasyon ilkesine aykırı. Playwright testlerinden sonra tablo şöyleydi (bir ziyaretçi her şeyi reddetti, diğeri analytics'e evet deyip sonra geri aldı):

Id  CustomerId  Visitor    Purpose   Granted  NoticeVersion     Source            RecordedAtUtc
--  ----------  --------  ---------  -------  -------------  -------------  --------------------------
 1              02A27BCD  analytics        0  2026-11        cookie-banner  2026-11-15 06:56:36.432576
 2              02A27BCD  marketing        0  2026-11        cookie-banner  2026-11-15 06:56:36.432576
 3              1A14CDF3  analytics        1  2026-11        cookie-banner  2026-11-15 06:56:36.715276
 4              1A14CDF3  marketing        0  2026-11        cookie-banner  2026-11-15 06:56:36.715276
 5              1A14CDF3  analytics        0  2026-11        cookie-banner  2026-11-15 06:56:36.913096
 6              1A14CDF3  marketing        0  2026-11        cookie-banner  2026-11-15 06:56:36.913096

Rıza kayıtları da envantere girdi (consent faaliyeti). Ne kadar saklanacakları, özellikle 04. yazıdaki "hesabımı sil" sonrasında ispat için tutulup tutulmayacakları hukuk ekibinin sorusu; envanterde şimdilik "Ask legal" yazıyor.

Kurum'un Çerez Rehberi Ne Diyor

Kurum'un Çerez Uygulamaları Hakkında Rehber'inin sitedeki güncel PDF'i KVKK Yayınları No: 69, Temmuz 2025 tarihli. Rehber kendini internet sitesi işleten veri sorumlularına pratik tavsiyeler sunan, yol gösterici bir doküman olarak tanımlıyor; yönetmelik gibi bağlayıcı bir metin değil ama Kurum'un çereze nasıl baktığını gösteriyor. Geliştiriciyi ilgilendiren noktalar:

  • Kullanım amacına göre dört tür sayıyor: kesinlikle gerekli (zorunlu), işlevsel, performans-analitik ve reklam/pazarlama çerezleri.
  • Açık rıza dışındaki şartlara dayanabilecek çerezler için iki ölçüt veriyor: Kriter A (yalnız iletişimin elektronik haberleşme şebekesi üzerinden sağlanması) ve Kriter B (kullanıcının açıkça talep ettiği hizmet için kesinlikle gerekli olma). Oturum, sepet, güvenlik ve rıza tercihini hatırlayan çerez Kriter B örnekleri.
  • Birinci taraf analitik çerezleri belirli koşullarla (yalnız anonim istatistik, siteler arası takip yok, makul ömür, verinin üçüncü taraflara iletilmemesi) Kriter B kapsamında değerlendirilebileceğini söylüyor; davranışsal reklam çerezleri ise açık rıza gerektiriyor.
  • Açık rıza çerezler yerleştirilmeden önce ve aktif bir eylemle alınmalı; siteye girmiş olmak rıza sayılmaz. Açık rızaya tabi çerezler panelde ilk açılışta pasif gelmeli.
  • Panelde "kabul et", "reddet" ve "tercihler" butonlarının renk, büyüklük ve punto açısından eşit sunulmasını iyi uygulama örneği olarak veriyor. Rızanın geri alınabilmesi için panele erişimin sayfanın bir köşesindeki küçük bir ikon ya da bantla sürmesini öneriyor; her girişte yeniden sormanın rıza yorgunluğu yaratacağını da ekliyor.
  • Rızanın hizmetin ön koşulu yapıldığı çerez duvarlarının özgür iradeyi sakatlayabileceğini, aydınlatmada çerezin adı, amacı, süresi ve birinci ya da üçüncü taraf olup olmadığının yazılmasını tavsiye ediyor.

Bookstore'un analytics'i üçüncü taraf bir araç ve veriyi yurt dışına gönderiyor (07. yazının konusu); bu yüzden onu birinci taraf analitik istisnasına sokmadık ve rızaya bağladık. Bu bir mühendislik tercihi, hukuki değerlendirme değil. Bookstore'un çerezleri, aydınlatma metnine giden haliyle:

ÇerezTürTarafSüreDayanak
bookstore_consentZorunlu (rıza tercihi)Birinci taraf180 gün (örnek)Kriter B, rıza gerekmez
Oturum ve sepetZorunluBirinci tarafOturum sonuna kadarKriter B
AnalyticsPerformans-analitikÜçüncü tarafSağlayıcının ayarıAçık rıza
ReklamPazarlamaÜçüncü tarafSağlayıcının ayarıAçık rıza

Google Consent Mode, Google tag'lerine ziyaretçinin kararını bildiren bir API; kendisi bir banner değil, kararı toplamak senin işin. Google'ın dokümanı, varsayılan durumun her sayfada, tag yüklenmeden ve config ya da event komutlarından önce set edilmesini istiyor. Bookstore'da bu, index.html'in head'inde Angular'dan önce çalışan küçük bir script:

<script>
  // Uygulamadan ve her tag'den önce çalışır: ziyaretçi karar verene kadar her şey denied.
  window.dataLayer = window.dataLayer || [];
  function gtag() { dataLayer.push(arguments); }
  gtag('consent', 'default', {
    ad_storage: 'denied',
    ad_user_data: 'denied',
    ad_personalization: 'denied',
    analytics_storage: 'denied',
    wait_for_update: 500
  });
</script>

wait_for_update milisaniye cinsinden; asenkron yüklenen bir rıza aracının update çağırması için tag'lere tanınan süre. Google iki uygulama biçimi tarif ediyor. Basic modda tag'ler ziyaretçi banner'la etkileşene kadar hiç yüklenmiyor ve Google'a veri gitmiyor. Advanced modda tag'ler sayfayla yükleniyor, rıza denied iken çerezsiz ölçüm ping'leri gönderiyor. Bookstore basic modu kullanıyor: rehberin "çerezden önce rıza" çizgisine en yakın olanı ve test etmesi en kolayı. Advanced modun çerezsiz ping'lerinin KVKK karşısındaki yeri hukuk ekibine sorulacak bir soru. Örnekte gerçek bir Google tag'i ya da ölçüm kimliği yok; tag'in yerinde yerel bir stub (/analytics-stub.js) yükleniyor ve sahte bir analytics çerezi yazıyor.

Kararı kaydeden Angular service'i çerezi yazıyor, tag'e update gönderiyor, geri almada analytics çerezlerini siliyor ve kararı API'ye kaydediyor:

async save(choices: ConsentChoices): Promise<void> {
  const visitorId = this.stored()?.visitorId ?? crypto.randomUUID();
  const value: StoredConsent = { ...choices, notice: NOTICE_VERSION, visitorId };
  writeCookie(value);
  this.stored.set(value);
  updateGoogleConsent(choices);
  if (!choices.analytics) {
    // Geri alma, analytics'in daha önce yazdığı çerezleri de siler.
    ANALYTICS_COOKIES.forEach(name => (document.cookie = `${name}=; path=/; max-age=0`));
  }
  await firstValueFrom(this.http.post('/api/consents', { visitorId, noticeVersion: NOTICE_VERSION, choices }));
}

Script'i yükleyen AnalyticsLoader bir effect ile choices().analytics signal'ını izliyor ve yalnız true olduğunda script element'ini ekliyor. Banner'ın üç butonu aynı CSS class'ını kullanıyor; tercih kutuları mevcut karardan, karar yoksa false'tan başlıyor. Karar verildikten sonra sol alt köşede küçük bir "Cookie settings" butonu kalıyor. Örnekteki metinler İngilizce; gerçek sitede Türkçe aydınlatma metniyle birlikte gelir.

06-consent-flow-tr.png

Playwright ile Doğrulamak

Banner'ın hukuki beklentilerini dört testte topladık. Testler API'yi ve Angular dev server'ı Playwright'ın webServer ayarıyla başlatıyor ve Playwright'ın kendi headless Chromium'unda çalışıyor. İlki giriş sorusunun en önemli maddesi:

test('nothing optional runs before the visitor decides', async ({ page, context }) => {
  const scripts: string[] = [];
  page.on('request', r => r.resourceType() === 'script' && scripts.push(new URL(r.url()).pathname));
  await page.goto('/');

  await expect(page.getByRole('dialog', { name: 'Cookie consent' })).toBeVisible();
  expect(scripts).not.toContain('/analytics-stub.js');
  expect(await analyticsLoaded(page)).toBe(false);
  expect((await context.cookies()).map(c => c.name)).toEqual([]);
  expect(await consentUpdates(page)).toEqual([['default', 'denied']]);
});

Diğer üçü butonların genişlik, yükseklik, font, renk ve arka plan değerlerinin aynı olduğunu; reddetmenin analytics'i kapalı tuttuğunu, kararı 204 ile kaydettiğini ve tag'e denied güncellemesi gönderdiğini; tercih kutularının boş başladığını ve köşedeki butonla geri almanın analytics çerezini sildiğini, sayfa yeniden yüklendiğinde script'in gelmediğini kontrol ediyor:

cd web
npx playwright test --reporter=list

  ✓  1 e2e/consent.spec.ts:7:1 › nothing optional runs before the visitor decides (128ms)
  ✓  2 e2e/consent.spec.ts:19:1 › accept, reject and preferences look the same (113ms)
  ✓  3 e2e/consent.spec.ts:32:1 › reject keeps analytics off and records the choice (200ms)
  ✓  4 e2e/consent.spec.ts:45:1 › preference boxes start unticked and withdrawal works from the corner button (455ms)

  4 passed (4.0s)

Testin gerçekten yakaladığını görmek için AnalyticsLoader'daki koşulu kaldırıp script'i her durumda yükledim; ilk test kırıldı (dizi kısaltıldı):

✘  1 e2e/consent.spec.ts:7:1 › nothing optional runs before the visitor decides (117ms)
  Error: expect(received).not.toContain(expected) // indexOf
  Expected value: not "/analytics-stub.js"
  Received array:     ["/@vite/client", "/main.js", ..., "/@ng/component", "/analytics-stub.js"]

Giriş sorusunun cevabı: "devam ederek kabul etmiş olursunuz" metni aktif bir eylem değil; tek "Tamam" butonu reddetme imkânı vermiyor; script onaydan önce yükleniyor; geri almanın bir yolu yok. Yani dört nokta, ilk ikisi rehberin doğrudan açık rıza bölümüne takılıyor.

Ticari Elektronik İleti ve İYS

Kampanya e-postası ayrı bir rejime tabi: 6563 sayılı Kanun'a dayanan Ticari İletişim ve Ticari Elektronik İletiler Hakkında Yönetmelik (15 Temmuz 2015 tarihli ve 29417 sayılı Resmî Gazete; İYS (İleti Yönetim Sistemi) hükümleri 4 Ocak 2020 tarihli ve 30998 sayılı Resmî Gazete'deki değişiklikle geldi). Koda dönüşen hükümler: İYS üzerinde onayı bulunmayan alıcıya ticari elektronik ileti gönderilemez (md. 5/3); sipariş, teslimat ve tahsilat bildirimleri onay gerektirmez ama bu iletilerde mal ya da hizmet tanıtılamaz (md. 6/2); onay metninde olumlu beyan önceden seçili olamaz ve onay mal ya da hizmetin ön şartı yapılamaz (md. 7/8, 7/9); İYS dışında alınan onaylar üç iş günü içinde İYS'ye kaydedilir, kaydedilmeyenler geçersiz sayılır (md. 7/11, 7/12); ret bildirimleri de üç iş günü içinde İYS'ye bildirilir ve gönderim üç iş günü içinde durur (md. 9/6, 10/1). İYS'nin sıkça sorulan sorular sayfası cumartesi, pazar ve resmî tatillerin iş gününden sayılmadığını yazıyor.

// Sipariş ve teslimat bildirimi onay istemez; kampanya e-postası ister.
public async Task<bool> CanSendAsync(int customerId, MessageKind kind, CancellationToken ct = default) =>
    kind == MessageKind.Transactional || await consents.HasConsentAsync(customerId, ConsentCatalog.CommercialEmail, ct);

// Onay da ret de İYS'ye gider; e-posta gönderimi senkronizasyonu beklemeden hemen durur.
public async Task SetEmailPermissionAsync(int customerId, bool granted, string source, CancellationToken ct = default)
{
    Customer customer = await db.Customers.SingleAsync(c => c.Id == customerId, ct);
    DateTime now = clock.GetUtcNow().UtcDateTime;
    db.Add(new ConsentRecord
    {
        CustomerId = customerId,
        Purpose = ConsentCatalog.CommercialEmail,
        Granted = granted,
        NoticeVersion = ConsentCatalog.NoticeVersion,
        Source = source,
        RecordedAtUtc = now,
    });
    db.Add(new IysSyncItem
    {
        Address = customer.Email,
        Channel = "EPOSTA",
        Granted = granted,
        RecordedAtUtc = now,
        DueDate = BusinessDays.Add(DateOnly.FromDateTime(now), 3, holidays.Days),
    });
    await db.SaveChangesAsync(ct);
}

IysSyncItem bir outbox satırı: rıza kaydıyla aynı transaction'da yazılıyor, İYS'ye gönderen job ayrı çalışıyor ve DueDate'i geçmiş gönderilmemiş satırlar için alert üretmeli. Testte cuma günü verilen bir ret, salı tatil sayılınca perşembe gününe düşüyor. Resmî tatil listesi her yıl değiştiği için konfigürasyondan geliyor. İYS'nin teknik tarafı için sayfadaki bilgiler: izinler İYS Web'den tek tek ya da toplu, İYS API üzerinden teknik entegrasyonla eklenebiliyor; API'ye yalnız tanımlı IP adreslerinden erişiliyor; çoklu izin ekleme servisinin döndüğü subRequestId iznin eklendiğini değil İYS'ye iletildiğini gösteriyor, durumu ayrıca sorgulamak gerekiyor; iletişim adresi sayısı 250.000'in altındaki hizmet sağlayıcılar entegrasyonu ancak yetkilendirdikleri bir entegratör üzerinden yapabiliyor. Bu yazıda İYS API'si çağrılmadı; outbox'ı tüketen istemci arayüzün arkasında boş bırakıldı.

KVKK açık rızası ile İYS onayı iki ayrı hukuki rejim. Tek bir onay kutusunun ikisini birden karşılayıp karşılamadığını hukuk ekibine sor; kodda ikisi ayrı amaç olarak tutulabilecek şekilde tasarla.

Üretimde Dikkat

index.html'deki inline script bir CSP (Content Security Policy; tarayıcıya hangi script'lerin çalışabileceğini söyleyen başlık) ile çakışır; script'i nonce ya da hash ile izinli hâle getir. Banner'ın çerezi Secure ve SameSite=Lax ile yazılmalı; örnek yerel HTTP'de Secure'u yalnız HTTPS'te ekliyor. Cookie flag'lerinin ayrıntısı Web Güvenliği (OWASP Top 10) serisinin cookie flag'lerini anlatan A07 yazısında. Aydınlatma metni değişince NOTICE_VERSION değişmeli; frontend ve API aynı değeri göstermezse kayıt API'si 409 döner ve bu bir deployment hatasıdır, monitor et. Birden fazla alt alan adı varsa rıza çerezinin hangi domain'de yazılacağına baştan karar ver. Son olarak sağlayıcı tarafı: analytics ve reklam aracının kendi saklama süresini, IP ayarlarını ve veri paylaşım seçeneklerini envanterle aynı tut.

Sık Düşülen Tuzaklar

En yaygını analytics script'ini onaydan önce yüklemek; tag manager'a "consent mode var" diye güvenip default komutunu tag'den sonra çalıştırmak da aynı sonucu verir. İkincisi önceden işaretli kutular ve "devam ederek kabul edersiniz" metni. Üçüncüsü, rızayı geri almanın arayüzde olmaması ya da yalnız gizlilik politikasının dibindeki bir e-posta adresinden mümkün olması. Dördüncüsü, rızayı yalnız tarayıcı çerezinde tutup sunucuda hiçbir kayıt bırakmamak; ispat yükü veri sorumlusunda. Beşincisi, rıza tablosunu güncellenen tek bir satır olarak tasarlayıp geçmişi kaybetmek. Altıncısı, sipariş bildirimi şablonuna kampanya bloğu eklemek: o anda ileti ticari elektronik iletiye dönüşür ve İYS onayı gerekir.

Bu Yazının Dayandığı Kaynaklar

Erişim tarihi 15 Kasım 2026.

  • 6698 sayılı Kanun md. 3 ve 10: mevzuat.gov.tr/mevzuatmetin/1.5.6698.pdf; Aydınlatma Tebliği: mevzuat.gov.tr, mevzuat no. 24454
  • KVKK, Çerez Uygulamaları Hakkında Rehber, KVKK Yayınları No: 69, Temmuz 2025: kvkk.gov.tr/SharedFolderServer/CMSFiles/fb193dbb-b159-4221-8a7b-3addc083d33f.pdf
  • Ticari İletişim ve Ticari Elektronik İletiler Hakkında Yönetmelik: mevzuat.gov.tr, mevzuat no. 20914; İYS sıkça sorulan sorular ve kurumsal hizmetler: iys.org.tr
  • Google tag consent mode: developers.google.com/tag-platform/security/guides/consent ve developers.google.com/tag-platform/security/concepts/consent-mode; GDPR Art. 7: eur-lex.europa.eu/eli/reg/2016/679/oj

Küçük Bir Deneme

★☆☆ NOTICE_VERSION'ı frontend'de 2026-12 yap, API'yi değiştirme ve banner'da "Reject all"a bas. API'nin 409 döndüğünü gör; sonra Playwright'a bu durumu yakalayan bir test ekle.

★★☆ Banner'a bir "Functional" kategorisi ekle (ör. son bakılan kitapları hatırlayan bir çerez). Kategori backend kataloğuna, aydınlatma tablosuna ve Playwright testlerine eklenmeden build'in kırılmasını sağlayacak bir kontrol tasarla.

★★★ IysSyncItem satırlarını işleyen bir job yaz: satırları bir arayüz üzerinden gönderen, başarılı gönderimde SentAtUtc'yi set eden, DueDate'i geçmiş satırlar için alert log'u yazan ve aynı satırı iki kez göndermeyen. Arayüzün sahte implementasyonuyla iş günü sınırını test et.

Rızayı aldık; analytics verisi ise Bookstore'un sunucusundan değil, ziyaretçinin tarayıcısından doğrudan yurt dışındaki bir sağlayıcıya gidiyor. Serinin son yazısında yurt dışına aktarım rejimine, cloud region'ına, LLM sağlayıcılarına giden prompt'lara, standart sözleşmenin beş iş günlük bildirimine ve 72 saatlik veri ihlali bildirimine hazırlığa bakıyoruz.