---
title: 'Dosya İzinleri ve Sahiplik'
source: 'https://academia.sh/tr/kurslar/bt-temelleri/dosya-izinleri-ve-sahiplik'
course: 'Bilgi Teknolojileri ve Sistem Temelleri'
language: tr
updated: '2026-08-17T18:08:38+00:00'
license: 'CC BY-SA 4.0'
---

# Dosya İzinleri ve Sahiplik

Aynı 70 erişim isteğinin iki izin modelinde koşturulması: izin bitleri modelinin gevşek ifadesinin 6 fazla izin, sıkı ifadesinin 6 fazla ret üretmesi, iki ifadenin birbirinden 12 istekte ayrılması, erişim denetim listesinin politikayı tam ifade etmesi ama girdi sırası değiştiğinde 6 isteğin sonucunun dönmesi ve sahipliğin iki modelin de dışında kalması.

Önceki ders temiz kurulumun bıraktığı 17 riskli kalemi saydı ve birkaçının doğrudan izin düzenini
ayarladığını belirtti. Kurulum bittiğinde makinede bir izin düzeni vardır: hesaplar, gruplar ve
nesnelerin kimin neyine açık olduğu.

Bu ders o düzenin içine iner. İzin bitlerinin mekaniği — üç sınıf, üç erişim türü, sekizlik
gösterim, sınıf seçiminin dışlayıcılığı — Linux'a Giriş kursunda kurulmuştu ve burada
tekrarlanmaz. Buradaki soru başkadır: **aynı politika iki ayrı izin modelinde ifade edildiğinde
kaç istekte farklı sonuç çıkar ve hangi model hangi isteği hiç ifade edemez.**

## Ölçülen Şey Mekanik Değil, İfade Gücü

Bir izin modeli iki işi birden yapar. Birincisi bir erişim isteğine yanıt vermektir; bu, mekaniktir
ve öğrenilir. İkincisi, kurumun aklındaki politikayı **taşıyabilmektir**; bu, modelin ifade
gücüdür ve sınırlıdır.

İki iş karıştırıldığında ölçüm kaybolur. "İzinler doğru ayarlandı" cümlesi mekanik iştir. Karar
taşıyan cümle şudur: bu politika bu modelde **tam olarak** ifade edilebiliyor mu, edilemiyorsa
en yakın ifadenin bedeli kaç istektir ve bu bedel hangi yöne düşer — fazladan verilen izne mi,
fazladan yapılan reddin engellediği meşru işe mi.

## Politika, İki Model ve 70 İstek

Örnek, kurgu **bölgesel ölçüm ağı**nın şube sunucusundaki beş dosyasıdır. Özneler, dosyalar ve
politika kurgudur; aşağıdaki değerlendirme bir **modeldir**, gerçek bir sistem ya da ürün yoktur.

**DI17:** yedi özne, beş nesne ve iki işlem 70 istek üretir; `niyet`, politikanın istediği
sonuçtur. **DI18:** izin bitleri modeli üç sınıf taşır ve sınıf seçimi dışlayıcıdır. **DI19:** her
nesne için grup, **sapması en az olan** grup seçilir; modele en iyi şans verilir. **DI20:** iki
ifade stratejisi denenir — `gevsek`, diğerleri sınıfına dışarıdaki ihtiyaçların birleşimini verir;
`siki`, diğerleri sınıfını boş bırakır. **DI21:** erişim denetim listesi modelinde ilk eşleşen
girdi karar verir; liste yazıldığı sırayla ve ters sırayla değerlendirilir. **DI22:** sapma iki
yönlü sayılır — fazla izin ve fazla ret ayrı sütunlardır.

```js
// bt/izin.mjs — ayni erisim istegi kumesinin iki izin modelindeki sonucu (model): kurgu olcum
// aginin dosyalari, gercek bir sistem ya da urun yok. Rastgelelik yok.

export const OZNE = { "saha-teknisyeni": "saha", "sube-yoneticisi": "sube",
  "toplayici-servis": "servis", "faturalama-servisi": "servis", "veri-analisti": "analiz",
  "denetci": "denetim", "misafir-cihaz": "misafir" };
export const GRUP = [...new Set(Object.values(OZNE))];
export const ISLEM = ["r", "w"];

// niyet: politikanin istedigi erisim. acl: yoneticinin yazdigi liste (ret girdileri once).
export const NESNE = [
  { ad: "okuma-ham", sahip: "toplayici-servis",
    niyet: { "toplayici-servis": "rw", "saha-teknisyeni": "r", "sube-yoneticisi": "r",
      "veri-analisti": "r", "denetci": "r" },
    acl: [["ret", "faturalama-servisi", "rw"], ["izin", "servis", "rw"], ["izin", "saha", "r"],
      ["izin", "sube", "r"], ["izin", "analiz", "r"], ["izin", "denetim", "r"]] },
  { ad: "okuma-dogrulanmis", sahip: "veri-analisti",
    niyet: { "veri-analisti": "rw", "faturalama-servisi": "r", "sube-yoneticisi": "r",
      "denetci": "r" },
    acl: [["ret", "toplayici-servis", "rw"], ["izin", "servis", "r"], ["izin", "analiz", "rw"],
      ["izin", "sube", "r"], ["izin", "denetim", "r"]] },
  { ad: "fatura-taslak", sahip: "faturalama-servisi",
    niyet: { "faturalama-servisi": "rw", "sube-yoneticisi": "r", "denetci": "r" },
    acl: [["ret", "toplayici-servis", "rw"], ["izin", "servis", "rw"], ["izin", "sube", "r"],
      ["izin", "denetim", "r"]] },
  { ad: "anahtar-dosyasi", sahip: "toplayici-servis",
    niyet: { "toplayici-servis": "r" },
    acl: [["ret", "faturalama-servisi", "rw"], ["izin", "servis", "r"]] },
  { ad: "denetim-gunlugu", sahip: "denetci",
    niyet: { "denetci": "r", "toplayici-servis": "w", "faturalama-servisi": "w" },
    acl: [["izin", "servis", "w"], ["izin", "denetim", "r"]] },
];

export const ISTEK = Object.keys(OZNE).flatMap((o) =>
  NESNE.flatMap((n) => ISLEM.map((i) => ({ o, n, i }))));
export const niyet = (n, o, i) => (n.niyet[o] || "").includes(i);

// Izin bitleri modeli: uc sinif, sinif secimi dislayicidir (M03/K01'de kurulmustur).
const birlestir = (n, kim) => kim.filter((o) => o !== n.sahip)
  .map((o) => n.niyet[o] || "").join("");
export function bitler(n, grup, gevsek) {
  const uye = Object.keys(OZNE).filter((o) => OZNE[o] === grup);
  const dis = Object.keys(OZNE).filter((o) => OZNE[o] !== grup && o !== n.sahip);
  return { grup, sahip: n.niyet[n.sahip] || "", g: birlestir(n, uye),
    d: gevsek ? birlestir(n, dis) : "" };
}
export const bitSonuc = (b, n, o, i) =>
  (o === n.sahip ? b.sahip : OZNE[o] === b.grup ? b.g : b.d).includes(i);

// En iyi grup secimi: sapmasi en az olan grup. Sapma = fazla izin + fazla ret.
export function enIyi(n, gevsek) {
  return GRUP.map((g) => bitler(n, g, gevsek))
    .map((b) => ({ b, ...sapma((o, i) => bitSonuc(b, n, o, i), [n]) }))
    .reduce((a, x) => (x.fazlaIzin + x.fazlaRet < a.fazlaIzin + a.fazlaRet ? x : a));
}

// Erisim denetim listesi modeli: ilk eslesen girdi karar verir.
export const aclSonuc = (n, o, i, tersSira) => {
  const l = tersSira ? [...n.acl].reverse() : n.acl;
  const g = l.find(([, kim, ops]) => (kim === o || kim === OZNE[o]) && ops.includes(i));
  return g ? g[0] === "izin" : false;
};

export function sapma(f, nesneler = NESNE) {
  const k = ISTEK.filter((x) => nesneler.includes(x.n));
  return { fazlaIzin: k.filter((x) => f(x.o, x.i, x.n) && !niyet(x.n, x.o, x.i)).length,
    fazlaRet: k.filter((x) => !f(x.o, x.i, x.n) && niyet(x.n, x.o, x.i)).length };
}
```

```js
// bt/izinolc.mjs — ayni istek kumesi iki izin modelinde: kac istekte fark, kac istek ifade edilemiyor.
import { OZNE, NESNE, ISTEK, niyet, bitSonuc, enIyi, aclSonuc, sapma } from "./izin.mjs";

const yaz = (g, ...s) => console.log(s.map((v, i) =>
  (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join(""));

const B = { gevsek: {}, siki: {} };
for (const n of NESNE) for (const s of ["gevsek", "siki"]) B[s][n.ad] = enIyi(n, s === "gevsek").b;
const bitF = (s) => (o, i, n) => bitSonuc(B[s][n.ad], n, o, i);
const MODEL = [["izin-bitleri (gevsek)", bitF("gevsek")], ["izin-bitleri (siki)", bitF("siki")],
  ["erisim-listesi (ret once)", (o, i, n) => aclSonuc(n, o, i, false)],
  ["erisim-listesi (izin once)", (o, i, n) => aclSonuc(n, o, i, true)]];

const izinli = ISTEK.filter((x) => niyet(x.n, x.o, x.i)).length;
console.log(`${Object.keys(OZNE).length} ozne x ${NESNE.length} nesne x 2 islem = ` +
  `${ISTEK.length} istek; niyette izinli olan ${izinli}, reddedilen ${ISTEK.length - izinli}`);

const A = [-28, 12, 11, 14];
console.log("\n1. her model niyetten ne kadar sapiyor");
yaz(A, "model", "fazla izin", "fazla ret", "niyetle ayni");
for (const [ad, f] of MODEL) {
  const s = sapma(f);
  yaz(A, ad, s.fazlaIzin, s.fazlaRet, ISTEK.length - s.fazlaIzin - s.fazlaRet);
}

const C = [-20, -14, -12, 12, 11];
console.log("\n2. izin bitleri modelinde nesne basina artik (en iyi grup secimiyle)");
yaz(C, "nesne", "gevsek grup", "siki grup", "fazla izin", "fazla ret");
for (const n of NESNE) {
  const g = enIyi(n, true);
  const s = enIyi(n, false);
  yaz(C, n.ad, g.b.grup, s.b.grup, g.fazlaIzin, s.fazlaRet);
}

const D = [-56, 10];
console.log("\n3. modeller arasi fark (kac istekte sonuc farkli)");
yaz(D, "cift", "farkli");
for (let x = 0; x < MODEL.length; x++)
  for (let y = x + 1; y < MODEL.length; y++)
    yaz(D, `${MODEL[x][0]} / ${MODEL[y][0]}`,
      ISTEK.filter((r) => MODEL[x][1](r.o, r.i, r.n) !== MODEL[y][1](r.o, r.i, r.n)).length);

const E = [-24, 14, 14];
console.log("\n4. fazladan erisim kime gidiyor");
yaz(E, "ozne", "gevsek bitler", "izin once acl");
for (const o of Object.keys(OZNE)) {
  const f = (g) => ISTEK.filter((x) => x.o === o && g(x.o, x.i, x.n) && !niyet(x.n, x.o, x.i)).length;
  const a = f(bitF("gevsek"));
  const b = f((oz, i, n) => aclSonuc(n, oz, i, true));
  if (a || b) yaz(E, o, a, b);
}
```

```
7 ozne x 5 nesne x 2 islem = 70 istek; niyette izinli olan 19, reddedilen 51

1. her model niyetten ne kadar sapiyor
model                         fazla izin  fazla ret  niyetle ayni
izin-bitleri (gevsek)                  6          0            64
izin-bitleri (siki)                    0          6            64
erisim-listesi (ret once)              0          0            70
erisim-listesi (izin once)             6          0            64

2. izin bitleri modelinde nesne basina artik (en iyi grup secimiyle)
nesne               gevsek grup   siki grup     fazla izin  fazla ret
okuma-ham           servis        saha                   1          3
okuma-dogrulanmis   saha          sube                   2          2
fatura-taslak       saha          sube                   3          1
anahtar-dosyasi     saha          saha                   0          0
denetim-gunlugu     servis        servis                 0          0

3. modeller arasi fark (kac istekte sonuc farkli)
cift                                                        farkli
izin-bitleri (gevsek) / izin-bitleri (siki)                     12
izin-bitleri (gevsek) / erisim-listesi (ret once)                6
izin-bitleri (gevsek) / erisim-listesi (izin once)               8
izin-bitleri (siki) / erisim-listesi (ret once)                  6
izin-bitleri (siki) / erisim-listesi (izin once)                12
erisim-listesi (ret once) / erisim-listesi (izin once)           6

4. fazladan erisim kime gidiyor
ozne                     gevsek bitler izin once acl
toplayici-servis                     2             3
faturalama-servisi                   0             3
veri-analisti                        1             0
misafir-cihaz                        3             0
```

Sayılar **ölçüm** sınıfındadır; girdileri DI17–DI22'dir.

## İzin Bitleri Neyi İfade Edemiyor

Birinci tablonun ilk iki satırı bu dersin ana bulgusudur. İzin bitleri modeli 70 isteğin 64'ünü
niyetle aynı sonuçlandırır; kalan 6 istek her iki stratejide de yanlıştır. Yön farklıdır: gevşek
ifade **6 fazla izin**, sıkı ifade **6 fazla ret** üretir.

Sıfır olmaması bir ayar hatası değildir. Kod her nesne için beş grubu da dener ve sapması en az
olanı seçer; modele en iyi şans verilmiştir. Kalan artık, modelin **yapısından** gelir: üç sınıf
vardır ve bir özneye ancak bu üç sınıftan biri üzerinden ulaşılabilir. Politikanın istediği ayrım
üç sınıfa sığmıyorsa — dört ayrı grupta okuyucu varsa ve bir özne dışarıda tutulacaksa — geriye
yalnızca yaklaşık ifade kalır.

İkinci tablo artığın nerede biriktiğini gösterir. `anahtar-dosyasi` ve `denetim-gunlugu` iki
stratejide de sıfır artık verir; ikisinde de erişim kümesi tek bir sahip ile tek bir grubun içine
düşer. `fatura-taslak` gevşek ifadede 3 fazla izin üretir, çünkü iki farklı gruptaki iki okuyucuyu
kapsamanın tek yolu diğerleri sınıfını açmaktır ve o sınıfta dört özne daha vardır.

Dördüncü tablo bedelin kime gittiğini yazar. Gevşek ifadede fazladan erişim alan öznelerden biri
`misafir-cihaz`'dır ve **3 istek** kazanır. Bu özne politikada hiçbir nesneye erişmez; modelde
onu dışarıda tutacak bir yer yoktur, çünkü "diğerleri" sınıfı herkesi kapsar. **İzin bitleri
modelinin ifade edemediği şey bir izin değil, bir istisnadır.**

## Yaklaşımın Yönü Seçilir, Varlığı Seçilmez

Üçüncü tablonun ilk satırı iki stratejiyi karşılaştırır: gevşek ve sıkı ifadeler birbirinden **12
istekte** ayrılır. Toplam sapma her ikisinde de 6 olduğu hâlde ayrıştıkları istek sayısı iki
katıdır, çünkü sapmalar farklı isteklerdedir ve zıt yönlüdür.

Bu, yaklaşık ifadenin yönetilebilir kısmıdır. Model tam ifade edemiyorsa yönetici bir yön seçer.
Gevşek yön işleri durdurmaz ama 6 istekte politika dışı erişim açar. Sıkı yön hiçbir fazladan
erişim vermez ama 6 meşru isteği reddeder; ölçüm ağında bu, denetçinin fatura taslağını okuyamaması
ve saha teknisyeninin ham okumaya erişememesi demektir.

Seçilemeyecek olan şey **sapmanın kendisidir**. Toplam sapma iki yönde de 6'dır; hangi stratejinin
seçildiği yalnızca bedelin nereye yazılacağını belirler. Bir izin modeli seçilirken sorulacak soru
"hangisi daha güvenli" değil, "politikam bu modelde kaç istekte ifade edilemiyor ve o isteklerin
bedelini hangi yöne yazabilirim" sorusudur.

## Erişim Denetim Listesi Ne Getiriyor, Ne Getirmiyor

Birinci tablonun üçüncü satırı sıfırdır: erişim denetim listesi modeli, ret girdileri önce
değerlendirildiğinde 70 isteğin 70'ini niyetle aynı sonuçlandırır. Özne başına girdi yazılabildiği
için üç sınıf sınırı ortadan kalkar ve `misafir-cihaz` sorunu doğmaz.

Dördüncü satır ise bedeli gösterir. Aynı liste, girdiler ters sırada değerlendirildiğinde **6 fazla
izin** üretir. Üçüncü tablonun son satırı bunu doğrudan yazar: iki sıralama birbirinden 6 istekte
ayrılır. Bu 6 istek, grup düzeyinde verilen bir iznin öznesi olan ama bireysel bir ret girdisiyle
dışarıda tutulması gereken öznelere aittir — `toplayici-servis` ve `faturalama-servisi`, dördüncü
tabloda 3'er istek kazanırlar.

Buradaki fark bir yazım hatası değil, modelin ikinci ekseninin **sıra** olmasıdır. İzin bitleri
modelinde bir nesnenin izin durumu tek bir değerdir ve okunduğunda sonucu belirler; erişim denetim
listesinde aynı politika farklı sıralarla yazılabilir ve iki liste aynı girdileri taşıdığı hâlde
farklı sonuç verir. **İfade gücü arttıkça sonucun okunması zorlaşır:** bir listenin doğruluğu
girdilerine bakılarak değil, ancak istek kümesi üzerinde koşturularak anlaşılır.

Sınırın yetmediği ikinci yer budur. Sıfır sapma, listenin doğru yazıldığı **ve** doğru sırada
değerlendirildiği varsayımına dayanır; bu iki koşuldan biri kaybolduğunda model, izin bitleri
modelinin gevşek ifadesiyle aynı sayıya — 6 fazla izne — düşer.

## İkisinin de Dışında: Sahiplik

Her iki modelde de ölçülmeyen bir kalem vardır. Nesnenin **sahipliği**, izin kararlarının içinde
değil, üstündedir: sahip, bitleri de listeyi de değiştirebilir. Modelde `denetim-gunlugu` dosyasının
sahibi `denetci`'dir ve politika denetçiye yalnız okuma verir — ama sahip olduğu için kendine yazma
verebilir.

Bu, kursun ölçüsüyle yazıldığında nettir. Bir nesnenin izin sınırını geçmek için gereken kalem, o
nesnede politika ne derse desin, **1'dir**: sahipliğin ele geçmesi. Sınır düştüğünde erişilen kalem
ise o nesnenin bütün izin kararlarıdır. Bu yüzden sahiplik bir izin satırı gibi denetlenmez; ayrı
sayılır. Ölçüm ağının beş dosyasında sahiplik dört ayrı özneye dağıtılmıştır ve bu dağılım, tek bir
öznenin ele geçmesinin kaç dosyanın izin düzenini açtığını belirler.

Sahipliğin ayrı sayılması ölçümün üçüncü sütununu da düzeltir. İlk iki sütun — sapma sayısı ve
sapmanın yönü — modelin ifade gücünü ölçer; üçüncü sütun, o ifadenin ne kadar süreyle geçerli
kaldığını ölçer. Sahipliği bir öznede toplanan bir dosya kümesinde politika, o özne ele geçtiği
anda geçersizdir ve sapma sayısı anlamını yitirir.

## Özet

- İzin bitleri modeli 70 isteğin 6'sını ifade edemez; gevşek ifade 6 fazla izin, sıkı ifade 6 fazla
  ret üretir. Artık, grup seçiminden değil, üç sınıflı yapıdan gelir.
- Modelin ifade edemediği şey bir izin değil bir istisnadır: politikada hiçbir erişimi olmayan
  `misafir-cihaz`, gevşek ifadede 3 istek kazanır çünkü "diğerleri" sınıfı herkesi kapsar.
- İki strateji birbirinden 12 istekte ayrılır. Sapmanın varlığı seçilemez, yalnız yönü seçilir:
  fazladan açılan erişim ile durdurulan meşru iş arasında.
- Erişim denetim listesi modeli aynı politikayı 70 istekte tam ifade eder, ama ikinci bir eksen
  getirir: girdiler ters sırada değerlendirildiğinde 6 istek fazla izne döner.
- İfade gücü arttıkça doğruluk okunamaz hâle gelir; bir listenin doğruluğu girdilerine bakılarak
  değil, istek kümesi üzerinde koşturularak anlaşılır.
- Sahiplik iki modelin de dışındadır: izin sınırını geçmek için gereken kalem, politika ne derse
  desin 1'dir ve sınır düştüğünde o nesnenin bütün izin kararları açılır.

## Sonraki Adım

İzin düzeni artık ölçülü: hangi modelin neyi ifade edebildiği ve edemediği sayıyla yazılı. Ancak
bütün bu ölçüm, izinlerin **kim tarafından ve nasıl** değiştirildiğini hiç sormadı. Bir izin
satırının değişmesi bir olaydır ve o olayın geriye bıraktığı iz, izin satırının kendisi kadar
önemlidir.

Sonraki ders aynı işi iki yönetim biçiminde yapar — grafik arayüzle ve komut satırıyla — ve her
birinin bıraktığı iz kalemini sayar: kaç kayıt düşüyor, kaçı yeniden üretilebiliyor, kaçı denetim
izinde hiç görünmüyor.
