# Harici gizli bilgi referansları

> Hedef veritabanı parolalarını HashiCorp Vault, AWS Secrets Manager ya da Azure Key Vault'ta tutun. QueryProxy referansı bağlantı açılırken çözer.

- Dokümantasyon: Kılavuzlar
- Kaynak: https://queryproxy.com/tr/docs/harici-gizli-bilgiler/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
Varsayılan olarak bir bağlantının parolası QueryProxy'de, uygulama anahtarıyla
şifrelenmiş saklanır. Politikanız veritabanı parolalarının bir sır yöneticisinde
durmasını söylüyorsa bağlantıya değer yerine bir **referans** verin. QueryProxy
sırrı bağlantıyı açarken okur, veritabanı sürücüsüne verir ve unutur. Saklanan
yalnızca referanstır.

Üç tür referans desteklenir:

| Depo | Referans |
| :-- | :-- |
| HashiCorp Vault | `vault://<mount>/<path>#<key>` |
| AWS Secrets Manager | `aws-sm://<secret-id>[#<json-key>]` |
| Azure Key Vault | `azure-kv://<vault-name>/<secret-name>[/<version>]` |

Vault'ta `#<key>`, sırrın içindeki alanı adlandırır. AWS'de `<secret-id>` sırrın
adı ya da ARN'sidir; sır bir JSON nesnesiyse `#<json-key>` tek bir anahtarı seçer,
verilmezse sır metninin tamamı parola olur. Azure'da sürüm isteğe bağlıdır ve
verilmezse güncel sürüm kullanılır.

```text
vault://secret/teams/payments/orders-db#password
aws-sm://prod/payments/orders-db#password
azure-kv://payments-vault/orders-db-password
```

Bir bağlantının parolası ile ayrı **okuma parolası** ayrı ayrı referans olabilir.
`vault://`, `aws-sm://` ya da `azure-kv://` ile başlayan düz bir parola artık
referans sayılır.

## Hangi takım hangi referansı kullanabilir

Referanslar **takım başına** sınırlanır ve bir takım hiçbiriyle başlamaz. Bu sınır
olmasa, bağlantı oluşturabilen biri bağlantının host'unu kendi sunucusuna çevirip
Vault token'ının okuyabildiği herhangi bir sırrı o sunucuya yollatabilirdi.

Sistem yöneticisi her takım için, bağlantılarının başvurabileceği **önekleri**
belirler. **Admin → Teams** ekranındaki *Secret paths* paneli ya da komut satırı:

```bash
php artisan queryproxy:team:secret-prefixes payments vault://secret/teams/payments
php artisan queryproxy:team:secret-prefixes payments            # listeyi göster
php artisan queryproxy:team:secret-prefixes payments --clear    # hiçbirine izin verme
```

Komut takımın kimliğini ya da slug'ını alır. Verdiğiniz önekler yeni listenin
**tamamıdır**. Kurallar:

- Referans, bir önekin altındaysa izinlidir; karşılaştırma tam yol parçaları
  üzerinden yapılır: `vault://secret/teams/pay`,
  `vault://secret/teams/payments`'ı kapsamaz.
- Önekte joker, `#key`, `..` ya da `%` olmaz; en çok 512 karakterdir. Sondaki `/`
  atılır.
- ARN olarak yazılmış bir AWS sırrı ile aynı sırrın adla yazılmış hâli iki ayrı
  adrestir; kullandığınız biçimi listeleyin. Biri ötekini kapsamaz.
- Değişiklik, öncesi ve sonrasıyla `team.secret_prefixes_changed` olarak denetim
  günlüğüne yazılır. Panel, bir önek başka bir takımınkiyle çakışıyorsa uyarır.
- Öneki olmayan takım referanslı bağlantı kaydedemez; bağlantı formu onun için
  harici kaynakları devre dışı bırakır. Bağlantıyı başka takıma taşımak referansı
  yeniden denetler.
- Denetim, bağlantı kaydedilirken **ve sır çözülürken yeniden**, önbelleğe
  bakılmadan önce yapılır; böylece başka takımın önbelleğe aldığı değer asla
  verilmez.

## Bağlantı formunda

**Connections → New connection**'ı (ya da bir bağlantının düzenlemesini) açın.
**Credential source** şunları sunar: *Stored password*, *HashiCorp Vault*, *AWS
Secrets Manager* ve *Azure Key Vault*. Harici kaynakta parola kutuları, beklenen
biçimi gösteren bir referans alanına dönüşür; yazdığınız biçime benzemiyorsa
uyarı verir. Uyarı yalnızca ipucudur: karar sunucudadır. Takımın izinli yolları
alanın altında listelenir.

Bağlantı listesinde **Credentials** sütunu kaynağı ve referans varsa referansın
kendisini gösterir, parolayı asla göstermez. Artık takımın öneklerinin dışında
kalan referans *Outside team paths* ile işaretlenir. Düzenlerken referans forma
gelir; kayıtlı parola asla gösterilmez.

**Test**, referansı gerçekten çözer. Bir şey ters giderse sırrı asla taşımayan,
bir neden adlandıran sabit bir mesaj verir.

## Çözümleme başarısız olursa

Çözümleme **kapalı biçimde** başarısız olur: talep genel bir mesajla `failed`
olur ve bağlantı denenmez. Ayrıntı uygulama günlüğüne (şema, host ya da yol,
neden, HTTP durumu) ve denetim günlüğüne `secret.resolve_failed` olarak
(şema ve yol, `#key` olmadan, ve neden) gider. Değer ve onu almak için kullanılan
token'lar hiçbir yere yazılmaz. Nedenler: `invalid_reference`, `not_allowed`,
`not_configured`, `auth_failed`, `access_denied`, `not_found`, `key_missing`,
`malformed_response` ve `unavailable`.

Değerler web ve worker süreçlerinin **bellekte** önbelleğinde tutulur; uygulama
önbelleğinde değil. Süreyi `QUERYPROXY_SECRET_CACHE_TTL` belirler (varsayılan
`300` saniye, `0` önbelleği kapatır). Depoda parolayı döndürdükten sonra
bağlantılar değişikliği bu süre içinde alır. Her sürecin kendi önbelleği vardır.

`php artisan queryproxy:doctor` içinde `secret_stores` denetimi vardır. Ağ çağrısı
yapmaz: kayıtlı bir referansın kullandığı depo yapılandırılmamışsa ya da kayıtlı
bir referans bozuksa veya takımın öneklerinin dışındaysa başarısız olur.

## Ayarlar

| Değişken | Varsayılan | Anlamı |
| :-- | :-- | :-- |
| `QUERYPROXY_SECRET_CACHE_TTL` | `300` | Çözülmüş değerin süreç belleğinde kalma süresi (saniye); `0` önbelleği kapatır |
| `QUERYPROXY_SECRET_TIMEOUT` | `5` | Bir deponun bağlanması ve yanıtlaması için tanınan saniye |

### HashiCorp Vault

| Değişken | Varsayılan | Anlamı |
| :-- | :-- | :-- |
| `QUERYPROXY_VAULT_ADDR` | yok | Vault adresi, örn. `https://vault.example.com:8200` |
| `QUERYPROXY_VAULT_NAMESPACE` | yok | Kullanıyorsanız Vault namespace'i |
| `QUERYPROXY_VAULT_AUTH` | `token` | `token`, `approle` ya da `kubernetes` |
| `QUERYPROXY_VAULT_TOKEN` | yok | `token` için token |
| `QUERYPROXY_VAULT_ROLE_ID`, `QUERYPROXY_VAULT_SECRET_ID` | yok | AppRole kimlik bilgileri |
| `QUERYPROXY_VAULT_APPROLE_MOUNT` | `approle` | AppRole yönteminin mount'u |
| `QUERYPROXY_VAULT_K8S_ROLE` | yok | Kubernetes yöntemi için Vault rolü |
| `QUERYPROXY_VAULT_K8S_MOUNT` | `kubernetes` | Kubernetes yönteminin mount'u |
| `QUERYPROXY_VAULT_K8S_JWT_PATH` | `/var/run/secrets/kubernetes.io/serviceaccount/token` | Giriş için kullanılan service account token'ı |
| `QUERYPROXY_VAULT_KV_VERSION` | `2` | `2` ya da `1` |
| `QUERYPROXY_VAULT_MOUNTS` | yok | KV mount yolları, virgülle ayrılmış |
| `QUERYPROXY_VAULT_CA_FILE` | yok | Özel sertifikalı bir Vault için CA paketi |

`QUERYPROXY_VAULT_MOUNTS` **KV v1 için zorunludur**; orada bir KV mount'unu başka
bir Vault API yolundan ayıran başka bir şey yoktur. `kv/prod` gibi adında eğik
çizgi olan mount'lar için de gerekir; en uzun eşleşen mount kullanılır. Ayarlandığı
anda izin listesi olur: yalnızca bu mount'lar okunur. Ayardan bağımsız olarak
`auth`, `sys`, `identity` ve `cubbyhole` altına giden referanslar reddedilir; bir
referans Vault'un kendi API yollarını okumak için kullanılamaz.

### AWS Secrets Manager

QueryProxy, AWS SDK'nın varsayılan kimlik bilgisi zincirini kullanır: ortam
değişkenleri, paylaşılan kimlik dosyaları, IRSA web identity, ECS görev rolü ve
instance profile. QueryProxy'ye özgü anahtar yoktur.

| Değişken | Varsayılan | Anlamı |
| :-- | :-- | :-- |
| `QUERYPROXY_AWS_REGION` | yok | Bölge. Ayarlı değilse `AWS_REGION` ve `AWS_DEFAULT_REGION` kullanılır; ARN kendi bölgesini taşır |

### Azure Key Vault

| Değişken | Varsayılan | Anlamı |
| :-- | :-- | :-- |
| `QUERYPROXY_AZURE_AUTH` | `auto` | `auto`, `client_secret`, `workload_identity` ya da `managed_identity`. `auto`, varsa client secret'ı, yoksa token dosyası varsa workload identity'yi, yoksa managed identity'yi kullanır |
| `QUERYPROXY_AZURE_TENANT_ID`, `QUERYPROXY_AZURE_CLIENT_ID` | yok | Kiracı ve uygulama. Ayarlı değillerse `AZURE_TENANT_ID` ve `AZURE_CLIENT_ID` kullanılır |
| `QUERYPROXY_AZURE_CLIENT_SECRET` | yok | `client_secret` için client secret |
| `QUERYPROXY_AZURE_FEDERATED_TOKEN_FILE` | yok | Workload identity için token dosyası (AKS `AZURE_FEDERATED_TOKEN_FILE` enjekte eder) |
| `QUERYPROXY_AZURE_VAULT_DNS_SUFFIX` | `vault.azure.net` | Vault host'unun kurulduğu DNS soneki; host yalnızca vault adından ve bu sondan türer, bu yüzden bir referans isteği başka yere yönlendiremez |

`QUERYPROXY_VAULT_TOKEN`, `QUERYPROXY_VAULT_SECRET_ID` ve
`QUERYPROXY_AZURE_CLIENT_SECRET` her zamanki `_FILE` sonekiyle dosyadan
okunabilir; bkz. [Dosyadan sırlar](/tr/docs/yapilandirma/#dosyadan-sırlar).

## Sonraki adımlar

- Bu ayarları pod'lara geçirmek için [Kubernetes ve Helm](/tr/docs/kubernetes-ve-helm/).
- Kontrol listesinin kalanı için [Üretim güvenliği](/tr/docs/uretim-guvenligi/).
- `secret.*` olayları için [Denetim kaydı ve SIEM](/tr/docs/denetim-kaydi-ve-siem/).
