PostgreSQL Rol ve Yetki (Ayrıcalık İzinleri) Yönetimi

PostgreSQL rol mantığı nedir ? Rol izinleri (Privileges) nasıl tanımlanır ?

Postgresql'de user kavramı yoktur ve her kullanıcı esasında bir rol olarak tanımlanır. Siz ilgili role ait şifreyi yalnızca bir kullanıcı ile paylaştığınızda kavramsal olarak user yaratmış olursunuz. Birden çok kullanıcı aynı user ile sisteme giriş yapıyorsa aynı roldeki kullanıcılar olduklarını varsayabilirsiniz. Yani rol ve user kavramları aynıdır.

Grup kavramı ise çok ince bir nüans ile ayrılmıştır. Sisteme login izni olmayan bir rol yaratıp bu rol altına üyeler eklerseniz grup yaratmış oluyorsunuz. Tabi grup altındaki rol(user)lerin login yetkisi olmalı ki sisteme giriş yapabilsinler. Peki grup burada ne işimize yarıyor ? Gerekli izin ve ayrıcalıkları gruba atadığınızda grup altındaki tüm kullanıcılar aynı yetkilere sahip oluyor. Böylece tek noktadan yönetim sağlayarak ayrı ayrı loglama ve takip yeteneği kazanıyorsunuz. İstisnai olarak grup içindeki bir üyeye (role,user,membership) ek izinler (ayrıcalık-privileges) vererek özelleştirme şansınız da mevcut olabiliyor.

Bu özet bilgiden sonra örnek kodlar ile konuyu pekiştirelim (Rol yaratırken psql console ya da PgAdmin IDE kullanabilirsiniz. Superuser benzeri rol açma yetkisine sahip bir kullanıcı olmanız yeterli).

psql -U Postgres -d database_adı ile psql console ekranına bağlandık.

  • -h => Host
  • -U => Username
  • -p => Port , eğer 5432 dışında portunuz varsa belirtiniz
  • -W => Passwordu ilk aşamada girmek isterseniz
  • -d => Veritabanı adı (Açacağınız roller bağlı olduğunuz veri tabanını kapsar)

psql konsolu içinde \du yazarak mevcut database kullanıcılarını listeleyebiliriz.

Bir grup yaratmak için

CREATE ROLE grup_adı WITH NOLOGIN;

Grup için rol yaratırken WITH NOLOGIN ibaresini kullanmazsanız grup içindeki kullanıcılar SUPERUSER olacağından başka roller açabilirler. Bu yüzden eğer DB yöneticileri için grup açmıyorsanız NOLOGIN kullanmanız gerekmektedir. NOLOGIN ile NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION güvenliğini sağlamış oluyoruz.

Bir role(user,membership hepsi aynı) yaratmak için;

CREATE ROLE rol_adı WITH LOGIN PASSWORD 'rol_şifresi';

Rol yaratırken dikkat ederseniz  LOGIN yetkisi verip şifre ataması yapıyoruz. Sistem bu şifreyi kriptolu olarak saklayacağından bir daha görme şansınız olmuyor.

Bir role silmek için;

DROP USER rol_adı;

Rol altında bir çok ayrıcalık tanımlı ise bunları kaldırmadan DROP edemezsiniz. Bunun için;

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA şema_adı from rol_adı --Ayrıcalıkları ihtiyacınıza göre ilgili ownership seviyesinde atamalısınız. Aşağıdaki ayrıcalık yönetimi konusunu okuduğunuzda burayı daha iyi anlayacaksınız.

 

Ayrıcalık (İzin - Yetki - Privileges) Yönetimi

Yukarıda grup ve rol yarattık fakat yarattığımız grup için hiç bir yetki vermedik ve kullanıcıları (role) gruba bağlamadık. Bu durumda veritabanımız üstünde anlamsızca duran rollere sahibiz diyebiliriz. Öyleyse grubumuza ayrıcalıklar (Privileges) vermeliyiz ki veritabanı üstünde yönetim işlerimizi yürütebilelim.

Rol ve grup ayrıcalıkları atanırken nesne, şema ve veritabanı bazında verilebilmektedir. Aşağıdaki şekilde basitçe database içinde şema içinde tablo, fonksiyon, kısıtlayıcı vb. nesneler bulunmaktadır. Yani buradan sonra özet olarak bir kaç ayrıcalık izni tanımlayacağım, bu ayrıcalığın database, şema veya tablo, function gibi nesne bazında olmasına kendiniz karar vereceksiniz.

Privileges Ownership - Ayrıcalık sahiplik kapsamı

 

Ayrıcalık atamalarında GRANT ayrıcalık izni verir ve TO syntaxıyla kullanılır.  REVOKE ayrıcalığı iptal eder ve FROM syntaxı ile kullanılır.

Atanabilecek izinler (ayrıcalık, yetki) şunlardır: SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER, CREATE, CONNECT, TEMPORARY, EXECUTE, and USAGE.

Role şema kapsamındaki tüm yetkileri(ayrıcalıkları) vermek için;

GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA şema_adı TO rol_adı;

Rolün şema kapsamındaki DROP, CREATE ve OWNER değiştirme izninin kapatılması için;

REVOKE CREATE ON SCHEMA şema_adı FROM rol_adı;

Database seviyesinde bir role sadece okuma ayrıcalığı atamak;

GRANT SELECT ON ALL TABLES IN DATABASE database_adı TO rol_adı;

Varolan bir role için CREATEDB izni vermek;

ALTER USER rol_adı CREATEDB;

Yukarıdaki genel örneklerin yeterli olduğunu düşünüyorum. Şimdi makalenin ilk kısmında başladığımız ve yarım bıraktığımız işi tamamlayalım. Önce rolleri gruba dahil edelim ve sonrasında grup için ayrıcalık atayıp makalemizi bitirelim.

Rolü gruba dahil etmek;

ALTER GROUP grup_rol_adı add user rol_adi

Önce grup için tüm yetkileri veriyoruz;

GRANT ALL PRIVILEGES ON DATABASE database_adı TO grup_role_adı; --Kavramsal olarak PostgresSQL'de grup, role, user hepsi aynı bu yüzden gruba ait rol adını yazmalısınız.

GRANT ALL PRIVILEGES ON SCHEMA şema_adı TO grup_role_adı;

GRANT SELECT, UPDATE, INSERT, DELETE, TRUNCATE, REFERENCES ON ALL TABLES IN SCHEMA şema_adı TO grup_role_adı;

Sonra tüm şemalardaki CREATE yetkisini iptal ediyoruz. Yani database bazında iptal ediyoruz. Böylece DROP TABLE, CREATE FUNCTION veya bir nesnenin ownerlığını değiştiremezler;

REVOKE CREATE ON DATABASE database_adı FROM grup_rol_adı;

Yalnızca TMP şemasına izin veriyorum. Bu şema içinde at oynatıp istedikleri gibi denemeler yapabilsinler :) ;

GRANT CREATE ON SCHEMA tmp TO grup_rol_adı;

 

SON olarak şifreleriyle beraber yeni kullanıcılar yaratarak grubumuza dahil ediyoruz;

CREATE ROLE yeni_role_adı WITH LOGIN PASSWORD 'şifresi';

ALTER GROUP yeni_role_adı ADD USER grup_rol_adı;

İLAVE BİLGİ

Bazen önceden mevcut olan bir grubu silmek istediğinizde depend it hatası alırsınız. Bu hata gruba atanmış ve iptal edilmemiş yetkiler bulunduğunda karşınıza çıkar. Bu durumda önce yetkileri iptal etmeli ve varsa sahiplikleri postgres kullanıcısına atayarak gruba ait rolü silmelisiniz.
 
Aşağıda "TEMP" şeması için ornek_grup rolüne ait yetki ve sahiplikler iptal edilmekte ve grup silinmektedir.
 
REVOKE ALL ON SCHEMA "TEMP" FROM ornek_grup;
REASSIGN OWNED BY ornek_grup TO postgres;
DROP OWNED BY ornek_grup;
DROP GROUP ornek_grup;

 
 
 
Burada yazılanları lütfen önce test ortamında test ediniz. Sonrasında canlı sunucu üstünde uygulayabilirsiniz. Versiyonlar arası farklılıklar vb. nedeniyle veritabanınıza zarar verirseniz sorumluluk size aittir. Beğendiyseniz paylaşabilir yahut Allah razı olsun diyebilirsiniz :)

Kaynaklar: