---
title: 'Politika ve Uyumluluk Taraması'
source: 'https://academia.sh/tr/kurslar/kod-olarak-altyapi/politika-ve-uyumluluk-taramasi'
course: 'Kod Olarak Altyapı'
language: tr
updated: '2026-08-17T18:09:07+00:00'
license: 'CC BY-SA 4.0'
---

# Politika ve Uyumluluk Taraması

Dışarıdan gelen kuralların altyapı kaydı üzerinde koşturulması: aynı politika kümesinin bir kez tanım metni üzerinde, bir kez çözülmüş plan üzerinde koşturulması, iki taramanın yakalanan, kaçan ve yanlış alarm sayılarının karşılaştırılması, hesaplanan değerlerin tanım taramasından nasıl kaçtığı, erkenlik ile doğruluk arasındaki değiş tokuş ve muafiyet kaydının rapordan düşürdüğü ihlallerin sayılması.

Önceki ders kaydın **doğruluğunu** sınadı: biçimi tutuyor mu, söz dizimi geçerli mi, başvurular
çözülüyor mu. Bunların hepsi kaydın kendi kurallarıydı. Ama kusursuz bir kayıt yine de kabul
edilemez olabilir — şifrelemesi kapalı bir arşiv, açık ağa bakan bir makine ya da yedeği üç gün olan
bir veri deposu söz dizimi bakımından kusursuzdur.

**Politika taraması** dışarıdan gelen kuralları kayıt üzerinde koşturur. Yakalanan, kaçan ve yanlış
alarm üçlüsü daha önce **uygunluk işlevi** ölçülürken mimari kurallar üzerinde kurulmuştu; mekaniği
orada ölçüldüğü için burada tekrarlanmaz, değişen ölçülen nesnedir. Bu dersin sorusu şudur:
politika **tanım** üzerinde mi, yoksa **plan** üzerinde mi koşmalı? Tanım erkendir ve sağlayıcıya
hiç bağlanmaz ama yalnız yazılanı görür; plan geçtir ve sağlayıcı çağrısı ister ama çözülmüş değeri
görür. İki tarama aynı politika kümesiyle aynı kayıt üzerinde koşturulur ve dört şey sayılır:
yakalanan, kaçan, yanlış alarm ve muafiyetin açtığı yol. Through-line **bölgesel ölçüm ağıdır** ve
kurgudur.

## Yazılan Değer ile Çözülen Değer

Bir kayıtta yazılan her değer okunduğu gibi değildir. Dört yerde metin ile gerçek ayrılır:
**değişken** (değer başka satırda tanımlıdır), **sağlayıcı varsayılanı** (alan bırakılır, değeri
sağlayıcı koyar), **küme temelli yineleme** (tek blok birden çok örneğe açılır) ve **koşul** (blok
belirli bir ortamda hiç yaratılmaz). Politikanın hangi katmanda koşacağı sorusu tam da bu dördü
yüzünden vardır.

**AD7 — ölçüm ağının üretim ortamı tek bir kayıt dosyasında tutulur ve dördünü de içerir (kurgu).**
**AD8 — sağlayıcı varsayılanları kurgudur**: makinenin genel ağ alanı boş bırakılırsa `evet`,
nesne deposunun şifreleme alanı boş bırakılırsa `hayir` gelir. **AD9 — uygulama anında atanan
değerler kayıtta `@atanacak` olarak durur ve planda da çözülmez.**

```js
// kayit.mjs — olcum aginin uretim ortami kaydini yazar; degisken, saglayici varsayilani,
// kume temelli yineleme ve kosul icerir (kurgu)
import { writeFileSync } from "node:fs";

const KAYIT = `degisken ortam = uretim
degisken sahip = olcum-ekibi
degisken yedek = 3

kaynak ag/omurga-bati:
  bolge = bati
  blok  = 10.20.0.0/16
  sahip = $sahip

kaynak ag/omurga-dis:
  bolge = bati
  blok  = 198.51.100.0/24
  sahip = $sahip

kaynak makine/toplayici:
  yinele      = bati,dogu,kuzey
  bolge       = $yinele
  genel_ip    = evet
  genel_adres = @atanacak
  sahip       = $sahip

kaynak makine/gecit:
  bolge       = bati
  genel_ip    = evet
  genel_adres = @atanacak
  sahip       = $sahip
  muafiyet    = P2:2026-03-31

kaynak makine/arsivci:
  bolge       = bati
  genel_ip    = @varsayilan
  genel_adres = @atanacak
  sahip       = $sahip

kaynak makine/deneme:
  kosul       = ortam=hazirlik
  bolge       = bati
  genel_ip    = evet
  genel_adres = @atanacak
  sahip       = $sahip

kaynak veri_deposu/olcum-deposu:
  bolge    = bati
  yedek    = $yedek
  sahip    = $sahip
  muafiyet = *:2026-06-30

kaynak kuyruk/olcum-kuyrugu:
  bolge   = bati
  saklama = 720

kaynak kuyruk/deneme-kuyrugu:
  kosul   = ortam=hazirlik
  bolge   = bati
  saklama = 720
  sahip   = $sahip

kaynak nesne_deposu/olcum-arsiv:
  bolge    = bati
  sifreli  = @varsayilan
  sahip    = $sahip
  muafiyet = P1:2025-11-30
`;

writeFileSync("kayit.tanim", KAYIT);
const say = (k) => (KAYIT.match(k) ?? []).length;
console.log(`kayit.tanim: ${KAYIT.split("\n").length - 1} satir, ${say(/^degisken /gm)} degisken, ` +
  `${say(/^kaynak /gm)} blok\n`);
console.log(`cozulmesi gereken deger: ${say(/= \$/gm)} degisken basvurusu, ` +
  `${say(/@varsayilan/g)} saglayici varsayilani, ${say(/@atanacak/g)} uygulamada atanan; ` +
  `${say(/^  yinele /gm)} yinelemeli blok, ${say(/^  kosul /gm)} kosullu blok, ` +
  `${say(/^  muafiyet /gm)} muafiyet kaydi`);
```

```
kayit.tanim: 62 satir, 3 degisken, 10 blok

cozulmesi gereken deger: 11 degisken basvurusu, 2 saglayici varsayilani, 4 uygulamada atanan; 1 yinelemeli blok, 2 kosullu blok, 3 muafiyet kaydi
```

On blok yazılıdır ama plana on blok girmez: biri yinelemeyle üç örneğe açılır, ikisi koşulu
tutmadığı için hiç girmez. Tanım katmanında on yedi değer henüz çözülmemiş durumdadır.

## İki Tarama

**AD10 — politika kümesi yedi kuraldır ve ekipçe kabul edilmiştir (kurgu).** P1 nesne deposu
şifreli olmalı, P2 makine açık ağa bakmamalı, P3 veri deposu yedeği en az yedi gün olmalı, P4 kuyruk
saklaması en çok 168 saat olmalı, P5 her kaynağın sahibi yazılmalı, P6 ağ bloğu özel aralıkta
olmalı, P7 makinenin genel adresi kayıtlı aralıkta olmalı. **AD11 — muafiyet kaydı bir politika
koduna (ya da `*` jokerine) ve bir bitiş tarihine bağlıdır; bugün 2026-02-15 kabul edilir (kurgu).**
**AD12 — plan üretimi sağlayıcıya tür başına bir çağrı yapar; çağrı dört, örnek başına plan hesabı
bir saniyedir (kurgu).**

Her politika okuduğu alanı bildirir. Bir tarama o alanın değerini çözemiyorsa — değer `$` ya da `@`
ile başlıyorsa — kural **kararsız** kalır ve ne ihlal ne uygun sayılır. Plan taraması gerçeği
görür; tanım taraması onunla karşılaştırılır.

```js
// tara.mjs — ayni politika kumesi once tanim uzerinde, sonra plan uzerinde kosturulur (model)
import { readFileSync } from "node:fs";

const BUGUN = "2026-02-15";
const VARSAYILAN = { "makine.genel_ip": "evet", "nesne_deposu.sifreli": "hayir" }; // kurgu
// [kod, kural, kuralin okudugu alan (null: degere bakmaz)]
const POLITIKA = [
  ["P1", (t, a) => t !== "nesne_deposu" || a.sifreli === "evet", "sifreli"],
  ["P2", (t, a) => t !== "makine" || a.genel_ip === "hayir", "genel_ip"],
  ["P3", (t, a) => t !== "veri_deposu" || Number(a.yedek) >= 7, "yedek"],
  ["P4", (t, a) => t !== "kuyruk" || Number(a.saklama) <= 168, "saklama"],
  ["P5", (t, a) => a.sahip !== undefined, null],
  ["P6", (t, a) => t !== "ag" || a.blok.startsWith("10."), "blok"],
  ["P7", (t, a) => t !== "makine" || a.genel_adres.startsWith("10."), "genel_adres"],
];

const DEGISKEN = {}, BLOK = [];
let c = null;
for (const s of readFileSync("kayit.tanim", "utf8").split("\n")) {
  const d = /^degisken (\w+) = (.+)$/.exec(s), h = /^kaynak ([a-z_]+)\/([a-z0-9-]+):$/.exec(s);
  const a = /^\s+(\w+)\s*=\s*(.+)$/.exec(s);
  if (d) DEGISKEN[d[1]] = d[2];
  else if (h) BLOK.push((c = { tur: h[1], ad: h[2], alan: {} }));
  else if (a && c) c.alan[a[1]] = a[2].trim();
}

// plan: kosul degerlendirilir, yineleme acilir, degisken ve saglayici varsayilani cozulur;
// "@atanacak" cozulmez, cunku degeri uygulama aninda atanir
const PLAN = [];
for (const b of BLOK) {
  const [k, v] = (b.alan.kosul ?? "=").split("=");
  if (b.alan.kosul && DEGISKEN[k] !== v) continue;
  for (const oge of b.alan.yinele ? b.alan.yinele.split(",") : [null]) {
    const alan = {};
    for (const [ad, deger] of Object.entries(b.alan)) {
      if (["yinele", "kosul", "muafiyet"].includes(ad)) continue;
      alan[ad] = deger === "@varsayilan" ? VARSAYILAN[`${b.tur}.${ad}`]
        : deger === "$yinele" ? oge
          : deger.startsWith("$") ? DEGISKEN[deger.slice(1)] : deger;
    }
    PLAN.push({ tur: b.tur, blok: b.ad, ad: oge ? `${b.ad}-${oge}` : b.ad, alan,
      muafiyet: b.alan.muafiyet });
  }
}

const cozulmemis = (v) => v !== undefined && /^[$@]/.test(v);
const muafMi = (n, kod) => {
  const [p, tarih] = (n.muafiyet ?? ":").split(":");
  return (p === "*" || p === kod) && tarih >= BUGUN;
};
function tara(nesneler) {
  const bulgu = [];
  let kararsiz = 0;
  for (const n of nesneler) for (const [kod, kural, alan] of POLITIKA) {
    if (alan && cozulmemis(n.alan[alan])) { kararsiz += 1; continue; }
    if (!kural(n.tur, n.alan)) bulgu.push({ ad: n.ad, blok: n.blok, kod, muaf: muafMi(n, kod) });
  }
  return { bulgu, kararsiz };
}

const tanimNesnesi = BLOK.map((b) => ({ tur: b.tur, ad: b.ad, blok: b.ad, alan: b.alan,
  muafiyet: b.alan.muafiyet }));
const T = tara(tanimNesnesi), P = tara(PLAN);
const esit = (x, y) => x.blok === y.blok && x.kod === y.kod;
const yakalanan = P.bulgu.filter((p) => T.bulgu.some((t) => esit(t, p)));
const yanlis = T.bulgu.filter((t) => !P.bulgu.some((p) => esit(t, p)));
const SURE = new Set(BLOK.map((b) => b.tur)).size * 4 + PLAN.length; // AD12: kurgu saniye

console.log(`${"tarama".padEnd(9)}${"gordugu deger".padEnd(15)}${"bulgu".padStart(6)}` +
  `${"yakalanan".padStart(11)}${"kacan".padStart(7)}${"yanlis alarm".padStart(14)}` +
  `${"muaf".padStart(6)}${"raporlanan".padStart(12)}${"kararsiz".padStart(10)}${"hazir".padStart(8)}`);
for (const [ad, deger, S, yak, yan, sure] of [
  ["tanim", "yazili", T, yakalanan.length, yanlis.length, 0],
  ["plan", "cozulmus", P, P.bulgu.length, 0, SURE]]) {
  const muaf = S.bulgu.filter((b) => b.muaf).length;
  console.log(`${ad.padEnd(9)}${deger.padEnd(15)}${String(S.bulgu.length).padStart(6)}` +
    `${`${yak}/${P.bulgu.length}`.padStart(11)}${String(P.bulgu.length - yak).padStart(7)}` +
    `${String(yan).padStart(14)}${String(muaf).padStart(6)}` +
    `${String(S.bulgu.length - muaf).padStart(12)}${String(S.kararsiz).padStart(10)}` +
    `${`${sure} sn`.padStart(8)}`);
}

console.log(`\nyalniz planin gordugu ihlaller:`);
for (const p of P.bulgu.filter((p) => !T.bulgu.some((t) => esit(t, p)))) {
  const alan = POLITIKA.find(([k]) => k === p.kod)[2];
  console.log(`  ${p.kod}  ${p.ad.padEnd(16)}${alan.padEnd(12)}tanimda ` +
    `"${BLOK.find((b) => b.ad === p.blok).alan[alan]}", planda "${PLAN.find((n) => n.ad === p.ad).alan[alan]}"`);
}

const M = BLOK.filter((b) => b.alan.muafiyet).map((b) => ({ ad: `${b.tur}/${b.ad}`,
  kayit: b.alan.muafiyet, yururlukte: b.alan.muafiyet.split(":")[1] >= BUGUN }));
console.log(`\n${"muafiyet".padEnd(28)}${"kayit".padEnd(16)}${"durum".padEnd(14)}` +
  `${"kapattigi politika".padStart(19)}${"dusurdugu ihlal".padStart(17)}`);
for (const m of M) {
  const d = P.bulgu.filter((b) => b.muaf && `${PLAN.find((n) => n.ad === b.ad).tur}/${b.blok}` === m.ad);
  const kapsam = m.yururlukte ? (m.kayit.startsWith("*") ? POLITIKA.length : 1) : 0;
  console.log(`${m.ad.padEnd(28)}${m.kayit.padEnd(16)}` +
    `${(m.yururlukte ? "yururlukte" : "suresi dolmus").padEnd(14)}` +
    `${String(kapsam).padStart(19)}${String(d.length).padStart(17)}`);
}
console.log(`\ntanim taramasinin yanlis alarmi: ` +
  yanlis.map((y) => `${y.kod} ${y.ad}`).join(", ") + ` (kosulu yanlis, plana hic girmiyor); ` +
  `her iki taramanin da karar veremedigi politika P7 — genel_adres uygulama aninda atanir`);
```

```
tarama   gordugu deger   bulgu  yakalanan  kacan  yanlis alarm  muaf  raporlanan  kararsiz   hazir
tanim    yazili              7       7/10      3             2     1           6         7    0 sn
plan     cozulmus           10      10/10      0             0     2           8         5   30 sn

yalniz planin gordugu ihlaller:
  P2  arsivci         genel_ip    tanimda "@varsayilan", planda "evet"
  P3  olcum-deposu    yedek       tanimda "$yedek", planda "3"
  P1  olcum-arsiv     sifreli     tanimda "@varsayilan", planda "hayir"

muafiyet                    kayit           durum          kapattigi politika  dusurdugu ihlal
makine/gecit                P2:2026-03-31   yururlukte                      1                1
veri_deposu/olcum-deposu    *:2026-06-30    yururlukte                      7                1
nesne_deposu/olcum-arsiv    P1:2025-11-30   suresi dolmus                   0                0

tanim taramasinin yanlis alarmi: P2 deneme, P4 deneme-kuyrugu (kosulu yanlis, plana hic girmiyor); her iki taramanin da karar veremedigi politika P7 — genel_adres uygulama aninda atanir
```

## Kimin Ne Gördüğü

Plan taraması on ihlal bulur; tanım taraması bunların yedisini yakalar, üçünü kaçırır ve üstüne iki
yanlış alarm verir. Kaçan üçünün ortak yanı çıktının ikinci bölümünde tek tek yazılıdır: hepsi
**hesaplanan değerdir**. Arşivci makinesinin genel ağ alanı tanımda `@varsayilan` yazar, planda
`evet` olur; veri deposunun yedeği tanımda `$yedek` yazar, planda `3` olur; arşivin şifreleme alanı
tanımda `@varsayilan` yazar, planda `hayir` olur. Üçünde de kayıt metni ihlali **saklamaz**, yalnız
göstermez — değer kaydın başka bir yerinde ya da sağlayıcıdadır.

İki yanlış alarmın nedeni de aynı asimetrinin öteki ucudur: koşulu tutmayan iki blok plana hiç
girmez, ama tanım metninde ihlalli değerleriyle dururlar. Tanım taraması bunları raporlar ve
raporlanan altı bulgunun ikisi, yani üçte biri, hiç yaratılmayacak kaynaklara aittir.

İki taramayı birlikte koşturmak da bedelsiz değildir. Tanım raporunun altı satırından dördü ile
plan raporunun sekiz satırından altısı aynı dört kusuru anlatır; ekip aynı ihlali iki ayrı raporda
görür ve hangisinin kapatıldığını izlemek için üçüncü bir kayıt tutar. Kapıya yalnız birini koymak
zorunda olan bir hat içinse soru "hangisi daha doğru" değil, **hangi hata biçiminin daha pahalı
olduğudur**: yanlış alarm insan zamanı harcar ve sonunda kuralın kapatılmasıyla biter, kaçan ihlal
ise üretime iner.

Bir üçüncü fark sayıda saklıdır. Tanım taraması yedi bulgu üretir ama bunların beşi gerçek
ihlaldir; o beş bulgu planın yedi ihlalini kapsar, çünkü yinelemeli tek blok üç örneğe açılır. Aynı
kusur tanımda bir kez, planda üç kez raporlanır. Düzeltme her iki durumda da tek satırdadır; fark
raporun uzunluğunda ve sayının nasıl okunacağındadır.

## Erkenlik ile Doğruluk

Tabloda son iki sütun bu dersin değiş tokuşudur. Tanım taraması sıfır saniyede hazırdır: tek
dosyayı okur, sağlayıcıya bağlanmaz, kayıt her değiştiğinde koşabilir. Plan taraması otuz saniye
bekler — beş kaynak türü için birer sağlayıcı çağrısı, sonra on plan örneği için hesap — ve ancak
plan üretilebilen bir ortamda koşar; yetkisi olmayan bir katkı hattında hiç koşamaz.

Pratikte ikisinin yeri de farklıdır. Tanım taraması kaydın yazıldığı yerde, katkı daha
birleşmeden koşabilir; yanlış alarmı orada en ucuzdur, çünkü bloğun koşullu olduğunu bilen kişi
raporu okuyan kişidir. Plan taraması ise planın üretildiği kapıda durur ve orada verdiği karar
bağlayıcıdır.

Karşılığında aldığı şey doğruluktur: kaçan sıfır, yanlış alarm sıfır. Buradan çıkan sonuç
"hangisi daha iyi" değildir, ikisinin **farklı hata biçimleri** olduğudur. Tanım taraması yanlış
alarm üretir ve hesaplanan değeri kaçırır; plan taraması geç gelir ve bir sağlayıcı bağlantısına
bağımlıdır. Kararsız sütunu ikisinin ortak sınırını gösterir: tanım yedi, plan beş kuralda karar
veremez, ve ikisinin de karar veremediği P7'nin nedeni aynıdır — genel adres uygulama anında
atanır, iki katmanda da yazılı değildir.

## Muafiyetin Açtığı Yol

Üç muafiyet kaydı var ve üçü üç ayrı davranış gösteriyor. Geçidin muafiyeti bir politikaya bağlıdır
ve yürürlüktedir: tek bir ihlali rapordan düşürür, geçidin öteki altı politikası açık kalır. Veri
deposunun muafiyeti jokerdir: bugün yine tek bir ihlali düşürür, ama kapattığı politika sayısı
yedidir — o kaynağa sonradan eklenecek her ihlal de sessizce geçer, muafiyet süresi dolana dek.
Arşivin muafiyetinin süresi dolmuştur ve düşürdüğü ihlal sıfırdır; şifrelemenin kapalı olması
rapora geri dönmüştür.

Muafiyetin kendisi de bir kayıttır ve bakımı kimsede değildir. Üç kayıttan biri süresi dolmuş
hâlde durmaktadır; kimse silmemiştir. Süresi dolmuş muafiyet görünürdür — ihlali rapora geri getirir
ve kendini duyurur. Tehlikeli olan öteki uçtur: süresi dolmamış ve unutulmuş bir muafiyet sessizdir,
raporu kısaltır ve ihlali yerinde bırakır. Muafiyet kaydını denetleyen tek şey tarihtir; joker
kaydın kapsamını denetleyen bir kural yoktur.

Sayı olarak: plan taraması on ihlal buldu, ikisi muafiyetle düştü, sekizi raporlandı. Muafiyetin
açtığı yol **iki ihlal** genişliğindedir ve bunun biri joker kaydın açtığı yoldur. Muafiyetin
bedeli düşürdüğü ihlal sayısıyla değil, **kapattığı politika sayısıyla** ölçülür: bir politikaya
bağlı muafiyet bir kapı açar, joker muafiyet yedi kapı birden.

## Özet

- Aynı yedi kurallık politika kümesi kurgu ölçüm ağı kaydının iki katmanında koşturuldu: yazılı
  tanım metni ve çözülmüş plan.
- Plan taraması 10 ihlal buldu; tanım taraması 7'sini yakaladı, 3'ünü kaçırdı ve 2 yanlış alarm
  verdi — raporladığı 6 bulgunun 2'si hiç yaratılmayacak kaynaklara aitti.
- Kaçan üç ihlalin üçü de **hesaplanan değerdir**: ikisi sağlayıcı varsayılanı (`@varsayilan` →
  `evet` ve `hayir`), biri değişken (`$yedek` → `3`); tanım metni bunları göstermez.
- Erkenlik ile doğruluk takas edilir: tanım taraması 0 saniyede ve sağlayıcıya bağlanmadan hazırdır,
  plan taraması 30 saniye ve beş sağlayıcı çağrısı ister; ikisinin de karar veremediği P7'nin değeri
  uygulama anında atanır (tanımda 7, planda 5 kural kararsız kalır).
- Üç muafiyet kaydının ikisi yürürlüktedir ve 10 ihlalin 2'sini rapordan düşürür; joker muafiyet tek
  başına 7 politikayı birden kapatırken politikaya bağlı muafiyet 1 politikayı kapatır, süresi
  dolmuş muafiyet ise ihlali rapora geri getirir.

## Sonraki Adım

İki tarama da kaydı okudu — biri yazıldığı gibi, öteki çözüldüğü gibi. İkisinin de göremediği şey
kaynağın **koştuğu hâlidir**: P7 kararsız kaldı çünkü genel adres uygulama anında atanır, ve
politika kümesinin hiçbir kuralı "bu makine gerçekten açılıyor mu, kuyruğa yazılan ileti veri
deposuna ulaşıyor mu" diye sormaz. Sonraki ders bu soruyu üç seviyede sorar: altyapı tanımına
bakan birim doğrulaması, iki kaynağın arasındaki anlaşmayı sınayan sözleşme doğrulaması ve gerçek
kaynak yaratan uçtan uca doğrulama. Aynı kusur kümesinde üçünün tuttuğu, süresi ve maliyeti sayılır
— ve üçünün birden kaçırdığı ortak boşluk adıyla yazılır.
