---
title: 'Rol Tabanlı Erişim Denetimi'
source: 'https://academia.sh/tr/kurslar/orkestrasyon/rol-tabanli-erisim-denetimi'
course: 'Konteyner Orkestrasyonu'
language: tr
updated: '2026-08-17T18:09:09+00:00'
license: 'CC BY-SA 4.0'
---

# Rol Tabanlı Erişim Denetimi

Bir özne × fiil × nesne × ad alanı yetki matrisi kurulur ve geniş yetkiden en az yetkiye inince kaç işlemin düştüğü sayılır: izinli işlem, rol tanımının satır maliyeti ve bir öznenin başka bir öznenin yetkisine ulaşabildiği yükseltme yolları ölçülür.

Önceki iki dersin denetleyicileri kümede kısıtsız iş gördü. Dağıtım denetleyicisi sürüm nesnesini
değiştirdi, kapsül sildi, havuz üyeliğini yazdı; sağlık denetimleri süreç öldürdü. Aynı arayüzü
insanlar ve öteki otomatik süreçler de kullanıyor ve şimdiye kadar hiçbiri "bunu yapmaya yetkin
var mı" sorusuyla karşılaşmadı. Kimlik ve en az yetki daha önce ölçüldü; buranın farkı, yetkinin
**küme nesneleri üzerinde** tanımlanması ve her nesnenin başka nesnelere ulaşma imkânı taşımasıdır.

Devredilen karar şudur: bir isteğin yürütülüp yürütülmeyeceğine, isteği yapanın kim olduğuna
bakarak küme arayüzü karar verir. Bunun için bilmesi gereken üç kalem vardır — kim, ne yapmak
istiyor, neyin üstünde — ve bu üçüne bir dördüncüsü eklenir: hangi ad alanında. Kalemlerin
çarpımı, sistemin doldurması gereken tablodur. Bu dersin ölçüsü o tablonun boyu, doldurmanın
maliyeti ve **boş bırakmanın** bedelidir.

- **OI13.** Model kurgusal bölgesel ölçüm ağının sekiz öznesini, yedi fiili, sekiz nesne türünü ve
  üç ad alanını taşır. Gerçek bir küme koşturulmuyor; ölçülen şey `node` ile kurulan modeldir.
- **OI14.** İşlem izi otuz günlük bir kayıttan çıkarılmış sayılır ve elle yazılmıştır. İzde
  görünmeyen işlem "gerekmiyor" kabul edilir. Seyrek koşan bakım işleri böyle bir izde görünmez;
  en az yetki onları da düşürür ve ilk koşumlarında engellenirler.
- **OI15.** Buradaki ad alanı **kümenin** ad alanıdır: nesnelerin gruplandığı ve yetkinin
  sınırlandığı bölme. Tek makinedeki yalıtımın görünürlük eşlemesi anlamındaki ad alanıyla aynı
  sözcüktür, farklı nesnedir.
- **OI16.** Yetki yükseltme iki kurala indirgendi: rol tanımı yazabilen özne o ad alanındaki her
  yetkiyi kendine verebilir; sır nesnesini okuyabilen özne o ad alanındaki bir öznenin kimliğini
  ele geçirebilir. Gerçekte daha çok yol vardır, bu yüzden sayılan değer bir alt sınırdır.
- **OI17.** Rol tanımı satırı kendi küçük şemamızla sayılır; şema ders içinde tanımlıdır. Satır
  sayısı biçim seçimine bağlıdır, büyüklük sırası değil.
- **OI18.** Aynı yetki kümesine sahip özneler tek role indirilir. Rol adları üretilmiştir; okunur
  adlar satır sayısını değiştirmez.

## Yetki Matrisi

```js
// yetki.mjs — ozne x fiil x nesne x ad alani yetki matrisi; gercek kume degil, bir modeldir
export const OZNE = ['okuma-toplayici', 'dogrulayici', 'faturalama', 'is-emri',
  'gecelik-toplu-is', 'yayin-denetleyicisi', 'nobetci', 'pano-okuyucu'];
export const FIIL = ['oku', 'listele', 'izle', 'olustur', 'guncelle', 'sil', 'yetkilendir'];
export const NESNE = ['kapsul', 'surum-nesnesi', 'servis-nesnesi', 'yapilandirma-nesnesi',
  'sir-nesnesi', 'kota', 'rol-tanimi', 'dugum'];
export const ALAN = ['gelistirme', 'hazirlik', 'uretim'];
const U = ['uretim'], H = ['hazirlik', 'uretim'], T = ALAN;

// Otuz gunluk kayittan cikarilan islem izi; elle yazildi, rastgelelik yok.
export const IZ = [
  ['okuma-toplayici', 'oku', 'yapilandirma-nesnesi', U], ['okuma-toplayici', 'listele', 'kapsul', U],
  ['dogrulayici', 'oku', 'yapilandirma-nesnesi', H], ['dogrulayici', 'oku', 'sir-nesnesi', H],
  ['dogrulayici', 'listele', 'servis-nesnesi', H],
  ['faturalama', 'oku', 'yapilandirma-nesnesi', U], ['faturalama', 'oku', 'sir-nesnesi', U],
  ['is-emri', 'oku', 'yapilandirma-nesnesi', U], ['is-emri', 'listele', 'servis-nesnesi', U],
  ['gecelik-toplu-is', 'oku', 'sir-nesnesi', U], ['gecelik-toplu-is', 'olustur', 'kapsul', U],
  ['gecelik-toplu-is', 'listele', 'kapsul', U],
  ['yayin-denetleyicisi', 'guncelle', 'surum-nesnesi', T], ['yayin-denetleyicisi', 'listele', 'kapsul', T],
  ['yayin-denetleyicisi', 'sil', 'kapsul', T], ['yayin-denetleyicisi', 'izle', 'kapsul', T],
  ['nobetci', 'oku', 'kapsul', T], ['nobetci', 'listele', 'kapsul', T],
  ['nobetci', 'izle', 'kapsul', T], ['nobetci', 'oku', 'sir-nesnesi', U],
  ['pano-okuyucu', 'listele', 'kapsul', T], ['pano-okuyucu', 'listele', 'servis-nesnesi', T],
];

export const anahtar = (o, f, n, a) => `${o}|${f}|${n}|${a}`;
export function enAz() {
  const s = new Set();
  for (const [o, f, n, alanlar] of IZ) for (const a of alanlar) s.add(anahtar(o, f, n, a));
  return s;
}
export function genis() {                              // her ozneye her fiil, her nesne, her alan
  const s = new Set();
  for (const o of OZNE) for (const f of FIIL) for (const n of NESNE) for (const a of ALAN) s.add(anahtar(o, f, n, a));
  return s;
}
// Yukseltme: rol tanimi yazabilen o alandaki her yetkiyi kendine verebilir; sir nesnesini
// okuyabilen o alandaki bir oznenin kimligini ele gecirebilir.
export function yukseltme(izin) {
  const var_ = (o, f, n, a) => izin.has(anahtar(o, f, n, a));
  const alanOzne = (a) => OZNE.filter((o) => [...izin].some((k) => k.startsWith(`${o}|`) && k.endsWith(`|${a}`)));
  const kenar = new Set();
  for (const o of OZNE) for (const a of ALAN) {
    const rolYazar = ['olustur', 'guncelle', 'yetkilendir'].some((f) => var_(o, f, 'rol-tanimi', a));
    const sirOkur = var_(o, 'oku', 'sir-nesnesi', a);
    if (!rolYazar && !sirOkur) continue;
    for (const t of alanOzne(a)) if (t !== o) kenar.add(`${o}->${t}`);
  }
  let n = kenar.size, once;                            // gecisli kapanis
  do {
    once = n;
    for (const k1 of [...kenar]) for (const k2 of [...kenar]) {
      const [a1, b1] = k1.split('->'), [a2, b2] = k2.split('->');
      if (b1 === a2 && a1 !== b2) kenar.add(`${a1}->${b2}`);
    }
    n = kenar.size;
  } while (n !== once);
  return kenar;
}
```

İzin listesi ile matris arasındaki fark şudur: matris bütün hücreleri taşır, iz yalnız dolu
olanları. `genis` işlevi bütün hücreleri doldurur — hiçbir soru sormadan her özneye her şeyi
verir. `enAz` yalnız izde görüneni doldurur. İkisi arasındaki bütün fark, otuz günlük kayda
bakmanın maliyetidir.

## Geniş Yetkiden En Az Yetkiye

```js
// kosum5.mjs — genis yetki ile en az yetki karsilastirilir
import { OZNE, FIIL, NESNE, ALAN, IZ, enAz, genis } from './yetki.mjs';

const g = genis(), e = enAz();
console.log(`ozne ${OZNE.length} x fiil ${FIIL.length} x nesne ${NESNE.length} x ad alani ${ALAN.length}` +
  ` = ${OZNE.length * FIIL.length * NESNE.length * ALAN.length} olasi islem`);
console.log(`gozlenen iz: ${IZ.length} satir, ad alanlarina acilinca ${e.size} ayri islem\n`);
console.log('olcut                         genis yetki  en az yetki  fark');
const satir = (ad, x, y) => console.log(`${ad.padEnd(29)} ${String(x).padEnd(12)} ${String(y).padEnd(12)} ${x - y}`);
satir('izinli islem', g.size, e.size);
satir('yetkili ozne', OZNE.length, new Set([...e].map((k) => k.split('|')[0])).size);
const ff = (s) => new Set([...s].map((k) => k.split('|').slice(0, 2).join('|'))).size;
satir('ozne-fiil cifti', ff(g), ff(e));
const nn = (s) => new Set([...s].map((k) => k.split('|')[2])).size;
satir('dokunulan nesne turu', nn(g), nn(e));
const sir = (s) => [...s].filter((k) => k.split('|')[1] === 'oku' && k.split('|')[2] === 'sir-nesnesi').length;
satir('sir nesnesi okuma izni', sir(g), sir(e));
const rol = (s) => [...s].filter((k) => k.split('|')[2] === 'rol-tanimi').length;
satir('rol tanimina dokunan izin', rol(g), rol(e));
```

```
ozne 8 x fiil 7 x nesne 8 x ad alani 3 = 1344 olasi islem
gozlenen iz: 22 satir, ad alanlarina acilinca 43 ayri islem

olcut                         genis yetki  en az yetki  fark
izinli islem                  1344         43           1301
yetkili ozne                  8            8            0
ozne-fiil cifti               56           18           38
dokunulan nesne turu          8            5            3
sir nesnesi okuma izni        24           5            19
rol tanimina dokunan izin     168          0            168
```

Bin üç yüz bir işlem düştü — matrisin yüzde doksan yedisi. Geriye kalan kırk üç işlem, sekiz
öznenin otuz gün boyunca gerçekten yaptığı her şeydir. İkinci satır bu düşüşün **hangi eksende
olmadığını** gösteriyor: yetkili özne sayısı sekizden sekize, yani hiç değişmedi. En az yetki
kimseyi kümeden çıkarmıyor; herkesin **ne yapabildiğini** daraltıyor.

Daralma nesne ekseninde en sert. Sekiz nesne türünden beşine dokunuluyor; üç tür — kota, rol
tanımı ve düğüm — otuz gün boyunca hiçbir özne tarafından kullanılmadı. Bunların iki tanesi
kümenin kendi işletimine ait nesnelerdir ve iş yükü öznelerinin bunlara erişmesi için bir neden
yoktur. Son satır bunun sayısını veriyor: geniş yetkide rol tanımına dokunan yüz altmış sekiz izin
vardı, en az yetkide sıfır. Yüz altmış sekiz iznin tamamı, hiç kullanılmadığı hâlde açık duran ve
her biri kendisini genişletmeye yarayan izinlerdi.

Sır nesnesi satırı ise düşüşün durduğu yeri gösteriyor: yirmi dörtten sıfıra değil, **beşe**
indi. Dört özne sırlara gerçekten erişiyor — doğrulayıcı iki ad alanında, faturalama, gecelik
toplu iş ve nöbetçi üretimde. Bu beş izin izde vardır, dolayısıyla en az yetki onları düşüremez.

## Yazma Bedeli ve Yükseltme Yolları

En az yetkinin ikinci bedeli ilk tabloda görünmüyor: matrisin doldurulmayan hücreleri bedava,
doldurulanların her biri yazılmak zorunda. Bunu saymak için yetki kümesi kendi şemamızla metne
dökülür.

```js
// kosum6.mjs — iki modelin rol tanimi kendi semamizla yazilir ve satiri sayilir
import { OZNE, enAz, genis, yukseltme } from './yetki.mjs';

// Sema: "rol <ad>" / "  <nesne>: <fiil>,<fiil>" / "bag <rol> -> <ozne> @ <alan>"
function yaz(izin) {
  const kume = new Map();                              // (ozne, alan) -> nesne:fiiller
  for (const k of izin) {
    const [o, f, n, a] = k.split('|');
    const m = kume.get(`${o}|${a}`) ?? new Map();
    m.set(n, (m.get(n) ?? new Set()).add(f));
    kume.set(`${o}|${a}`, m);
  }
  const rol = new Map(), bag = [];                     // ayni yetki kumesi tek role indirilir
  for (const [oa, m] of kume) {
    const govde = [...m].sort().map(([n, fs]) => `  ${n}: ${[...fs].sort().join(',')}`).join('\n');
    if (!rol.has(govde)) rol.set(govde, `rol-${rol.size + 1}`);
    const [o, a] = oa.split('|');
    bag.push(`bag ${rol.get(govde)} -> ${o} @ ${a}`);
  }
  const metin = [...rol].map(([g, ad]) => `rol ${ad}\n${g}`).concat(bag).join('\n');
  return { metin, rol: rol.size, bag: bag.length, satir: metin.split('\n').length };
}
const g = yaz(genis()), e = yaz(enAz());
console.log('model        rol  bag  toplam satir  izinli islem  islem/satir');
for (const [ad, y, izin] of [['genis yetki', g, genis()], ['en az yetki', e, enAz()]]) {
  console.log(`${ad.padEnd(12)} ${String(y.rol).padEnd(4)} ${String(y.bag).padEnd(4)} ` +
    `${String(y.satir).padEnd(13)} ${String(izin.size).padEnd(13)} ${(izin.size / y.satir).toFixed(1)}`);
}
console.log('\nen az yetki tanimindan iki rol ve iki bag:');
console.log(e.metin.split('\n').slice(0, 6).join('\n'));
console.log(e.metin.split('\n').filter((l) => l.startsWith('bag')).slice(0, 2).join('\n'));

// Sir nesnesi okuma izni kaldirilirsa yukseltme yollari ne oluyor
const kis = new Set([...enAz()].filter((k) => !(k.split('|')[1] === 'oku' && k.split('|')[2] === 'sir-nesnesi')));
console.log('\nyukseltme yolu sayisi ve her ozneye ulasan ozne:');
for (const [ad, s] of [['genis yetki', genis()], ['en az yetki', enAz()], ['sir okuma kaldirildi', kis]]) {
  const k = yukseltme(s);
  const tam = OZNE.filter((o) => [...k].filter((x) => x.startsWith(`${o}->`)).length === OZNE.length - 1).length;
  console.log(`  ${ad.padEnd(22)} yol ${String(k.size).padEnd(4)} tam yetkiye ulasan ${tam}  izinli islem ${s.size}`);
}
```

```
model        rol  bag  toplam satir  izinli islem  islem/satir
genis yetki  1    24   33            1344          40.7
en az yetki  9    15   42            43            1.0

en az yetki tanimindan iki rol ve iki bag:
rol rol-1
  kapsul: listele
  yapilandirma-nesnesi: oku
rol rol-2
  servis-nesnesi: listele
  sir-nesnesi: oku
bag rol-1 -> okuma-toplayici @ uretim
bag rol-2 -> dogrulayici @ hazirlik

yukseltme yolu sayisi ve her ozneye ulasan ozne:
  genis yetki            yol 56   tam yetkiye ulasan 8  izinli islem 1344
  en az yetki            yol 28   tam yetkiye ulasan 4  izinli islem 43
  sir okuma kaldirildi   yol 0    tam yetkiye ulasan 0  izinli islem 38
```

Yazma bedeli otuz üç satırdan kırk iki satıra çıktı — yüzde yirmi yedi artış, dokuz satır. Bu,
bin üç yüz bir işlemi düşürmenin bütün maliyetidir. Son sütun ikisinin arasındaki ilişkiyi tek
sayıya indiriyor: geniş yetkide yazılan her satır kırk işlem açıyor, en az yetkide tam olarak
bir. Geniş yetkinin ucuzluğu **yazmadığı** satırlardan gelir; en az yetkide izin verilen her işlem
ayrı ayrı yazılmak zorundadır, çünkü genelleme yapan hiçbir kural yoktur. Kırk iki satırın
bakımı da buradan doğar: iz değiştiğinde tanım değişmek zorundadır.

Alt tablo bu dersin asıl sonucudur. Geniş yetkide elli altı yükseltme yolu var ve sekiz öznenin
sekizi de her özneye ulaşıyor — beklenen sonuç. En az yetkide izinli işlem kırk üçe indi ama
yükseltme yolu yalnız yarıya, yirmi sekize düştü ve **dört özne hâlâ her özneye ulaşıyor**. İzinli
işlemin yüzde doksan yedisini düşürmek, yükseltme yolunun yalnız yüzde ellisini düşürdü. İki sayı
aynı şeyi ölçmüyor.

Üçüncü satır nedeni veriyor. Sır nesnesi okuma izni kaldırıldığında izinli işlem kırk üçten
otuz sekize iniyor — beş işlem — ve yükseltme yolu yirmi sekizden **sıfıra** düşüyor. Yirmi sekiz
yolun tamamını beş izin taşıyordu. Kalan otuz sekiz iznin hiçbiri bir özneyi başka bir öznenin
yerine geçirmiyor.

Bu beş izin gereksiz değildi; izde vardılar, yani o süreçler sırlara gerçekten erişiyordu. Sayının
söylediği şey iznin kaldırılması değil, **sırrın kümeden okunmak yerine sürece başka bir yolla
ulaştırılması** gerektiğidir. Karar burada bir ölçüye bağlanabilir hâle geliyor: bir izni
kaldırmanın işlem maliyeti beş, yükseltme kazancı yirmi sekiz. Aynı hesap kota, rol tanımı ve
düğüm için yapılsaydı kazanç sıfır çıkardı, çünkü o izinler zaten kapalıydı.

## Sistemin Bilmediği

Küme arayüzü bir isteği değerlendirirken tek bir soruya cevap arar: bu dörtlü tabloda var mı.
Niyeti, bağlamı, zamanı ve sırayı bilmez. Nöbetçinin üretimde sır nesnesi okuması, bir arıza
sırasında da olağan bir salı sabahı da aynı hücreye düşer; tablo ikisini ayırt edemez çünkü
ayırt edecek kalemi taşımıyor. Aynı nedenle "bu izni son ne zaman kullandı" sorusu da tablodan
cevaplanamaz — kırk üç iznin hangilerinin hâlâ canlı olduğu, ancak izin yeniden toplanmasıyla
bilinir. Bu, devredilen kararın sürekli beslenmesi gereken bir bilgi kalemi olduğu anlamına gelir:
tablo bir kez doğru kurulduğunda doğru kalmaz, iz değiştikçe eskir.

Eskimenin iki yönü var ve bedelleri simetrik değil. İz genişlediğinde — yeni bir servis, yeni bir
bakım işi — tablo dar kalır ve sistem **meşru bir işlemi reddeder**; bu hemen görünür, çünkü
birileri engellendiğini bildirir. İz daraldığında — bir süreç emekliye ayrılır, bir fiil
kullanılmaz olur — tablo geniş kalır ve sistem **gereksiz bir işlemi kabul etmeye devam eder**;
bu hiç görünmez, çünkü kimse şikâyet etmez. Yüz altmış sekiz rol tanımı izni geniş yetkide tam
olarak böyle duruyordu: kullanılmıyorlardı, kimseyi rahatsız etmiyorlardı ve elli altı yükseltme
yolunun büyük bölümünü taşıyorlardı. Otuz günlük izden türetilen en az yetkinin değeri, bu ikinci
yönü **bir kereliğine** kapatmasıdır; kapalı tutması için iz ölçümünün sürmesi gerekir.

## Özet

- Sekiz özne, yedi fiil, sekiz nesne türü ve üç ad alanı 1344 hücrelik bir matris kurar; otuz
  günlük iz bunun 43'ünü dolduruyor, en az yetkiye inmek 1301 işlem düşürüyor.
- Düşüş özne ekseninde değil: yetkili özne sayısı sekizden sekize sabit kaldı, daralan şey her
  öznenin ne yapabildiğidir.
- Rol tanımına dokunan 168 izin en az yetkide sıfıra iniyor; hiçbiri otuz gün boyunca
  kullanılmamıştı.
- En az yetkinin yazma bedeli 33 satırdan 42 satıra, yüzde yirmi yedi artıştır; geniş yetkide
  yazılan satır başına 40,7 işlem açılırken en az yetkide tam olarak 1 işlem açılır.
- İzinli işlem sayısı ile yükseltme yolu sayısı aynı şeyi ölçmez: işlemlerin yüzde doksan yedisi
  düştüğünde yollar yalnız yarıya indi ve dört özne hâlâ her özneye ulaşıyordu.
- Kalan 28 yolun tamamını beş sır okuma izni taşıyordu; o beş izin kapandığında yol sayısı sıfıra
  iniyor. İzin kaldırmanın maliyeti ve kazancı ayrı ayrı ölçülebilir.

## Sonraki Adım

Bu dersin matrisi kimin **küme arayüzü üzerinden** ne yapabileceğini sınırlıyor. İki kapsül
arasındaki trafik bu matristen geçmez: doğrulayıcı, faturalama servisinin ucuna doğrudan bağlanır
ve küme arayüzüne hiç uğramaz. Yetki matrisinde birbirine ulaşamayan iki özne, ağ üzerinde
birbirine serbestçe ulaşabilir. Sonraki ders erişilebilirlik matrisini politika ile kurar ve
varsayılan açık ile varsayılan kapalı arasındaki farkı sayar: kaç yol kapanıyor, kaç meşru yol
yanlışlıkla kapanıyor, politika kaç kural istiyor ve yeni bir servis eklendiğinde kaç kural
güncelleniyor.
