03 Mar 2025·7 dk okuma

Çok kiracılı uygulamalar için PostgreSQL satır düzeyi güvenlik desenleri

PostgreSQL satır düzeyi güvenliğini, tenant izolasyonu ve rol kuralları için pratik desenlerle öğrenin; böylece erişim sadece uygulamada değil, veritabanında da zorunlu olur.

Çok kiracılı uygulamalar için PostgreSQL satır düzeyi güvenlik desenleri

İş uygulamalarında veritabanı tarafından uygulanmış erişimin önemi

İş uygulamalarında genellikle “kullanıcılar sadece kendi şirketlerinin kayıtlarını görebilir” veya “yalnızca yöneticiler iadeleri onaylayabilir” gibi kurallar olur. Birçok ekip bu kuralları UI veya API katmanında uygular ve bunun yeterli olduğunu varsayar. Sorun şu: veritabanına erişen her ek yol veri sızıntısı için ayrı bir şans yaratır: dahili bir yönetici aracı, arka plan işi, analytics sorgusu, unutulmuş bir endpoint veya bir kontrolü atlayan bir hata.

Kiracı izolasyonu demek, bir müşterinin (kiracı) başka bir müşterinin verisini asla okuyamaması veya değiştirememesi demektir — kazara bile. Rol tabanlı erişim ise aynı kiracı içindeki kişilerin farklı yetkileri olduğu anlamına gelir; örneğin ajanlar, yöneticiler, finans gibi. Bu kurallar tanımlanması kolay ama birden fazla yerde tutulduğunda tamamen tutarlı hale getirilmesi zordur.

PostgreSQL satır düzeyi güvenliği (RLS), veritabanının hangi satırların bir isteğe gösterileceğine veya değiştirileceğine karar vermesini sağlayan bir özelliktir. Uygulamanızdaki her sorgunun doğru WHERE koşulunu hatırlamasına güvenmek yerine, veritabanı politikaları otomatik olarak uygular.

RLS her şeye karşı sihirli bir kalkan değildir. Şemayı tasarlamaz, kimlik doğrulamanın yerini almaz veya zaten güçlü bir veritabanı rolüne sahip bir kişiden (superuser gibi) sizi korumaz. Ayrıca "birinin bir satırı güncellemesi ama seçememesi" gibi mantık hatalarını otomatik olarak önlemez; hem okuma hem yazma için politikalar yazmanız gerekir.

Bununla birlikte elde ettiğiniz şey güçlü bir güvenlik ağıdır:

  • Veritabanına erişen her kod yolu için tek bir kural seti
  • Yeni bir özellik yayına alındığında daha az “ups” anı
  • Erişim kurallarının SQL içinde görünür olması sayesinde daha açık denetimler
  • Bir API hatası kaçsa bile daha iyi bir savunma

Küçük bir kurulum maliyeti vardır. "Bu kullanıcı kim" ve "hangi kiracı" bilgisini veritabanına tutarlı şekilde geçirmek ve uygulama büyüdükçe politikaları sürdürmek gerekir. Getiri büyük olur; özellikle hassas müşteri verisinin söz konusu olduğu SaaS ve dahili araçlar için.

Jargondan uzak Satır Düzeyi Güvenliğin temelleri

Satır Düzeyi Güvenlik (RLS), bir sorgunun hangi satırları görebileceğini veya değiştirebileceğini otomatik olarak filtreler. Kuralların her ekran, API endpoint veya raporda "hatırlanmasına" güvenmek yerine veritabanı bunları sizin için uygular.

PostgreSQL RLS ile SELECT, INSERT, UPDATE ve DELETE işlemlerinde kontrol edilen politikalar yazarsınız. Politika "bu kullanıcı sadece A kiracısına ait satırları görebilir" diyorsa, unutulmuş bir yönetici sayfası, yeni bir sorgu veya aceleyle yapılmış bir hotfix yine aynı korumayı görür.

RLS, GRANT/REVOKE'den farklıdır. GRANT bir rolün tabloya genel erişip erişemeyeceğini (veya belirli sütunlara) belirler. RLS ise o tablodaki hangi satırların ulaşılıp ulaşılamayacağını belirler. Uygulamada sıkça her ikisini birlikte kullanırsınız: tabloya kimlerin erişebileceğini sınırlamak için GRANT, neye erişebileceklerini sınırlamak için RLS.

RLS gerçek dünyada da işe yarar. Görünümler (views) genellikle RLS kurallarına uyar çünkü altta yatan tablo erişimi hâlâ politikayı tetikler. Join'ler ve alt sorgular da filtrelenir; bir kullanıcı başka birinin verisine "join" yoluyla erişemez. Politika hangi istemcinin sorguyu çalıştırdığına bakmaksızın uygulanır: uygulama kodu, SQL konsolu, arka plan işi veya raporlama aracı.

RLS, güçlü kiracı izolasyonu ihtiyaçlarınız, aynı veriye birden çok yolla erişim veya birçok rolün tabloları paylaştığı durumlar için uygundur (SaaS ve dahili araçlarda yaygındır). Bir güvenilir backend'in olduğu küçük uygulamalar veya hassas olmayan ve tek bir kontrollü serviste kalan veriler için fazla gelebilir. Yönetici araçları, dışa aktarımlar, BI ve betikler gibi birden fazla giriş noktası olduğunda RLS genellikle kendini amorti eder.

İlk önce kiracıları, rolleri ve veri sahipliğini haritalayın

Tek bir politika yazmadan önce kimin neye sahip olduğunu netleştirin. PostgreSQL RLS, veri modeliniz zaten kiracıları, rolleri ve sahipliği yansıtıyorsa en iyi şekilde çalışır.

Kiracılarla başlayın. Çoğu SaaS uygulamasında basit kural şudur: müşteri verisi içeren her paylaşılan tabloda bir tenant_id olur. Bu faturalar gibi "açık" tabloları kapsar ama ayrıca insanların unuttuğu ekler, yorumlar, denetim kayıtları ve arka plan işleri gibi tabloları da içerir.

Sonra insanların gerçekten kullandığı rolleri adlandırın. Küçük ve anlaşılır tutun: owner, manager, agent, read-only gibi. Bunlar veritabanı rolleriyle aynı şey değildir; iş rolleridir ve daha sonra politika kontrollerine eşleneceklerdir.

Ardından kayıtların nasıl sahiplenildiğine karar verin. Bazı tablolar tek bir kullanıcıya aittir (örneğin özel not). Diğerleri ekip sahipliğindedir (örneğin paylaşılan bir gelen kutusu). Karışık bir şekilde plan olmadan bunları karıştırmak, okunması zor ve atlanması kolay politikalara yol açar.

Kurallarınızı belgelemek için tablolar bazında şu sorulara cevap verin:

  • Kiracı sınırı nedir (hangi sütun bunu zorunlu kılar)?
  • Kim satırları okuyabilir (rol ve sahiplik bazında)?
  • Kim satır oluşturup güncelleyebilir (hangi koşullarda)?
  • Kim satır silebilir (genellikle en katı kural)?
  • Hangi istisnalar izinli (destek personeli, otomasyon, dışa aktarımlar)?

Örnek: “Invoices” tablosu yöneticilerin tüm kiracı faturalarını görmesine, ajanların atandıkları müşterilere ait faturaları görmesine ve salt-okuyucu kullanıcıların sadece okumaya izinli olmasına olanak verebilir. Hangi kuralların katı olması gerektiğini (kiracı izolasyonu, silmeler) ve hangilerinin esnek olabileceğini (yöneticiler için ek görünürlük) önceden kararlaştırın. AppMaster gibi bir no-code araçla inşa ediyorsanız, bu haritalama UI beklentileri ile veritabanı kurallarını hizalamaya yardımcı olur.

Çok kiracılı tablolar için tasarım desenleri

Çok kiracılı RLS, tablolarınızın öngörülebilir göründüğü durumlarda en iyi şekilde çalışır. Her tablo kiracıyı farklı şekilde saklıyorsa politikalarınız bir bulmacaya dönüşür. Tutarlı bir yapı PostgreSQL RLS'i okumayı, test etmeyi ve zaman içinde doğru tutmayı kolaylaştırır.

Öncelikle tek bir kiracı tanımlayıcısı seçin ve her yerde onu kullanın. UUID'ler tahmin edilmesi zor ve birçok sistemde kolay oluşturuldukları için yaygındır. İç uygulamalar için integer'lar da uygundur. Slug'lar (örneğin "acme") insan dostudur ama değişebilirler; bu yüzden bunları temel anahtar yerine görüntü alanı olarak değerlendirin.

Kiracı kapsamındaki veriler için, kiracıya ait her tabloya tenant_id sütunu ekleyin ve mümkün olduğunca NOT NULL yapın. Bir satır kiracı olmadan var olabiliyorsa genellikle bu bir koku işaretidir. Genellikle global ve kiracı verilerini aynı tabloda karıştırdığınız anlamına gelir ve bu da RLS politikalarını zor ve kırılgan kılar.

Dizinleme (indexing) basit ama önemlidir. Bir SaaS uygulamasındaki çoğu sorgu önce kiracı ile, sonra iş alanıyla (durum veya tarih gibi) filtrelenir. Varsayılan iyi bir seçim tenant_id üzerinde bir indeks, yoğun trafikli tablolar için ise (tenant_id, created_at) veya (tenant_id, status) gibi bileşik indekslerdir.

Erken karar verin hangi tablolar global hangileri kiracıya ait. Yaygın global tablolar arasında ülkeler, para birimi kodları veya plan tanımları bulunur. Kiracıya ait tablolar arasında müşteriler, faturalar, ticket'lar ve kiracının sahip olduğu her şey yer alır.

Sürdürülebilir bir kural seti isterseniz dar tutun:

  • Kiracı kapsamlı tablolar: tenant_id NOT NULL, RLS etkin, politikalar her zaman tenant_id kontrol etsin.
  • Global referans tablolar: tenant_id yok, kiracı politikası yok, çoğu rol için salt-okuma.
  • Paylaşılan ama kontrollü tablolar: konsept başına ayrı tablolar (global ve kiracı satırlarını karıştırmaktan kaçının).

AppMaster gibi bir araçla inşa ediyorsanız, bu tutarlılık veri modelinde de fayda sağlar. tenant_id standart bir alan haline geldiğinde aynı desenleri modüller arasında sürpriz olmadan yeniden kullanabilirsiniz.

Adım adım: ilk kiracı politikanızı oluşturun

Yeni özellikler ekleyin, riski artırmadan
Ödeme, mesajlaşma ve otomasyonu bağlayın; kiracı sınırlarınızı bozmadan özellik ekleyin.
Entegrasyonları Keşfet

PostgreSQL RLS ile iyi bir ilk kazanım, yalnızca mevcut kiracı içinde okunabilen tek bir tablo yapmaktır. Amaç basittir: API'de birisi WHERE koşulunu unutsa bile veritabanı diğer kiracıların satırlarını döndürmeyi reddeder.

tenant_id sütunu içeren bir tablo ile başlayın:

ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;

RLS etkinleştirildiğinde, başlangıçta insanları şaşırtan varsayılan davranış şudur: bir rol RLS'ye tabi ise ve eşleşen bir politika yoksa SELECT sıfır satır döndürür (yazmalar başarısız olur). Bu başlangıç için istenen davranıştır.

Şimdi minimal bir okuma politikası ekleyin. Bu örnek, uygulamanızın oturum açtıktan sonra app.tenant_id gibi bir session değişkeni ayarladığını varsayar:

CREATE POLICY invoices_tenant_read
ON invoices
FOR SELECT
USING (tenant_id = current_setting('app.tenant_id')::uuid);

Ardından yazma kurallarını ekleyin. RLS'de USING mevcut satırlara hangi koşullarda dokunabileceğinizi kontrol eder, WITH CHECK ise hangi yeni değerleri yazabileceğinizi kontrol eder.

CREATE POLICY invoices_tenant_insert
ON invoices
FOR INSERT
WITH CHECK (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY invoices_tenant_update
ON invoices
FOR UPDATE
USING (tenant_id = current_setting('app.tenant_id')::uuid)
WITH CHECK (tenant_id = current_setting('app.tenant_id')::uuid);

CREATE POLICY invoices_tenant_delete
ON invoices
FOR DELETE
USING (tenant_id = current_setting('app.tenant_id')::uuid);

Politikalar varsayılan olarak PERMISSIVE'dir; yani herhangi bir politika erişime izin verebilir. RESTRICTIVE seçeneğini, tüm kuralların aynı anda geçmesi gerektiği durumlarda kullanın (örneğin “sadece aktif hesaplar” gibi ikinci bir koruyucu eklemek için).

Politikaları küçük ve role odaklı tutun. Bir büyük OR içeren tek bir koca kural yerine, hedef kitle başına ayrı politikalar (invoices_tenant_read_app_user ve invoices_tenant_read_support_agent gibi) oluşturun. Test etmek, gözden geçirmek ve sonraki değişiklikleri güvenli yapmak daha kolay olur.

Kiracı ve kullanıcı bağlamını güvenli şekilde iletme

PostgreSQL RLS'in çalışması için veritabanının "kim çağırıyor" ve "hangi kiracıya ait" olduğunu bilmesi gerekir. RLS politikaları yalnızca sorgu zamanında veritabanının okuyabileceği değerlerle karşılaştırma yapabilir, bu yüzden bu bağlamı oturum içine geçirmeniz gerekir.

Yaygın bir desen, kimlik doğrulama sonrası session değişkenleri ayarlamak ve politikaların current_setting() ile bunları okumasıdır. Uygulama kimliği doğrular (örneğin JWT doğrulaması yaparak), sonra tenant ve user ID'lerini veritabanı bağlantısına yazar.

-- Her istek (veya işlem) için çalıştırın
SELECT set_config('app.tenant_id', '3f2a0c3e-9c7b-4d3f-9c5c-3c5e9c5d1a11', true);
SELECT set_config('app.user_id',   '8d9c6b1a-6b6d-4e32-9c0d-2bfe6f6c1111', true);
SELECT set_config('app.role',      'support_agent', true);

-- Bir politikada
-- tenant_id sütunu UUID'dir
USING (tenant_id = current_setting('app.tenant_id', true)::uuid);

Üçüncü argüman true'yu kullanmak, değerin geçerli işlemle (transaction) sınırlı olmasını sağlar. Bu, connection pooling kullanıyorsanız önemlidir: havuzlanan bir bağlantı başka bir istek tarafından tekrar kullanıldığında dünkü kiracı bağlamının kalmasını istemezsiniz.

JWT iddialarından bağlam doldurma

API'niz JWT kullanıyorsa, iddiaları doğrudan gerçek bilgi olarak değil giriş verisi olarak ele alın. Önce token imzasını ve geçerlilik süresini doğrulayın, sonra sadece ihtiyaç duyduğunuz alanları (tenant_id, user_id, role) oturum ayarlarına kopyalayın. Müşterilerin bu değerleri doğrudan header veya query param olarak göndermesine izin vermeyin.

Eksik veya geçersiz bağlam: varsayılan olarak reddet

Politikaları eksik ayarlarda satır bulunamaz sonuç verecek şekilde tasarlayın.

current_setting('app.tenant_id', true) kullanın ki eksik değerler NULL döndürsün. Doğru türe cast etmek (örneğin ::uuid) kötü biçimlendirilmiş değerlerin hızlıca hata vermesini sağlar. Kiracı/kullanıcı bağlamı ayarlanamıyorsa isteği varsayılan bir değere tahmin etmek yerine reddedin.

Bu, bir sorgu UI'yi atladığında veya yeni bir endpoint eklendiğinde erişim kontrolünün tutarlı kalmasını sağlar.

Yönetimi sürdürülebilir kılan pratik rol desenleri

Kiracı güvenli uygulamaları hızlıca oluşturun
PostgreSQL ile çok kiracı bir backend oluşturun ve erişim kurallarını baştan itibaren tutarlı tutun.
AppMaster'ı Deneyin

PostgreSQL RLS politikalarını okunur tutmanın en kolay yolu kimlik ile izinleri ayırmaktır. Sağlam bir temel, bir users tablosu artı bir memberships tablosudur; bu tablo bir kullanıcıyı bir kiracıya ve bir role (veya birkaç role) bağlar. Politikalarınız sonra tek bir soruyu cevaplar: “Mevcut kullanıcının bu satır için doğru üyeliği var mı?”

Rol isimlerini gerçek eylemlere bağlı tutun, iş unvanlarına değil. “invoice_viewer” ve “invoice_approver” gibi isimler zaman içinde “manager” gibi isimlerden daha iyi işler çünkü politika düz metinle yazılabilir.

Bazı basit rol desenleri:

  • Sadece sahibi: satırın created_by_user_id (veya owner_user_id) alanı vardır ve erişim tam eşleşme ile kontrol edilir.
  • Takım bazlı: satırın team_id vardır ve politika kullanıcının aynı kiracı içindeki o takımın üyesi olduğunu kontrol eder.
  • Onaylı-only: okumalar sadece status = 'approved' ise izinlidir ve yazmalar sadece onaylayıcılara açıktır.
  • Karışık kurallar: önce sıkı başlayın, sonra küçük istisnalar ekleyin (örneğin "destek sadece kiracı içinde okuyabilir").

Çapraz-kiracı yöneticileri (cross-tenant admins) çoğu ekibin sorun yaşadığı alandır. Onları gizli bir "superuser" kısa yolu olarak değil, açıkça ele alın. platform_admin gibi global bir kavram oluşturun ve politikada kasıtlı bir kontrol gerektirin. Daha da iyisi, çapraz-kiracı erişimini varsayılan olarak salt-okuma yapın ve yazmalar için daha yüksek bir eşik belirleyin.

Dokümantasyon düşündüğünüzden daha önemlidir. Her politikanın üstüne kısa bir yorum ekleyin; amaç açıklansın, SQL değil. “Approvers statüyü değiştirebilir. Viewers sadece onaylanmış faturaları okuyabilir.” Altı ay sonra bu not politika değişikliklerini güvenli tutar.

AppMaster gibi bir no-code araçla inşa ediyorsanız, bu desenler hâlâ geçerlidir. UI ve API hızlı hareket edebilir, ama veritabanı kuralları memberships ve net rol anlamına dayandığı sürece stabil kalır.

Örnek senaryo: faturalar ve destek içeren basit bir SaaS

Kiracı veri modelinizi standartlaştırın
Data Designer'da tenant_id alanını bir kez modelleyin ve her tablo ve modülde yeniden kullanın.
İnşa Etmeye Başla

Küçük bir SaaS düşünün; birden fazla şirkete hizmet veriyor. Her şirket bir kiracı. Uygulamada faturalar (para) ve destek ticket'ları (günlük yardım) var. Kullanıcılar ajan, yönetici veya destek olabilir.

Veri modeli (basitleştirilmiş): her fatura ve ticket satırında tenant_id var. Ticket'larda ayrıca assignee_user_id var. Uygulama, oturum açıldıktan hemen sonra mevcut kiracı ve kullanıcıyı veritabanı oturumuna ayarlar.

PostgreSQL RLS günlük riski nasıl değiştirir gösterelim.

Tenant A'dan bir kullanıcı, Tenant B'ye ait bir fatura ID'sini tahmin edip invoices ekranını açmaya çalışır (veya UI yanlışlıkla bunu gönderir). Sorgu çalışır ama politika invoice.tenant_id = current_tenant_id gerektirdiği için veritabanı sıfır satır döndürür. "Erişim reddedildi" bilgisi sızmaz, sadece boş bir sonuç gelir.

Aynı kiracı içinde roller erişimi daha da daraltır. Bir yönetici kendi kiracısındaki tüm faturaları ve ticket'ları görebilir. Bir ajan sadece kendisine atanmış ticket'ları (ve belki kendi taslaklarını) görebilir. Bu, filtrelerin isteğe bağlı olduğu yerlerde API tarafında sık yapılan hataların olduğu yerdir.

Destek özel bir durumdur. Müşterilere yardım etmek için faturaları görmeleri gerekebilir ama amount, bank_account veya tax_id gibi hassas alanları değiştirmemelidirler. Pratik bir desen:

  • Destek rolüne faturalar için SELECT izni verin (hala kiracı kapsamlı).
  • UPDATE iznini sadece "güvenli" bir yol üzerinden verin (örneğin düzenlenebilir sütunları açığa çıkaran bir view ya da korunan alanları reddeden katı bir update politikası).

Şimdi "kazara API hatası" senaryosu: bir endpoint refactor sırasında kiracı filtresini uygulamayı unutuyor. RLS yoksa bu çapraz-kiracı faturalara sızıntıya yol açar. RLS ile veritabanı oturum kiracısı dışındaki satırları döndürmeyi reddettiği için hata ekran bozukluğu ile sınırlı kalır; veri ihlali olmaz.

AppMaster ile böyle bir SaaS inşa ediyorsanız, veritabanında bu kuralların olmasını yine istersiniz. UI kontrolleri yardımcıdır ama bir şey kayarsa işi tutan veritabanı kurallarıdır.

Yaygın hatalar ve nasıl kaçınılır

PostgreSQL RLS güçlüdür ama küçük ihmaller “güvenli”yi “şaşırtıcı” hale getirebilir. Çoğu sorun yeni bir tablo eklendiğinde, bir rol değiştiğinde veya biri yanlış veritabanı kullanıcısıyla test ettiğinde ortaya çıkar.

Yaygın bir hata yeni bir tabloda RLS'i etkinleştirmeyi unutmak. Core tablolar için dikkatli politikalar yazıp sonra "notes" veya "attachments" gibi bir tabloyu tam erişimli şekilde yayına almak kolaydır. Alışkanlık haline getirin: yeni tablo = RLS etkin + en azından bir politika.

Sık bir tuzak da işlemler arasında uyumsuz politikalar yazmaktır. INSERT'e izin verip SELECT'i engelleyen bir politika oluşturursanız, satırlar oluşturulduktan sonra "veri kayboluyor" hissi oluşur. Tersi de acı verir: kullanıcılar oluşturabildikleri ama okuyamadıkları satırlara göre UI'yi aşındırır. Akışları düşünün: "oluştur sonra görüntüle", "güncelle sonra tekrar aç", "sil sonra listele".

SECURITY DEFINER fonksiyonları konusunda dikkatli olun. Bu fonksiyonlar fonksiyon sahibinin ayrıcalıklarıyla çalışır ve eğer dikkatli olmazsanız RLS'i atlayabilir. Kullanıyorsanız küçük tutun, girdileri doğrulayın ve gerçekten ihtiyaç yoksa dinamik SQL'den kaçının.

Ayrıca uygulama tarafı filtrelemeye güvenip veritabanı erişimini açık bırakmayın. İyi inşa edilmiş API'ler bile yeni endpoint'ler, arka plan işleri ve yönetici script'leri üretir. Eğer veritabanı rolü her şeyi okuyabiliyorsa, er ya da geç bir şey sızar.

Sorunları erken yakalamak için şu kontrolleri yapın:

  • Üretim uygulamanızın kullandığı aynı DB rolüyle test yapın, kişisel admin kullanıcıyla değil.
  • Her tablo için bir negatif test ekleyin: başka bir kiracıdan gelen bir kullanıcı sıfır satır görmeli.
  • Her tablonun beklenen eylemleri desteklediğini doğrulayın: SELECT, INSERT, UPDATE, DELETE.
  • SECURITY DEFINER kullanımını gözden geçirin ve neden gerekli olduğunu belgeleyin.
  • RLS etkin mi? kontrolünü kod inceleme checklist'ine ve migrationlara ekleyin.

Örnek: bir destek ajanı bir fatura notu oluşturuyor ama geri okuyamıyorsa genellikle INSERT politikası vardır ama karşılık gelen SELECT politikası yoktur (veya o oturum için kiracı bağlamı ayarlanmamıştır).

RLS kurulumunuzu doğrulamak için hızlı kontrol listesi

Daha güvenli bir backend göndərin
Gereksinimler değiştiğinde temiz kaynak kodu üreten üretim hazır bir API oluşturun.
Backend Oluştur

RLS gözden geçirmede doğru görünebilir ama gerçek kullanımda başarısız olabilir. Doğrulama, politikaları okumaktan çok bunları gerçek hesaplarla kırmayı denemekle ilgilidir. Uygulamanızın kullanacağı biçimde test edin, umduğunuz şekilde değil.

İlk olarak küçük bir test kimlik seti oluşturun. En az iki kiracı (Kiracı A ve Kiracı B) kullanın. Her kiracı için normal bir kullanıcı ve admin/manager rolü ekleyin. Eğer "destek ajanı" veya "salt-okuyucu" rolleri destekliyorsanız onlar için de birer hesap ekleyin.

Sonra RLS'i küçük, tekrarlanabilir kontrollerle baskıya alın:

  • Her rol için temel işlemleri çalıştırın: listeleme, id ile tek satır alma, ekleme, güncelleme ve silme. Her işlem için hem "izinli" hem "engellenmeli" durumları deneyin.
  • Kiracı sınırlarını kanıtlayın: Kiracı A olarak, Kiracı B verilerini bilinen id'lerle okumaya veya değiştirmeye çalışın. Sıfır satır veya izin hatası almalısınız; asla "bazı satırlar" olmamalı.
  • Join'lerde kaçak kontrolü: korunan tabloları diğer tablolarla (lookup tablolar dahil) join edin. Bir join'in yabancı anahtar veya view aracılığıyla başka bir kiracının satırlarını çekemediğini doğrulayın.
  • Eksik veya yanlış bağlam erişimi reddetmeli: per-request ayarladığınız tenant/user bağlamını temizleyin ve yeniden deneyin. "Bağlam yok" kapalı başarısızlık (fail closed) olmalı. Ayrıca geçersiz bir tenant id deneyin.
  • Temel performansı doğrulayın: sorgu planlarına bakın ve indekslerin tenant filtresi deseninizi desteklediğinden emin olun (tenant_id artı sıralama veya arama yaptığınız alanlar).

Herhangi bir test sizi şaşırtırsa, önce politikayı veya bağlam ayarını düzeltin. UI veya API tarafında geçici yamayla işi kapatmaya çalışmayın.

Sonraki adımlar: güvenli şekilde yaygınlaştırma ve tutarlılığı koruma

PostgreSQL RLS'i bir güvenlik sistemi gibi ele alın: dikkatlice tanıtın, sık doğrulayın ve ekibinizin takip edeceği kadar basit kurallar tutun.

Küçük başlayın. Sızıntı zararı en büyük olan tabloları seçin (ödeme, faturalar, İK verileri, müşteri mesajları) ve önce orada RLS'i etkinleştirin. Erken kazanımlar, kimsenin tamamen anlamadığı kocaman bir yayından daha iyidir.

Pratik bir yayılma sırası genelde şu şekildedir:

  • Önce core "sahip olunan" tablolar (satırlar belirgin şekilde bir kiracıya ait)
  • Kişisel veri içeren tablolar (PII)
  • Kiracı tarafından filtrelenen paylaşılan tablolar (raporlar, analytics)
  • Join tabloları ve kenar durumlar (çoktan-çoğa ilişkiler)
  • Temel stabil olduktan sonra diğerleri

Test etmeyi zorunlu kılın. Otomatik testler farklı kiracılar ve rollerle aynı sorguları çalıştırmalı ve beklenen sonuçları doğrulamalı. Hem "izin verilmeli" hem "reddedilmeli" kontrolleri ekleyin; çünkü en pahalı hatalar sessizce fazla izin verme hatalarıdır.

İstek akışınızda oturum bağlamının ayarlandığı tek net bir yer tutun. Tenant id, user id ve role bir kere, erken ve asla tahmin edilmeden uygulanmalı. Bağlamı bir işlemin ortasında ayarlarsanız, sonunda eksik veya eski değerlerle bir sorgu çalıştırırsınız.

AppMaster ile üretirken, üretilen backend API'leriniz ile PostgreSQL politikalarınız arasındaki tutarlılığı planlayın. Her endpoint için aynı session değişkenlerini kullanacak şekilde standartlaştırın ki politikalar her yerde aynı davransın. Eğer AppMaster'ı appmaster.io üzerinde kullanıyorsanız, RLS'i kiracı izolasyonu için nihai otorite olarak ele almak yine önemlidir; UI tarafı kontroller yararlı olsa da veritabanı kuralları nihai korumadır.

Son olarak, başarısızlıkları izleyin. Yetkilendirme reddiyatları özellikle yayına alımdan hemen sonra faydalı sinyallerdir. Tekrarlayan reddiyatları bir saldırı, bozuk bir istemci akışı veya fazla katı bir politika olup olmadığını araştırın.

Kısa bir alışkanlık listesi RLS'in sağlıklı kalmasına yardımcı olur:

  • Varsayılan olarak reddetme zihniyeti, istisnalar kasıtlı eklenir
  • Net politika isimleri (tablo + eylem + hedef kitle)
  • Politika değişiklikleri kod değişikliği gibi gözden geçirilir
  • Yayına alımın erken döneminde reddiyatlar loglanıp incelenir
  • Her yeni RLS tablosu için küçük bir test seti eklenir
Başlaması kolay
Harika bir şey yaratın

Ücretsiz planla AppMaster ile denemeler yapın.
Hazır olduğunuzda uygun aboneliği seçebilirsiniz.

Başlayın