İçeriğe atla
0 XP 0
12 dkderinleşmeyle 13 dk56 XP6 etkinlik

Yetki ve çok kiracılı RAG

Bu derste
  • Çok kiracılı bir RAG sisteminde yetki filtresinin neden aramadan önce çalıştığını, skor yan kanalını ve kiracı kimliğinin doğru kaynağını öğrenirsin.
  • Bu derste yetki kontrolünün hangi adımda yapılması gerektiğini ve indeks sızıntısını göreceksin.
  • Sonunda yanlış yerde yapılan bir filtrelemeyi kodda yakalayacaksın.

Puan bütün etkinlikleri cevaplayınca hesaba yazılır. Bu dersi tamamlayınca +56 XP alacaksın. Giriş yapmadan ilerlersen puan yalnız bu tarayıcıda durur.

Altay Yazılım bir destek platformu işletiyor. Yüzlerce şirket kendi belgelerini platforma yüklüyor ve çalışanları aynı asistana soru soruyor. Bir gün Toros Yapı'dan bir çalışan fiyat listesini sordu. Cevapta başka bir müşterinin, acme kiracısının, bayi indirim oranı da vardı.

Kimse sisteme sızmamıştı. Asistan yalnız yanlış sırayla kurulmuş bir aramanın sonucunu okudu. Bu derste çok kiracılı bir RAG sisteminde sınırın nereye çizildiğini göreceksin.

Önce yetki filtresinin hangi adımda çalışması gerektiğini, sonra geç filtrelemenin kodda nasıl göründüğünü inceleyeceksin. Ardından metin sızmadan bilgi sızdıran skor kanalını ve kiracı kimliğinin doğru kaynağını öğreneceksin.

Tek indeks, çok kiracı

Çok kiracılı (multi-tenant) bir sistemde tek bir altyapı birçok müşteriye hizmet eder. Her müşteri bir kiracıdır. Maliyet düşer, işletme kolaylaşır. Buna karşılık her sorgu, yanlış kurulduğunda başka bir kiracının belgesine dokunur.

Kiracıları ayırmanın üç yaygın yolu vardır. En güçlüsü her kiracıya ayrı bir indeks ya da ayrı bir tablo vermektir. Ortadaki yol, tek indeksi kiracıya göre bölümlere ayırmaktır. En zayıfı ise tek bir ortak indeks kurup her parçaya kiracı etiketi yazmak ve sorguda bu etikete göre süzmektir.

pgvector belgeleri de bu konuda net bir uyarı yapar. Kiracılar arasında paylaşılan yaklaşık bir indekste bir kiracının vektörleri başka kiracının sonuç kalitesini ve hızını etkiler. Yalıtım için liste bölümleme ya da ayrı tablo önerilir.

İstemcitarayıcı, JavaScriptUygulamayönlendirme, iş kuralıŞablon motoruçıktı üretimiVeri katmanıSQL, dosya
İstemci kiracı seçemez. Uygulama katmanı kiracıyı oturumdan çözer, veri katmanı yalnız o kiracının satırlarını döner, çıktı da yalnız bu satırlardan üretilir.

Ortak indeks kullanıyorsan yetki kontrolü üç yerde yapılabilir: aramadan önce, aramadan sonra ya da cevabı gösterirken. Tek doğru yer birincisidir. Fark zamanlamadadır. Aramadan önce kurulan filtre, sorgunun kendisini kiracıya göre daraltır.

İndeks başka kiracının parçasını hiç aday olarak değerlendirmez. Aramadan sonra ya da cevap gösterirken yapılan filtreleme ise önce geniş bir arama yapar, sonucu görür ve ardından eler. Fark küçük görünse de sonucu büyüktür.

Geç filtreleme, sistemin bir anlığına da olsa yetkisiz veriyi işlediği anlamına gelir. O an bellek, günlük ya da önbellek o veriyi tutabilir. Erken filtreleme yetkisiz veriyi sisteme hiç sokmaz, bu yüzden sonradan sızacak bir şey de kalmaz.

Bir de şu soruyu sor: asistan kimin yetkisiyle arıyor? Çoğu kurulumda indeksi bir hizmet hesabı doldurur ve bu hesap bütün belgeleri okuyabilir. Asistan da arama yaparken aynı geniş yetkiyi kullanır. Bu durumda kullanıcıyla veri arasındaki tek sınır, uygulamanın koyduğu filtredir.

Filtre bir kez unutulursa asistan, kullanıcının hiç erişemeyeceği bir belgeyi onun adına okur. Güvenlik literatürü buna karışık vekil (confused deputy) sorunu der.

Yetkili bir aracı, yetkisiz birinin isteğini kendi yetkisiyle yerine getirir. Daha güvenli tasarım, aramayı kullanıcının kendi yetkisiyle yapmaktır. Kullanıcı adına alınmış bir belirteç ya da veritabanındaki satır politikası, bu sınırı uygulama kodundan bağımsız tutar.

Etkinlik 1 / 6

Yetki filtresi hangi adımda uygulanmalı?

Geç filtreleme: çözümlü örnek

Sonradan filtreleme neden yetmez? Çünkü sistem parçayı çoktan okumuştur. Parça prompta girdiyse model onu görmüştür. Cevabı gizlesen bile özet, sayı, tarih ya da üslup sızabilir.

Parça prompta girmeden elendiyse bile uygulama onu belleğe almış, belki günlüğe yazmıştır. Kural kısadır: görülen veri sızmış veridir. Gerçek kurulumlarda geç filtrelemenin sık bir nedeni performanstır.

pgvector gibi bazı yaklaşık indekslerde filtre, indeks tarandıktan sonra uygulanır. Bu yüzden filtreli sorgu beklenenden az sonuç döndürebilir. pgvector belgesine göre koşul satırların yüzde onuyla eşleşiyorsa, varsayılan ayarla ortalama dört satır döner. Ekip kaliteyi kurtarmak için filtreyi aramanın dışına taşır ve farkında olmadan sınırı kaldırır.

# Yanlis: once getir, sonra ele
parcalar = indeks.ara(soru, k=10)
izinli = [p for p in parcalar if p.kiraci == kullanici.kiraci]
cevap = model.uret(soru, izinli)

# Dogru: filtreyi aramaya goster
parcalar = indeks.ara(soru, k=10, filtre={"kiraci": kullanici.kiraci})
cevap = model.uret(soru, parcalar)
İki satır fark. Üstteki kurulumda on parça okunur, alttaki kurulumda yalnız izinliler aranır.
-- Kiraci yalitimi veritabaninda: politika her sorguya kendiliginden eklenir
ALTER TABLE parcalar ENABLE ROW LEVEL SECURITY;
ALTER TABLE parcalar FORCE ROW LEVEL SECURITY;
CREATE POLICY kiraci_yalitimi ON parcalar
  USING (kiraci_id = current_setting('app.kiraci_id')::int);

-- Her istek kendi islemi icinde, oturumdan gelen kiraciyla calisir
BEGIN;
SET LOCAL app.kiraci_id = '42';
SET LOCAL hnsw.iterative_scan = strict_order;
SELECT id, icerik FROM parcalar ORDER BY gomme <=> $1 LIMIT 10;
COMMIT;
PostgreSQL ve pgvector ile aynı kural veritabanı katmanında. Sorgu filtre yazmasa da politika yetkisiz satırı döndürmez.

Python bloğunda yanlış sürüm on parçayı kiracıya bakmadan getirir, sonra eler. Doğru sürüm filtreyi arama çağrısının içine koyar. SQL bloğu aynı kuralı bir adım daha aşağıya, veritabanına indirir.

ENABLE satırı satır düzeyi güvenliği açar. FORCE satırı önemlidir, çünkü tablo sahibi rol normalde bu politikaları atlar. Uygulama tablo sahibi rolle bağlanıyorsa FORCE olmadan politika hiç çalışmaz.

Süper kullanıcı ve BYPASSRLS yetkili roller ise FORCE ile bile politikayı atlar. Uygulamayı bu rollerle bağlama. CREATE POLICY satırı her sorguya kiracı koşulunu kendiliğinden ekler. SET LOCAL değeri yalnız o işlem boyunca geçerli kılar.

Bağlantı havuzunda bir isteğin kiracısı sonraki isteğe taşınmaz. Değer ayarlanmamışsa koşul ifadesi hata verir ve sorgu boş dönmek yerine durur. iterative_scan satırı ise pgvector 0.8.0 ile gelen yinelemeli taramayı açar ve filtreli sorguda sonuç sayısını korur.

Etkinlik 2 / 6

Bu kodda yetki sınırını ihlal eden satırı işaretle.

Zafiyetli satıra tıkla.

Etkinlik 3 / 6

Doğru mu, yanlış mı?

Yaklaşık indekste filtreli sorgu az sonuç döndürdüğü için filtreyi aramadan sonraya taşımak güvenli bir kalite düzeltmesidir.

Skor yan kanalı

İkinci risk indeks sızıntısıdır. Vektör veritabanları çoğu zaman yalnız metni değil; skor, parça kimliği, üst veri ve toplam eşleşme sayısını da döner. Geliştirici bu alanları hata ayıklarken işe yarar diye API yanıtına bırakır.

Yetkisiz bir kullanıcı sonuç gövdesini göremese bile skorları görebilir. Skor tek başına bilgi taşır.

Aradığın terim başka bir kiracıda geçiyor mu, geçmiyor mu? Toplam eşleşme sayısı da aynı soruya cevap verir. Bu alanlar zararsız sayısal veriler gibi görünür. Ama her biri başka kiracının indeksine açılan küçük bir penceredir.

Bu bir yan kanal saldırısıdır. Saldırgan yüzlerce sorgu atar ve skor değişimlerine bakar. Örneğin Kartal Projesi gibi bir ad sorduğunda skor birden yükseliyorsa, bu adın başka bir kiracının belgelerinde geçtiğini öğrenir.

Hiçbir metin sızmaz, yine de bilgi sızar. Çözüm, yanıtı yalnız sorgulayan kiracının verisiyle kurmaktır.

Ham skorları, başka kiracıya ait kimlikleri ve toplam sonuç sayısını dışarı verme. Vektörlerin kendisini de API'den döndürme, çünkü gömme vektörü sanıldığından çok metin bilgisi taşır. Tespit için kısa sürede çok sayıda benzer sorgu atan hesapları izle. Ad listesi tarar gibi ilerleyen sorgu dizileri belirgin bir desen bırakır.

// Riskli yanit: kiraci disina bilgi tasiyor
{ "toplam_eslesme": 37,
  "sonuclar": [ { "id": "c-91f2", "kiraci": "acme", "skor": 0.83 } ] }

// Guvenli yanit: yalniz kendi kiracisinin parcalari, ham skor ve toplam yok
{ "sonuclar": [ { "id": "p-1207", "baslik": "Fiyat listesi 2026" } ] }
Aynı sorgunun iki yanıtı. Üstteki metin vermez, yine de başka kiracı hakkında üç bilgi sızdırır.

Etkinlik 4 / 6

Doğru mu, yanlış mı?

Yetkisiz kullanıcıya belge metni dönmese de benzerlik skorları dönüyorsa, yüzlerce sorgudaki skor değişimi başka kiracının belgelerinde hangi terimlerin geçtiğini ele verir.

Derinleş:Gömme vektörü de metin taşır

Gömme vektörü bir dizi sayıdır ve ilk bakışta okunamaz görünür. Bu yüzden ekipler vektörleri çoğu zaman metin kadar korumaz. Araştırmalar bu varsayımı çürüttü.

Morris ve arkadaşlarının EMNLP 2023'te yayımlanan çalışması, vektörü adım adım düzelterek metni geri kurmayı denedi. Yöntem, 32 belirteçlik metinlerin yüzde 92'sini birebir geri kurdu. Klinik notlardan oluşan bir veri kümesinde tam hasta adlarını da çıkarabildi.

OWASP'ın LLM08 maddesi bu riski gömme ters çevirme saldırısı olarak sayar. Pratik sonuç şudur: vektörleri kişisel veri taşıyan metinle aynı gizlilik düzeyinde sakla. Vektör veritabanına erişimi metin deposuna erişim gibi yetkilendir. Vektörleri dışa aktarma, yedekleme ve üçüncü taraf hizmete gönderme adımlarını da aynı denetimden geçir.

Kiracı kimliği nereden gelir

Üçüncü risk üst veri karışmasıdır. Belgeler yüklenirken kiracı kimliği yanlış atanabilir. Toplu içe aktarma, klasör senkronizasyonu ve veri göçü klasik hata kaynaklarıdır.

Örneğin içe aktarma betiği kiracı alanı boş gelen kayda varsayılan bir değer yazar. O varsayılan değer de ilk müşterinin kimliğidir.

Tek bir yanlış etiket, uzun süre fark edilmeden yanlış tarafa cevap üretir. Bu yüzden içe aktarmada boş ya da tanınmayan kiracı alanını reddet, varsayılan değer verme. Her yüklemeden sonra kiracı başına parça sayısını önceki günle karşılaştır. Beklenmedik bir sıçrama, yanlış etiketin ilk izidir.

İzleme bu riskleri birbirine bağlar. Sorgu günlüğüne hangi kullanıcının hangi kiracı kimliğiyle sorgu attığını yaz. İndeks günlüğüne filtrenin gerçekten uygulanıp uygulanmadığını ve dönen parçaların kiracısını yaz.

İki günlük eşleşmezse bir yapılandırma hatası var demektir. Yani sorgu bir kiracı için gelmişken indeks başka kiracının parçasını döndürmüşse hemen uyarı üret. Böyle bir uyarı sızıntı büyümeden yanlış kurulumu yakalar.

Bu kontrolü üretimde beklemeden de çalıştırabilirsin. Her kiracı için birkaç deneme sorgusu hazırla ve dönen parçaların hepsinin o kiracıya ait olduğunu her yayında test et.

Bu hata yeni değildir. OWASP API Security Top 10 2023 listesinin ilk maddesi, nesne düzeyinde yetki kırılmasıdır (BOLA). İstemci bir nesne kimliği gönderir, sunucu bu nesnenin o kullanıcıya ait olup olmadığını denetlemez. RAG'deki karşılığı, istemcinin gönderdiği kiracı alanına güvenmektir.

Kural aynıdır: yetkiyle ilgili hiçbir değeri istemciden alma. Kiracıyı, rolü ve grup üyeliğini sunucu tarafında doğrulanmış oturumdan ya da imzası denetlenmiş bir belirteçten çöz. İstemci gövdesinde bu alanlar gelirse yok say ve isteği kayda geçir. Böyle bir alanın hiç gelmemesi gerekir, gelmesi ise denemenin işaretidir.

Etkinlik 5 / 6

Bu istekte kiracı kimliği gövdeden geliyor. İsteği güvenli hale getirmek için gövdeden çıkarılması gereken alanı yaz.

İsteği tamamla ve gönder.

POST /api/rag/sorgu HTTP/1.1
Authorization: Bearer <oturum>
Content-Type: application/json
Gövdeden silinmesi gereken alan

Parça düzeyinde ve güncel yetki

Yetki modelini belge düzeyinde bırakma, parça düzeyine indir. Bir belgenin bazı bölümleri herkese açık, bazı bölümleri kısıtlı olabilir. Bir sözleşmenin genel koşulları bütün ekibe açıkken fiyat eki yalnız satış ekibine açık olabilir. Parça oluştururken kaynak belgenin erişim listesini ve bölümün kısıtını parçaya kopyala.

İndeks filtresini bu alan üzerinden çalıştır. Aynı kiracının içinde de sınır vardır. İnsan kaynakları klasöründeki bir parça, aynı şirketin yazılım ekibine dönmemelidir. Çok kiracılı yalıtım dış sınırı çizer, parça düzeyindeki erişim listesi ise iç sınırları çizer.

{
  "parca": "sozlesme-2026-14#7",
  "kiraci": "toros",
  "kaynak_belge": "sozlesme-2026-14",
  "bolum": "Ek-2 Fiyatlar",
  "gruplar": ["satis", "hukuk"],
  "guven": "ic"
}
Bir parçanın üst verisi. Filtre kiracıya ve gruplara birlikte bakar, böylece fiyat eki yalnız satış ve hukuk ekibine döner.

Erişim listesi zamanla değişir. Bir çalışan ekipten ayrıldığında yetkisi de kalkmalı. İndeksteki kopya güncellenmezse eski yetki yaşamaya devam eder. Bu yüzden erişim bilgisini indekste dondurmak yerine sorgu anında kimlik kaynağından çöz.

Pratikte parçaya grup kimliklerini yazarsın. Sorgu anında ise kullanıcının güncel grup üyeliğini kimlik sağlayıcısından alır ve filtreye koyarsın. Grup üyeliğini önbelleğe alıyorsan süreyi kısa tut ve ayrılan çalışanın oturumunu hemen kapat.

Son bir nokta: asistanın araçları da aynı kuralı izlemeli. Arama doğru filtrelense bile geniş yetkili bir araç sınırı arkadan delebilir.

Etkinlik 6 / 6

Güvenli bir çok kiracılı sorgunun adımlarını sıraya diz.

Sürükleyip doğru sıraya koy.

Bir öğeye odaklan, yukarı ve aşağı ok tuşlarıyla taşı. Home tuşu en üste, End tuşu en alta alır.

  • 1Cevap kaynak atıflarıyla birlikte döner
  • 2Dönen parçalar prompta eklenir
  • 3İndekse filtreli benzerlik sorgusu gönderilir
  • 4Oturumdan kullanıcı ve kiracı kimliği çözülür
  • 5Kullanıcının güncel erişim listesi alınır

Bu derste bir hata mı gördün? Bildir