Mobil uygulama geliştirme süreçlerinde CI/CD otomasyonu artık bir lüks değil, zorunluluk haline geldi. Özellikle Flutter ve Android projelerinde release sürecini Azure DevOps üzerinden yönetirken en kritik konulardan biri, keystore şifrelerinin güvenli şekilde saklanmasıdır. Pek çok geliştirici hâlâ key.properties dosyası içinde veya pipeline YAML dosyasında şifreleri hardcode ederek ilerliyor. Ancak bu yöntem hem güvenlik riski oluşturur hem de kurumsal projelerde ciddi açıklar doğurabilir.
Bu yazıda, Azure DevOps ile Flutter & Android CI/CD sürecinde keystore şifrelerini hardcode etmeden nasıl güvenli saklayabileceğinizi (Secure Variable kullanarak) adım adım ele alacağız.
Özellikle:
- Azure DevOps Secure Variables nedir?
- Pipeline içinde gizli değişkenler nasıl tanımlanır?
- Flutter & Android build sürecinde keystore bilgileri nasıl güvenli şekilde kullanılır?
- YAML pipeline yapısında güvenli konfigürasyon nasıl sağlanır?
gibi konulara teknik ve uygulanabilir örneklerle değineceğiz.
CI/CD sürecinde şifreleri doğrudan repoya eklemek; versiyon kontrol sistemlerinde kalıcı iz bırakır, ekip içi erişim risklerini artırır ve güvenlik denetimlerinde problem yaratır. Bunun yerine Azure DevOps Library ve Secure Variable mekanizması kullanarak hem güvenliği artırabilir hem de profesyonel bir DevOps mimarisi kurabilirsiniz.
Eğer siz de Flutter projenizde Android release build alırken keystore şifrelerini güvenli, ölçeklenebilir ve kurumsal standartlara uygun şekilde yönetmek istiyorsanız, bu rehber tam size göre.
Adım 1:
Öncelikle Android klasörü altında yer alan key.properties dosyasındaki bilgileri Azure DevOps ortamına secure variable olarak eklemek olacak.
Azure DevOps -> Pipelines -> Library altında projenizde kullandığınız variable group içerisindeki enviroment dosyanıza STORE_PASSWORD, KEY_PASSWORD ve KEY_ALIAS değerlerini ekleyin. Ardından value ifadelerinin yanındaki kilit ikonlarına tıklayarak eklediğiniz değişkenleri kilitleyin.

Adım 2:
İşimizin bittiği key.properties dosyasını artık silebiliriz .gitigone dosyasına mutlaka sildiğiniz dosyanın yolunu ekleyin:android/key.propertiesBir sonraki adımda key.jks dosyamızı Azure’a taşıyalım.
Adım 3:Azure DevOps -> Pipelines -> Library -> Secure Files sekmesine geçerek jks uzantılı key dosyanızı buraya ekleyin. Dosya ismini birazdan pipeline içerisinde kullanacağımız için dosya isimli önemlidir.
Adım 4:
Projenizin android -> app -> build.gradle dosyasında aşağıdaki değişikliklerin yapılması gerekiyor:
android {
…
def storePasswordValue = System.getenv("STORE_PASSWORD")
def keyPasswordValue = System.getenv("KEY_PASSWORD")
def keyAliasValue = System.getenv("KEY_ALIAS")
def storeFilePathValue = System.getenv("STORE_FILE")
signingConfigs {
release {
storeFile = file(storeFilePathValue)
storePassword = storePasswordValue
keyAlias = keyAliasValue
keyPassword = keyPasswordValue
}
}
…
}
Böylelikle build.gradle’a enviroment dosyası içerisinde yer alan secret keylerden alınacak değişken isimlerini vermiş olduk.
Adım 5:
Pipeline’ı konfigüre edelim. Pipeline tarafından yönetilen .yml uzantılı dosyamızda jobs ‘ın altında yer alan variables altına group olarak enviromentimizi tanımlayalım. Bunu bütün steplerdeki job altında yer alan variables içerisine uygulayın:
- group: ${{ variables.groupEnvPrefix }}${{ variables.environment }}
Eğer projeniz Flutter projesi ise pub get işleminin yapıldığı argumentten sonra jks dosyasının getirilmesi için task ekleyin:
- task: DownloadSecureFile@1
name: keystore
inputs:
secureFile: 'sensat.jks'
- script: |
echo "##vso[task.setvariable variable=STORE_FILE]$(keystore.secureFilePath)"
displayName: 'Set keystore path'
Son adım olarak release apk ve app bundle aldığınız taskların hemen peşinden key dosyalarının yolunu ilgili değişkenlere atamanız gerekmektedir:
- task: FlutterCommand@0
inputs:
projectDirectory: '.'
arguments: 'build apk --release'
env:
STORE_FILE: $(keystore.secureFilePath)
STORE_PASSWORD: $(STORE_PASSWORD)
KEY_PASSWORD: $(KEY_PASSWORD)
KEY_ALIAS: $(KEY_ALIAS)
Yapacağımız işlemlerin tümü bu kadar. Artık pipeline’ı çalıştırarak güvenli bir çıktı alabilirsiniz. Flutter & Android projelerinde CI/CD sürecini Azure DevOps üzerinden yönetirken keystore şifrelerini hardcode etmek kısa vadede pratik görünse de, uzun vadede ciddi güvenlik ve bakım problemleri oluşturur. Özellikle ekip büyüdükçe, repo erişimleri arttıkça ve farklı ortamlarda (dev, staging, prod) build alınmaya başlandığında bu risk katlanarak büyür.
CI/CD tarafında yapılan küçük ama doğru mimari kararlar, uzun vadede sizi büyük güvenlik açıklarından ve operasyonel sorunlardan korur. Eğer Flutter projelerinizi profesyonel seviyeye taşımak ve Android release süreçlerinizi kurumsal güvenlik standartlarına uygun hale getirmek istiyorsanız, Secure Variable kullanımı artık bir tercih değil, gerekliliktir.

















