---
title: 'Kimlik ve Kaynak Temelli Politikalar'
source: 'https://academia.sh/tr/kurslar/bulut-yonetisimi/kimlik-ve-kaynak-temelli-politikalar'
course: 'Bulut Yönetişimi, Güvenlik ve Maliyet'
language: tr
updated: '2026-08-17T18:06:55+00:00'
license: 'CC BY-SA 4.0'
---

# Kimlik ve Kaynak Temelli Politikalar

Aynı erişim isteği iki ayrı politika kümesinden geçirilir ve kesişimi hesaplanır: kaç istek yalnız bir yönde izinli olduğu için reddediliyor, hesap sınırı aşıldığında kaynak temelli politikanın neden zorunlu olduğu ve bir retin nedenini bulmanın kaç belge okumayı gerektirdiği sayılır.

Önceki dersin beş belgesi tek bir yerde duruyordu ve hepsi bir özneye bağlıydı. Kaynağın kendisi de
politika taşıyabilir: deponun üstüne yazılan bir belge, ona kimin erişebileceğini kaynak tarafından
söyler. İki yön aynı soruya iki ayrı yerden cevap verir — biri "bu özne nereye erişebilir", öbürü
"bu kaynağa kimler erişebilir" — ve bir istek ikisinden birden geçer.

İki yönün var olma nedeni farklıdır. Kimlik temelli belge özneyi yöneten ekibin elindedir, kaynak
temelli belge kaynağı işletenin. Aynı hesabın içinde ikisi birbirinin yerine geçebilir, hesap sınırı
aşıldığında geçemez. Bu dersin ölçüsü kesişimin boyu ve o kesişimi okumanın maliyetidir.

- **BI13.** Model sekiz özne, beş fiil, yirmi bir kaynak ve üç hesap taşır. Gerçek bir hesap
  koşturulmuyor; ölçülen şey `node` ile kurulan modeldir.
- **BI14.** Değerlendirme kuralı ders içinde tanımlıdır: aynı hesapta bir yönün izin vermesi
  yeterli, hesap sınırı aşıldığında iki yönün de izin vermesi gerekli, açık ret her iki yönde de
  kazanır.
- **BI15.** On bir kimlik temelli, altı kaynak temelli belge elle yazıldı. Sayılar bu kümeye
  bağlıdır; ölçüm biçimi değildir.
- **BI16.** Otuz günlük kullanım izi elle yazıldı ve ortam ayrımı taşımaz — izde görünen bir üçlü
  üç ortamda da meşru sayılır. Kullanılmayan izin sayısı bu yüzden bir alt sınırdır.
- **BI17.** "Bakılacak belge" sayısı özneye bağlı belge, kaynağa uyan belge ve hesap kuralının
  toplamıdır. Gerçekte devralınan belgeler sayıyı büyütür; ölçülen değer alt sınırdır.
- **BI18.** Kuruluş yapısı üç hesaba indirgendi; hesapların birbirini kapsaması modele girmedi.

## İki Yön

```js
// yon.mjs — iki degerlendirme yonu; gercek bir hesap degil, node ile kurulan modeldir
export const FIIL = ['oku', 'listele', 'yaz', 'sil', 'yapilandir'];
const ORTAM = ['gelistirme', 'hazirlik', 'uretim'];
export const TUR_HESAP = {                               // kaynak turu hangi hesapta duruyor
  'olcum-deposu': 'hesap-olcum', 'kayit-akisi': 'hesap-olcum', 'kenar-dugum-grubu': 'hesap-olcum',
  'nesne-deposu': 'hesap-analitik', 'islev-paketi': 'hesap-analitik',
  'makine-kumesi': 'hesap-ortak', 'ag-yapilandirmasi': 'hesap-ortak',
};
export const OZNE_HESAP = {
  'toplama-hizmeti': 'hesap-olcum', 'dogrulama-hizmeti': 'hesap-olcum', 'kenar-toplayici': 'hesap-olcum',
  'analitik-is': 'hesap-analitik', 'pano-okuyucu': 'hesap-analitik',
  'faturalama-is': 'hesap-ortak', 'saha-bakim': 'hesap-ortak', 'yedek-dogrulama': 'hesap-ortak',
};
export const OZNE = Object.keys(OZNE_HESAP);
export const KAYNAK = Object.keys(TUR_HESAP).flatMap((t) =>
  ORTAM.map((o) => ({ ad: `${t}/${o}`, tur: t, hesap: TUR_HESAP[t] })));
export const ISTEK = OZNE.flatMap((o) => FIIL.flatMap((f) => KAYNAK.map((k) => ({ ozne: o, fiil: f, kaynak: k }))));

const OKU = ['oku', 'listele'], OKU_YAZ = ['oku', 'listele', 'yaz'];
const K = (ad, ozne, etki, fiil, kaynak) => ({ ad, ozne, etki, fiil, kaynak });
const R = (ad, kaynak, etki, ozne, fiil) => ({ ad, kaynak, etki, ozne, fiil });
export const KIMLIK_BELGE = [                            // ozneye bagli: nerede ne yapabilir
  K('k1', 'toplama-hizmeti', 'izin', OKU_YAZ, ['olcum-deposu/*', 'kayit-akisi/*']),
  K('k2', 'toplama-hizmeti', 'ret', ['sil'], ['*']),
  K('k3', 'dogrulama-hizmeti', 'izin', OKU, ['*']),
  K('k4', 'kenar-toplayici', 'izin', OKU_YAZ, ['kenar-dugum-grubu/*', 'kayit-akisi/*']),
  K('k5', 'analitik-is', 'izin', OKU, ['olcum-deposu/*', 'nesne-deposu/*']),
  K('k6', 'analitik-is', 'izin', ['yaz'], ['nesne-deposu/hazirlik', 'nesne-deposu/gelistirme']),
  K('k7', 'pano-okuyucu', 'izin', OKU, ['olcum-deposu/*', 'kayit-akisi/*']),
  K('k8', 'faturalama-is', 'izin', OKU, ['olcum-deposu/*', 'nesne-deposu/*', 'kayit-akisi/*']),
  K('k9', 'saha-bakim', 'izin', [...OKU_YAZ, 'yapilandir'], ['makine-kumesi/*', 'ag-yapilandirmasi/*', 'kenar-dugum-grubu/*']),
  K('k10', 'saha-bakim', 'ret', ['sil'], ['*/uretim']),
  K('k11', 'yedek-dogrulama', 'izin', OKU, ['nesne-deposu/*', 'olcum-deposu/*']),
];
export const KAYNAK_BELGE = [                            // kaynaga bagli: kim ne yapabilir
  R('r1', ['olcum-deposu/*'], 'izin', ['analitik-is', 'faturalama-is'], OKU),
  R('r2', ['nesne-deposu/*'], 'izin', ['*'], OKU),
  R('r3', ['kayit-akisi/*'], 'izin', ['toplama-hizmeti', 'kenar-toplayici'], OKU_YAZ),
  R('r4', ['makine-kumesi/*', 'ag-yapilandirmasi/*'], 'izin', ['saha-bakim'], [...OKU_YAZ, 'yapilandir']),
  R('r5', ['*/uretim'], 'ret', ['pano-okuyucu'], ['yaz', 'sil', 'yapilandir']),
  R('r6', ['kenar-dugum-grubu/*'], 'izin', ['kenar-toplayici', 'saha-bakim'], OKU_YAZ),
];
// Otuz gunluk kullanim izi: (ozne, fiil, kaynak turu); elle yazildi, ortam ayrimi tasimaz
export const IZ = new Set([
  ['toplama-hizmeti', OKU_YAZ, ['olcum-deposu', 'kayit-akisi']],
  ['dogrulama-hizmeti', ['oku'], ['olcum-deposu', 'kayit-akisi', 'makine-kumesi']],
  ['kenar-toplayici', ['oku', 'yaz'], ['kenar-dugum-grubu', 'kayit-akisi']],
  ['analitik-is', OKU, ['olcum-deposu', 'nesne-deposu']],
  ['pano-okuyucu', OKU, ['olcum-deposu', 'kayit-akisi']],
  ['faturalama-is', ['oku'], ['olcum-deposu', 'nesne-deposu', 'kayit-akisi']],
  ['saha-bakim', ['oku', 'yaz', 'yapilandir'], ['makine-kumesi', 'ag-yapilandirmasi']],
  ['yedek-dogrulama', ['oku'], ['nesne-deposu', 'olcum-deposu']],
].flatMap(([o, fs, ts]) => fs.flatMap((f) => ts.map((t) => `${o}|${f}|${t}`))));
export const izde = (i) => IZ.has(`${i.ozne}|${i.fiil}|${i.kaynak.tur}`);

export const desen = (p, s) =>
  new RegExp(`^${p.split('*').map((x) => x.replace(/[.+?^${}()|[\]\\]/g, '\\$&')).join('.*')}$`).test(s);
export const kimlikBelgeleri = (i, kb = KIMLIK_BELGE) => kb.filter((b) => b.ozne === i.ozne);
export const kaynakBelgeleri = (i, rb = KAYNAK_BELGE) => rb.filter((b) => b.kaynak.some((p) => desen(p, i.kaynak.ad)));
const uyar = (b, i) => b.fiil.includes(i.fiil) && b.kaynak.some((p) => desen(p, i.kaynak.ad)) &&
  (typeof b.ozne === 'string' ? b.ozne === i.ozne : b.ozne.includes('*') || b.ozne.includes(i.ozne));
export function yon(belgeler, i) {                       // bir yonun sonucu
  const u = belgeler.filter((b) => uyar(b, i));
  if (u.some((b) => b.etki === 'ret')) return 'acik-ret';
  return u.some((b) => b.etki === 'izin') ? 'izin' : 'yok';
}
// Model kurali: ayni hesapta bir yon yeter, hesap sinirinda iki yon de izin vermeli
export function degerlendir(i, kb = KIMLIK_BELGE, rb = KAYNAK_BELGE) {
  const a = yon(kimlikBelgeleri(i, kb), i), b = yon(kaynakBelgeleri(i, rb), i);
  if (a === 'acik-ret' || b === 'acik-ret') return 'acik-ret';
  const ayni = OZNE_HESAP[i.ozne] === i.kaynak.hesap;
  return (ayni ? a === 'izin' || b === 'izin' : a === 'izin' && b === 'izin') ? 'izin' : 'ortuk-ret';
}
```

İki belge türünün alanları aynı, taşıdıkları liste farklı: kimlik temelli belge bir özneye bağlıdır
ve kaynak deseni taşır, kaynak temelli belge bir kaynağa bağlıdır ve özne listesi taşır. `r2`
belgesindeki `*` özne listesi bu farkın en görünür yeri — kaynak, kendisine kimin erişebileceğini
adıyla saymak yerine hepsini açabiliyor.

## Kesişim

```js
// kosum1.mjs — ayni istek iki yonden gecirilir ve kesisim hesaplanir
import { ISTEK, OZNE, KAYNAK, FIIL, OZNE_HESAP, KIMLIK_BELGE, KAYNAK_BELGE,
  kimlikBelgeleri, kaynakBelgeleri, yon, degerlendir } from './yon.mjs';

const ayniHesap = (i) => OZNE_HESAP[i.ozne] === i.kaynak.hesap;
const yonler = ISTEK.map((i) => ({ i, a: yon(kimlikBelgeleri(i), i), b: yon(kaynakBelgeleri(i), i),
  ayni: ayniHesap(i), sonuc: degerlendir(i) }));
console.log(`${OZNE.length} ozne x ${FIIL.length} fiil x ${KAYNAK.length} kaynak = ${ISTEK.length} istek`);
console.log(`kimlik temelli belge ${KIMLIK_BELGE.length}, kaynak temelli belge ${KAYNAK_BELGE.length}`);
console.log(`ayni hesap ${yonler.filter((y) => y.ayni).length}, hesap sinirini asan ${yonler.filter((y) => !y.ayni).length}\n`);

const say = (f) => yonler.filter(f).length;
console.log('iki yonun kesisimi        ayni hesap  hesap siniri  izinli sonuc');
const satir = (ad, f) => console.log(`${ad.padEnd(25)} ${String(say((y) => y.ayni && f(y))).padEnd(11)} ` +
  `${String(say((y) => !y.ayni && f(y))).padEnd(13)} ${say((y) => f(y) && y.sonuc === 'izin')}`);
satir('yalniz kimlik yonu izin', (y) => y.a === 'izin' && y.b !== 'izin' && y.b !== 'acik-ret');
satir('yalniz kaynak yonu izin', (y) => y.b === 'izin' && y.a !== 'izin' && y.a !== 'acik-ret');
satir('iki yon de izin', (y) => y.a === 'izin' && y.b === 'izin');
satir('hicbir yon izin vermiyor', (y) => y.a !== 'izin' && y.b !== 'izin');
satir('en az bir yonde acik ret', (y) => y.a === 'acik-ret' || y.b === 'acik-ret');

const s = { izin: 0, 'acik-ret': 0, 'ortuk-ret': 0 };
for (const y of yonler) s[y.sonuc]++;
console.log(`\nsonuc: izin ${s.izin}, acik ret ${s['acik-ret']}, ortuk ret ${s['ortuk-ret']}`);
const tekYonYeterdi = say((y) => y.sonuc !== 'izin' && (y.a === 'izin' || y.b === 'izin') &&
  y.a !== 'acik-ret' && y.b !== 'acik-ret');
console.log(`bir yonde izinli oldugu halde reddedilen: ${tekYonYeterdi} istek — hepsi hesap sinirini asiyor`);
```

```
8 ozne x 5 fiil x 21 kaynak = 840 istek
kimlik temelli belge 11, kaynak temelli belge 6
ayni hesap 285, hesap sinirini asan 555

iki yonun kesisimi        ayni hesap  hesap siniri  izinli sonuc
yalniz kimlik yonu izin   29          45            29
yalniz kaynak yonu izin   6           18            6
iki yon de izin           57          39            96
hicbir yon izin vermiyor  193         453           0
en az bir yonde acik ret  17          32            0

sonuc: izin 131, acik ret 49, ortuk ret 660
bir yonde izinli oldugu halde reddedilen: 63 istek — hepsi hesap sinirini asiyor
```

Sekiz yüz kırk isteğin yüz otuz biri izinli. İlk iki satır aynı hesapla hesap sınırının neden ayrı
sütun olduğunu gösteriyor: aynı hesapta yalnız kimlik yönünde izinli yirmi dokuz istek var ve
yirmi dokuzu izinli sonuçlanıyor, yalnız kaynak yönünde izinli altı istek de öyle. Hesap sınırında
aynı satırlar kırk beş ve on sekiz, ama izinli sonuç sıfır.

Son satır bunu tek sayıya indiriyor: altmış üç istek bir yönde açıkça izinli olduğu hâlde
reddediliyor. Birileri gerçekten bir belge yazdı, belge eşleşiyor, ama karşı yön yazılmadığı için
erişim olmuyor. Hesap sınırının yaptığı iş budur — bir yönün yazılmasını yeterli olmaktan çıkarıp
iki tarafın anlaşmasını zorunlu kılar.

## Hesap Sınırı

```js
// kosum2.mjs — hesap siniri: kaynak temelli belge ne zaman zorunlu oluyor
import { ISTEK, KAYNAK_BELGE, KIMLIK_BELGE, TUR_HESAP, OZNE_HESAP, OZNE, desen,
  kimlikBelgeleri, yon, degerlendir, izde, IZ } from './yon.mjs';

const disHesap = ISTEK.filter((i) => OZNE_HESAP[i.ozne] !== i.kaynak.hesap);
console.log('kaynak turu        hesap           izin veren belge  sinir asan istek  izin  kimlik izinli ama ret');
for (const t of Object.keys(TUR_HESAP)) {
  const d = disHesap.filter((i) => i.kaynak.tur === t);
  const belge = KAYNAK_BELGE.filter((b) => b.etki === 'izin' && b.kaynak.some((p) => desen(p, `${t}/uretim`))).length;
  const izin = d.filter((i) => degerlendir(i) === 'izin').length;
  const kesik = d.filter((i) => degerlendir(i) !== 'izin' && yon(kimlikBelgeleri(i), i) === 'izin').length;
  console.log(`${t.padEnd(18)} ${TUR_HESAP[t].padEnd(15)} ${String(belge).padEnd(17)} ${String(d.length).padEnd(17)} ` +
    `${String(izin).padEnd(5)} ${kesik}`);
}
const kesim = (kb, rb) => ISTEK.filter((i) => degerlendir(i, kb, rb) === 'izin');
const mesru = (l) => l.filter(izde).length;
const tam = kesim(KIMLIK_BELGE, KAYNAK_BELGE);
console.log(`\nizinli istek ${tam.length}; izde gorunen ${mesru(tam)}, kullanilmayan izin ${tam.length - mesru(tam)}`);
console.log(`iz ${IZ.size} (ozne, fiil, tur) uclusu tasiyor\n`);

// Kaynak temelli belgeyi daraltmanin uc kademesi
const r2Dar = KAYNAK_BELGE.map((b) => (b.ad === 'r2'
  ? { ...b, ozne: OZNE.filter((o) => [...IZ].some((k) => k.startsWith(`${o}|`) && k.endsWith('|nesne-deposu'))) } : b));
console.log('kaynak temelli belge kumesi        izin  izde gorunen  duran mesru is');
for (const [ad, rb] of [['degismeden (r2 ozne *)', KAYNAK_BELGE], ['r2 ozne listesi ize gore', r2Dar],
  ['r2 kaldirildi', KAYNAK_BELGE.filter((b) => b.ad !== 'r2')], ['hicbiri yok', []]]) {
  const k = kesim(KIMLIK_BELGE, rb);
  console.log(`${ad.padEnd(34)} ${String(k.length).padEnd(5)} ${String(mesru(k)).padEnd(13)} ${mesru(tam) - mesru(k)}`);
}
```

```
kaynak turu        hesap           izin veren belge  sinir asan istek  izin  kimlik izinli ama ret
olcum-deposu       hesap-olcum     1                 75                12    12
kayit-akisi        hesap-olcum     1                 75                0     12
kenar-dugum-grubu  hesap-olcum     1                 75                9     3
nesne-deposu       hesap-analitik  1                 90                18    0
islev-paketi       hesap-analitik  0                 90                0     6
makine-kumesi      hesap-ortak     1                 75                0     6
ag-yapilandirmasi  hesap-ortak     1                 75                0     6

izinli istek 131; izde gorunen 75, kullanilmayan izin 56
iz 32 (ozne, fiil, tur) uclusu tasiyor

kaynak temelli belge kumesi        izin  izde gorunen  duran mesru is
degismeden (r2 ozne *)             131   75            0
r2 ozne listesi ize gore           119   75            0
r2 kaldirildi                      107   69            6
hicbiri yok                        86    60            15
```

`islev-paketi` satırı kuralı en yalın biçimde gösteriyor: bu türe bağlı izin veren bir kaynak
belgesi yok, dolayısıyla hesap sınırını aşan doksan isteğin hepsi reddediliyor ve altısı kimlik
tarafında yazılmış izinlere sahip. O altı izin bir yerde duruyor, bakımı yapılıyor, denetimde
görünüyor ve hiçbir işe yaramıyor. `kayit-akisi` satırında bir izin belgesi var ama saydığı iki
özne aynı hesapta olduğu için sınır aşan yetmiş beş isteğin hiçbirine yaramıyor.

Alt tablo daraltmanın kademelerini veriyor. `r2` belgesinin `*` özne listesi otuz günlük izde
görünen öznelerle değiştirilince izinli istek yüz otuz birden yüz on dokuza iniyor ve duran meşru
iş sıfır: on iki iznin tamamı kullanılmayan izindi. `r2` tamamen kaldırılınca izin yüz yediye
düşüyor ve altı meşru iş duruyor; bütün kaynak temelli belgeler kaldırılırsa izin seksen altıya,
duran meşru iş on beşe çıkıyor. Daraltmanın ilk kademesi bedava, ikincisi değil.

## Neden Reddedildi

```js
// kosum3.mjs — bir erisimin neden reddedildigini bulmak kac belgeye bakmayi gerektiriyor
import { ISTEK, OZNE_HESAP, kimlikBelgeleri, kaynakBelgeleri, yon, degerlendir } from './yon.mjs';

const neden = (i) => {
  const a = yon(kimlikBelgeleri(i), i), b = yon(kaynakBelgeleri(i), i);
  if (a === 'acik-ret') return 'kimlik yonunde acik ret';
  if (b === 'acik-ret') return 'kaynak yonunde acik ret';
  if (a === 'izin' || b === 'izin') return 'hesap siniri: tek yon izin veriyor';
  return 'iki yonde de izin yok';
};
const ret = ISTEK.filter((i) => degerlendir(i) !== 'izin');
const belge = (i) => kimlikBelgeleri(i).length + kaynakBelgeleri(i).length + 1;  // +1: hesap kurali
const ort = (l, f) => (l.reduce((a, x) => a + f(x), 0) / l.length).toFixed(1);

console.log(`reddedilen ${ret.length} istek; bakilacak belge = ozneye bagli + kaynaga uyan + hesap kurali\n`);
console.log('ret nedeni                          istek  belge ortalama  en cok');
for (const n of ['kimlik yonunde acik ret', 'kaynak yonunde acik ret',
  'hesap siniri: tek yon izin veriyor', 'iki yonde de izin yok']) {
  const l = ret.filter((i) => neden(i) === n);
  console.log(`${n.padEnd(35)} ${String(l.length).padEnd(6)} ${String(ort(l, belge)).padEnd(15)} ` +
    `${Math.max(...l.map(belge))}`);
}
console.log(`${'toplam'.padEnd(35)} ${String(ret.length).padEnd(6)} ${String(ort(ret, belge)).padEnd(15)} ` +
  `${Math.max(...ret.map(belge))}`);
console.log(`tek yon okunsaydi (yalniz kimlik): ortalama ${ort(ret, (i) => kimlikBelgeleri(i).length)} belge`);

// Tek yone bakan bir okuyucu kac istekte yanlis cevap verir
const yalniz = (i) => (yon(kimlikBelgeleri(i), i) === 'izin' ? 'izin' : 'ret');
const gercek = (i) => (degerlendir(i) === 'izin' ? 'izin' : 'ret');
const yanlis = ISTEK.filter((i) => yalniz(i) !== gercek(i));
console.log(`\nyalniz kimlik yonune bakan okuyucu ${ISTEK.length} istegin ${yanlis.length} tanesinde yanilir`);
console.log(`bunlarin ${yanlis.filter((i) => OZNE_HESAP[i.ozne] !== i.kaynak.hesap).length} tanesi hesap sinirini asiyor`);
const aralik = (f) => { const v = ISTEK.map(f); return `${Math.min(...v)}-${Math.max(...v)}`; };
console.log(`ozneye bagli belge ${aralik((i) => kimlikBelgeleri(i).length)}, ` +
  `kaynaga uyan belge ${aralik((i) => kaynakBelgeleri(i).length)}`);
```

```
reddedilen 709 istek; bakilacak belge = ozneye bagli + kaynaga uyan + hesap kurali

ret nedeni                          istek  belge ortalama  en cok
kimlik yonunde acik ret             28     4.4             5
kaynak yonunde acik ret             21     3.9             4
hesap siniri: tek yon izin veriyor  63     3.5             5
iki yonde de izin yok               597    3.5             5
toplam                              709    3.5             5
tek yon okunsaydi (yalniz kimlik): ortalama 1.4 belge

yalniz kimlik yonune bakan okuyucu 840 istegin 51 tanesinde yanilir
bunlarin 45 tanesi hesap sinirini asiyor
ozneye bagli belge 1-2, kaynaga uyan belge 0-2
```

Bir retin nedenini bulmak ortalama üç buçuk belge okumayı gerektiriyor, en kötü durumda beş. Sayının
küçük olmasının nedeni modelin küçük olmasıdır; asıl bilgi oranda. Tek yön okunsaydı ortalama bir
virgül dört belgeye bakılacaktı: ikinci yönü eklemek okunacak belgeyi iki buçuk kat artırıyor ve bu
artış her ret sorgusunda ödenir.

Bedelin karşılığı son iki satırda. Yalnız kimlik yönüne bakan bir okuyucu sekiz yüz kırk isteğin
elli birinde yanlış cevap verir — hepsinde "izinli" der, oysa istek reddedilir. Kırk beşinin nedeni
hesap sınırıdır, kalan altısında kaynak yönünde bir açık ret vardır. Belge doğru okunmuştur; yanlış
olan tek belgeye bakmaktır.

## Özet

- 840 isteğin 131'i izinli; 285 istek aynı hesapta, 555'i hesap sınırını aşıyor.
- 63 istek bir yönde açıkça izinli olduğu hâlde reddediliyor ve hepsi hesap sınırını aşıyor; aynı
  hesapta bu sayı sıfırdır, çünkü orada bir yön yeter.
- `islev-paketi` türünde izin veren kaynak belgesi yok: sınır aşan 90 isteğin tamamı reddediliyor
  ve 6 kimlik temelli izin hiçbir işe yaramadan duruyor.
- İzinli 131 isteğin 75'i izde görünüyor; `r2`'nin `*` özne listesini ize göre yazmak 12 kullanılmayan
  izni kapatıyor ve hiçbir meşru işi durdurmuyor.
- İkinci kademe bedava değil: `r2` kaldırılınca 6, bütün kaynak temelli belgeler kaldırılınca 15
  meşru iş duruyor.
- Bir retin nedenini bulmak ortalama 3,5 belge ister, tek yön okunsaydı 1,4; yalnız kimlik yönüne
  bakan okuyucu 840 isteğin 51'inde yanılır.

## Sonraki Adım

Bu dersin sekiz öznesi kalıcı kimliklerdi ve her birinin uzun ömürlü bir kimlik bilgisi vardı. İlk
derste sayılan yüzey buydu: yirmi dokuz saklama yeri ve sekiz yüz seksen günlük bir anahtar. İzin
bağlantısı ne kadar dar yazılırsa yazılsın, anahtar sızdığında bütün belgeler onu taşıyanın lehine
çalışır. Sonraki ders erişimi kalıcı kimlikten ayırır: bir özne başka bir kimliği geçici olarak
üstlenir. Ölçülen kalemler sızıntı penceresi, üstlenme zincirinin uzunluğu, güven ilişkisinin kimin
üstlenebileceğini belirlemesi ve denetim kaydında asıl öznenin kaç adım sonra kaybolduğudur.
