---
title: 'Sır Deposu Mimarisi'
source: 'https://academia.sh/tr/kurslar/calisma-zamani-guvenligi/sir-deposu-mimarisi'
course: 'Çalışma Zamanı Güvenliği ve Sır Yönetimi'
language: tr
updated: '2026-08-17T18:06:42+00:00'
license: 'CC BY-SA 4.0'
---

# Sır Deposu Mimarisi

Sır deposu erişim denetimi cinsinden ölçülür: yol öneki politikası dokuz uygulamaya 79 (uygulama, sır) kalemi açıyor, doksan günlük okuma kaydı 31 diyor ve 48 kalem hiç kullanılmadan duruyor. Üç sırrı hiçbir uygulama okumuyor; en geniş veri sırrına altı uygulama erişebiliyor. Merkezîleşmenin bedeli tek noktadır — dokuz uygulamanın hiçbiri depo olmadan başlayamıyor ve günde 41 başlatma denemesi bu tek noktadan geçiyor.

Önceki ders istek katmanını kapattı: uygulama katmanı güvenlik duvarının ve davranış puanlamasının
neyi yakaladığı, neyi kaçırdığı ve neyi yanlış yere kestiği sayıldı. Bütün o katmanların arkasında
tek bir sessiz varsayım duruyordu — uygulamanın veri deposuna, kuyruğa ve dış geçitlere bağlanmak
için taşıdığı anahtarların **yerli yerinde ve yalnız kendisinde** olduğu. Bu ders o varsayımı
kaldırır ve anahtarların durduğu yeri, yani **sır deposunu**, tek bir eksende ölçer: kim neye
erişebiliyor.

Sırrın nerede saklandığı, kaç kopya hâlinde durduğu ve merkezî bir deponun kopyayı nasıl azalttığı
daha önce ölçüldü ve burada tekrarlanmıyor. Buranın sorusu depo kurulduktan **sonra** başlıyor:
depo kurulmuş, sırlar içine konmuş ve her uygulamaya bir politika yazılmıştır. O politika kaç
kaleme izin veriyor, uygulamalar kaçını gerçekten okuyor ve aradaki fark ele geçen bir uygulamadan
ne kadar açıyor.

- **SR1.** Abone portalı ve saha uygulamasının üretim ortamı **kurgudur**: dokuz uygulama, yirmi
  sır ve bir sır deposu. Ölçülen şey `node` ile yazılmış bir **modeldir**.
- **SR2.** Modelde **gerçek sır değeri yoktur**; yalnız sır yolları, uygulama adları ve sayılar
  taşınır. Sır yolu `alan/kalem` biçimindedir ve politika **yol öneki** ile yazılır.
- **SR3.** Bir politika kuralı, kendisiyle başlayan her sır yolunu açar. `veri/` kuralı beş veri
  sırrının beşini birden verir; tam yol yazan kural tek sır verir.
- **SR4.** Okuma kaydı iki pencerede okunur: son otuz gün ve son doksan gün. Doksan günlük pencere
  bu modelde gerçek ihtiyaç sayılır; gerçekte hiçbir pencere ihtiyacın tamamını göstermez.
- **SR5.** Rastgelelik yok; bütün sayılar model tablolarından türetiliyor ve çıktı koşumdan koşuma
  aynı. Yeniden başlatma sayıları kurgu birimdir.
- **SR6.** Deponun kendi kesintisi tek değerli modellenir: depo ya vardır ya yoktur. Kısmi bozulma
  ve çoğaltılmış depo modellenmiyor; çoğaltma kesinti kalemini düşürür, erişim kalemini düşürmez.

## Erişim Matrisi

```js
// depo.mjs — sir deposu envanteri, politika kurallari ve okuma kaydi. MODELDIR.
// Abone portali ve saha uygulamasinin uretim ortami KURGUDUR; dokuz uygulama, bir depo.
// GERCEK SIR YOKTUR: yalniz sir YOLLARI, uygulama adlari ve sayilar modellenir.
export const SIR = Object.entries({
  veri: ["portal-birincil", "portal-okuma", "saha-birincil", "fatura-birincil", "arsiv"],
  kuyruk: ["olcum-alim", "bildirim-kuyrugu", "is-emri-kuyrugu"],
  dis: ["odeme-gecidi", "harita-servisi", "kisa-mesaj-gecidi", "eposta-gecidi", "kimlik-saglayici"],
  imza: ["oturum-imzalama", "belge-imzalama", "ic-cagri-imzalama"],
  altyapi: ["nesne-deposu", "onbellek", "olcut-yazma", "gunluk-yazma"],
}).flatMap(([a, l]) => l.map((k) => `${a}/${k}`));

// kural: politikanin verdigi yol oneki. okur: son 30 gunun okuma kaydindaki sirlar.
// bicim/omur: sirrin nasil alindigi. yb: gunde kac yeniden baslatma (dagitim + olcek).
export const UYG = {
  "portal-onyuz": { kural: ["dis/kimlik-saglayici", "imza/"], bicim: "baslangicta", omur: 0, yb: 6,
    okur: ["imza/oturum-imzalama"] },
  "portal-api": { kural: ["veri/", "imza/", "altyapi/"], bicim: "onbellekli", omur: 60, yb: 12,
    okur: ["veri/portal-birincil", "veri/portal-okuma", "imza/oturum-imzalama",
      "imza/ic-cagri-imzalama", "altyapi/onbellek"] },
  "abone-kayit": { kural: ["veri/", "dis/"], bicim: "baslangicta", omur: 0, yb: 3,
    okur: ["veri/portal-birincil", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"] },
  "fatura-servisi": { kural: ["veri/", "dis/", "imza/belge-imzalama"], bicim: "onbellekli",
    omur: 240, yb: 2,
    okur: ["veri/fatura-birincil", "veri/portal-okuma", "dis/odeme-gecidi", "imza/belge-imzalama"] },
  "odeme-koprusu": { kural: ["dis/"], bicim: "her-istekte", omur: -1, yb: 2,
    okur: ["dis/odeme-gecidi"] },
  "saha-api": { kural: ["veri/", "kuyruk/", "dis/harita-servisi", "imza/"], bicim: "onbellekli",
    omur: 60, yb: 8,
    okur: ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "dis/harita-servisi",
      "imza/ic-cagri-imzalama"] },
  "is-emri": { kural: ["veri/", "kuyruk/"], bicim: "baslangicta", omur: 0, yb: 4,
    okur: ["veri/saha-birincil", "kuyruk/is-emri-kuyrugu", "kuyruk/bildirim-kuyrugu"] },
  "bildirim": { kural: ["kuyruk/", "dis/"], bicim: "onbellekli", omur: 15, yb: 3,
    okur: ["kuyruk/bildirim-kuyrugu", "dis/eposta-gecidi", "dis/kisa-mesaj-gecidi"] },
  "rapor-uretici": { kural: ["veri/", "altyapi/"], bicim: "baslangicta", omur: 0, yb: 1,
    okur: ["veri/portal-okuma", "veri/arsiv", "altyapi/nesne-deposu"] },
};
export const AD = Object.keys(UYG);
// 30 gunluk pencerede hic gorunmeyen, 90 gunde goruleni olan mesru okumalar.
export const NADIR = [["fatura-servisi", "veri/arsiv"], ["is-emri", "dis/harita-servisi"],
  ["portal-api", "altyapi/gunluk-yazma"], ["rapor-uretici", "dis/eposta-gecidi"]];

export const erisir = (a, s) => UYG[a].kural.some((k) => s.startsWith(k));
export const okur90 = (a) => [...UYG[a].okur, ...NADIR.filter((n) => n[0] === a).map((n) => n[1])];
export const topla = (f) => AD.reduce((t, a) => t + f(a), 0);
export const gen = (B) => (h) => h.map((v, j) => j ? String(v).padStart(B[j])
  : String(v).padEnd(B[0])).join("");

if (import.meta.url === `file://${process.argv[1]}`) {
  const yz = gen([16, 8, 14, 12, 12, 11]);
  console.log(`model: ${SIR.length} sir, ${AD.length} uygulama, 1 depo (kurgu uretim ortami)\n`);
  console.log(yz(["uygulama", "kural", "erisebildigi", "30 g okur", "90 g okur", "fazladan"]));
  for (const a of AD) {
    const e = SIR.filter((s) => erisir(a, s)).length;
    console.log(yz([a, UYG[a].kural.length, e, UYG[a].okur.length, okur90(a).length,
      e - okur90(a).length]));
  }
  const E = topla((a) => SIR.filter((s) => erisir(a, s)).length);
  const O30 = topla((a) => UYG[a].okur.length), O90 = topla((a) => okur90(a).length);
  console.log(yz(["toplam", topla((a) => UYG[a].kural.length), E, O30, O90, E - O90]));

  const ters = SIR.map((s) => [s, AD.filter((a) => erisir(a, s)).length,
    AD.filter((a) => okur90(a).includes(s)).length]).sort((x, y) => y[1] - x[1]);
  console.log("\nen genis dort sir (kac uygulama erisebiliyor / kaci gercekten okuyor):");
  for (const [s, e, o] of ters.slice(0, 4)) console.log(`  ${s.padEnd(24)} ${e} / ${o}`);
  const hic = ters.filter((t) => t[2] === 0), pay = ters.filter((t) => t[2] > 1);
  console.log(`hicbir uygulamanin okumadigi sir: ${hic.length} (${hic.map((t) => t[0]).join(", ")})`);
  console.log(`birden cok uygulamanin okudugu sir: ${pay.length} / ${SIR.length}; ` +
    `bu sirlarin biri degistiginde ortalama ` +
    `${(pay.reduce((t, x) => t + x[2], 0) / pay.length).toFixed(1)} uygulama etkilenir`);
  console.log(`\nele gecen bir uygulamadan acilan sir — politikayla ortalama ` +
    `${(E / AD.length).toFixed(1)}, en genis ${Math.max(...AD.map((a) =>
      SIR.filter((s) => erisir(a, s)).length))}; en az yetkiyle ortalama ` +
    `${(O90 / AD.length).toFixed(1)}, en genis ${Math.max(...AD.map((a) => okur90(a).length))}`);
  console.log(`en az yetki politikasi: ${O90} satir (bugun ${topla((a) => UYG[a].kural.length)}), ` +
    `kapanan kalem ${E - O90}; 30 gunluk gozlemle yazilsa ${O90 - O30} mesru okuma kesilirdi`);
}
```

```
model: 20 sir, 9 uygulama, 1 depo (kurgu uretim ortami)

uygulama           kural  erisebildigi   30 g okur   90 g okur   fazladan
portal-onyuz           2             4           1           1          3
portal-api             3            12           5           6          6
abone-kayit            2            10           3           3          7
fatura-servisi         3            11           4           5          6
odeme-koprusu          1             5           1           1          4
saha-api               4            12           4           4          8
is-emri                2             8           3           4          4
bildirim               2             8           3           3          5
rapor-uretici          2             9           3           4          5
toplam                21            79          27          31         48

en genis dort sir (kac uygulama erisebiliyor / kaci gercekten okuyor):
  veri/portal-birincil     6 / 2
  veri/portal-okuma        6 / 3
  veri/saha-birincil       6 / 2
  veri/fatura-birincil     6 / 1
hicbir uygulamanin okumadigi sir: 3 (dis/kimlik-saglayici, kuyruk/olcum-alim, altyapi/olcut-yazma)
birden cok uygulamanin okudugu sir: 12 / 20; bu sirlarin biri degistiginde ortalama 2.2 uygulama etkilenir

ele gecen bir uygulamadan acilan sir — politikayla ortalama 8.8, en genis 12; en az yetkiyle ortalama 3.4, en genis 6
en az yetki politikasi: 31 satir (bugun 21), kapanan kalem 48; 30 gunluk gozlemle yazilsa 4 mesru okuma kesilirdi
```

Yirmi bir kural satırı yetmiş dokuz `(uygulama, sır)` kalemi açıyor. Doksan günlük okuma kaydında
görünen kalem otuz bir. Aradaki **kırk sekiz kalem**, yani açılan erişimin yüzde altmış biri,
hiçbir uygulamanın hiç dokunmadığı sırlara verilmiş durumda. Bu fark bir tembellikten değil, kural
biçiminden geliyor: `veri/` yazmak bir satırdır, beş sır verir; beş sırrın hangisinin gerçekten
gerektiğini yazmak beş satırdır.

Satır satır bakıldığında en pahalı iki kalem saha uygulaması tarafındadır. `saha-api` dört kural
satırıyla on iki sırra erişebiliyor, dördünü okuyor; sekiz kalem karşılıksız. `portal-api` on iki
sırra erişip altısını okuyor. Karşılıksız kalemin en büyük tek kaynağı `veri/` önekidir: beş veri
sırrının her birine **altı uygulama** erişebiliyor, ama en çok okunanı üç uygulama, en az okunanı
tek uygulama okuyor. Fatura veri tabanının birincil kimlik bilgisine altı uygulama ulaşabiliyor;
onu okuyan tek uygulama var.

Üç sır listede hiç görünmüyor: kimlik sağlayıcı sırrı, ölçüm alım kuyruğunun anahtarı ve ölçüt
yazma anahtarı doksan gün boyunca hiçbir uygulama tarafından okunmamış. Bunlar erişim matrisinin
en ucuz kalemleridir — okuyanı olmayan sır, kimseyi kesmeden kapatılır.

Bir sonraki satır matrisi ters yönde okuyor ve bu dersin dışına taşan tek sayıyı veriyor: yirmi
sırrın on ikisi birden çok uygulama tarafından okunuyor, ortalama 2,2 uygulama tarafından. Erişim
matrisi daraltılsa bile bu paylaşım kalır — çünkü paylaşım politikadan değil, mimariden gelir; iki
uygulama aynı veri tabanına yazıyorsa aynı kimlik bilgisini okur. Bu on iki sırrın herhangi biri
değiştirildiğinde ortalama iki uygulama aynı anda yeni değere geçmek zorundadır, ve o geçişin
nasıl yapılacağı erişim denetiminin çözebileceği bir soru değildir.

Son iki satır kararı veriyor. Ele geçen bir uygulama bugünkü politikayla ortalama 8,8 sır açıyor,
en kötü durumda on iki. En az yetkiye inildiğinde ortalama 3,4'e, en kötü durum altıya iniyor.
Bedel de aynı satırda: politika yirmi bir satırdan otuz bir satıra çıkıyor. **Daraltma politikayı
kısaltmaz, uzatır.** Ve daraltma otuz günlük gözlemle yazılırsa dört meşru okumayı keser — yıl sonu
arşiv okuması, toplu rota yeniden hesabı, tanı kipindeki günlük yazımı ve aylık özet gönderimi. Bu
dördü otuz günlük pencerede hiç görünmez; kesildiklerinde de dağıtım anında değil, ilk çalıştıkları
gün fark edilirler.

## Merkezîleşmenin Tek Noktası

```js
// kesinti.mjs — merkezilesmenin tek nokta bedeli: depo dustugunde kim durur, kim baslayamaz
import { AD, UYG, topla, gen } from "./depo.mjs";

const yz = gen([14, 14, 17, 16, 20]);
const YB = topla((a) => UYG[a].yb);                       // gunluk yeniden baslatma (kurgu)
const derhal = AD.filter((a) => UYG[a].bicim === "her-istekte");
const biten = (D) => AD.filter((a) => UYG[a].bicim === "onbellekli" && UYG[a].omur < D);
console.log(`gunluk yeniden baslatma ${YB} (dagitim + olcek); depo olmadan baslayabilen ` +
  `uygulama 0 / ${AD.length}\n`);
console.log(yz(["kesinti(dk)", "derhal duran", "onbellegi biten", "duran uygulama",
  "basarisiz baslatma"]));
for (const D of [1, 15, 30, 60, 120, 240, 480, 1440])
  console.log(yz([D, derhal.length, biten(D).length, derhal.length + biten(D).length,
    Math.round((D / 1440) * YB)]));

console.log(`\nbicim dagilimi:`);
for (const b of ["her-istekte", "onbellekli", "baslangicta"]) {
  const l = AD.filter((a) => UYG[a].bicim === b);
  console.log(`  ${b.padEnd(13)} ${l.length}  ${l.join(", ")}`);
}
const ayakta = AD.filter((a) => UYG[a].bicim === "baslangicta");
console.log(`\n1440 dk kesintide: ${derhal.length + biten(1440).length} uygulama durur, ` +
  `${ayakta.length} uygulama calismaya devam eder ama ${YB} baslatma denemesi basarisiz olur`);
console.log(`kesintiden hic etkilenmeyen uygulama: 0 / ${AD.length}`);
```

```
gunluk yeniden baslatma 41 (dagitim + olcek); depo olmadan baslayabilen uygulama 0 / 9

kesinti(dk)     derhal duran  onbellegi biten  duran uygulama  basarisiz baslatma
1                          1                0               1                   0
15                         1                0               1                   0
30                         1                1               2                   1
60                         1                1               2                   2
120                        1                3               4                   3
240                        1                3               4                   7
480                        1                4               5                  14
1440                       1                4               5                  41

bicim dagilimi:
  her-istekte   1  odeme-koprusu
  onbellekli    4  portal-api, fatura-servisi, saha-api, bildirim
  baslangicta   4  portal-onyuz, abone-kayit, is-emri, rapor-uretici

1440 dk kesintide: 5 uygulama durur, 4 uygulama calismaya devam eder ama 41 baslatma denemesi basarisiz olur
kesintiden hic etkilenmeyen uygulama: 0 / 9
```

Kırk sekiz kalemi kapatmanın karşılığında ne alındığı bu tablodadır. Bir yerde toplanan sır, bir
yerde toplanan **bağımlılıktır**. Deponun bir dakikalık kesintisinde bile bir uygulama duruyor:
ödeme köprüsü sırrı her istekte okuyor, dolayısıyla depoya erişemediği anda ödeme almıyor. Bu, en
duyarlı sırrın en sıkı okunmasının doğal sonucudur — sıkı okuma, kesintiye en açık olma biçimidir.

Sonraki satırlar önbellek ömrünün gecikmeli bir tampon olduğunu gösteriyor. Otuz dakikalık
kesintide bildirim servisi düşüyor (önbellek ömrü on beş dakika), iki saatte portal ve saha
uygulama arayüzleri de düşüyor, sekiz saatte önbellekli dört uygulamanın dördü duruyor. Önbellek
kesintiyi engellemiyor, **erteliyor**; ertelediği süre tam olarak önbellek ömrü kadar.

Sağdaki sütun tablonun asıl bulgusudur. Başlangıçta okuyan dört uygulama kesinti boyunca çalışmaya
devam ediyor ve ilk bakışta bağışık görünüyorlar. Bağışık değiller: dokuz uygulamanın **hiçbiri**
depo olmadan başlayamıyor ve bu ortamda günde kırk bir yeniden başlatma var — dağıtım, ölçek
büyütme ve sağlıksız örneğin değiştirilmesi. Dört saatlik bir kesinti yedi başlatma denemesini,
bir günlük kesinti kırk birini düşürür. Yük artışıyla aynı saate denk gelen bir depo kesintisinde
ölçek büyütme çalışmaz; sistem, ayakta kalan örnekleriyle yükün altında kalır.

Tablonun son satırı merkezîleşmenin gerçek ifadesidir: kesintiden hiç etkilenmeyen uygulama
sıfırdır. Depoyu kurmak kırk sekiz karşılıksız erişim kalemini kapatılabilir hâle getirir; aynı
adım, dokuz uygulamanın tamamına **ortak bir başlatma bağımlılığı** yazar. İkinci kalem birincinin
faturasıdır ve çoğaltmayla küçültülebilir, sıfırlanamaz.

## Daha Ucuz Aşama

Kırk sekiz karşılıksız kalem çalışma zamanında ölçüldü, ama çalışma zamanında **doğmadı**. Her
kalem, bir uygulamaya politika yazılırken doğdu: `veri/` öneki, o uygulamanın hangi veri sırrına
ihtiyaç duyduğu bilinmediği için yazıldı. Aynı kalem dağıtım aşamasında kapanabilirdi — her
uygulama ihtiyaç duyduğu sır yollarını dağıtım tanımında **açıkça bildirseydi**, politika o
bildirimden üretilir ve otuz bir kalem dışında hiçbir kalem hiç açılmazdı. İşin ölçüsü de farklı:
dokuz uygulama için dokuz bildirim yazmak ile yetmiş dokuz kalemlik matrisi elle gözden geçirip
hangisinin gereksiz olduğuna karar vermek arasında yaklaşık dokuz kat fark var — ve ikincisi her
yeni sır eklendiğinde yeniden yapılır, birincisi bir kez yazılır.

Çalışma zamanında ölçülmesi gereken tek kalem, bildirimin kendisinin doğru olup olmadığıdır: okuma
kaydı bildirilenden fazlasını gösteriyorsa bildirim eksiktir, azını gösteriyorsa fazladır. Bu
karşılaştırma bir denetimdir, bir savunma değil.

## Özet

- Yirmi bir kural satırı dokuz uygulamaya 79 `(uygulama, sır)` kalemi açıyor; doksan günlük okuma
  kaydı 31 diyor. Kırk sekiz kalem, açılan erişimin %61'i, hiç kullanılmıyor.
- Karşılıksız kalemin kaynağı yol öneki kuralıdır: `veri/` bir satırdır ve beş sır verir; beş veri
  sırrının her birine altı uygulama erişebiliyor, en çok okunanını üç uygulama okuyor.
- Üç sırrı hiçbir uygulama okumuyor; bunlar kimseyi kesmeden kapatılabilecek en ucuz kalemlerdir.
- En az yetki ele geçen bir uygulamadan açılan sırrı ortalama 8,8'den 3,4'e, en kötü durumda
  12'den 6'ya indiriyor. Bedeli politikanın 21 satırdan 31 satıra uzamasıdır; otuz günlük gözlemle
  yazılırsa dört meşru okumayı keser ve kesinti ancak o iş ilk çalıştığında görünür.
- Merkezîleşmenin bedeli tek noktadır: bir dakikalık kesinti bir uygulamayı durduruyor, sekiz
  saatlik kesinti beşini; dokuz uygulamanın hiçbiri depo olmadan başlayamıyor ve günde 41 başlatma
  denemesi bu noktadan geçiyor.
- Kırk sekiz kalem çalışma zamanında ölçüldü ama dağıtım aşamasında doğdu; sır yolları dağıtım
  tanımında bildirilseydi hiç açılmayacaktı — dokuz bildirim ile 79 kalemlik matris incelemesi
  arasında yaklaşık dokuz kat fark var.

## Sonraki Adım

Bu ders erişimi daralttı ama sırların kendisine hiç dokunmadı. Otuz bir kalemin her birinde duran
şey hâlâ **ömrü olmayan bir değerdir**: kurulum günü yazılmış, o gün bu gündür aynı. Erişim
matrisi daraltıldığında bir uygulamadan açılan sır altıya iner, ama o altı sır sızdığında ne kadar
süre çalışacağı sorusu hiç sorulmadı. Sonraki ders o süreyi ölçer: statik bir sır sızdığında açık
pencere kaç gün sürüyor, istek üzerine üretilen kısa ömürlü bir kimlik bilgisi aynı pencereyi kaç
kata indiriyor ve bu daralmanın karşılığında depoya günde kaç ek istek, sisteme kaç yeni bağımlılık
ekleniyor.
