---
title: 'Hat Güvenliği'
source: 'https://academia.sh/tr/kurslar/ci-cd/hat-guvenligi'
course: 'Sürekli Tümleştirme ve Teslimat'
language: tr
updated: '2026-08-17T18:09:03+00:00'
license: 'CC BY-SA 4.0'
---

# Hat Güvenliği

Hattın kendisi ölçülür: dokuz iş adımının kaç sırra ve hedefe eriştiği, en az yetkiye inince düşen erişim ve bedeli, aynı çalıştırıcıda art arda koşan işler arasında taşınan durum, ve bilinen kötüye kullanım girişimlerinde her kısıtlamanın kapattığı, kaçırdığı ve durdurduğu meşru iş.

Önceki ders çıktıyı imzaladı ve dağıtım anında doğruladı: on sekiz sahtenin on sekizi durdu,
anahtar tek bir öznede kaldı. O özne bir insan değildi, **hattın kendisiydi.** Bu kursta ölçülen
her kapı, kapıyı koşturan makinenin dürüst çalıştığı varsayımına dayandı ve o varsayım hiç
sayılmadı.

Bu ders onu sayar: hattın kaç sırra eriştiğini, iki iş arasında ne taşındığını, kötüye kullanım
girişimlerinin kaçının kapandığını. Ölçü yine kapıdır — önünde duran artık bir değişiklik değil,
hattın kendi adımı.

**DD31.** Kurgu bölgesel ölçüm ağının hattı dokuz adımdır; 12 sır ve 6 hedef `node` ile
modellenir ve model olduğu yazılır — **sır değerleri yazılmaz, yalnız adları geçer.** **DD32.**
Bir adımın *ihtiyacı* gerçekten kullandığıdır, *bildirileni* hat tanımına yazılan; ikisi iki
adımda ayrışır.

## Hattın Yetki Yüzeyi

```js
// olcum-agi/yetki.mjs — hattin yetki yuzeyi: hangi adim hangi sirra ve hedefe erisiyor (model)
const SIR = ["kod-deposu-okuma", "paket-deposu-okuma", "paket-deposu-yazma", "nesne-deposu-yazma",
  "imza-anahtari", "dagitim-jetonu-gelistirme", "dagitim-jetonu-hazirlik", "dagitim-jetonu-uretim",
  "veritabani-hazirlik", "veritabani-uretim", "bildirim-jetonu", "toplayici-anahtari"];
const HEDEF = ["gelistirme", "hazirlik", "uretim", "yapi-cikti-deposu", "nesne-deposu", "bildirim-kanali"];

// Kurgu bolgesel olcum agi hatti: dokuz adim. `ihtiyac` adimin gercekten kullandigi,
// `bildirilen` hat tanimina yazilan kume. Ikisi iki adimda ayrisir.
const ADIM = [
  ["bicim-cozumlemesi", [], []],
  ["derleme", ["kod-deposu-okuma", "paket-deposu-okuma"], []],
  ["birim-sinamasi", [], []],
  ["sozlesme-sinamasi", [], []],
  ["tumlesim-sinamasi", ["veritabani-hazirlik"], ["hazirlik"]],
  ["paketleme", ["paket-deposu-yazma"], ["yapi-cikti-deposu"]],
  ["envanter-uretimi", ["paket-deposu-okuma"], ["yapi-cikti-deposu"]],
  ["imzalama", ["imza-anahtari"], ["yapi-cikti-deposu"]],
  ["dagitim", ["dagitim-jetonu-uretim", "nesne-deposu-yazma", "bildirim-jetonu"],
    ["uretim", "nesne-deposu", "bildirim-kanali"]],
].map(([ad, sir, hedef]) => ({ ad, sir, hedef }));
const EKSIK = { "envanter-uretimi": ["paket-deposu-okuma"], dagitim: ["bildirim-jetonu"] };
const bildirilen = (a) => a.sir.filter((s) => !(EKSIK[a.ad] ?? []).includes(s));

const topla = (f) => ADIM.reduce((t, a) => t + f(a), 0);
const tekSir = ADIM.length * SIR.length, tekHedef = ADIM.length * HEDEF.length;
const azSir = topla((a) => bildirilen(a).length), azHedef = topla((a) => a.hedef.length);
const enGenis = Math.max(...ADIM.map((a) => bildirilen(a).length + a.hedef.length));

const SUTUN = [26, 12, 14, 22, 0];
const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(SUTUN[i])).join(""));
satir(["yerlesim", "kimlik", "sir erisimi", "hedef erisimi", "ele gecen adimin ulastigi"]);
satir(["tek hat kimligi", 1, `${tekSir}/${tekSir}`, `${tekHedef}/${tekHedef}`,
  `${SIR.length} sir + ${HEDEF.length} hedef`]);
satir(["adim basina kimlik", ADIM.length, `${azSir}/${tekSir}`, `${azHedef}/${tekHedef}`,
  `en cok ${enGenis} kayit`]);

const sirsiz = topla((a) => (a.sir.length === 0 ? 1 : 0));
const duran = ADIM.filter((a) => a.sir.length > bildirilen(a).length).map((a) => a.ad);
console.log("");
console.log(`dusen erisim ${tekSir + tekHedef - azSir - azHedef}/${tekSir + tekHedef} ` +
  `(%${(100 * (1 - (azSir + azHedef) / (tekSir + tekHedef))).toFixed(0)}); bedeli ` +
  `${ADIM.length} kimlik tanimi ve ${azSir + azHedef} baglama kaydi`);
console.log(`hic sir kullanmayan adim ${sirsiz}/${ADIM.length} — ` +
  `tek kimlikte yine ${SIR.length} sirra erisiyor`);
console.log(`gercek ihtiyac ${topla((a) => a.sir.length)} sir, bildirilen ${azSir}; ` +
  `bildirimi eksik ${duran.length} adim (${duran.join(", ")}) -> ${duran.length} mesru is durur`);
```

```
yerlesim                  kimlik      sir erisimi   hedef erisimi         ele gecen adimin ulastigi
tek hat kimligi           1           108/108       54/54                 12 sir + 6 hedef
adim basina kimlik        9           7/108         7/54                  en cok 5 kayit

dusen erisim 148/162 (%91); bedeli 9 kimlik tanimi ve 14 baglama kaydi
hic sir kullanmayan adim 3/9 — tek kimlikte yine 12 sirra erisiyor
gercek ihtiyac 9 sir, bildirilen 7; bildirimi eksik 2 adim (envanter-uretimi, dagitim) -> 2 mesru is durur
```

Tek hat kimliğinde erişim sayısı **162'dir**: dokuz adımın her biri on iki sırrın ve altı hedefin
hepsine ulaşır. Adım başına kimlikte aynı hat **14 erişimle** koşar; düşen 148 erişim yüzeyin
**%91'idir**, bedeli dokuz kimlik tanımı ve on dört bağlama kaydıdır.

Dokuz adımın **üçü hiç sır kullanmıyor** — biçim çözümlemesi, birim sınaması, sözleşme sınaması —
ama tek kimlikte o üçü de on iki sırra erişiyordu. Bu bir kusur değil bir varsayılandır: kimlik
hatta verilir, adıma değil. Ele geçen adımın ulaştığı kayıt 18'den **en çok 5'e** iner.

Son satır kapının öteki yüzüdür: gerçek ihtiyaç dokuz sır, bildirilen yedi, iki iş durur.
**Yanlış tutmanın kaynağı kısıtlama değil, yine bir listedir** — `hat-tasarimi/08`'de tetikleyici
filtresi, `hat-tasarimi/05`'te önbellek anahtarı aynı yerden bozulmuştu.

## İki İş Arasında Taşınan

**DD33.** Çalıştırıcıda dört durum türü taşınabilir: önbellek, ortam değişkeni, artık dosya,
kimlik belleği; bırakma ve okuma çekilişleri tohum `70413+i`'den gelir. **DD34.** Koşum tabanı
120 saniye, önbellek isabeti 45 saniye kazandırır.

```js
// olcum-agi/yalitim.mjs — ayni calistiricida art arda kosan isler arasinda tasinan durum (model)
const uretec = (tohum) => () =>
  (tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648;
const TUR = ["onbellek", "ortam degiskeni", "artik dosya", "kimlik bellegi"];

// Kurgu is dizisi: on iki is, dort servis, biri dis katkidan gelir. Her is bazi durumlari
// birakir, bazilarini okur; birakma ve okuma cekilisleri tohumdan gelir.
const IS = Array.from({ length: 12 }, (_, i) => {
  const r = uretec(70413 + i);
  return { no: i + 1, disKatki: i === 6,
    birakir: TUR.filter((_, k) => k === 0 || r() < 0.45),      // onbellek her zaman birakilir
    okur: TUR.filter(() => r() < 0.5) };
});

// Uc yalitim duzeyi: hangi tur is arasinda silinir.
const DUZEY = [
  ["paylasilan calistirici", []],
  ["is basina temiz calisma alani", ["artik dosya"]],
  ["is basina yeni calistirici", TUR],
];

// Bedel: isabet dusunce kosum uzar. Taban 120 s, isabet 45 s kazandirir.
const SUTUN = [31, 10, 9, 8, 8, 14, 10, 0];
const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(SUTUN[i])).join(""));
satir(["yalitim", "onbellek", "ortam", "artik", "kimlik", "toplam / disa", "isabet", "on iki is"]);

for (const [ad, silinen] of DUZEY) {
  const sayim = Object.fromEntries(TUR.map((t) => [t, 0]));
  let disaTasan = 0, isabet = 0;
  const kalan = new Map();                        // tur -> birakan isin numarasi
  for (const is of IS) {
    for (const t of silinen) kalan.delete(t);     // is baslamadan once temizlenen turler
    for (const t of is.okur) {
      if (!kalan.has(t)) continue;
      sayim[t] += 1;                              // onceki isin durumu bu ise gecti
      if (t === "onbellek") isabet += 1;
      if (is.disKatki || kalan.get(t) === 7) disaTasan += 1;   // dis katkiya ya da ondan
    }
    for (const t of is.birakir) kalan.set(t, is.no);
  }
  const toplam = TUR.reduce((a, t) => a + sayim[t], 0);
  satir([ad, ...TUR.map((t) => sayim[t]), `${toplam} / ${disaTasan}`,
    `${isabet}/${IS.length}`, `${IS.length * 120 - isabet * 45} s`]);
}
```

```
yalitim                        onbellek  ortam    artik   kimlik  toplam / disa isabet    on iki is
paylasilan calistirici         6         9        8       5       28 / 5        6/12      1170 s
is basina temiz calisma alani  6         9        0       5       20 / 4        6/12      1170 s
is basina yeni calistirici     0         0        0       0       0 / 0         0/12      1440 s
```

Paylaşılan çalıştırıcıda on iki iş arasında **28 taşıma** olur; beşinin bir ucunda dış katkıdan
gelen iş vardır. Yalnız altısı önbellektir — dokuzu ortam değişkeni, sekizi artık dosya, **beşi
kimlik belleği**, yani bir öncekinin çözdüğü jetonun bellekte kalması. Yetki yüzeyindeki "adım
başına kimlik" kazancı burada delinir: yetkiyi adıma bağlamak, adımın bıraktığını sonrakinin
okumasını engellemiyor.

Orta satır en sık uygulanan yalıtımdır: çalışma alanını temizlemek artık dosyaların **sekizini
sıfıra indirir**, ama ortam değişkeni ve kimlik belleği kalır — toplam 20, dışa taşan dört,
**taşımanın %71'i hâlâ açık.**

İş başına yeni çalıştırıcı dördünü birden kapatır: **28 taşımanın 28'i sıfırlanır.** Bedeli tek
kalemdir — isabet altıdan sıfıra düşer, on iki iş 1.170 yerine **1.440 saniye** sürer: 270
saniye, **%23.** Çalıştırıcı türlerinin para hesabı `hat-tasarimi/06`'da ölçüldü ve tekrarlanmaz;
buradaki yenilik, oradaki "temiz başlama" üstünlüğünün bir de **taşıma sayısı** olarak
okunmasıdır.

## Bilinen Kötüye Kullanım Kümesi

**DD35.** Kötüye kullanım kümesi kurgudur: üç sınıfta 40 girişim ve 60 meşru iş, tohum `56092`.
Bir girişim, yollarından en az biri açıkken başarılıdır. **DD36.** "Yetkili özne" yolu hiçbir
kısıtlamanın kapatmadığı yoldur.

```js
// olcum-agi/kotuye-kullanim.mjs — bilinen kotuye kullanim kumesi ve kisitlamalarin defteri (model)
const uretec = (tohum) => () =>
  (tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648;
const r = uretec(56092);                          // tohum gorunur
const SINIF = [
  ["dis katkidan sirra erisim", "dis-katki-sirri", "tasinan-durum", 0.40],
  ["bagimlilik uzerinden kod kosturma", "kurulum-betigi", "tasinan-durum", 0.30],
  ["hat tanimini degistirme", "tanim-degisikligi", "dis-katki-sirri", 0.25],
];

// Kurgu defterler. Bir girisim, yollarindan en az biri acikken basarili olur.
const GIRISIM = Array.from({ length: 40 }, () => {
  const [ad, yol, ikinci, p] = SINIF[Math.floor(r() * SINIF.length)];
  const yollar = [yol];
  if (r() < p) yollar.push(ikinci);
  if (r() < 0.15) yollar.push("yetkili-ozne");    // hicbir kisitlamanin kapatmadigi yol
  return { sinif: ad, yollar };
});
const MESRU = Array.from({ length: 60 }, () => ({
  disKatki: r() < 0.35, sirIster: r() < 0.30,
  kurulumBetigi: r() < 0.12, tanimDegisikligi: r() < 0.18,
}));

const KISIT = [
  ["dis katkida sir verilmez", "dis-katki-sirri", (m) => m.disKatki && m.sirIster],
  ["dis katki isleri elle onay bekler", "dis-katki-sirri", (m) => m.disKatki],
  ["bagimlilik kurulum betigi kosturulmaz", "kurulum-betigi", (m) => m.kurulumBetigi],
  ["hat tanimi degisikligi ayri onay ister", "tanim-degisikligi", (m) => m.tanimDegisikligi],
  ["is basina yeni calistirici", "tasinan-durum", () => false],
];
const gecen = (aktif) => GIRISIM.filter((g) =>
  g.yollar.some((y) => !aktif.some(([, kapali]) => kapali === y))).length;
const TAM = gecen(KISIT);

const SUTUN = [40, 12, 11, 0];
const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(SUTUN[i])).join(""));
satir(["kisitlama", "kapattigi", "marjinal", "durdurdugu mesru is"]);
for (const k of KISIT)
  satir([k[0], GIRISIM.filter((g) => g.yollar.includes(k[1])).length,
    gecen(KISIT.filter((o) => o !== k)) - TAM, MESRU.filter(k[2]).length]);

const sifir = KISIT.filter((k) => gecen(KISIT.filter((o) => o !== k)) === TAM);
console.log("");
console.log(`girisim ${GIRISIM.length} (${SINIF.map(([a]) =>
  GIRISIM.filter((g) => g.sinif === a).length).join("/")}), mesru is ${MESRU.length}; tohum 56092`);
console.log(`kisitlama yokken gecen ${GIRISIM.length}, tam kumede ${TAM} ` +
  `— hepsi yetkili ozne yolundan`);
console.log(`marjinali sifir ${sifir.length}: ${sifir.map((k) => k[0]).join(" | ")}; ` +
  `ikisi birden kaldirilinca gecen ` +
  `${gecen(KISIT.filter((o) => o[1] !== "dis-katki-sirri"))}/${GIRISIM.length}`);
```

```
kisitlama                               kapattigi   marjinal   durdurdugu mesru is
dis katkida sir verilmez                16          0          7
dis katki isleri elle onay bekler       16          0          16
bagimlilik kurulum betigi kosturulmaz   14          12         8
hat tanimi degisikligi ayri onay ister  13          12         9
is basina yeni calistirici              5           3          0

girisim 40 (13/14/13), mesru is 60; tohum 56092
kisitlama yokken gecen 40, tam kumede 5 — hepsi yetkili ozne yolundan
marjinali sifir 2: dis katkida sir verilmez | dis katki isleri elle onay bekler; ikisi birden kaldirilinca gecen 19/40
```

Tam kısıtlama kümesi kırk girişimin **otuz beşini** kapatır. Geçen beşi aynı yoldan geçer:
**yetkili öznenin kendi yetkisini kullanması.** Hiçbir kısıtlama onu kapatmaz, çünkü kapatmak
yetkiyi kaldırmak demektir; `depo-tabanli-dagitim/05`'teki "anahtara erişen imzalayabilir"
sınırının karşılığı budur — %12,5.

Marjinal sütunu kısıtlamaları ayırır: kurulum betiği yasağı **12**, hat tanımı onayı **12**
girişimi tek başına kapatır. İş başına yeni çalıştırıcı 5 kapatır, 3'ü marjinaldir ve **hiçbir
meşru işi durdurmaz** — bedeli yalnız 270 saniyedir.

Son satır **kaldırılması daha iyi olan kısıtlamayı** verir. İki kısıtlamanın marjinali sıfırdır,
çünkü aynı yolu kapatırlar; ikisi birden kaldırılınca geçen girişim **19'a** çıkar, yani yol
kapalı kalmalıdır. Hangisiyle kapatılacağını meşru iş sütunu söyler: "sır verilmez" 7, "elle onay
bekler" **16** işi durdurur. Aynı korumayı iki kat pahalıya alan kaldırılır.

## Özet

- Tek hat kimliğinde 162 erişimin 162'si açıktır, adım başına kimlikte 14'ü; düşen 148 erişim
  yüzeyin %91'idir, bedeli 9 kimlik tanımı ve 14 bağlama kaydıdır.
- Dokuz adımın üçü hiç sır kullanmaz ama tek kimlikte on iki sırra erişir; ele geçen adımın
  ulaştığı kayıt 18'den en çok 5'e iner. Bildirimi eksik 2 adım 2 meşru işi durdurur.
- Paylaşılan çalıştırıcıda 28 taşıma olur (6/9/8/5), 5'inin ucunda dış katkı vardır; çalışma
  alanı temizliği 20'ye, yeni çalıştırıcı 0'a indirir. Bedeli 1.170 yerine 1.440 saniyedir.
- Tam kısıtlama kümesi 40 girişimin 35'ini kapatır; geçen 5'in hepsi, hiçbir kısıtlamanın
  kapatmadığı yetkili özne yolundandır.
- Marjinali sıfır iki kısıtlama aynı yolu kapatır; ikisi birden kaldırılınca geçen girişim 19'a
  çıkar. Yol kapalı kalmalı, 16 meşru işi durduranla değil 7'sini durduranla.

## Kurs Kapanışı

| Ders | Kapı | Tuttuğu / kaçırdığı / yanlış tuttuğu | Eklediği süre |
|---|---|---|---|
| `hat-tasarimi/01` | birleştirme | 90 çatışma / 10 uyuşmazlık / 2 | 23 dk/değişiklik |
| `hat-tasarimi/02` | elle onay | 5, marjinal 2 / 38 / 26 | 226,5 dk bekleme |
| `hat-tasarimi/03` | sözleşme sınaması | 18, marjinal 1 / 119 / 17 | 6.138 çalıştırıcı dk |
| `hat-tasarimi/04` | saklama kuralı | 38, marjinal 1 / 2 / 47 | 338 dk kurtarma |
| `hat-tasarimi/05` | tümleşim sınaması | 3, marjinal 2 / 2 önbellekten / — | 768 s, sekiz koşum |
| `hat-tasarimi/06` | temiz çalıştırıcı | 8, marjinal 2 / 0 / 0 | 40 s/koşum |
| `hat-tasarimi/07` | şema doğrulayıcısı | 4 hata / 2 hata / 0 | 80 s, yirmi değişiklik |
| `hat-tasarimi/08` | yol filtresi | 7 gereksiz koşum / 0 / 10 | 3,1 saat gecikme |
| `yayin-stratejileri/01` | tümleştirme | 34, marjinal 24 / 8 / 2–54 | 490–1.638 kapı dk |
| `yayin-stratejileri/02` | ortam terfisi | 7, marjinal 7 ve 1 / 7 / 5 | 3 sa 56 dk bekleme |
| `yayin-stratejileri/03` | yüzde artırma | 200/200 belirgin / %18–60 silik / %27–32 | 30–70 dk merdiven |
| `yayin-stratejileri/04` | geri alma | 18, tek turda 11 / 7 yayın, 491 satır / 178 | 40.320 kopya-dk |
| `yayin-stratejileri/05` | bayrak koşulu | 0, 76 fatura / 4 yol / 1 bekleyen | 18 okuma noktası |
| `yayin-stratejileri/06` | ön koşul denetimi | 5, marjinal 2 / 1 / 2 | 12 tur, 17 tur bedel |
| `yayin-stratejileri/07` | uyumluluk denetimi | 1, marjinal 1 / 1 / 1 | 3 tur, üç şema adımı |
| `depo-tabanli-dagitim/01` | gözden geçirme | 24, marjinal 13 / 11 / 7 | 796 saat, doksan gün |
| `depo-tabanli-dagitim/02` | uzlaştırma turu | 48, marjinal 17 / 6 / 9 | 8,5 dk yayılma |
| `depo-tabanli-dagitim/03` | çözme yetkisi | 682 çift, hepsi marjinal / 35 / 11 | 385 dk eskalasyon |
| `depo-tabanli-dagitim/04` | çıktı ağacı denetimi | 14, hepsi marjinal / 0 / 3 | 12 dosya/değişiklik |
| `depo-tabanli-dagitim/05` | dağıtımda doğrulama | 18 sahte, hepsi marjinal / 0 / 18 | özet ve liste araması |
| `depo-tabanli-dagitim/06` | en az yetki, yalıtım | 35, marjinal 12-12-3 / 5 özne / 16 | 270 s, on iki iş |

Kursun kuralı tablodan okunur: **bir kapı yalnız kendisinin yakaladığı kusur kadar değerlidir;
tuttuğu, kaçırdığı ve beklettiği birlikte yazılmadıkça kapı savunulamaz.** Tuttuğu sayısı tek
başına karar taşımaz — biçim kapısı 51 tutup 51'ini tek başına tutar, sözleşme kapısı 18 tutup
1'ini.

Marjinali sıfır çıkan kapılar kursta dört yerde ölçüldü: `hat-tasarimi/08`'in zaman tetikleyicisi
(84 boş koşum, gecikmeye katkı 0,0 saniye), `depo-tabanli-dagitim/04`'ün beyan dosyalarını okuyan
kapısı (beyan dışı bileşenin sıfırını tutar), `depo-tabanli-dagitim/05`'in hat sonu doğrulaması
(18 sahtenin 18'ini geçirir) ve buradaki "elle onay bekler" (16 meşru iş). Dördü de
kaldırılabilir; sebep zayıf olmaları değil, **başkasının zaten tuttuğunu tutmalarıdır.** Ölçü
ters yönde de çalışır: `hat-tasarimi/07`'nin gözden geçirmesi 714 dakikada tek bir hata tutar,
ama o hata bir kapıyı kaldıran değişikliktir.

Hat artık uygulamayı üretime taşıyor ve yolun her adımı sayılı. Altındaki makineler, ağ ve
depolar ise hâlâ başka bir yolla kuruluyor: hiçbir kapıdan geçmeyen, kaydı tutulmayan, geri alma
birimi tanımsız bir yolla. **M22/K05 Kod Olarak Altyapı** bunu sorar — onlar da aynı kapılardan
geçebilir mi, ve geçtiklerinde bu tablonun yirmi bir satırı onlar için ne gösterir?
