---
title: 'Köken Bilgisi'
source: 'https://academia.sh/tr/kurslar/guvenlik-otomasyonu/koken-bilgisi'
course: 'Güvenlik Otomasyonu ve Tedarik Zinciri'
language: tr
updated: '2026-08-17T18:06:44+00:00'
license: 'CC BY-SA 4.0'
---

# Köken Bilgisi

Yapının nerede ve nasıl üretildiğini anlatan belge alan alan kurulur ve tek bir sayıya indirgenir: on dört alanın kaçı bağımsız olarak doğrulanabiliyor, kaçı yalnız beyan olarak kalıyor, yeniden üretim kaç alanı kanıta çeviriyor ve doğrulama eşiği yükseldikçe hattan kaç saniye gidiyor.

Önceki ders imzanın kapsadığı alan ile doğrulayıcının sınayabildiği alanı ayırdı: beyan dokuz
alana çıktığında imza dokuzunu da kapsıyordu, ama doğrulayıcı yalnız birini yeniden
hesaplayabiliyordu. Kalan sekiz alan imzalanmış olarak geçiyordu ve imzalı olmak onları
doğru yapmıyordu.

Bu ders o sekiz alanın yerine geçen belgeyi kurar: yapının nerede ve nasıl üretildiğini anlatan
köken bilgisi. Ölçü tek bir sayıdır — belgenin kaç alanı **bağımsız olarak doğrulanabiliyor**,
kaçı yalnız beyan olarak kalıyor. Bir alan, doğrulayanın kendi elde edebildiği bir nesneden
yeniden hesaplanabiliyorsa kanıttır; hesaplanamıyorsa beyandır ve doğruluğu onu yazana güvenmeye
kalır.

**TZ11.** Köken belgesi dört öbekte on dört alandır: hangi kaynak, hangi işlem, hangi ortam, hangi
girdi. Belge ve nesneler `node` ile modellenir. **TZ12.** Doğrulayıcının bağımsız elde edebildiği
nesne kümesi dörttür: kaynak ağacı, yapı tanımı dosyası, bağımlılık kilit dosyası ve yapı
çıktısının baytları.

## Belgenin On Dört Alanı

```js
// olcum-agi/koken.mjs — koken belgesi alan alan kurulur: kaci bagimsiz dogrulanabiliyor
import { createHash } from "node:crypto";

const ozet = (b) => createHash("sha256").update(b).digest("hex").slice(0, 12);

// Kurgu bagimsiz nesneler: dogrulayici bunlari kendi elde edebilir ve yeniden ozetleyebilir.
const KAYNAK = Buffer.from(["ana.js", "olcum.js", "ayar.json"]
  .map((y) => `${y}\n// kurgu abone portali\n`).join(""));
const YAPI_TANIMI = Buffer.from("adim: derle, sina, paketle, imzala\n");
const KILIT = Buffer.from(Array.from({ length: 73 }, (_, i) => `bilesen-${i}@2.0`).join("\n"));
const CIKTI = Buffer.concat([Buffer.from("abone-portali\n"), Buffer.alloc(16384, "u")]);
const ELDEKI = { kaynak: KAYNAK, "yapi-tanimi": YAPI_TANIMI, kilit: KILIT, cikti: CIKTI };

// Koken belgesi: dort obek, on dort alan. `yazilan` belgeye konan deger.
const BELGE = [
  ["kaynak", "depo", "abone-portali", false],
  ["kaynak", "isleme", ozet(KAYNAK), true],
  ["kaynak", "dal", "ana", false],
  ["islem", "yapi-tanimi", ozet(YAPI_TANIMI), true],
  ["islem", "adim-listesi", "derle, sina, paketle, imzala", false],
  ["islem", "cagri-parametresi", "hedef=uretim", false],
  ["ortam", "calistirici-turu", "yalitilmis-kap", false],
  ["ortam", "temel-imaj", "7ad3e1c95006", false],
  ["ortam", "yalitim-duzeyi", "is basina yeni calistirici", false],
  ["ortam", "ag-erisimi", "kapali", false],
  ["girdi", "kilit", ozet(KILIT), true],
  ["girdi", "ortam-degiskeni-adlari", "HEDEF, SURUM", false],
  ["girdi", "onbellek-anahtari", "b41c-2", false],
  ["cikti", "cikti", ozet(CIKTI), true],
];

// Bir alan ancak elde edilebilir bir nesneden yeniden hesaplanabiliyorsa kanittir.
const S = [8, 24, 29, 0];
const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(S[i])).join(""));
satir(["obek", "alan", "dogrulama yolu", "tur"]);
let kanit = 0;
for (const [obek, alan, yazilan, hesaplanir] of BELGE) {
  if (hesaplanir) kanit++;
  satir([obek, alan, hesaplanir ? "nesne yeniden ozetlenir" : "karsilastirilacak nesne yok",
    hesaplanir ? "kanit" : "beyan"]);
}
console.log("");
console.log(`belge ${BELGE.length} alan: ${kanit} kanit, ${BELGE.length - kanit} beyan`);

// Bes alana kasten yanlis deger yazilir; dogrulayici elindeki nesnelerle sinar.
const YANLIS = { isleme: "0000deadbeef", "yapi-tanimi": "111122223333",
  "temel-imaj": "999988887777", "yalitim-duzeyi": "paylasilan calistirici", cikti: "aaaabbbbcccc" };
const anahtar = { isleme: "kaynak", "yapi-tanimi": "yapi-tanimi", kilit: "kilit", cikti: "cikti" };
let yakalanan = 0;
for (const [, alan, , hesaplanir] of BELGE) {
  if (!(alan in YANLIS)) continue;
  if (hesaplanir && ozet(ELDEKI[anahtar[alan]]) !== YANLIS[alan]) yakalanan++;
}
console.log(`kasten yanlis yazilan ${Object.keys(YANLIS).length} alanin ${yakalanan} tanesi ` +
  `yakalandi, ${Object.keys(YANLIS).length - yakalanan} tanesi beyan oldugu icin sinanmadi`);
```

```
obek    alan                    dogrulama yolu               tur
kaynak  depo                    karsilastirilacak nesne yok  beyan
kaynak  isleme                  nesne yeniden ozetlenir      kanit
kaynak  dal                     karsilastirilacak nesne yok  beyan
islem   yapi-tanimi             nesne yeniden ozetlenir      kanit
islem   adim-listesi            karsilastirilacak nesne yok  beyan
islem   cagri-parametresi       karsilastirilacak nesne yok  beyan
ortam   calistirici-turu        karsilastirilacak nesne yok  beyan
ortam   temel-imaj              karsilastirilacak nesne yok  beyan
ortam   yalitim-duzeyi          karsilastirilacak nesne yok  beyan
ortam   ag-erisimi              karsilastirilacak nesne yok  beyan
girdi   kilit                   nesne yeniden ozetlenir      kanit
girdi   ortam-degiskeni-adlari  karsilastirilacak nesne yok  beyan
girdi   onbellek-anahtari       karsilastirilacak nesne yok  beyan
cikti   cikti                   nesne yeniden ozetlenir      kanit

belge 14 alan: 4 kanit, 10 beyan
kasten yanlis yazilan 5 alanin 3 tanesi yakalandi, 2 tanesi beyan oldugu icin sinanmadi
```

Belge on dört alan taşır ve **dördü kanıttır**. Dördünün ortak özelliği şudur: hepsi bir nesnenin
özetidir ve o nesne doğrulayanın elinde vardır. İşleme özeti kaynak ağacından, yapı tanımı özeti
depodaki dosyadan, kilit özeti bağımlılık kilit dosyasından, çıktı özeti yapı çıktısının
baytlarından yeniden hesaplanır. Belge yanlış yazsa bile bu dört alanda yalan tutmaz.

Kalan **on alan beyandır** ve ilginç olan, aralarında hiç önemsiz bir alan bulunmamasıdır. Yalıtım
düzeyi, ağ erişimi, çalıştırıcı türü ve temel imaj — dördü de yapının güvenilirliğine dair en çok
şey söyleyen alanlardır. Hiçbiri sınanamaz, çünkü hiçbirinin karşılığı doğrulayanın elde
edebileceği bir nesne değildir. "Ağ erişimi kapalıydı" cümlesi yapıyı koşturan tarafın kendi
hakkında verdiği bir ifadedir.

Son satır bu ayrımı sayıya çevirir: beş alana kasten yanlış değer yazıldığında **üçü yakalanır,
ikisi sınanmaz**. Yakalanmayan ikisi temel imaj ve yalıtım düzeyidir. Belgede "iş başına yeni
çalıştırıcı" yazar, gerçekte paylaşılan çalıştırıcı kullanılmıştır ve hiçbir doğrulama bunu
görmez. **Bir köken belgesinin değeri alan sayısıyla değil, kanıt olan alan sayısıyla ölçülür.**

## Yeniden Üretim Neyi Kanıta Çevirir

On beyan alanının bir bölümü aslında çıktıya girer: adım listesi, çağrı parametresi ve temel imaj
farklı olsaydı çıktı da farklı olurdu. Bu, sınanabilirlik için bir kaldıraç sunar — aynı bildirilen
girdilerle yapı yeniden koşturulur ve çıktı aynı çıkarsa bildirim doğrulanmış olur.

**TZ13.** Yapı işlevi kurgudur ve bildirilen girdilerden çıktı üretir. On iki yapının üçünde
**bildirilmemiş bir girdi** çıktıya girer, birinde çıktı sonradan değiştirilmiştir; tohum `410277`
görünürdür.

```js
// olcum-agi/yeniden-uretim.mjs — yeniden uretim hangi alani kanita cevirir
import { createHash } from "node:crypto";

const ozet = (b) => createHash("sha256").update(b).digest("hex").slice(0, 12);
// Kurgu yapi islevi: bildirilen girdilerden cikti uretir. Gizli girdi varsa ciktiya o da girer.
const yap = (g) => Buffer.from([g.kaynak, g.kilit, g.adimlar, g.parametre, g.temelImaj,
  g.gizli ?? ""].join("|"));

const uretec = (tohum) => () =>
  (tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648;
const r = uretec(410277);                                  // tohum gorunur

// On iki kurgu yapi. Uc tanesinde bildirilmemis girdi var, birinde cikti sonradan degistirildi.
const GIZLI = [3, 7, 11], DEGISTIRILEN = 9;
const YAPI = Array.from({ length: 12 }, (_, i) => {
  const no = i + 1;
  const girdi = { kaynak: `kaynak-${no}`, kilit: `kilit-${no}`, adimlar: "derle,sina,paketle",
    parametre: "hedef=uretim", temelImaj: no % 2 ? "temel-a" : "temel-b" };
  const gercek = yap(GIZLI.includes(no) ? { ...girdi, gizli: `kosum-${Math.floor(r() * 900)}` } : girdi);
  const beyanEdilen = no === DEGISTIRILEN ? ozet(Buffer.from("degistirilmis")) : ozet(gercek);
  return { no, girdi, beyanEdilen, gizliVar: GIZLI.includes(no) };
});

const S = [7, 16, 18, 12, 0];
const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(S[i])).join(""));
satir(["yapi", "beyan edilen", "yeniden uretilen", "eslesme", "sebep"]);
let eslesen = 0, gercekBulgu = 0, yanlisIsaret = 0;
for (const y of YAPI) {
  const tekrar = ozet(yap(y.girdi));                       // yalniz BILDIRILEN girdilerle
  const esit = tekrar === y.beyanEdilen;
  if (esit) eslesen++;
  else if (y.gizliVar) yanlisIsaret++;
  else gercekBulgu++;
  if (y.no <= 4 || !esit)
    satir([y.no, y.beyanEdilen, tekrar, esit ? "evet" : "HAYIR",
      esit ? "-" : (y.gizliVar ? "bildirilmemis girdi" : "cikti degistirilmis")]);
}
console.log("");
console.log(`on iki yapinin ${eslesen}'i yeniden uretimde eslesiyor, ` +
  `${YAPI.length - eslesen} tanesi eslesmiyor: ${gercekBulgu} gercek, ${yanlisIsaret} yanlis isaret`);

// Yeniden uretim, ciktiya giren her bildirilen girdiyi sinanabilir kilar.
const CIKTIYA_GIREN = ["adim-listesi", "cagri-parametresi", "temel-imaj"];
const ONCE = 4, ALAN = 14;
console.log(`kanit alani ${ONCE}/${ALAN} -> ${ONCE + CIKTIYA_GIREN.length}/${ALAN}; ` +
  `sinanabilir hale gelen: ${CIKTIYA_GIREN.join(", ")}`);
console.log(`beyan olarak kalan ${ALAN - ONCE - CIKTIYA_GIREN.length}: ` +
  `depo, dal, calistirici-turu, yalitim-duzeyi, ag-erisimi, ortam-degiskeni-adlari, onbellek-anahtari`);
```

```
yapi   beyan edilen    yeniden uretilen  eslesme     sebep
1      bf07d2a43010    bf07d2a43010      evet        -
2      1ddced3cf18e    1ddced3cf18e      evet        -
3      e8ef828e21d6    708285ad34af      HAYIR       bildirilmemis girdi
4      ec17c7d09dca    ec17c7d09dca      evet        -
7      02dfd006731d    7837452fb129      HAYIR       bildirilmemis girdi
9      3dfd53002487    9c98f23fe16b      HAYIR       cikti degistirilmis
11     1e1126a5aff6    1f5be23c2504      HAYIR       bildirilmemis girdi

on iki yapinin 8'i yeniden uretimde eslesiyor, 4 tanesi eslesmiyor: 1 gercek, 3 yanlis isaret
kanit alani 4/14 -> 7/14; sinanabilir hale gelen: adim-listesi, cagri-parametresi, temel-imaj
beyan olarak kalan 7: depo, dal, calistirici-turu, yalitim-duzeyi, ag-erisimi, ortam-degiskeni-adlari, onbellek-anahtari
```

Yeniden üretim kanıt alanını **4'ten 7'ye** çıkarır. Kazanılan üç alanın hepsi çıktıya giren
girdilerdir: adım listesi, çağrı parametresi ve temel imaj yanlış yazılsaydı yeniden üretilen çıktı
tutmazdı. Kalan yedi alan hiçbir koşulda sınanabilir hale gelmez, çünkü **çıktıya hiç girmezler**.
Dal adı, çalıştırıcı türü, yalıtım düzeyi ve önbellek anahtarı üretilen baytları etkilemez; bir
şeyi etkilemeyen bildirim de o şeyden geri okunamaz. Belgenin yarısı beyan olarak kalır ve bu bir
eksiklik değil, yöntemin sınırıdır.

Ortadaki iki sayı ise kaldıracın bedelidir. On iki yapının dördü eşleşmez ve dördünden **yalnız
biri gerçektir**; üçünde çıktıya bildirilmemiş bir girdi karışmıştır — koşum numarası, üretim anı,
çalıştırıcı adı gibi bir değer. Bu üçünde yapı doğrudur, belge doğrudur, değişen tek şey ilan
edilmemiş bir girdinin çıktıya sızmasıdır. **Yanlış işaret oranı %75'tir** ve bu oran taramanın
işe yaramadığı durumun tam tanımıdır: dört uyarının üçü boşuna incelenirse dördüncüsü de aynı
işaretin altında kalır.

Yanlış işaretin kaynağı da yöntemin kendisindedir. Yeniden üretim, bildirilen girdi kümesinin
**eksiksiz** olduğunu varsayar; eksikse fark çıktıda görünür ama farkın nedeni belgede yazmaz.
Eşleşmeyen bir yapının hangi sınıfa girdiğini anlamak için çıktı baytları karşılaştırılır ve sızan
değer elle bulunur — bu, uyarı başına ayrı bir inceleme demektir. Üç yanlış işaretin üçü de
düzeltilebilir kusurlardır; düzeltmenin yolu belgeye alan eklemek değil, o değeri çıktıdan
çıkarmaktır. Kaldıracın kullanılabilir olması için yapının önce ilan edilmemiş girdiden
arındırılması gerekir ve bu iş kökene değil, yapı tanımına aittir.

## Eşik Yükseldikçe

Üç ölçüm bir politika sorusunu doğurur: dağıtımdan önce hangi eşik aranmalı?

**TZ14.** Kırk kurgu dağıtım isteği vardır; bozuk istekler de **geçerli imza taşır** — önceki
dersin sonucudur, imza iddiayı kanıtlamaz. Köken üretimi 12 saniye, yeniden üretim 214 saniye
olarak **veri** verilmiştir, ölçülmüş değildir; tohum `87344` görünürdür.

```js
// olcum-agi/koken-esigi.mjs — dogrulama esigi yukseldikce gecen, bloke olan ve hattan giden sure
const uretec = (tohum) => () =>
  (tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648;
const r = uretec(87344);                                   // tohum gorunur

// Bozuk istek de gecerli imza tasir: onceki dersin sonucu — imza iddiayi kanitlamaz.
const ISTEK = Array.from({ length: 40 }, () => {
  const bozuk = r() < 0.12;
  return { bozuk, imzali: true, kokenVar: bozuk || r() < 0.85,
    kanitUyuyor: !bozuk, gizliGirdi: r() < 0.18 };         // gizli girdi: yeniden uretim eslesmez
});

// Sureler VERI olarak verilmistir, olculmus degil: koken uretimi 12 s, yeniden uretim 214 s.
const KOKEN_S = 12, TEKRAR_S = 214;
const ESIK = [
  ["imza yeter", (i) => i.imzali, 0],
  ["imza + koken belgesi", (i) => i.imzali && i.kokenVar, KOKEN_S],
  ["imza + dort kanit alani", (i) => i.imzali && i.kokenVar && i.kanitUyuyor, KOKEN_S],
  ["imza + yeniden uretim", (i) => i.imzali && i.kokenVar && i.kanitUyuyor && !i.gizliGirdi,
    KOKEN_S + TEKRAR_S],
];

const BOZUK = ISTEK.filter((i) => i.bozuk).length;
const S = [26, 9, 9, 14, 0];
const satir = (s) => console.log(s.map((v, i) => String(v).padEnd(S[i])).join(""));
satir(["esik", "gecen", "bloke", "yanlis bloke", "kacan bozuk / hat suresi"]);
for (const [ad, kural, sure] of ESIK) {
  const gecen = ISTEK.filter(kural);
  const bloke = ISTEK.filter((i) => !kural(i));
  satir([ad, gecen.length, bloke.length, bloke.filter((i) => !i.bozuk).length,
    `${gecen.filter((i) => i.bozuk).length} / ${sure * ISTEK.length} s`]);
}
console.log("");
console.log(`istek ${ISTEK.length}, gercekten bozuk ${BOZUK}, ` +
  `bildirilmemis girdi tasiyan ${ISTEK.filter((i) => i.gizliGirdi).length}, ` +
  `koken belgesi olmayan ${ISTEK.filter((i) => !i.kokenVar).length}; tohum 87344`);
```

```
esik                      gecen    bloke    yanlis bloke  kacan bozuk / hat suresi
imza yeter                40       0        0             4 / 0 s
imza + koken belgesi      35       5        5             4 / 480 s
imza + dort kanit alani   31       9        5             0 / 480 s
imza + yeniden uretim     26       14       10            0 / 9040 s

istek 40, gercekten bozuk 4, bildirilmemis girdi tasiyan 7, koken belgesi olmayan 5; tohum 87344
```

İkinci satır bu kursun en sık karşılaşılan yanılgısını sayıya çevirir. Köken belgesinin **varlığını**
aramak dört bozuk isteğin dördünü de geçirir — belge bozuk isteklerde de vardır, çünkü belgeyi
üreten yapının kendisidir. Karşılığında hattan 480 saniye gider ve **beş meşru istek yanlış yere
bloke olur**. Marjinal değeri sıfır olan bir kapı budur: bir alanı dolduran, hiçbir şeyi
karşılaştırmayan bir aşama.

Üçüncü satır aynı 480 saniyeyle dört bozuk isteğin dördünü de tutar. Aradaki fark tek bir işlemdir:
belgenin dört kanıt alanı, doğrulayanın kendi elde ettiği nesnelerle **karşılaştırılır**.
Yanlış bloke sayısı değişmez, kaçan bozuk 4'ten 0'a iner. **Köken belgesinin değeri üretilmesinde
değil, karşılaştırılmasındadır.**

Dördüncü satır kaldıracın fiyatını gösterir. Yeniden üretim hiçbir yeni bozuk isteği tutmaz — dördü
zaten üçüncü satırda tutulmuştu — ama hat süresini 480 saniyeden **9.040 saniyeye** çıkarır ve
yanlış bloke sayısını 5'ten 10'a, yani kırk isteğin dörtte birine yükseltir. Kanıt alanını 7'ye
çıkarmanın karşılığı budur ve karşılığın ödenip ödenmeyeceği kaçan bozuk sayısına bakılarak karar
verilir, alan sayısına bakılarak değil. Dört isteğinden birinin boşuna durduğu bir eşik, eninde
sonunda atlanan bir eşiktir.

## Özet

- Köken belgesi dört öbekte on dört alandır; 4 alan kanıt, 10 alan beyandır. Kanıt olanların ortak
  özelliği, doğrulayanın elindeki bir nesnenin özeti olmalarıdır.
- Beyan kalan on alan arasında önemsiz alan yoktur: yalıtım düzeyi, ağ erişimi, çalıştırıcı türü ve
  temel imaj sınanamaz. Kasten yanlış yazılan beş alanın 3'ü yakalanır, 2'si sınanmaz.
- Yeniden üretim kanıt alanını 4'ten 7'ye çıkarır; kazanılan üç alan çıktıya giren girdilerdir.
  Kalan 7 alan hiçbir koşulda sınanamaz, çünkü üretilen baytları etkilemez.
- On iki yapının 4'ü yeniden üretimde eşleşmez ve yalnız 1'i gerçektir; yanlış işaret oranı %75'tir.
- Köken belgesinin varlığını aramak 4 bozuk isteğin 4'ünü de geçirir ve 480 saniye alır; aynı süreyle
  dört kanıt alanını karşılaştırmak kaçan bozuğu 0'a indirir. Yeniden üretim eşiği hiçbir yeni bozuk
  tutmaz, hat süresini 9.040 saniyeye ve yanlış blokeyi 10'a çıkarır.

## Sonraki Adım

Köken belgesi kuruldu, kanıt ile beyan ayrıldı ve eşik yükseltmenin fiyatı yazıldı. Ortada duran
şey yedi beyan alanıdır ve bunların dördü doğrudan tek bir konuyu anlatır: yapının **hangi ortamda**
koştuğunu. Çalıştırıcı türü, yalıtım düzeyi, ağ erişimi ve ortam değişkeni adları belgede yazar,
hiçbiri sınanamaz — ve sınanamadıkları için değerleri yalnız o ortamın gerçekten öyle
kurulmuş olmasına bağlıdır.

Sonraki ders o ortamı kalem kalem sayar. Ölçü artık belgenin alanı değil, derleme ortamının kendi
yetkisidir: hat kaç sırra erişiyor, kaçı gerçekten gerekiyor, ağ erişimi kapatıldığında kaç adım
kırılıyor ve dış katkıdan gelen bir değişiklik koştuğunda kaç sır açığa çıkabiliyor?
