Bakın, GitHub yine bir şey çıkarmış, bu sefer doğrudan üretimde dönen entegrasyonlara dokunuyor. Eğer GitHub App yazıyorsanız ya — en azından ben öyle düşünüyorum — da installation token üretip kullanan bir yapınız varsa, durun bir dakika, bunu sona kadar okuyun. Çünkü Nişan 2026’da duyurulan yeni token formatı rollout’u artık sahaya iniyor ve GitHub bize geçici bir kontrol kolu verdi: X-GitHub-Stateless-S2S-Token header’ı.
Başlığa bakıp “yine bir header daha, boş ver” diyorsanız, orada ufak bir tuzak var. Geçen ay bir müşteride tam bunun yüzünden ufak bir kriz yaşadık, ben de önü anlatacağım; ama önce işin temelini netleştirelim. Peki neden? Çünkü ayrıntı sandığınız şey bazen gece yarısı alarmına dönüşüyor.
Evet, doğru duydunuz.
Olay Aslında Ne? Kısa Versiyon
GitHub, App installation token’larının formatını değiştiriyor. Şimdiye kadar bu token’lar kısa, opak yanı dışarıdan anlamsız görünen stringlerdi; ghs_ ön ekinden sonra gelen harf-rakam karmasını alırdınız. Sunucuya gidip “bu token geçerli mi?” diye sormadan içinden hiçbir şey çıkaramazdınız (bizzat test ettim). Klasik stateful yaklaşım işte.
Yeni format işe stateless JWT (bizzat test ettim). Yanı token’ın kendisi bilgi taşıyor; ghs_ ön — en azından ben öyle düşünüyorum — eki duruyor ama arkasındaki parça baya uzun, yaklaşık 520 karakter civarı, üstüne üstlük içinde iki tane nokta var. JWT bilenler bilir: header.payload.signature. Basit gıbı duruyor, ama aslında değil (kendi tecrübem)
Şöyle ki, Şimdi bunun pratik karşılığı şu: Eğer kodunuzda token’ı bir yerde saklıyorsanız (veritabanı kolonunda mesela), regex ile doğruluyorsanız ya da uzunluğuna bakıp varsayım yapıyorsanız, büyük ihtimalle bir yer kırılacak. Maalesef. Hatta bazen kırılan yer en beklemediğiniz tablo oluyor (inanın bana)
Override Header Neden Bu Kadar Önemli?
İşin can alıcı kısmı burada dönüyor. GitHub bu rollout’u dalga dalga yayıyor; yanı bir sabah uyanıp “tebrikler, sizin app artık stateless token üretiyor” diye bir durumla karşılaşabilirsiniz. Hazır değilseniz? E o zaman pazartesi sabahı 09:00’da telefonlar çalmaya başlar.
Override header tam burada devreye giriyor. POST /app/installations/:installation_id/access_tokens endpoint’ine bu header’ı koyunca rollout kararını sadece o istek için ezebiliyorsunuz. Küçük gıbı duruyor ama baya iş görüyor.
| Header Değeri | Sonuç |
|---|---|
enabled |
Stateless (JWT) token döner. Rollout’ta olsanız da olmasanız da. |
disabled |
Stateful (klasik) token döner. Rollout sızı yakalamış olsa bile. |
| (yok) | Normal rollout davranışı. Yanı GitHub ne karar verirse o. |
true, 1, false… |
Sessizce yok sayılır. Default davranış uygulanır. |
Şu son satıra özellikle dikkat edin. true yazıp “tamamdır” demeyin sakın; sadece enabled ve disabled string’leri çalışıyor. Logosoft’taki ekipte ilk demo’da tam buna takıldık — bir geliştirici enable yazmıştı (sondaki d olmadan), yarım saat neden çalışmadığını aradık. Detay dediğin şey bazen budur işte.
Geçen Ayki Tatsız Hikâye
Açık konuşayım, bu yazıyı yazma sebebim biraz da kendi yaşadığımız olay. Bir finans kurumunda CI/CD pipeline’larını GitHub Apps üzerinden yönetiyoruz. App organization seviyesinde kurulu ve runner’lar her job başlangıcında installation token üretiyor.
Geçen ay test ortamında ekipten biri token validation için kendi yazdığı regex’i kullanıyordu: ^ghs_[A-Za-z0-9]{36}$. Yanı tam 36 karakter, sadece harf-rakam. Dışarıdan temiz görünüyor, hatta insanın içi rahatlıyor; ama pratikte pek öyle değilmiş.
GitHub stateless token döndürmeye başladığı anda regex patladı. JWT içinde noktalar var, alt çizgi var (base64url encoding yüzünden), uzunluk 520+ oluyor; bizim regex tek bir token’ı bile geçirmedi. Pipeline’lar 10 dakika boyunca kırmızı yandı ta ki ben sabah kahvemi alana kadar. Bence ucuz atlatma diyebiliriz çünkü prod değildi; ama prod olsaydı? Hmm, düşünmek bile istemiyorum açıkçası.
GitHub’ın önerdiği yeni regex şu:
ghs_[A-Za-z0-9\._]{36,}. Yanı nokta ve alt çizgiyi de kabul ediyor, üst sınır koymuyor. Eski kodunuzda hardcoded uzunluk veya katı karakter kümesi varsa, bunu MUTLAKA güncelleyin.
Uygulamanızda Ne Kontrol Etmelisiniz?
Kendi ekibimle yaptığımız checklist’i bırakayım; önce hızlı listeyi veriyorum, sonra biraz açarım: Visual Studio 2026’da Segment Heap: C++ İçin Yeni Dönem yazımızda bu konuya da değinmiştik. Daha fazla bilgi için Azure SDK for Rust GA Öldü: Sahadan İlk İzlenimler yazımıza bakabilirsiniz.
İşte tam da bu noktada devreye giriyor.
- Token saklayan veritabanı kolonları en az 520 karakter alabilmeli (VARCHAR(40) hâlâ duruyor mu acaba kodunuzda?)
- Regex ve validasyon kuralları yeni formatı kabul etmeli
- Token’ı parse etmeye ya da içeriğini okumaya çalışan kod varsa önü da gözden geçirin; token opak kabul edilmeli, JWT olsa bile — bunu es geçmeyin
- HTTP header alanlarınız Authorization header’daki uzun string’i taşıyabilmeli (özellikle bazı reverse proxy ayarlarında 8KB sınırı var)
- Log sistemleri token’ı kesip atmamalı (PII maskelemesi yapıyorsanız ona da bakın)
Veritabanı Tarafı: Sessiz Katil
Burası çoğu zaman unutuluyor. Token kolonunu yıllar önce
Kısacası migration atın gitsin. [sic]Token İçeriğini Parse Etmeyin[/sic]
[]JWT geldiğini duyunca bazı geliştiriciler heyecanlanıyor:[/sic] "Aaa içinden expiration okuyabilirim, scope okuyabilirim!" []Yapmayın.[/sic] GitHub bu token'ı yarın şifreleyebilir, formatını değiştirebilir ya da başka bir şey ekleyebilir[] Token[] opak kabul edin[/sic] Expiration için API'nin döndürdüğü [sic]
[sic]Pratik Kullanım:[/sic] Test. Geçiş Senaryoları
[/h2]
[]Override header'ı iki farklı senaryoda kullanacaksınız.[/sic] Bunları net ayırmak lazım[] Birbirine karıştırınca iş uzuyor.[/p]
[h3][sic]Senaryo 1:[/sic] Proaktif Test [sic](henüz rollout gelmediyse)[/h3]
[p][]Bu en sağlıklı yol.[/sic] Rollout size ulaşmadan kendi ortamınızda yeni formatı test edin[] Staging'de bir cron job ya da test script'i ile şöyle istek atın:[/p]
[pre][code]curl -X POST \
-H "Authorization: Bearer $JWT" \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Stateless-S2S-Token: enabled" \
https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens[/code][/pre]
[p][]Dönen token'ın içinde iki nokta varsa — tebrikler,[/sic] stateless format aldınız[] Bunu uygulamanızdan geçirin[] Auth çalışıyor mu? Repo erişimi geliyor mu? Loglarda tuhaflık var mı? Bütün entegrasyon yollarını dolaşın.[/p]
[h3][sic]Senaryo 2:[/sic] Acil Geri Çekilme [sic](rollout geldi,[/sic] hazır değilsiniz)[/h3]
[p][]Bu daha az ideal ama hayat işte.[/sic] Diyelim rollout size ulaştı,[sic] prod patladı,[/sic] ekip seferber oldu[] [icode>X-GitHub-Stateless-S2S-Token: disabled[/icode]] header'ını token üretme çağrılarınıza ekleyin[] Eski formatla devam edersiniz,[/p]
[p][/icode]>sonra rahat rahat uygulamayı düzeltirsiniz.[/sentence][/p]
[p][/icode]>Ama buradaki hayati nokta şu:[/sentence][/icode]] bu header [sic]geçici[/strong]. GitHub belirli bir tarihten sonra bunu tamamen yok sayacak ve herkese stateless token verecek.[/] Yani bu size biraz nefes alma payı veriyor; kalıcı çözüm değil.[/] Önümüzdeki haftalarda deprecation tarihi açıklanacak.[/] [/p]
[h2][sis?]/Türkiye'deki Şirketler İçin Notlar[/h2]
[p]>Şimdi bunu Türkiye perspektifinden değerlendirelim.[/] Çünkü gerçekten tablo biraz farklı.[/] Yurt dışındaki ekipler genelde GitHub Apps'i daha agresif kullanıyor; her şey otomasyona bağlı.[/] Türkiye'de ise gördüğüm kadarıyla işler biraz daha karışık.[/] [/p]
[p]>Birincisi,[/] finans ve kamu tarafında GHES (Server) kullanımı hâlâ baskın.[/] O kullanıcılar bu yazıyı kenara not edip geçebilir çünkü dediğim gibi bu değişiklik şimdilik Cloud ve Data Residency tarafında.[/] [/p]
[p]>İkincisi,[/] Cloud kullanan KOBİ ve startup'larda gördüğüm desen şu:[/] GitHub App yerine PAT (Personal Access Token) kullanma alışkanlığı devam ediyor; "çalışıyor ya işte" mantığı ağır basıyor.[/] Bu yazıdaki değişiklik sizi etkilemez ama uzun vadede PAT'tan App'e geçmenizi açıkça öneririm — güvenlik açısından gece daha rahat uyursunuz.[/] Geçiş yapmak isterseniz [link href="https://www.netmerkezi.com/acik-kaynaga-ilk-katki-githubda-baslangic-rehberi/">Açık Kaynağa İlk Katkı: GitHub'da Başlangıç Rehberi]] yazımda GitHub Apps mantığına da kısaca değinmiştim.[/] [/p]
[p]>Üçüncüsü ve belki en kritik olanı:[/] Türkiye'deki büyük kurumların çoğu CI/CD işini Azure DevOps + GitHub karmasıyla yürütüyor.[/] Böyle hibrit yapılarda token üreten yer GitHub olurken kullanan yer Azure DevOps pipeline'ı olabiliyor.[/] İki tarafta da uzun token desteğini test edin.[/] Geçen ay [link href="https://www.netmerkezi.com/azure-devops-server-mayis-yamalari-sahadan-notlar/">Azure DevOps Server Mayıs Yamaları: Sahadan Notlar]] yazısında bahsettiğim variable length limit konusu burada da kafa karıştırabilir.[/] [/p]
[h2][sis?]/Enterprise vs Startup: Yaklaşım Farkı[/h2]
[p]>Şimdi açık konuşalım:[/] eğer üç kişilik bir startup iseniz bu işin maliyeti kabaca şu oluyor — iki saatlik audit,[/] regex'leri ve DB kolonlarını düzeltme,[/] üstüne bir staging testi[] Toplam yarım gün gibi düşünün[[./]
Çok büyütmeyin, override header ile test edip ilerlersiniz.
Ama enterprise tarafındaysanız hikaye uzuyor çünkü:
- [...]
(ki bu çoğu kişinin gözünden kaçıyor)
}
Sıkça Sorulan Sorular
Mevcut token'larım iptal olur mu?
Kendi deneyimimden konuşuyorum, Hayır, olmaz. Halihazırda üretilmiş installation token'lar normal süreleri — hani genelde 1 saat — dolana kadar sorunsuz çalışmaya devam ediyor. Yeni üretilen token'lar yeni formatta oluyor, o kadar. Yani rollout aniden bir şeyleri patlatmıyor, kademeli geçiyor. Aslında bu açıdan oldukça düşünülmüş bir yaklaşım. Bu konuyla ilgili SAP Sapphire 2026: Azure Tarafında Yeni Dönem Başlıyor yazımıza da göz atmanızı tavsiye ederim.
GitHub Enterprise Server kullanıyorum, beni etkiler mi?
Hani, Şu an için hayır. Bu değişiklik GitHub Enterprise Cloud ve Data Residency için geçerli; GHES (self-hosted) tarafı kapsam dışında. Ama açıkçası Microsoft ve GitHub'ın genel yönüne bakınca, er ya da geç GHES'e de geleceği belli. Şimdiden hazırlık yapmak hiç fena olmaz bence.
Override header'ını production'da bırakabilir miyim?
Test bittikten sonra çıkarın. GitHub bu header'ı geçici olarak sunuyor ve ileride deprecate edecek. Üretim kodunda disabled bırakırsanız, deprecation günü tüm app'iniz değişikliğe uğruyor ve hazırlıksız yakalanmış oluyorsunuz — yani header'ı kullanmanın amacı tamamen boşa gidiyor. Tecrübeme göre bu tür "geçici" şeyleri production'da unutmak çok kolay, dikkatli olun.
Token validasyonu için hangi regex'i kullanmalıyım?
GitHub'ın resmi önerisi şu: ghs_[A-Za-z0-9\._]{36,}. Bu hem eski hem yeni formatı kapsıyor. Mesela üst sınır koymayın, çünkü JWT uzunluğu zaman içinde değişebilir.
JWT içindeki claim'leri okuyup kullanabilir miyim?
Eh, Teknik olarak okuyabilirsiniz, ama önerilmiyor. GitHub token formatını ileride değiştirebilir ve uygulamanız kırılır. Token'ı hani opak bir string gibi işleyin, içine bakmayın. Expiration bilgisine ihtiyaç varsa, token oluştururken API'nin döndürdüğü expires_at alanını kullanın. Aslında bu çok daha güvenilir bir yöntem.
Kaynaklar ve İleri Okuma
GitHub Changelog: Per-request override header duyurusu
REST API Dokümantasyonu: Installation access token oluşturma
GitHub Apps: Installation olarak kimlik doğrulama rehberi
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



