Sorun
Türk finansal regülasyonları (BDDK, MASAK) bankacılık sistemlerinden log saklaması, erişilebilirlik ve değişmezlik konusunda katı gereksinimler talep eder. Bunlar yalnızca "log tutun" demez; hangi olayların ne kadar süre saklanacağını, kim tarafından erişilebileceğini ve denetim sırasında nasıl sunulacağını da belirler.
PayGate projesinde BDDK denetimine 8 hafta kalan noktada kapsamlı bir log altyapısı eksikliğiyle karşılaştık. Bu yazı, sıfırdan kurduğumuz mimarinin teknik detaylarını aktarıyor.
BDDK Log Gereksinimleri
Denetim öncesinde masaya oturup gereksinimleri somutlaştırdık:
- Saklamanın türü: İşlem logları 10 yıl, erişim logları 5 yıl
- Değişmezlik kanıtı: Her log kaydının sonradan değiştirilemeyeceğini ispatlayan kriptografik zincir
- Yapısal format: Serbest metin değil, şema doğrulanabilir JSON
- Gerçek zamanlı erişim: Denetçilerin önceden belirlenmiş sorgularla anlık veri çekebilmesi
- Anonimleştirme politikası: KVKK kapsamında kişisel verilerin maskelenmesi
Önemli Ayrım
BDDK log gereksinimleri uygulama logları ile işlem audit loglarını ayırt eder. İkincisi kriptografik kanıt gerektirir; birincisi gözlemlenebilirlik içindir. Her iki pipeline'ı birbirinden bağımsız tasarlayın.
Mimari: İki Paralel Pipeline
1. Gözlemlenebilirlik Pipeline'ı
Uygulama logu için OpenTelemetry tabanlı bir yapı kurduk:
- Collector: OpenTelemetry Collector, tüm servislerden logları toplar
- Format: OTLP JSON — her log kaydında
service.name,trace_id,span_idzorunlu - Depolama: Elasticsearch — 90 günlük hot storage, ardından S3 Glacier'a arşiv
- Görselleştirme: Grafana loki stack ile gerçek zamanlı dashboard
Bu pipeline operasyon ekibinin günlük kullandığı katman. P50 sorgu süresi 42ms, P99 280ms.
2. Audit Log Pipeline'ı
Regülatör denetimi için ayrı, değişmez bir pipeline:
İşlem Olayı → Kafka Topic (audit.events) → Audit Processor → Append-Only PostgreSQL → S3 WORM Bucket
Her audit log kaydı şu alanları içerir:
{
"event_id": "uuid-v7",
"event_type": "PAYMENT_INITIATED",
"actor_id": "usr_masked_sha256",
"timestamp_utc": "2026-01-15T14:32:01.847Z",
"payload_hash": "sha256:...",
"prev_hash": "sha256:...",
"signature": "ed25519:..."
}
prev_hash alanı blockchain benzeri bir zincir oluşturur. Herhangi bir kaydı değiştirmek zinciri kırar ve doğrulama scripti bunu anında tespit eder.
Kişisel Veri Maskeleme
KVKK kapsamında TC kimlik numarası, IBAN ve telefon numarası log akışına girmeden önce maskeler:
const SENSITIVE_PATTERNS = [
{ pattern: /\b\d{11}\b/g, label: 'TC_ID' },
{ pattern: /TR\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{2}/g, label: 'IBAN' },
{ pattern: /(\+90|0)\s?5\d{2}\s?\d{3}\s?\d{2}\s?\d{2}/g, label: 'PHONE' },
];
function maskSensitive(input: string): string {
return SENSITIVE_PATTERNS.reduce(
(acc, { pattern, label }) => acc.replace(pattern, `[MASKED:${label}]`),
input
);
}
Bu fonksiyon log collector middleware olarak tüm servislerden geçer — uygulama katmanında tek bir yerde tanımlı.
Anomali Tespiti
Audit pipeline üzerine gerçek zamanlı anomali tespiti ekledik:
- Yüksek frekanslı işlemler: 60 saniyede 50'den fazla işlem yapan hesap → otomatik inceleme kuyruğu
- Alışılmadık saat: Hesabın tarihsel örüntüsünden sapan saatte işlem → risk skoru artırımı
- Coğrafi imkansızlık: Birbirini izleyen iki işlemin fiziksel olarak imkansız hızdaki konum değişimi → anlık blok
Bu kurallar kod değil, YAML konfigürasyonuyla yönetilir. Yeni bir kural eklemek deployment gerektirmiyor.
Denetim Sonucu
BDDK denetimi ilk sunuşta geçti. Denetçilerin özellikle beğendiği noktalar:
- Kriptografik zincir bütünlüğünün anlık doğrulanabilmesi
- Denetçi erişiminin kendi audit loguna düşmesi (iç içe denetlenebilirlik)
- Veri saklama politikasının sistem konfigürasyonuyla tam uyumu
Denetim sürecinde talep edilen 847 spesifik işlem kaydının tamamı ortalama 1.2 saniyede döndürüldü.
Sonuç
Regülatör uyumlu log altyapısı teknik bir zorunluluk değil, iş sürekliliğinin güvencesidir. Doğru mimarinin anahtarı: gözlemlenebilirlik ile audit logunu ayrı pipeline'larda yönetmek ve kriptografik kanıtı baştan tasarıma dahil etmek.

