
# Ortam ayarlarını güncelleyin

`PATCH /v1/environment-settings` · izin `environment-settings:write`

Ortam ayarlarını JSON birleştirme yaması (`application/merge-patch+json`, RFC 7396) ile günceller. `If-Match` zorunludur: eksikse `428`, sürüm güncel değilse `412` döner. Ayarlar hiç yazılmamışsa sürüm `"0"` olur ve ilk yazma satırı oluşturur. Hiçbir şeyi değiştirmeyen bir yama hiçbir şey yazmaz ve sürümü korur.

## İstek

| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
| `If-Match` | header | evet | Ayarların son okunduğu andaki `ETag` değeri (hiç yazılmamışsa `"0"`). Eksikse: `428`; güncel değilse: `412`. |
| `locales.enabled` | string[] | hayır | Etkin dil kodları (kayıtlı diller), 1-64 girdi, yinelenen yok. `null` olamaz. |
| `locales.default` | string | hayır | Varsayılan dil; `locales.enabled` içinde olmalıdır. `null` olamaz. |
| `default_zoneinfo` | string | hayır | IANA saat dilimi adı (varsayılan `UTC`). `null` olamaz. |
| `session.idle_timeout_s` | integer | hayır | Boşta kalma zaman aşımı, saniye cinsinden, 60-8640000 (varsayılan 259200); `session.absolute_timeout_s` değerinden büyük olamaz. `null` olamaz. |
| `session.absolute_timeout_s` | integer | hayır | Mutlak ömür, saniye cinsinden, 60-31536000 (varsayılan 2592000). `null` olamaz. |
| `session.max_concurrent` | integer | hayır | Kullanıcı başına eşzamanlı oturum sayısı, 0-500; `0` sistem sınırı anlamına gelir (varsayılan). `null` olamaz. |
| `session.concurrent_mode` | string | hayır | `evict_oldest` (varsayılan) veya `deny_new`. `null` olamaz. |
| `session.anomaly_action` | string | hayır | `enforce` (varsayılan) veya `log`. `null` olamaz. |
| `signup.mode` | string | hayır | `open` (varsayılan), `invite_only` veya `closed`. `null` olamaz. |
| `signup.email_domain_mode` | string | hayır | `off` (varsayılan), `allowlist` veya `denylist`. `null` olamaz. |
| `signup.email_domains` | string[] \| null | hayır | En fazla 1000 alan adı; tüm listeyi değiştirir (RFC 7396 dizileri birleştirmez). `null` veya `[]` listeyi temizler. Girdiler normalleştirilir (küçük harf, IDNA A-etiketi), yinelenenler çıkarılır ve liste sıralı saklanır. Mod `off` iken de korunur. |
| `security_notifications.enabled` | boolean | hayır | Ana anahtar (varsayılan `true`). `null` olamaz. |
| `security_notifications.events` | string[] \| null | hayır | 12 güvenlik olayının alt kümesi (`password_changed`, `password_reset`, `email_changed`, `phone_changed`, `authenticator_added`, `authenticator_removed`, `recovery_code_used`, `recovery_codes_regenerated`, `account_locked`, `breached_password_detected`, `new_device_sign_in`, `account_recovery_started`); tüm listeyi değiştirir ve kanonik sırada döner. `null` veya `[]` temizler (hiçbir olay yok). |
| `account_recovery.mode` | string | hayır | `self_service_waiting` (varsayılan), `admin_only` veya `disabled`. `null` olamaz. |
| `account_recovery.waiting_hours` | integer | hayır | 24-168 saat (varsayılan 72); her modda saklanır. `null` olamaz. |
| `account_recovery.support_url` | string | hayır | Boş veya en fazla 2048 bayt, kullanıcı bilgisi veya parça (fragment) içermeyen bir `https://` URL'si. Kurtarma `disabled` olduğunda gösterilir. `null` olamaz. |
| `mfa.email_second_factor_enabled` | boolean | hayır | E-posta ikinci faktörü açık veya kapalı (varsayılan `false`). `null` olamaz. |
| `mfa.email_second_factor_acr` | string | hayır | E-posta faktörünün sağladığı güvence düzeyi: `1fa` (varsayılan) veya `mfa`. `null` olamaz. |
| `mfa.totp_issuer_label` | string | hayır | TOTP veren etiketi, en fazla 64 karakter; boş ise ortamın görünen adı kullanılır. Denetim karakteri, `:` ve baştaki/sondaki boşluklar yok. `null` olamaz. |
| `mfa.recovery_codes_enabled` | boolean | hayır | Kurtarma kodları açık veya kapalı (varsayılan `true`). `null` olamaz. |
| `mfa.recovery_code_count` | integer | hayır | Kurtarma kodu sayısı, 8-16 (varsayılan 10). `null` olamaz. |
| `mfa.required` | boolean | hayır | Ortamdaki her girişte ikinci faktör iste (varsayılan `false`). Uygulama, kuruluş ve istek gereksinimleriyle VEYA ile birleştirilir; bu düzeyin altındaki mevcut bir SSO oturumu yükseltme için yönlendirilir (`prompt=none` ile `interaction_required`). `null` olamaz. |
| `mfa.min_acr` | string | hayır | Ortamdaki her girişin ulaşması gereken en düşük güvence düzeyi: `1fa` (varsayılan, etkisiz), `mfa` veya `phr`. Ortam, uygulama, kuruluş ve istek eşiklerinin en yükseği uygulanır; yeni girişlere ve SSO oturumu yeniden kullanımına uygulanır. `null` olamaz. |
| `mfa.enrollment_grace_days` | integer | hayır | İkinci faktörü olmayan bir kullanıcının kayıt olmadan giriş yapmaya devam edebileceği gün sayısı; bu kullanıcıdan ilk kez kayıt istendiği andan itibaren sayılır, 0-14 (varsayılan `0`, süre tanınmaz). Süre yalnızca ortam ve kuruluş ekseninin gerektirdiklerini erteler; uygulamanın `min_acr` değeri ve istenen `acr_values` asla ertelenmez. Aralık dışı değer `out_of_range` koduyla `422 validation_failed` döner. Süreyi kısaltmak hemen etkili olur. `null` olamaz. |
| `frontchannel_logout_enabled` | boolean | hayır | Ön kanal (Front-Channel) çıkışı açık veya kapalı (varsayılan `false`); kapatmak kayıtlı URI'leri korur. `null` olamaz. |
| `allowed_first_factors` | string[] | hayır | İzin verilen birincil faktörler: `password`, `passkey`, `email_otp`, `magic_link`, `sms_otp`, `social`, `enterprise` değerlerinden en az biri, yinelenen yok. Tüm listeyi değiştirir ve bu sırayla döner. Varsayılan `password`, `passkey`, `social`, `enterprise`; `email_otp`, `magic_link` ve `sms_otp` yalnızca açıkça eklenirse etkindir. Boş liste `422 required` döner (kimsenin giriş yapamayacağı bir ortam). `null` olamaz. |

## Davranış

- Gruplar özyinelemeli olarak birleşir: `locales`, `session`, `signup`, `security_notifications`, `account_recovery` ve `mfa` içinde yalnızca değiştirdiğiniz alanları gönderin. Grubun kendisi `null` olamaz.
- Oturum ömrünü kısaltmak, eşzamanlı oturum sınırını düşürmek, kayıt olma veya hesap kurtarmayı daraltmak, e-posta ikinci faktörünü `mfa` iken `1fa`'ya indirmek ve `allowed_first_factors` listesinden bir faktörü çıkarmak, yeni oturumlara ve girişlere hemen uygulanır; mevcut oturumlar kendi ömrünü korur.
- Doğrulama hataları alanın JSON işaretçisini taşır; örneğin `out_of_range` koduyla `/session/idle_timeout_s`. Liste girdisindeki bir hata girdinin kendisini gösterir: `unknown_value` (bilinmeyen değer) için `/allowed_first_factors/1` veya `duplicate` (tekrarlanan değer).
- `allowed_first_factors`, uygulama ve kuruluş politikalarıyla kesiştirilir: bunlar yalnızca bu kümeyi daraltabilir.
- Yeni küme, kendi `allowed_first_factors` değerine sahip bir uygulamayla ortak hiçbir yöntem bırakmıyorsa istek `422 policy_conflict` döner; önce uygulamanın kümesini değiştirin.
- Denetim kaydı ve değişiklik olayı, değiştirilen alanların değerlerini değil yalnızca adlarını taşır. Saldırı koruması ayrı bir kaynaktır ve bu kaynağın parçası değildir.

## Yanıt

Güncellenmiş ayarlar ve yeni `ETag` ile `200 OK`.

```json
{
  "locales": {"enabled": ["en", "tr"], "default": "tr"},
  "default_zoneinfo": "Europe/Istanbul",
  "session": {"idle_timeout_s": 3600, "absolute_timeout_s": 2592000, "max_concurrent": 5, "concurrent_mode": "evict_oldest", "anomaly_action": "enforce"},
  "signup": {"mode": "invite_only", "email_domain_mode": "allowlist", "email_domains": ["example.com"]},
  "security_notifications": {"enabled": true, "events": ["password_changed", "password_reset"]},
  "account_recovery": {"mode": "self_service_waiting", "waiting_hours": 72, "support_url": ""},
  "mfa": {"email_second_factor_enabled": false, "email_second_factor_acr": "1fa", "totp_issuer_label": "Acme", "recovery_codes_enabled": true, "recovery_code_count": 10, "required": false, "min_acr": "1fa", "enrollment_grace_days": 0},
  "frontchannel_logout_enabled": false,
  "allowed_first_factors": ["password", "passkey", "magic_link", "enterprise"],
  "updated_at": "2026-10-05T09:30:00.123456Z"
}
```

## Hatalar

| HTTP | code | Ne zaman |
|---|---|---|
| 400 | `unknown_field` | Yama bilinmeyen veya salt okunur bir alan içeriyor ya da bir JSON nesnesi değil (`malformed_request`). |
| 412 | `precondition_failed` | `If-Match` mevcut sürümle eşleşmiyor. |
| 415 | `unsupported_media_type` | İçerik türü `application/merge-patch+json` değil. |
| 422 | `validation_failed` | Bir değer geçersiz (işaretçi alanı gösterir) ya da `null` olamayan bir alan `null` yapılmış (`code: invalid`). |
| 422 | `policy_conflict` | Yeni `allowed_first_factors`, kendi kümesi olan bir uygulamayla ortak hiçbir yöntem bırakmıyor. |
| 428 | `precondition_required` | `If-Match` başlığı eksik. |
| 401 | `unauthenticated` | Kimlik bilgisi eksik, geçersiz veya iptal edilmiş. |
| 403 | `insufficient_permissions` | Kimlik bilgisinin gerekli izni yok. |
| 429 | `rate_limited` | Hız sınırı aşıldı; `Retry-After` süresinden sonra yeniden deneyin. |
| 503 | `service_unavailable` | Bir bağımlılık geçici olarak kullanılamıyor; `Retry-After` süresinden sonra yeniden deneyin. |

## Örnek

E-posta sihirli bağlantılarını açın ve parolaları kapatın:

```bash
curl -X PATCH https://api.eu.keenauth.com/v1/environment-settings \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "0"' \
  -d '{"allowed_first_factors":["passkey","magic_link","social","enterprise"]}'
```

Oturum ve kayıt ayarları:

```bash
curl -X PATCH https://api.eu.keenauth.com/v1/environment-settings \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/merge-patch+json" \
  -H 'If-Match: "0"' \
  -d '{"session":{"idle_timeout_s":3600},"signup":{"mode":"invite_only","email_domain_mode":"allowlist","email_domains":["example.com"]}}'
```
