# Onay akışı

> Roller, bağlantı tanımlamaları ve bir sorgu talebinin gönderimden onaya, maskelenmiş ve denetlenmiş sonuca uzanan yaşam döngüsü.

- Dokümantasyon: Kılavuzlar
- Güncelleme: 2026-10-31
- Kaynak: https://queryproxy.com/tr/docs/onay-akisi/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
QueryProxy'de her şey tek bir nesnenin etrafında döner: **sorgu talebi**. Bu
kılavuz kimin ne yapabildiğini ve bir talebin her adımda başına gelenleri anlatır.

## Roller

| Rol | Yetkileri |
| :-- | :-- |
| **Admin** | Sistem genelinde her şey: takımlar, kullanıcılar, tüm ayarlar. Kullanıcı bazında verilir (`is_admin`). |
| **DBA** | Bağlantıları ve maskeleme kurallarını yönetir, erişim tanımlar, talepleri onaylar/reddeder; takımın her bağlantısına sorgu da gönderebilir. |
| **Developer** | Tanımlanmış bağlantılar üzerinden sorgu gönderir, kendi (maskelenmiş) sonuçlarını görür. |
| **Auditor** | Denetim günlüğüne (ve CSV dışa aktarımına) ve takımın Talepler listesi ile talep detayına (SQL, durum, talep sahibi, onaylayan, onay izi, DDL işareti) salt-okunur erişim; sonuç satırlarını görüntüleyemez ve indiremez; bağlantılara, onaylara, maskelemeye ve ChatOps ayarlarına erişimi yoktur. |

Admin globaldir; DBA, Developer ve Auditor **takım bazındadır**. Bir kullanıcı
birden çok takımda farklı rollerle yer alabilir. Bağlantılar, talepler,
maskeleme kuralları ve denetim günlükleri takım sınırını asla aşmaz.

Denetim günlüğü Auditor ve Admin'e ayrılmıştır; DBA'in erişimi yoktur.

### Kullanıcıları askıya alma ve silme

Bir Admin, Users ekranında bir kullanıcıyı **askıya alabilir**. Askıdaki kullanıcı
oturum açamaz, açık oturumlar sona erer ve Slack ile Teams kimlikleri çalışmaz
olur; bekleyen talepleri yerinde kalır ve normal kurallarla karara bağlanır.
Resume erişimi geri verir. Bir kullanıcıyı **silmek** aynı etkiyle bir soft
delete'tir ve ayrıca onun `pending` taleplerini iptal eder (`system` aktörüyle
`request.cancelled` olarak denetlenir); onaylanmış ve kuyruğa alınmış taleplere
dokunulmaz. Talep geçmişi korunur: foreign key'ler hard delete'i reddeder ve
silinmiş bir kullanıcının e-posta adresi rezerve kalır. Kimse kendi hesabını
askıya alamaz ya da silemez.

## Bağlantılar ve tanımlamalar

DBA'ler hedef veritabanlarını **Connections** altında kaydeder. Kimlik bilgileri
(host, port, veritabanı, kullanıcı adı, parola) AES-256 ile şifreli saklanır.
Parola kaydedildikten sonra bir daha gösterilmez — düzenleme formu onu boş
bırakır, boş bırakmak da kayıtlı parolayı korur. Kimlik bilgileri günlüklere veya hata mesajlarına da düşmez.

Bir geliştirici, bir bağlantıyı ancak DBA kendisine **tanımladıktan** sonra
görür (Connections → Grants). Tanımlanmamış bağlantılar Query Studio'da
görünmez.

### Süreli tanımlamalar ve erişim talepleri

Bir tanımlama, biri elle kaldırana kadar değil, belirli bir süre için de geçerli
olabilir. DBA bir bağlantıyı tanımlarken (Connections → Grants) şunları ayarlar:

- **erişim düzeyi**: `write` (varsayılan) ya da `read`. `read` tanımlaması, SQL
  guard'ın yazma ya da DDL saydığı bir talebi açamaz; Query Studio 403 döner.
- **süre**: kalıcı (varsayılan) ya da bir zaman aralığı. Erişim süre dolduğu anda
  biter.
- isteğe bağlı bir **gerekçe**.

Panel her geliştiricinin düzeyini ve kalan süreyi gösterir; DBA tanımlamayı
değiştirebilir ya da geri alabilir. Mevcut tanımlamalar tam erişimle kalıcı
kalır. `connections:expire-grants` adlı zamanlanmış görev her dakika çalışır,
süresi dolan satırları siler ve denetim günlüğüne `grant.expired` yazar; bu yüzden
kayıt, erişimin gerçekte bittiği andan biraz sonra yazılabilir. Tanımlama bittiğinde
zaten `pending` ya da `approved` olan talepler iptal edilmez; tanımlama yalnızca
talep gönderme hakkı verir, her talebin kendi onayı yine gerekir.

**Erişim isteme.** Geliştirici panoda kendi takımının bir bağlantısına erişim
isteyebilir: düzeyi, bir süreyi (1 saat, 4 saat, 1 gün, 7 gün ya da en fazla 30
günlük özel bir süre) seçer ve zorunlu olan gerekçeyi yazar. Talep, DBA'in
**Approvals** sayfasındaki **Access requests** sekmesinde görünür; DBA onaylar ya da
gerekçe yazarak reddeder. Tanımlama onaylandığı anda başlar. Süreli tanımlaması olan
geliştirici düzeyini ve kalan süreyi görür, süreyi uzatmak için talep açabilir.

Onayın erişimi yanlışlıkla genişletmesini önleyen kurallar:

- Kimse kendi talebine karar vermez; talep açıkken DBA olan talep sahibi de.
- Talep, yürürlükteki tanımlamayla uyuşmalıdır. Yürürlükteki tanımlamadan farklı bir
  düzey için ya da o düzeyde kalıcı bir tanımlama varken herhangi bir düzey için
  açılan talep, hem açılırken hem onaylanırken reddedilir. Var olan bir tanımlamayı
  değiştirmek için DBA onu Connections sayfasında düzenler.
- Aynı düzeydeki bir onay süreli tanımlamayı yalnızca **uzatır**. Onu asla
  kısaltmaz ve kalıcı yapmaz.

DBA'ler uygulamada ve takımın Slack ya da Teams kanalında bilgilendirilir (serbest
metin gerekçe olmadan); talep sahibine karar ve yürürlükteki tanımlama bildirilir.
Denetim olayları `grant.requested`, `grant.approved`, `grant.rejected` ve
`grant.expired`'dır. Elle geri alma yine `connection.grant_revoked` kaydeder;
`connection.grant_added` artık erişim düzeyini, bitiş zamanını ve gerekçeyi taşır.

## Talebin yaşam döngüsü

```
pending ──▶ approved ──▶ queued ──▶ running ──▶ completed
   │                                              │
   ├──▶ rejected  (gerekçe zorunlu)               └──▶ failed
   └──▶ cancelled (talep sahibi ya da admin)
```

- **Gönderim.** Geliştirici Query Studio'da SQL yazar.
  [SQL korumaları](/tr/docs/sql-korumalari/) gönderimden önce doğrular — kural
  ihlal eden talep kuyruğa hiç girmez.
- **Bekleme.** Talep, biri karar verene kadar süresiz bekler; otomatik zaman
  aşımı yoktur. Takım DBA'leri portalda ve yapılandırıldıysa
  [Slack](/tr/docs/slack-entegrasyonu/) / [Teams](/tr/docs/teams-entegrasyonu/)
  üzerinden bilgilendirilir. `QUERYPROXY_PENDING_REMIND_AFTER` saat sonra
  (varsayılan `4`; `0` kapatır) takımın DBA'leri ve yöneticileri bir hatırlatma
  alır ve sohbet kartı yeni bir aksiyon token'ıyla yeniden yayınlanır. Talep
  sahibi gönderirken isteğe bağlı bir not ekleyebilir; DBA'ler onu talebiyle birlikte
  görür.
- **Hassas filtre rozeti.** Bir talep, takımın bir kolon kuralıyla maskelediği bir
  kolona göre filtrelediğinde (`WHERE`, `JOIN`, `HAVING`, `GROUP BY`, `ORDER BY`),
  onay ekranı ve talep detayı kolon adlarını içeren bir rozet gösterir. Maskeli
  bir kolon, sorgu adayları sınadığında yine de çıkarım yoluyla bir değeri
  sızdırabilir; bu yüzden onaylamadan önce ona bakın. Yalnızca kolon adlarını
  gösterir. Kolon takma adlarını ya da türetilmiş tabloları çözmez, regex ve
  validator kurallarını yok sayar; yükseltmeden önce gönderilmiş talepler rozet
  taşımaz.
- **Onay / Red.** Takımın herhangi bir DBA'i karar verebilir — **kendi**
  talepleri hariç: kendine onay engellidir. Admin'ler bu engeli aşabilir; aşım
  denetim günlüğünde işaretlenir. Red için yazılı gerekçe zorunludur. Aşım
  için her kanalda **yazılı bir gerekçe** (en fazla 1000 karakter) gerekir; o da
  denetim günlüğüne kaydedilir. Karar
  sohbetten geliyorsa aynı kurallara ek olarak iki koşul daha aranır: kontrolün
  taşıdığı **tek kullanımlık aksiyon token'ı** (o tek talebe bağlı, 24 saat
  ömürlü) geçerli olmalı ve çözülen onaylayan **entegrasyonun takımına üye**
  olmalıdır. [REST API](/tr/docs/rest-api/) aynı kuralları izler; tek fark aşımı
  hiç kabul etmemesidir: web formuna bir bağlantıyla `403` döner.
- **Çalıştırma.** Onaylanan talepler kuyruğa girer ve işçi tarafından alınır.
  Okumalar veritabanı cursor'ı üzerinden sonuç dosyasına akar; her satıra
  yazılmadan önce [maskeleme](/tr/docs/veri-maskeleme/) uygulanır. Yazmalar
  etkilenen satır sayısını raporlar; çok ifadeli talepler atomik çalışır ve
  herhangi bir ifade başarısız olursa tamamı geri alınır. Okumalar hedef
  veritabanında salt okunur bir oturumda, bir ifade ve bir kilit zaman aşımıyla
  çalışır (bkz.
  [Yapılandırma](/tr/docs/yapilandirma/#okuma-kimlik-bilgileri-ve-zaman-aşımları)).
  Bir bağlantıda aynı anda en fazla `QUERYPROXY_CONNECTION_SLOTS` talep
  (varsayılan `2`) çalışır; diğerleri bir yuva boşalana kadar `queued` kalır.
- **Durdurma.** Talep sahibi, takımın DBA'leri ve yöneticiler, veritabanı oturumu
  bilinen `running` bir talepte **Stop query**'ye basabilir (SQLite'ta değil).
  Veritabanı ifadeyi iptal eder ve geri alabildiğini geri alır; zaten commit
  edilmiş değişiklikler kalır. Talep `cancelled` olur ve denetim günlüğü
  `execution.cancelled` kaydeder. SQL Server bunun için ek yetki ister; bkz.
  [Yapılandırma](/tr/docs/yapilandirma/#stop-query-için-yetkiler).
- **Sonuçlar.** Talep sahibi (ve takımın DBA'leri) sonuçları sayfa sayfa
  görüntüleyebilir ya da CSV indirebilir. Denetçiler talep meta verisini,
  geçmişi ve onay izlerini görür — sonuç verisinin kendisini değil. Sonuç
  dosyaları yapılandırılan saklama süresi sonunda otomatik silinir.

## Bildirimler

Talep sahipleri, talepleri karara bağlandığında ve çalıştırma bittiğinde;
DBA'ler yeni gönderimlerde bilgilendirilir. Bildirimler portalın zil menüsünde
görünür. Yeni gönderimler ve kararlar, sohbet kanalı yapılandırıldıysa orada da
duyurulur; çalıştırma-bitti bildirimi yalnızca portalda talep sahibine gider,
Slack'e ya da Teams'e gönderilmez.

**E-posta.** Her kullanıcı Profile sayfasında hangi olayların e-postayla da
gelmesini istediğini seçer: inceleme bekleyen talep, kendi talebine verilen karar,
biten, başarısız olan ya da durdurulan talep, bekleyen talep hatırlatması, bir
DBA'i bekleyen erişim talebi ve erişim talebine verilen karar. Hepsi varsayılan
olarak kapalıdır. E-posta sorgu sonucu, onaylayanın gerekçesi, karar notu ya da hata
mesajı taşımaz; içindeki SQL'in değerleri gizlidir. E-postadaki bağlantılar talebi QueryProxy'de
açar ve açık bir oturum ister; e-postadan hiçbir şey onaylanmaz. E-posta kuyruktan
gönderilir, yani işçinin çalışması gerekir; e-posta hatası talebi hiçbir zaman
engellemez. `MAIL_MAILER=log` iken hiçbir şey teslim edilmez ve Profile sayfası
bunu söyler.

## Denetim izi

Yukarıdaki her adım bir denetim kaydı yazar: gönderim, karar (kanal ve aşım
işaretiyle), çalıştırma başlangıcı/bitişi (süre ve etkilenen satırlarla), sonuç
indirmeleri; ayrıca girişler, tanımlamalar ve yapılandırma değişiklikleri.
Denetim kayıtları değiştirilemez — model katmanı ve veritabanı trigger'ları
güncelleme ve silmeyi reddeder, kayıtlar da `php artisan audit:verify`'ın
denetlediği bir hash zinciri oluşturur. Denetçiler izi filtreleyebilir ve CSV
olarak dışa aktarabilir. Denetim ekranı ve CSV, SQL'i literalleri redakte edilmiş
(`sql_redacted`) gösterir, ham ifadeyi asla göstermez. Olaylar bir SIEM'e de
aktarılabilir: bkz.
[Denetim zinciri ve SIEM aktarımı](/tr/docs/denetim-kaydi-ve-siem/).

Kayıtlar istemci IP'sini QueryProxy'nin gördüğü hâliyle tutar. Bir ters vekil
arkasında bu, vekili `TRUSTED_PROXIES`'e yazmadıkça vekilin kendi adresidir —
bkz. [Yapılandırma](/tr/docs/yapilandirma/).
