Mobil uygulamanın kaynak koduna gömülen bir API anahtarı, App Store veya Play Store'a yüklendiği andan itibaren herkese açık hale gelir — çünkü dağıttığın paket, kullanıcının cihazına inen ve istenildiği zaman decompile edilebilen bir dosyadır. Bu yazı, mobil uygulama api anahtarı sır yönetimi sorusuna üç katmanlı (derleme zamanı, çalışma zamanı, sunucu) bir çerçeveyle net bir cevap veriyor: hangi anahtar cihazda kalabilir, hangisi asla kalmamalı ve CI/CD hattında bunu nasıl garanti altına alırsın.
💡 Pro Tip: Bir anahtarı "gizlemek" yerine "gerektirmemeyi" hedefle — istemci tarafında hiç bulunmayan bir sır decompile edilemez; asıl kazanç obfuscation değil, mimari.
İçindekiler
- Tehdit Modeli: Binary'den Anahtar Çıkarmak Ne Kadar Kolay?
- Üç Katman: Derleme Zamanı, Çalışma Zamanı, Sunucu
- Hangi Anahtar Mobilde Durabilir, Hangisi Asla?
- CI/CD'de Sır Yönetimi ve İmzalama Anahtarları
- Sızan Anahtarı Tespit Etmek ve Rotasyon Planı
- Depoda Sır Taraması ve Pre-Commit Kancası
- Kontrol Listesi
- SSS
- API anahtarı mobil uygulamada nereye konmalı?
- Koda gömülen anahtar nasıl bulunuyor?
- CI'da sırlar nasıl yönetiliyor?
- Native kodda (C/C++) anahtar saklamak güvenli mi?
- Secret scanning geçmiş commit'leri de tarar mı?
- Sızan bir anahtarı fark ettiğimde ilk adımım ne olmalı?
- Güncelleme (Eylül 2026)
- Sonuç
- Kaynaklar
Tehdit Modeli: Binary'den Anahtar Çıkarmak Ne Kadar Kolay?
Android'in resmi güvenlik dokümanı bu konuda dolaylaştırma yapmıyor: derlenmiş bir uygulamanın kaynak kodundaki kaynaklarına gömülü bir API anahtarı varsa, "bir saldırganın uygulamayı decompile edip bu kaynakları bulması mümkündür" (developer.android.com/privacy-and-security/security-tips). Bu cümlenin pratik anlamı şu: mobil binary, sunucu kodundan temelde farklı bir güven sınırında yaşar. Sunucundaki koda kullanıcı fiziksel olarak erişemez; ama cihaza kurulan her paket bir disassembler veya decompiler'a doğrudan açıktır — APK'yı indirip açan herkes string tablolarını ve, obfuscate edilmemişse, kaynak yapılarını inceleyebilir.
Bu noktada iOS tarafında da durum farklı değil: IPA dosyası da bir arşivdir, App Store'dan indirilen her paket açılıp incelenebilir. Platformlar arasındaki tek fark, decompile işleminin zorluk derecesidir — kolaylık farkı, güvenlik garantisi değildir.
Burada sık düşülen bir tuzak var: "anahtarı native (C/C++) tarafa taşırsam görünmez olur" varsayımı. Aynı Android dokümanı, native kodun bellek bozulması hatalarına (buffer overflow gibi) Java/Kotlin koduna göre daha yatkın olduğunu da vurguluyor. Yani native tarafa taşımak decompile riskini ortadan kaldırmaz; üstüne farklı bir hata sınıfı — bellek güvenliği — ekler. Anahtarı native bir kütüphanede string olarak tutmak, temel bir ikili analizle yine çıkarılabilir; gerçek çözüm anahtarı hiç istemciye koymamaktır. Obfuscation (ProGuard/R8, kod karıştırma) bu süreci yavaşlatabilir ama imkânsız kılmaz — bir savunma katmanıdır, tek başına strateji değildir.
Bu tehdit modelinin sonucu net: mobil tarafta "gizlemek" diye bir kategori yok, yalnızca "orada olan" ve "orada olmayan" var. Bir anahtar binary'nin herhangi bir yerinde — kaynak dosyasında, native kütüphanede, hatta şifrelenmiş ama çözme anahtarı da binary içinde bulunan bir blob'da — bulunuyorsa, yeterince motive bir saldırgan için zaman meselesidir. Bu yüzden sonraki bölüm, hangi anahtarların bu kategoriye hiç girmemesi gerektiğini üç katmanlı bir çerçeveyle ayırıyor.
Üç Katman: Derleme Zamanı, Çalışma Zamanı, Sunucu
Sır yönetimini üç ayrı katmanda düşünmek, hangi aracı nerede kullanacağını netleştirir. Her katmanın kendi tehdit modeli, kendi aracı ve kendi "asla" kuralı vardır:
Katman | Ne saklanır | Tipik mekanizma | Mobilde düz metin kalabilir mi |
|---|---|---|---|
Derleme zamanı | Build-time enjekte edilen ortam değişkenleri | Gradle/Xcode build config, CI secret enjeksiyonu | Hayır — yalnız geçici, derleme çıktısına gömülür |
Çalışma zamanı | Cihazda üretilen/şifreli anahtarlar | Android Keystore, Apple Keychain | Evet — donanım destekli, dışarı çıkmaz |
Sunucu | Üçüncü taraf API'lerin sabit/paylaşılan anahtarları | Backend proxy, kısa ömürlü token | Hayır — istemciye hiç gönderilmemeli |
Derleme zamanında Android dokümanı net bir kural veriyor: "API anahtarlarını asla kaynak kodu deponuza commit etmeyin." Pratikte bu, anahtarların .gradle dosyalarına veya CI ortam değişkenlerine taşınması, secrets-gradle-plugin gibi araçlarla build sırasında enjekte edilmesi anlamına gelir. Bu tür bir eklentinin kullanımı yaygın bir yaklaşımdır; hangi aracı seçtiğin projene bağlı — önemli olan, anahtarın hiçbir zaman git log içinde düz metin olarak görünmemesidir. .gitignore'a alınmış bir local.properties veya .xcconfig dosyası, bu ayrımın en basit uygulamasıdır.
Çalışma zamanında ise hem Android hem Apple, donanım destekli, işletim sistemi seviyesinde şifreli bir depo sunar. Apple'ın Keychain Services dokümantasyonu bunu net tanımlıyor: Keychain, "kullanıcı adına küçük veri parçalarını güvenli şekilde saklar" — parola, kriptografik anahtar/sertifika, kısa notlar (developer.apple.com/documentation/security/keychain-services). Android tarafındaki karşılığı Android Keystore'dur; Android Keystore, anahtarı uygulama sürecinin dışında tutar — uygulama yalnızca "bu anahtarla imzala/şifrele" diyebilir, anahtarın kendisini okuyamaz.
Sunucu katmanı ise üçüncü taraf servislerin (ödeme sağlayıcı, harita API'si, analytics, push bildirim servisi) sabit/paylaşılan anahtarlarını barındırır. Bu anahtarlar tanım gereği tek bir uygulamaya değil, tüm kullanıcı tabanına hizmet verir; istemciye hiç gönderilmemeli, bir backend proxy arkasında kalmalıdır. Mobil uygulama bu servise doğrudan değil, kendi backend'in üzerinden, kendi kimlik doğrulamasıyla korunan bir uç noktadan erişmelidir.
kotlin
1// app/build.gradle.kts — secrets-gradle-plugin ile local.properties'ten enjeksiyon2plugins {3 id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")4}5// local.properties (git'e commit edilmez, .gitignore'da):6// MAPS_API_KEY=xxxxx7// Build sonucunda BuildConfig.MAPS_API_KEY olarak erişilir — kaynak kodunda literal yokHangi Anahtar Mobilde Durabilir, Hangisi Asla?
Bu ayrımı netleştirmek için iki kaynağı yan yana koymak yeterli: decompile riski (yukarıdaki tehdit modeli) ve Keychain/Keystore'un tasarım amacı — kullanıcı adına donanım-bağlı veri saklamak. Buradan çıkan pratik kural şu:
- Mobilde kalabilir: cihazda üretilen ve Keystore/Keychain'den dışarı çıkmayan anahtarlar — imzalama anahtarları, yerel şifreleme anahtarları, biyometrik doğrulamaya bağlı anahtarlar. Bunlar zaten "dışarı sızdırılamaz" olacak şekilde donanımla bağlıdır; uygulamanın kendisi bile anahtarın ham değerini okuyamaz, yalnızca "bu anahtarla işlem yap" diyebilir. iOS Keychain ve Güvenlik yazısında bu API'nin certificate pinning ile birlikte nasıl kullanılacağını detaylandırdım.
- Mobilde asla düz metin durmamalı: üçüncü taraf bir bulut API'sinin paylaşılan/sabit anahtarı. Decompile riski gerçek olduğu için, bu tür bir anahtar binary içine literal olarak gömülürse er ya da geç çıkarılabilir — anahtarın "kaç kullanıcıya" hizmet ettiği, sızıntının etki alanını da büyütür. Mobil Backend API Güvenliği yazısında rate limit ve token rotation ile bu riski backend tarafında nasıl azalttığımı anlatmıştım; mobil taraf bu tür anahtarları hiç görmemeli, yalnızca kendi backend'inin kısa ömürlü bir oturum token'ıyla konuşmalı.
Ara bir kategori de var: kullanıcıya özel, uzun ömürlü oturum token'ları (ör. "beni hatırla" refresh token'ı). Bunlar üçüncü taraf sabit anahtar değil ama yine de düz metin tutulmamalı — Keychain/Keystore'a şifreli olarak yazılmalı ve sunucu tarafında iptal edilebilir (revoke edilebilir) olmalıdır. iOS Security Best Practices yazısında bu tür oturum yönetimi kalıplarına genel bir çerçeve çizmiştim.
swift
1// Keychain'e şifreli yazma — anahtarın kendisi hiç kaynak kodunda görünmez2let query: [String: Any] = [3 kSecClass as String: kSecClassGenericPassword,4 kSecAttrAccount as String: "refresh_token",5 kSecValueData as String: tokenData,6 kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly7]8SecItemAdd(query as CFDictionary, nil)9// kSecAttrAccessibleWhenUnlockedThisDeviceOnly: cihaz kilitliyken okunamaz,10// yedeklere/başka cihaza taşınmazCI/CD'de Sır Yönetimi ve İmzalama Anahtarları
CI/CD hattı, mobil sır yönetiminin en sık ihmal edilen katmanı — çünkü anahtar artık geliştiricinin dizüstü bilgisayarında değil, her push'ta çalışan, üçüncü taraf action'lar içeren bir otomasyon ortamındadır. GitHub'ın kendi güvenlik dokümantasyonu (docs.github.com/en/actions/reference/security/secure-use) üç somut önlem sıralıyor:
- Action'ları tam commit SHA'sına pinle. Dokümantasyona göre bu, "immutable bir release kullanmanın tek yolu" — bir tag veya branch adına güvenmek, o referansın sonradan farklı bir koda işaret etmesine (tag hijack) açık kapı bırakır. Üçüncü taraf bir action'ın ele geçirilmesi, o action'ı kullanan her workflow'daki secret'lara erişim anlamına gelebilir.
GITHUB_TOKENiznini daralt. Varsayılan izni salt-okunur tutup yalnız gereken iş için artırmak "iyi güvenlik pratiği" olarak listeleniyor — bir workflow'un ihtiyaç duymadığı yazma iznine sahip olması, ele geçirilmiş bir action'ın etki alanını büyütür.- Bulut kimlik bilgilerinde statik secret yerine OIDC kullan. Workflow, bulut sağlayıcıdan yalnızca o iş için geçerli, otomatik süresi dolan kısa ömürlü bir token ister; kalıcı bir bulut kimlik bilgisi GitHub'da hiç saklanmaz.
Bu üç önlemi tek bir tabloda toplarsak, hangisinin hangi riski azalttığı netleşir:
Önlem | Azalttığı risk | Kaynak |
|---|---|---|
Action'ı tam commit SHA'sına pinle | Tag/branch hijack ile tedarik zinciri saldırısı | GitHub Docs — Security hardening |
GITHUB_TOKEN iznini varsayılanda salt-okunura indir | Ele geçirilmiş action'ın etki alanı (blast radius) | GitHub Docs — Security hardening |
Bulut kimlik bilgisinde OIDC kullan | Kalıcı statik secret'ın CI'da saklanması ve sızması | GitHub Docs — Security hardening |
yaml
1# .github/workflows/release.yml — SHA pinleme + daraltılmış izin + OIDC2permissions:3 contents: read # job'da permissions yazarsan belirtmediğin tüm izinler none olur — contents: read'i tekrar yaz4jobs:5 sign-and-deploy:6 runs-on: ubuntu-latest7 permissions:8 contents: read9 id-token: write # yalnız OIDC token istemek için10 steps:11 - uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # tam commit SHA12 - name: Bulut kimlik doğrulama (OIDC, statik secret yok)13 uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e034350214 with:15 role-to-assume: arn:aws:iam::123456789012:role/ci-deploy16 aws-region: eu-central-1İmzalama anahtarları (Android keystore dosyası, iOS distribution certificate + provisioning profile) bu üç kuralın en kritik uygulama alanı: bunlar CI ortamında yalnızca şifreli secret olarak tutulmalı, workflow loglarına asla yazdırılmamalı (GitHub secret'ları log'da otomatik maskeler ama secret değeri dönüştürülebildiği için otomatik redaksiyon garanti değildir; özellikle JSON/XML/YAML gibi yapılandırılmış veriyi secret olarak kullanmaktan kaçın) ve mümkünse yalnız release tag'inde tetiklenen, daraltılmış izinli ayrı bir job'da kullanılmalıdır. Flutter tarafında bu akışı Flutter CI/CD: GitHub Actions ve Fastlane yazısında Fastlane ile birlikte anlatmıştım; genel CI/CD otomasyon prensipleri (paralel job'lar, cache, release kanalları) için Mobile DevOps Best Practices yazısına bakabilirsin.
Sızan Anahtarı Tespit Etmek ve Rotasyon Planı
GitHub'ın secret scanning'i, bir depodaki tüm branch'lerin tüm Git geçmişini bilinen sır türleri için tarar — yani anahtar bir commit'te silinse bile, geçmişte kaldığı sürece taranabilir durumdadır (docs.github.com/en/code-security/concepts/secret-security/secret-scanning). Bu tarama davranışı, "anahtarı sildim, artık güvendeyim" varsayımını geçersiz kılar: sildiğin satır Git geçmişinde durduğu sürece, git log -p ile aynı anahtarı görebilen herkes onu görebilir. Bu yüzden sızıntı tespit edildiğinde tek doğru adım, geçmişi temizlemek değil (bu genelde pratik değildir ve force-push riskleri getirir), anahtarı derhal geçersiz kılmaktır.
Partner sağlayıcılarla (ör. bulut sağlayıcılar) entegre credential türlerinde, tespit doğrudan sağlayıcıya bildirilir — böylece kullanıcı fark etmeden bile revocation süreci başlayabilir. Bu, kendi tarafında hiçbir aksiyon almasan bile bir güvenlik ağı sağlar; ama buna güvenmek yerine kendi izleme sürecini kurman gerekir, çünkü her sağlayıcı bu entegrasyona sahip değildir.
Sızıntı tespit edildiğinde ilk adım, anahtarı sağlayıcı panelinden derhal geçersiz kılmak ve yenisiyle değiştirmektir — GitHub'ın secret scanning rehberi de alert aldığında ilgili credential'ı derhal rotasyona sokmanı söylüyor. Anahtar rotasyonunu düzenli bir bakım işi değil, "sızıntı tespit edildi" tetikleyicisine bağlı bir olay-müdahale adımı olarak planla; hangi anahtarın hangi servise ait olduğunu ve kimin sorumlu olduğunu önceden bir envanterde tutmak, olay anındaki gecikmeyi doğrudan azaltır.
Depoda Sır Taraması ve Pre-Commit Kancası
Secret scanning'in geçmişe dönük (push sonrası) tarama davranışı yukarıda net; bunun tamamlayıcısı, sırrın deponuza hiç ulaşmadan önce yakalanmasıdır. Bunun tamamlayıcısı, commit oluşturulmadan önce çalışan yerel bir tarayıcıdır: bilinen anahtar desenlerini (ör. sağlayıcıya özgü prefix'ler) yakalar ve commit'i reddeder.
Pratik kural basit: secret scanning'i depo/organizasyon seviyesinde açık tut (geçmişe dönük ağ), buna ek olarak yerel bir pre-commit kancası ekle (ilk savunma hattı). İkisi birbirini ikame etmez — biri geçmişi tarar, diğeri yeni commit'i daha depoya girmeden durdurmaya çalışır. Bir ekip için ikinci katmanın gerçek değeri, hatayı geliştiricinin kendi makinesinde, henüz kimseyle paylaşılmadan yakalamasıdır — bu, sonradan rotasyon yapmaktan çok daha ucuzdur.
bash
1#!/usr/bin/env bash2# .git/hooks/pre-commit — basit desen tabanlı kontrol örneği3if git diff --cached | grep -E "AIza[0-9A-Za-z_-]{35}|sk_live_[0-9a-zA-Z]{24}"; then4 echo "Olası API anahtarı tespit edildi — commit reddedildi."5 exit 16fiKontrol Listesi
- Kaynak kodu: API anahtarını asla commit etme;
.gitignore'a alınmış bir yerel dosyadan veya CI secret'ından enjekte et. - Statik/paylaşılan anahtar: mobil binary'de düz metin tutma — decompile riski gerçek, obfuscation tek başına yeterli değil.
- Keystore/Keychain: yalnız donanım-bağlı, dışarı çıkmayan anahtarlar için kullan; uzun ömürlü oturum token'larını da şifreli sakla.
- CI/CD: action'ları tam commit SHA'sına pinle,
GITHUB_TOKENiznini varsayılan salt-okunura indir, bulut kimlik bilgisinde OIDC kullan. - İmzalama anahtarları: ayrı, dar izinli, yalnız release tag'inde tetiklenen bir job'da kullan.
- Sızıntı: secret scanning'i organizasyon seviyesinde açık tut, tespit anında rotasyonu bir olay-müdahale adımı say.
- Pre-commit: yerel bir tarama kancasıyla geçmişe dönük taramayı tamamla, ekibe tek satırlık kurulum talimatı ver.
ALTIN İPUCU
Bu yazının en değerli bilgisi
Bu ipucu, yazının en önemli çıkarımını içeriyor.
Easter Egg
Gizli bir bilgi buldun!
Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?
Okuyucu Ödülü
Bu yazıdaki yedi maddelik kontrol listesini kendi projene uygulayacaksan, sırayı önceliklendirmek işini kolaylaştırır. Aşağıdaki liste, en yüksek riskten en düşüğe doğru, hangi adımı önce atman gerektiğini gösteriyor — özellikle "kaynak kodunda literal anahtar var mı" kontrolü genellikle ilk yapılması gereken, en hızlı kazanımdır; imzalama anahtarının izolasyonu ise en fazla mimari değişiklik gerektiren, ama en yüksek etkili adımdır.
SSS
API anahtarı mobil uygulamada nereye konmalı?
Anahtarın türüne göre değişir: cihazda üretilen ve dışarı çıkmayan anahtarlar — imzalama, yerel şifreleme, biyometrik doğrulamaya bağlı anahtarlar — Android Keystore veya Apple Keychain'de kalabilir. Üçüncü taraf bir servisin paylaşılan/sabit anahtarı ise mobil tarafa hiç konmamalı; bir backend proxy arkasında tutulmalı, cihaza yalnızca kısa ömürlü, kapsamı daraltılmış bir token gönderilmeli. Bu ayrımı yaparken kendine sorman gereken soru şu: "bu anahtar sızarsa, kaç kullanıcıyı etkiler?" — cevap "hepsini" ise, o anahtar mobil tarafta olmamalı.
Koda gömülen anahtar nasıl bulunuyor?
Android'in resmi dokümantasyonu bunu açıkça belirtiyor: derlenmiş bir uygulama decompile edilerek kaynak koduna ve kaynaklarına gömülü değerler çıkarılabilir. Obfuscation (ProGuard/R8) bu süreci zorlaştırır ama imkânsız kılmaz; asıl güvenlik, anahtarı hiç istemci tarafına koymamaktan gelir. iOS tarafında da IPA dosyası benzer şekilde açılıp incelenebilir bir arşivdir — platform farkı yalnızca zorluk derecesini değiştirir, garantiyi değil.
CI'da sırlar nasıl yönetiliyor?
GitHub Actions'ta sırlar şifreli secret olarak saklanır, workflow çalışırken ortam değişkeni olarak enjekte edilir ve loglara maskelenmiş görünür. Buna ek olarak action'ları tam commit SHA'sına pinlemek, GITHUB_TOKEN iznini daraltmak ve bulut kimlik bilgilerinde OIDC kullanmak, GitHub'ın kendi güvenlik rehberliğinde önerilen üç somut önlemdir. Bu üç önlem birbirini tamamlar: SHA pinleme tedarik zinciri riskini, izin daraltma blast-radius'u, OIDC ise kalıcı kimlik bilgisi tutma ihtiyacını azaltır.
Native kodda (C/C++) anahtar saklamak güvenli mi?
Hayır — Android'in güvenlik dokümanı native kodun bellek bozulması hatalarına (buffer overflow gibi) daha yatkın olduğunu belirtiyor; native tarafa taşımak decompile riskini ortadan kaldırmaz, yalnızca farklı bir hata sınıfı — bellek güvenliği — ekler. Bir anahtarı native kütüphanede string olarak tutmak, temel bir ikili analizle yine çıkarılabilir.
Secret scanning geçmiş commit'leri de tarar mı?
Evet — GitHub'ın secret scanning'i deponun tüm branch'lerindeki tüm Git geçmişini bilinen sır türleri için tarar; bu yüzden bir anahtarı sonradan sildiğin bir commit, geçmişte kaldığı sürece hâlâ tespit edilebilir durumdadır. Bu davranış, "sildim, sorun çözüldü" varsayımını geçersiz kılar — tek doğru adım geçmişi silmek değil, anahtarı derhal geçersiz kılmaktır.
Sızan bir anahtarı fark ettiğimde ilk adımım ne olmalı?
Önce anahtarı sağlayıcı panelinden geçersiz kıl ve yeni bir anahtarla değiştir; sonra hangi sistemlerin bu anahtarı kullandığını (mobil uygulama, backend, CI job'ları) güncelle. GitHub'ın kendi rehberliği de sızan bir credential için derhal rotasyonu öneriyor — geçmişi temizlemeye veya "kimse fark etmedi" varsayımına güvenme.
Güncelleme (Eylül 2026)
Bu yazının gövdesi 2025-10-16 tarihindeki araç ve dokümantasyon durumuna göre yazıldı. Eylül 2026'da GitHub tarafında iki somut değişiklik oldu; ikisi de doğrudan bu yazının konusuyla — mobil/CI sır sızıntısını engelleme — örtüşüyor:
- 9 Eylül 2026: GitHub, repository ruleset'lerine "pull request'lerde secret scanning alert'i açıkken merge'i engelle" kuralını ekledi (şu an public preview, GitHub Secret Protection/Advanced Security müşterileri için). Bypass izni olmayan geliştiriciler, merge edebilmek için her alert'i çözmek zorunda kalıyor. Bu kural push protection'dan farklı: push protection sırrı push anında yakalamaya çalışırken, bu yeni kural pull request katmanında ek bir engel katmanı ekliyor — push protection'ın kapalı bırakıldığı sır türlerinde (ör. jenerik desenler) bile bir güvenlik ağı sağlıyor (github.blog/changelog, 2026-09-09).
- 17 Eylül 2026: "Workflow execution protections", GitHub Enterprise/organizasyon/repository seviyesinde genel kullanıma açıldı (daha önce public preview'daydı). Bu özellik, bir Actions workflow'unu kimin tetikleyebileceğini ve hangi event'lerin başlatabileceğini tanımlayan bir allowlist kurmanı sağlıyor — "actor kuralları kimi, event kuralları neyi kapsar" mantığıyla çalışıyor ve GA ile birlikte workflow dosyası bazında hedefleme, denetim (insights) ve REST API üzerinden yönetim de eklendi. Aynı güncellemeyle, uygulanabilir bir event politikası henüz olmayan public repository'ler için
pull_request_targetevent'ini önce evaluate (gölge) modunda, otomatik zorlaması 2 Kasım 2026'da başlayacak şekilde varsayılan olarak devre dışı bırakan bir kural da devreye girdi: bu event, fork'tan gelen kodu base repository'nin secret'larına erişimle çalıştırabildiği için (yaygın adıyla "Pwn Request" zafiyeti), bu varsayılan değişiklik doğrudan sır sızıntısı riskini hedefliyor (github.blog/changelog, 2026-09-17). - Android'in resmi "Security tips" sayfası son olarak 2026-09-01'de güncellendi; sayfanın API anahtarı rehberliği — kaynak koduna commit etmeme, decompile riski, native kod uyarısı — bu yazının gövdesindeki tavsiyelerle aynı yönde kalıyor, çelişen bir değişiklik yok.
Bu üç değişikliğin ortak teması: GitHub, sır sızıntısını tek bir kontrol noktasında (push protection) yakalamaktan, hattın birden fazla katmanında (push, pull request, workflow tetikleme) yakalamaya doğru genişliyor. Bu yazıdaki "üç katman" çerçevesiyle aynı mantık — tek bir savunma hattına güvenme, birden fazla katmanı üst üste koy.
Sonuç
Mobil uygulamada sır yönetimi tek bir araç seçimi değil, üç katmanlı bir mimari kararı: derleme zamanında anahtarı kaynak koduna hiç yazmamak, çalışma zamanında yalnız donanım-bağlı anahtarları Keystore/Keychain'de tutmak, sunucu tarafında ise paylaşılan anahtarları istemciden tamamen uzak tutmak. CI/CD hattı bu üç katmanın kesişim noktası olduğu için SHA pinleme, daraltılmış GITHUB_TOKEN izni ve OIDC gibi önlemler ihmal edilemez; imzalama anahtarını ayrı ve dar izinli bir job'a taşımak, bu önlemler içinde en yüksek etkili adımdır.
Keychain API'sinin certificate pinning ile birlikte kullanımı için iOS Keychain ve Güvenlik yazısına, backend tarafında rate limit ve token rotation stratejileri için Mobil Backend API Güvenliği yazısına, genel iOS sertleştirme adımları için iOS Security Best Practices yazısına, Flutter'da Fastlane ile CI/CD kurulumu için Flutter CI/CD: GitHub Actions ve Fastlane yazısına ve genel CI/CD otomasyon prensipleri için Mobile DevOps Best Practices yazısına bakabilirsin.
Kaynaklar
- Android — Security tips — decompile riski, native kod uyarısı, kaynak koduna commit etmeme tavsiyesi; son güncelleme 2026-09-01.
- Apple Developer — Security documentation — Keychain Services'in donanım destekli veri saklama tanımı.
- GitHub Docs — Security hardening for GitHub Actions — action'ları tam commit SHA'sına pinleme, GITHUB_TOKEN izin daraltma, OIDC ile kısa ömürlü bulut kimlik bilgisi.
- GitHub Docs — Secret scanning — tüm Git geçmişinin taranması, partner bildirimleri, push protection.
- GitHub Changelog — Block pull requests with exposed secrets from merging — 9 Eylül 2026, PR merge engelleme kuralı.
- GitHub Changelog — Workflow execution protections generally available — 17 Eylül 2026, allowlist +
pull_request_targetvarsayılan kısıtlaması.

