PushizoDocs
OperasyonRunbook'lar

Postgres rol ayrımı (RLS'in üretimde etkin olması)

Kiracı izolasyonunun ikinci savunma hattı Postgres Row Level Security'dir (db/migrations/0005_rls.up.sql, FORCE ROW LEVEL SECURITY). Süper kullanıcılar ve BYPASSRLS rolleri RLS'e hiçbir koşulda tabi değildir; uygulama…

Kiracı izolasyonunun ikinci savunma hattı Postgres Row Level Security'dir (db/migrations/0005_rls.up.sql, FORCE ROW LEVEL SECURITY). Süper kullanıcılar ve BYPASSRLS rolleri RLS'e hiçbir koşulda tabi değildir; uygulama süper kullanıcıyla bağlanırsa politikalar sessizce devre dışı kalır. Bu yüzden üretimde üç rol kullanılır:

RolYetkiKullanan
postgressüper kullanıcıyalnızca yönetim: backup.sh, restore.sh, eklenti kurulumu
pushizoNOSUPERUSER NOBYPASSRLS NOCREATEDB NOCREATEROLE, veritabanı ve public şema sahibiAPI, worker, migrasyon (DATABASE_URL)
pushizo_exporterpg_monitor + tablolarda SELECT; rol düzeyinde app.rls_bypass=onpostgres-exporter (infra/monitoring/postgres-exporter/queries.yaml yalnızca toplam sayar)

Uygulama bağlantıları varsayılan olarak app.rls_bypass=on ile açılır (migrasyon, worker, guard sorguları); API kiracı isteklerinde SET LOCAL app.rls_bypass = off ile politikaları etkinleştirir (TenantRlsInterceptor). Bu ayar kötü niyetli SQL'e karşı değil, uygulama hatalarına karşı ikinci hattır.

Yeni kurulum (compose)

infra/compose/postgres/initdb/10-roles.sh boş veri dizininde otomatik çalışır. .env.prod içinde üç parola zorunludur: POSTGRES_PASSWORD (uygulama rolü), POSTGRES_SUPERUSER_PASSWORD, POSTGRES_EXPORTER_PASSWORD. Sonra her zamanki gibi deploy.sh (migrasyon pushizo rolüyle tablo sahibi olarak çalışır).

Mevcut kurulumu dönüştürme (veri dizini zaten var)

Eski compose POSTGRES_USER=pushizo ile süper kullanıcı oluşturuyordu. Bakım penceresinde:

docker compose --env-file .env.prod -f infra/compose/docker-compose.prod.yml exec -T postgres psql -U pushizo -d pushizo -v ON_ERROR_STOP=1 \
  -v su_password="$POSTGRES_SUPERUSER_PASSWORD" -v exporter_password="$POSTGRES_EXPORTER_PASSWORD" <<'SQL'
create role postgres login superuser password :'su_password';
create extension if not exists pg_stat_statements;
create role pushizo_exporter login nosuperuser nobypassrls password :'exporter_password';
grant pg_monitor to pushizo_exporter;
grant connect on database pushizo to pushizo_exporter;
grant usage on schema public to pushizo_exporter;
grant select on all tables in schema public to pushizo_exporter;
alter default privileges for role pushizo in schema public grant select on tables to pushizo_exporter;
alter role pushizo_exporter set app.rls_bypass = 'on';
SQL
# Süper kullanıcı yetkisi yeni `postgres` rolüyle alınır:
docker compose --env-file .env.prod -f infra/compose/docker-compose.prod.yml exec -T postgres psql -U postgres -d pushizo \
  -c "alter role pushizo nosuperuser nobypassrls nocreatedb nocreaterole"
```text

Ardından yeni compose dosyasıyla `deploy.sh prod` (postgres-exporter yeni rolle başlar).

## Doğrulama

```bash
docker compose --env-file .env.prod -f infra/compose/docker-compose.prod.yml exec -T postgres psql -U postgres -d pushizo -tAc \
  "select rolname, rolsuper, rolbypassrls from pg_roles where rolname like 'pushizo%'"
```text

Beklenen: `pushizo|f|f` ve `pushizo_exporter|f|f`. Tablo düzeyinde `select relname from pg_class where relkind in ('r','p') and relrowsecurity and not relforcerowsecurity` boş dönmelidir.

## Kubernetes / yönetilen Postgres

Helm chart veritabanını içermez (`DATABASE_URL` gizli değeri). Yönetilen hizmetlerde de uygulama kullanıcısı **süper kullanıcı veya `BYPASSRLS` olmamalı** (ör. RDS'te `rds_superuser` üyeliği verilmez); veritabanı ve `public` şema sahibi uygulama kullanıcısıdır. Exporter için yukarıdaki `pushizo_exporter` tanımı aynen uygulanır.

Bu sayfada