---
title: 'Roller ve Yetkiler'
source: 'https://academia.sh/tr/kurslar/veritabani-yonetimi/roller-ve-yetkiler'
course: 'İlişkisel Veritabanı Yönetimi'
language: tr
updated: '2026-08-17T18:08:56+00:00'
license: 'CC BY-SA 4.0'
---

# Roller ve Yetkiler

En az yetki ilkesinin veritabanında uygulanması: rol tabanlı erişim denetimi, rol devralmasının ürettiği fazla yetkinin sayılması, salt okunur bağlantıyla ikinci savunma katmanı ve uygulama hesabı ile bakım hesabının ayrılması.

Bu kursun buraya kadarki bölümü verinin nerede durduğunu ve hangi yoldan okunduğunu
kurdu: sayfa düzeni, günlük, dizin türleri, bölümleme ve parçalama kalıpları. Veri düzeni
ve erişim yolları yerine oturduğunda sistem çalışır hâle gelir — ama henüz işletilmiş
sayılmaz. İşletim, çalışan bir sistemin zaman içinde güvenli, kurtarılabilir ve
erişilebilir kalmasıdır.

Bu konunun ilk sorusu en eskisidir: bu veriye kim erişebilir ve ne yapabilir? Kütüphane
ödünç kayıtları örneğinde soru somutlaşır. Ödünç masasındaki uygulamanın ödünç kaydı
açması gerekir; üye kaydını silmesi gerekmez. Rapor aracının ödünç sayılarını okuması
gerekir; hiçbir satırı değiştirmesi gerekmez. Bu ayrımların yapılmadığı bir kurulumda
sistem yıllarca sorunsuz çalışabilir; tek bir hatalı sorgu ya da tek bir ele geçirilmiş
uygulama anahtarı, ayrımın yapılmamış olmasının bedelini bir defada ödetir.

## Kimlik Doğrulama ve Yetkilendirme

İki soru birbirine karışır. **Kimlik doğrulama (authentication)** "sen kimsin" sorusudur;
İnternet Nasıl Çalışır kursunda HTTPS bağlamında tanıtılmıştı. **Yetkilendirme
(authorization)** ise "kim olduğun belli, ne yapabilirsin" sorusudur. Veritabanı
motorları ikisini ayrı katmanlarda tutar: bağlantı kurulurken kimlik doğrulanır, her
deyimde yetki denetlenir.

SQL Temelleri kursunda `GRANT` ve `REVOKE` deyimleriyle nesne düzeyi izinler tanıtılmıştı.
O ders dili anlattı; bu ders, aynı deyimlerin işletimde nasıl düzenleneceğini anlatır.
Aradaki fark ölçektir: on tablo ve iki kullanıcı için izinleri tek tek vermek işler,
yüz tablo ve otuz hesap için işlemez. Ölçeklendiren yapı **rol (role)** kavramıdır.

## Rol Tabanlı Erişim Denetimi

**Rol tabanlı erişim denetimi (role-based access control)**, izinleri kişilere değil
görevlere bağlar. Önce görev tanımlanır — okuyucu, ödünç görevlisi, katalogcu — ve izinler
o göreve verilir. Kişi ya da uygulama hesabı sonradan role atanır.

Bunun işletimdeki karşılığı şudur: bir çalışan görev değiştirdiğinde ya da bir uygulama
kaldırıldığında değiştirilecek tek şey rol ataması olur. İzinler dağınık biçimde
hesaplara yazılmışsa, ayrılan bir çalışanın erişimini kapatmak bir arama işine dönüşür ve
o aramanın eksik kalması olağandır.

Rollerin ikinci özelliği **rol devralması (role inheritance)** — bir rolün başka bir rolün
izinlerini kapsamasıdır. Katalogcu, okuyucunun her şeyini yapabilsin diye okuyucu rolünü
devralır. Devralma yazımı kısaltır, ama bir yan etkisi vardır: etkin izin kümesi artık
yazıldığı yerde görünmez, hesaplanması gerekir. Bir hesabın gerçekte neye erişebildiğini
görmek için devralma zincirinin kapanışını almak gerekir.

## Fazla Yetkinin Hesaplanması

Aşağıdaki betik bir yetki çizelgesini modeller: roller, rollerin devraldığı roller,
hesapların rol atamaları ve her hesabın işini yapabilmesi için gerçekten gereken izinler.
Betik, devralmayı izleyerek etkin izin kümesini üretir ve gerekenden fazlasını çıkarır.

Bu bir modeldir; gerçek bir motorun yetki çizelgesi değildir. Modellenen şey devralmanın
kapanışı ve fark hesabıdır — motor hangisi olursa olsun bu iki adım aynıdır.

```bash
cat > yetki.mjs <<'EOF'
// Rol -> dogrudan verilmis izinler. Izin bicimi: "eylem:nesne".
const ROL_IZIN = {
  okuyucu:   ["select:kitap", "select:sube"],
  gorevli:   ["select:uye", "select:odunc", "insert:odunc", "update:odunc"],
  katalogcu: ["insert:kitap", "update:kitap", "delete:kitap"],
  yonetici:  ["delete:uye", "delete:odunc", "alter:*"],
};

// Rol -> devraldigi roller.
const ROL_DEVRAL = {
  okuyucu:   [],
  gorevli:   ["okuyucu"],
  katalogcu: ["okuyucu"],
  yonetici:  ["gorevli", "katalogcu"],
};

// Hesap -> atanmis roller.
const HESAP_ROL = {
  odunc_masasi:  ["gorevli"],
  katalog_ekibi: ["katalogcu"],
  rapor_araci:   ["gorevli"],
  bakim_hesabi:  ["yonetici"],
};

// Hesabin isini yapabilmesi icin gercekten gereken izinler.
const GEREKEN = {
  odunc_masasi:  ["select:kitap", "select:uye", "select:odunc", "insert:odunc", "update:odunc"],
  katalog_ekibi: ["select:kitap", "insert:kitap", "update:kitap"],
  rapor_araci:   ["select:kitap", "select:odunc"],
  bakim_hesabi:  ["select:kitap", "select:uye", "select:odunc", "alter:*"],
};

function etkinIzinler(rol, gorulen = new Set()) {
  if (gorulen.has(rol)) return new Set();          // devralma dongusune karsi
  gorulen.add(rol);
  const kume = new Set(ROL_IZIN[rol] ?? []);
  for (const ust of ROL_DEVRAL[rol] ?? []) {
    for (const izin of etkinIzinler(ust, gorulen)) kume.add(izin);
  }
  return kume;
}

function hesapIzinleri(hesap) {
  const kume = new Set();
  for (const rol of HESAP_ROL[hesap]) {
    for (const izin of etkinIzinler(rol)) kume.add(izin);
  }
  return kume;
}

const yaziciMi = (izin) => !izin.startsWith("select:");

console.log("hesap           | etkin | gereken | fazla | fazla yazici izin");
console.log("----------------|-------|---------|-------|------------------");
for (const hesap of Object.keys(HESAP_ROL)) {
  const etkin = hesapIzinleri(hesap);
  const gereken = new Set(GEREKEN[hesap]);
  const fazla = [...etkin].filter((i) => !gereken.has(i)).sort();
  console.log(
    hesap.padEnd(15) + " | " +
    String(etkin.size).padStart(5) + " | " +
    String(gereken.size).padStart(7) + " | " +
    String(fazla.length).padStart(5) + " | " +
    fazla.filter(yaziciMi).join(", ")
  );
}
EOF
node yetki.mjs
```

```text
hesap           | etkin | gereken | fazla | fazla yazici izin
----------------|-------|---------|-------|------------------
odunc_masasi    |     6 |       5 |     1 | 
katalog_ekibi   |     5 |       3 |     2 | delete:kitap
rapor_araci     |     6 |       2 |     4 | insert:odunc, update:odunc
bakim_hesabi    |    12 |       4 |     8 | delete:kitap, delete:odunc, delete:uye, insert:kitap, insert:odunc, update:kitap, update:odunc
```

Tablo dört ayrı sorunu aynı anda gösterir.

`odunc_masasi` bir izin fazlaya sahip ve o izin bir okuma iznidir (`select:sube`). Bu, en
az yetki ilkesinin ihlalidir ama etkisi sınırlıdır; devralmadan gelen kaçınılmaz artıktır.

`katalog_ekibi` kitap silme iznine sahip, oysa gerekenler arasında silme yok. Katalog
düzeltmesi yapan bir ekibin yanlışlıkla kayıt silmesi, sonradan onarılması pahalı bir
kazadır.

`rapor_araci` durumu en açık olanıdır. Yalnız okuma yapması beklenen bir hesap, `gorevli`
rolü üzerinden ödünç kaydı ekleme ve güncelleme iznine sahip. Bu, "uygun bir rol vardı,
onu verdik" kararının tipik sonucudur: rol adı işi anlatıyordu ama izin kümesi işten
genişti.

`bakim_hesabi` on iki izne sahip, dördü gerekli. Bakım hesabının geniş olması beklenir;
sorun genişliği değil, o hesabın gündelik iş için kullanılmasıdır.

## Salt Okunur Bağlantı

Yetki çizelgesi tek savunma katmanı değildir. İkinci katman **bağlantı düzeyi kısıtıdır**:
bağlantı, yazma yeteneği olmadan açılır. Rapor aracının hangi rolü taşıdığından bağımsız
olarak, bağlantısı salt okunur açılmışsa yazma denemesi bağlantı katmanında reddedilir.

```bash
rm -f kutuphane.db
sqlite3 kutuphane.db <<'SQL'
CREATE TABLE sube(id INTEGER PRIMARY KEY, ad TEXT NOT NULL);
INSERT INTO sube VALUES (1,'Merkez'),(2,'Sahil');
SQL

echo "--- salt okunur baglantidan yazma ---"
sqlite3 -readonly kutuphane.db "INSERT INTO sube VALUES (3,'Yeni');"
echo "cikis kodu: $?"

echo "--- ayni baglantidan okuma ---"
sqlite3 -readonly -box kutuphane.db "SELECT * FROM sube ORDER BY id;"
rm -f kutuphane.db
```

```text
--- salt okunur baglantidan yazma ---
Error: stepping, attempt to write a readonly database (8)
cikis kodu: 8
--- ayni baglantidan okuma ---
┌────┬────────┐
│ id │   ad   │
├────┼────────┤
│ 1  │ Merkez │
│ 2  │ Sahil  │
└────┴────────┘
```

Buradaki `-readonly` seçeneği ve hata iletisinin sözcükleri bu motora özgüdür; sunucu
tabanlı motorlarda karşılığı bir bağlantı parametresi ya da oturum ayarı olur. Ortak olan
düzenek şudur: yazma yeteneği bağlantı açılırken kapatıldığında, yetki çizelgesindeki bir
yanlışlık tek başına veri kaybına dönüşemez. İki katman birlikte bulunur; biri diğerinin
yerine geçmez.

## Hesapların Ayrılması

İşletimde üç hesap sınıfı birbirinden ayrı tutulur.

**Uygulama hesabı** gündelik işi yapar. Yalnız uygulamanın dokunduğu tablolar üzerinde,
yalnız yaptığı eylemler için izin taşır. Şema değiştirme izni taşımaz — uygulama kodunun
çalışma anında tablo yapısını değiştirmesi beklenmez.

**Rapor hesabı** yalnız okur. Ayrı bir hesap olmasının nedeni yalnız güvenlik değildir:
ayrı hesap, yavaş bir rapor sorgusunun kaynak tükettiğini izleme tarafında ayırt
edilebilir kılar. Bu ayrımın izleme değeri onuncu derste tekrar karşımıza çıkacak.

**Bakım hesabı** şema değişikliği, yedek alma ve kurtarma için kullanılır. Bu hesabın
geniş olması işin gereğidir; disiplini, gündelik bağlantılarda kullanılmamasıdır.
Uygulamanın bağlantı dizgisinde bakım hesabı yazıyorsa, uygulamadaki her kusur şema
kaybına dönüşme yeteneği kazanır.

Ayrımın sınanabilir bir sonucu vardır: uygulama hesabıyla açılmış bir bağlantıda tablo
silme denemesi yetki hatasıyla dönmelidir. Bu denemeyi bir kez elle yapmak, "izinleri
verdik" cümlesini "izinleri doğruladık" cümlesine çevirir.

## Yetkinin Zaman İçindeki Kayması

Yetki çizelgesi kurulduğu gün doğrudur; sonraki her ay biraz daha yanlıştır. Bir raporun
geçici olarak bir tabloya daha erişmesi gerekir, izin verilir, rapor kaldırılır, izin
kalır. Bu birikmeye **yetki sürünmesi (privilege creep)** denir ve tek çaresi düzenli
denetimdir.

Denetimin somut biçimi yukarıdaki betiğin yaptığı şeydir: hesabın etkin izin kümesi
çıkarılır, işin gerektirdiği kümeyle karşılaştırılır, fark listelenir. Farkın sıfır olması
gerekmez — devralmadan gelen artık izinler kabul edilebilir. Gerekli olan, farkın
**bilinmesi** ve yazıcı izinlerin fark listesinde bulunmamasıdır.

İkinci denetim sorusu erişim yollarıyla ilgilidir: yetki çizelgesi bir tabloyu kapatırken,
o tablonun sütunlarını gösteren bir görünüm açık kalmış olabilir. Görünümler SQL Temelleri
kursunda tanıtılmıştı; işletim tarafında görünüm, izin denetiminin atlanabildiği bir yol
hâline gelmemelidir. Denetim, tablo listesini değil erişilebilir nesnelerin tamamını
kapsar.

## Özet

- Kimlik doğrulama "kimsin", yetkilendirme "ne yapabilirsin" sorusudur; motorlar ikisini
  ayrı katmanlarda denetler.
- Rol tabanlı erişim denetimi izinleri kişiye değil göreve bağlar; görev değişikliğinde
  değişen tek şey rol ataması olur.
- Rol devralması etkin izin kümesini yazıldığı yerde görünmez kılar; etkin küme,
  devralma zincirinin kapanışı alınarak hesaplanır.
- En az yetki denetimi, etkin izin kümesi ile işin gerektirdiği kümenin farkını çıkarmaktır;
  fark listesinde yazıcı izin bulunmamalıdır.
- Salt okunur bağlantı, yetki çizelgesinden bağımsız ikinci bir savunma katmanıdır.
- Uygulama, rapor ve bakım hesapları ayrı tutulur; yetki sürünmesi düzenli denetimle
  karşılanır.

## Sonraki Adım

Bu dersteki izinlerin tamamı nesne düzeyindeydi: bir hesap bir tabloyu ya okuyabiliyordu
ya okuyamıyordu. Kütüphane örneğinde bu ayrım yetmez — Sahil şubesinin görevlisi ödünç
tablosunu okuyabilmeli, ama yalnız kendi şubesinin satırlarını. Aynı tabloda farklı
hesaplara farklı satır kümesi göstermek nesne düzeyi izinle ifade edilemez. Sonraki ders,
satırın hangi koşulla görüneceğini bir politika ifadesiyle tanımlayan satır düzeyi
güvenliği ele alıyor ve bir politikanın sızdırdığı satırların nasıl sayılacağını
gösteriyor.
