Bu yazıda Postgresql için, aklımızda mutlaka yer edinmesi gereken kullanıcı yönetim işlemlerini derledim.

Kullanıcı oluşturmak

Superuser kullanıcısı oluşturmak

Superuser kullanıcıları Postgresql’de (bundan sonra Postgres diyeceğim), tüm yetkilere sahip kullanıcılardır.

İlk metodda bunu Postgres ile birlikte gelen createuser programını kullanarak yapacağız. Bu program (veya komut da denebilir) Postgres için kullanıcılar açmak için kullanılmaktadır. Bence ismi fazla jenerik olduğu için Linux’taki adduser ile karıştırılabilmesi muhtemeldir.

sudo -u postgres /bin/bash
createuser --superuser --login --pwprompt dual

Program hakkında daha fazla bilgi edinmek için man createuser komutunu kullanabilirsiniz. Yukarıdaki örnekte sudo ile Postgres’in yönetici kullanıcısı olan postgres olarak yeni bir bash terminali açıyoruz. Ardından terminal içerisinden createuser programını kullanıyoruz. Kullanıcı oluşturmaya --superuser parametresi ile başlıyoruz, daha sonra --login ile kullanıcının giriş yapabilme iznini veriyoruz ve en son ise --pwprompt ile kullanıcı için şifre oluşturulması talebinde bulunuyoruz. Fakat bu parametreyi kullanmamız zorunlu değildir, zira ilgili kullanıcı “pg_hba.conf” dosyasından giriş metodu olarak “peer” ayarlanırsa şifresiz olarak local UNIX kullanıcısı olarak da Postgres’e erişim sağlayabilir. Şifreler genelde uzaktan erişim için tercih ediliyor.

İkinci metodda ise bir Postgresql client’ı olan psql programını kullanıyoruz.

sudo -u postgres psql
postgres=# CREATE USER dual WITH SUPERUSER LOGIN PASSWORD 'Dual1234';

Yukarıdaki örnekte sudo ile postgres kullanıcısı olarak Postgresql client’ına bağlanıyoruz ve CREATE USER SQL komutuyla yeni bir kullanıcı oluşturuyoruz.

Belirli yetkilere sahip kullanıcı oluşturmak

Superuser yerine kendi seçtiğimiz yetkilerle bir kullanıcı da oluşturabiliriz. Yukarıdaki örnekte olduğu gibi, createuser programıyla veya SQL komutuyla bu tür kullanıcılar oluşturabiliriz.

sudo -u postgres /bin/bash
createuser --login --pwprompt dev1

Kullanıcıyı bu şekilde oluşturduğumuzda sadece yetkili olduğu veritabanlarına verilen haklarla erişimi olacaktır. man createuser ile programın dökümantasyonuna baktığımızda yukarıdaki parametrelere ek olarak --createdb ve --createrole kullanılabilir. Kullanıcının veritabanı oluşturabilmesini istersek --createdb, yeni bir role ekleyebilmesini istersek --createrole de kullanabiliriz.

Diğer yöntemde ise SQL komutu kullanıyoruz:

sudo -u postgres psql
postgres=# CREATE USER dev1 WITH LOGIN PASSWORD 'Dev1234';
postgres=# CREATE USER dev1 WITH LOGIN CREATEDB CREATEROLE PASSWORD 'Dev1234';

Yeni oluşturulan kullanıcılar bu aşamada başka veritabanlarına bağlanabilir, tablolarını ve yapısını görebilir; fakat içeriklerini göremezler. Biz yetkilendirme yapmadığımız sürece de CRUD operasyonlarının hiç birini yapamazlar.

Kullanıcıları yetkilendirmek

Yeni bir kullanıcı oluşturduğumuzda (superuser kullanıcıları hariç) bu kullanıcıların yetkili olacakları veritabanlarını, şemaları ve burada neler yapabileceklerini de tanımlamamız gerekir. CREATEROLE yetkisi bulunan kullanıcılar başka kullanıcıların haklarında değişiklik yapabilirler.

Tüm hakları şema bazlı vermek

Bir kullanıcıya bir veritabanı için tüm hakları (SELECT, UPDATE, DELETE, DROP gibi..) vermek istersek, önce ilgili veritabanına bağlanmamız gerekir, daha sonra hakları hangi şema için vereceğimizi SQL komutuyla belirtmemiz gerekir.

sudo -u postgres psql
postgres=# \connect databaseName
postgres=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO dev1;

Yukarıdaki örnekte kullanıcıya public şemasındaki tüm tablolar için tüm hakları verdik. Böylece yeni tablolar oluşturabilirler, tablolarda CRUD operasyonları yapabilirler ve tabloyu silebilirler. Fakat yeni bir sequence ve fonksiyon oluşturamazlar. Eğer tablo oluştururken sequence kullanılacaksa ve yeni bir fonksiyon oluşturmasını da istersek bunları da ayrı ayrı tanımlamamız gerekir. Örnek:

postgres=# GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO dev1;
postgres=# GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO dev1;

Belirli hakları şema bazlı vermek

Aşağıdaki örnekte kullanıcıyı public şemasında sadece SELECT, INSERT ve UPDATE komutlarını çalıştırabilmesi için kısıtlıyoruz.

sudo -u postgres psql
postgres=# \connect databaseName
postgres=# GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO dev1;

Şema bazlı verilen hakları geri almak

Hakları verdiğimiz gibi, geri almasını da biliriz. Hakları geri alırken GRANT yerine REVOKE kullanıyoruz. Kullanıcıyı belirtirken de TO yerine FROM kullanıyoruz.

sudo -u postgres psql
postgres=# \connect databaseName
postgres=# REVOKE ALL PRIVILEGES ON ALL TABLES    IN SCHEMA public FROM dev1;
postgres=# REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM dev1;
postgres=# REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM dev1;

Veritabanı bazlı haklar (Postgres 14+ için)

Postgres versiyon 14 ve üzeri için önceden tanımlı haklar bulunmaktadır. Bu biraz daha yeni bir özellik olduğu için alt başlığı biraz aşağıda bıraktım. Postgres’de Predefined Roles olarak geçen bu yöntem ile kullanıcılara veritabanı bazında yetkiler tanımlayabiliriz. İşimize yarayacak olanları aşağıdaki tabloya ekledim.

YetkiAçıklama
pg_read_all_dataRead all data (tables, views, sequences), as if having SELECT rights on those objects, and USAGE rights on all schemas, even without having it explicitly. This role does not have the role attribute BYPASSRLS set. If RLS is being used, an administrator may wish to set BYPASSRLS on roles which this role is GRANTed to.
pg_write_all_dataWrite all data (tables, views, sequences), as if having INSERT, UPDATE, and DELETE rights on those objects, and USAGE rights on all schemas, even without having it explicitly. This role does not have the role attribute BYPASSRLS set. If RLS is being used, an administrator may wish to set BYPASSRLS on roles which this role is GRANTed to.

Mesela bir kullanıcının bir veritabanındaki tüm tablo, view ve sequence’leri okuyabilmesini istersek ona pg_read_all_data hakkını tanımlayabiliriz. Eğer tüm CRUD operasyonlarını yapabilmesini istersek de pg_write_all_data hakkını tanımlayabiliriz.

GRANT pg_read_all_data TO dev1;

Kullanıcılarda değişiklik yapmak

Şifre değişimi

İlk metodda Postgres client’ı ile \password komutunu kullanarak istediğimiz bir kullanıcının giriş şifresini değiştirebiliriz.

sudo -u postgres psql
postgres=# \password dev1

İkinci metodda yine client’tan SQL komutuyla değiştirebiliriz.

ALTER USER dev1 WITH PASSWORD 'Dev4321';

Yetki verme ve kaldırma

ALTER USER dev1 WITH LOGIN NOCREATEDB NOCREATEROLE;

Bu arada unutmayın, WITH sonrası yazılan yetkiler bir öncekini kaldırıp yenisiyle değiştirmez; sadece yetkilerin üzerine ekleme yapar. Mesela:

ALTER USER dev1 WITH NOLOGIN;

Yukarıdaki komuttan sonra aynı kullanıcı için yeni bir yetki tanımladıktan sonra diğer tanımlanan yetkileri değişmemiş olacak, onun yerine NOLOGIN üzerine NOCREATEDB eklenmiş olacaktır. Örneğin:

ALTER USER dev1 WITH NOCREATEDB; # = NOLOGIN + NOCREATEDB

Bu yüzden kullanıcıların yetkilerini kontrol etmelisiniz.

Kullanıcıları ve yetkilerini listeleme

Kullanıcıları listelemek ve yetkilerini kontrol etmek için Postgres’in client programından veritabanına bağlanıp \du komutunu gönderiyoruz.

sudo -u postgres psql
postgres=# \du

 Role name |                     Attributes                 |     Member of      
-----------+------------------------------------------------+--------------------
 dual      | Superuser                                      | {}
 dev1      |                                                | {pg_read_all_data}
 dev2      | Create role, Create DB                         | {}
 postgres  | Superuser, Create role, Create DB, Replication | {}

Kullanıcı silme

Kullanıcı silerken iki farklı metod kullanılabilir. Bunlardan ilki dropuser programıyla, diğeri ise SQL komutuyla.

İlk metodu kullanırken createdb programında olduğu gibi postgres kullanıcısı ile bir terminal açmamız gerekir.

sudo -u postgres /bin/bash
dropuser dev1

Kullanıcıyı silerken bir hata alınabilir. Oluşan hatalar kullanıcıyı silmenize engel olur. Bu yüzden engel olan sorunu çözmemiz gerekir. Örneğin silinmesini istediğimiz kullanıcı bir veritabanı ile hala ilişkili ise, ya veritabanını silmemiz gerekir ya da ilişkili olduğu veritabanının sahipliğini başka bir kullanıcıya devretmemiz gerekir.

sudo -u postgres psql
postgres=# \connect databaseName
postgres=# REASSIGN OWNED BY dev1 TO postgres;
postgres=# DROP OWNED BY dev1;

Yukarıdaki örnekte kullanıcının ilişkili olduğu veritabanına girdikten sonra, REASSIGN komutuyla sahipliği devrediyoruz, DROP ile de sahipliği siliyoruz. Eğer kullanıcının ilişkili olduğu bir veritabanı kalmadıysa artık başarılı olarak silinebilir.

İkinci metodda bu SQL komutuyla kullanıcıyı silebiliriz: DROP USER dev1;

Fakat bence kullanıcının giriş yapma yetkisini almak, silmekten daha güvenli bir yoldur.