CI/CD’DE SECRETS MANAGEMENT: GÜVENLİ SECRET YÖNETİMİ VE ANTİ-PATTERN’LER
CI/CD hattınız saniyeler içinde üretime deploy edebilir; ama bir secret yanlış yerde saklandıysa aynı hızla felaketi de üretir. “Token’ı env var’a koyduk, bitti” yaklaşımı çoğu zaman geriye dönük iz sürmeyi, erişim kontrolünü ve güvenli döngü yönetimini görünmez kılar.
Secrets management, sadece “gizli değerleri saklamak” değildir; secret’ın yaşam döngüsü (oluşturma, dağıtma, kullanma, döndürme, iptal etme) ve gözlemlenebilirliği (kim erişti, ne zaman, hangi kapsamda) birlikte ele alınır. Bu yazıda güvenli secret yönetimi için pratik bir çerçeve kuracak, CI/CD’de sık görülen anti-pattern’leri ve gerçekçi örnekleri konuşacağız.
Eğer ekibiniz DevOps pratiklerini olgunlaştırmak ve pipeline güvenliğini sistematik hale getirmek istiyorsa, CI/CD ve DevOps eğitimi içeriğine de göz atabilirsiniz.

Primary yaklaşım: CI/CD secrets management neden ayrı bir disiplin?
“CI/CD secrets management” pratikte üç problem alanını aynı anda çözer: saklama (at-rest şifreleme ve erişim), taşıma (in-transit güvenlik ve scope), kullanım (runtime’da minimum yetkiyle tüketim). Bu üçlüden birini zayıf bırakırsanız, diğer ikisi tek başına yeterli olmaz.
Secret nedir, credential nedir?
Secret genellikle API anahtarı, DB parolası, OAuth client secret, signing key gibi doğrudan yetki veren değerlerdir. Credential ise bazen daha geniş bir pakettir: token + süre + kapsam + kimlik doğrulama yöntemi. Modern mimarilerde hedef, mümkün olduğunca “kalıcı secret” yerine kısa ömürlü credential kullanmaktır.
Yaşam döngüsü ve sahiplik
Secret’ların kimin tarafından üretildiği, kim tarafından kullanıldığı ve ne zaman döndürüldüğü net değilse, olay anında karar almak zorlaşır. Bir secret’ın sahibi (owner) olmalı; rotation politikası ve iptal (revoke) prosedürü tanımlı olmalıdır.
Tehdit modeli: CI/CD hattında secret nasıl sızar?
Önce en sık görülen sızıntı kanallarını netleştirelim. CI/CD ortamları genellikle çok sayıda entegrasyona ve log üreten araca sahiptir; bu da “en zayıf halka” riskini büyütür.
Log’lar, artifact’ler ve debug çıktıları
Pipeline log’ları, hata ayıklama çıktıları ve build artifact’leri (örn. paketlenmiş config dosyaları) secret sızıntısının en yaygın kaynağıdır. Masking çoğu zaman yeterli değildir; bazı değerler farklı formatlarda log’a düşebilir veya base64 gibi dönüşümler masking’i bypass edebilir.
Yanlış scope: paylaşılan runner ve aşırı yetki
Paylaşılan runner’larda (self-hosted veya multi-tenant) job izolasyonu zayıfsa, başka bir job secret’lara erişebilir. Ayrıca “işi garantileyelim” diye verilen geniş IAM yetkileri, tek bir pipeline açığının hesabı ele geçirmesine yol açabilir. Burada hedef least privilege ve ephemeral erişimdir.
Supply chain: bağımlılıklar ve third-party action/plug-in’ler
CI/CD aşamasında kullanılan action, plugin ve container imajları, secret’ların işlendiği en kritik noktalardır. Sabitlenmemiş sürümler (unpinned), doğrulanmamış imajlar veya geniş network erişimleri, sızıntı riskini yükseltir.
Güvenli temel prensipler: saklama, erişim, rotasyon, denetim
Güvenli secret yönetimini dört temel ilkeye bağlayabilirsiniz: Merkezi ve kontrollü saklama, dinamik/kimlik tabanlı erişim, rotation ve audit.
Merkezi kasa: Vault / cloud secret manager
Bir secret kasası, at-rest şifreleme, policy tabanlı erişim, denetim izi ve sürümleme gibi özellikleri tek yerde toplar. HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GCP Secret Manager gibi seçenekler bu ihtiyaca yanıt verir.
Kimlik tabanlı erişim: statik secret yerine federasyon
CI job’un kendisini bir “kimlik” gibi doğrulamak, statik anahtarları azaltır. Örneğin OIDC ile CI ortamından bulut sağlayıcıya federasyon yaparak kısa ömürlü token/role alabilirsiniz. Böylece repo secret’larına uzun ömürlü access key koymak yerine, job runtime’da yetkisini “talep eder”.
Rotation: planlı döndürme ve otomatik iptal
Rotation sadece belirli aralıklarla parola değiştirmek değildir; eski credential’ın iptali, uygulamaların kesintisiz geçişi ve geri dönüş planıyla birlikte düşünülmelidir. Kritik secret’larda kısa TTL ve otomatik revoke, olgunluğun güçlü göstergesidir.
Audit: kim, neye, ne zaman erişti?
Denetim izi olmadan olay analizi “tahmin”e dönüşür. Secret kasasının audit log’ları SIEM’e akmalı; pipeline tarafında da hangi job’un hangi kapsamla secret tükettiği izlenmelidir.
Anti-pattern’ler: “çalışıyor” ama risk üretiyor
CI/CD’de secret yönetimi hatalarının çoğu niyetle değil, pratik kolaylıkla ortaya çıkar. Aşağıdaki anti-pattern’ler, küçük ekiplere başlangıçta “hız” kazandırsa da ölçeklendikçe maliyetli güvenlik borcu biriktirir.
Anti-pattern 1: Secret’ı repoya koymak (şifreli olsa bile)
Şifreli dosya (ör. base64, basit şifreleme) repoda tutulduğunda anahtar yönetimi ayrıca bir problem olur. Üstelik commit geçmişi, fork’lar ve üçüncü taraf erişimleri riski büyütür. Eğer GitOps zorunluysa, SOPS gibi araçlarla policy ve anahtar yönetimi sıkı kurgulanmalıdır.
Anti-pattern 2: Build sırasında secret’ı image içine gömmek
Docker build aşamasında secret eklemek, imaj layer’larına sızdırabilir. Daha sonra bu imaj registry’de dolaşır, taranır ve paylaşıma açılır. Build secret’ları için BuildKit secret mount gibi mekanizmalar kullanılmalı; runtime secret injection tercih edilmelidir.
Anti-pattern 3: Uzun ömürlü cloud access key’lerini CI secret olarak saklamak
Bir access key sızdığında etkisi büyüktür. OIDC federasyon, kısa ömürlü role assumption ve kısıtlı policy’ler bu riski dramatik biçimde azaltır. Burada hedef: “repo secret” değil “repo identity”.
Anti-pattern 4: Her ortama aynı secret
Dev/stage/prod aynı anahtarı kullanıyorsa, daha zayıf ortam üzerinden prod’a geçiş kolaylaşır. Ortam bazlı ayrıştırma, ayrı policy ve ayrı rotation ritmi şarttır.
Anti-pattern 5: Masking’e güvenmek ve log’lara secret basmak
Masking kuralları kaçırılabilir, farklı encoding’ler masking’i aşabilir. En iyi yaklaşım, secret’ın log’a hiç düşmemesidir. “Debug için bir kere yazdık” cümlesi genelde en pahalı cümledir.
Uygulama örneği: GitHub Actions + OIDC ile bulutta kısa ömürlü yetki
Bu senaryoda amaç, GitHub Actions job’unun bulut sağlayıcıdan kısa ömürlü yetki alması ve ardından secret’ı kasadan çekmesidir. Böylece repo seviyesinde uzun ömürlü cloud anahtarı tutmamış oluruz.
GitHub Actions workflow (OIDC ile role assumption)
Aşağıdaki örnek, OIDC token’ı kullanarak bir role üstlenme (assume role) yaklaşımını temsil eder. Adımlar sağlayıcıya göre değişir; mantık aynıdır: job kimliği doğrulanır, sınırlı yetkiyle kısa süreli oturum açılır.
name: deploy
on:
push:
branches: [ "main" ]
permissions:
id-token: write
contents: read
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure cloud credentials via OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/ci-deploy-role
aws-region: eu-central-1
- name: Fetch secret from secret manager
run: |
set -euo pipefail
DB_PASSWORD=$(aws secretsmanager get-secret-value --secret-id prod/app/db --query SecretString --output text)
echo "DB_PASSWORD is loaded (not printed)."
./deploy.sh
Bu örnekte kritik nokta, pipeline’ın kalıcı access key kullanmaması ve role policy’sinin yalnızca gerekli secret’lara erişecek şekilde sınırlandırılmasıdır. Ek olarak, deploy script’inin çıktılarında secret’ın görünmemesi için standart çıktı disiplinine ihtiyaç vardır.
Policy tasarımı: minimum yetki ve dar kapsam
- Role sadece gerekli secret path’lerine erişebilmeli.
- Network egress, yalnızca secret kasası ve gerekli deployment endpoint’leri ile sınırlandırılmalı.
- CI job’larının ortam bazlı ayrımı (prod vs stage) farklı role ve farklı policy ile yapılmalı.
Kubernetes tarafı: secret’ı runtime’da enjekte etmek ve merkezi yönetmek
Kubernetes’te “Secret” objesi çoğu zaman ilk durak olur; ancak salt Kubernetes Secret kullanmak, merkezi denetim ve rotation için yeterli olmayabilir. Bu noktada External Secrets Operator, CSI Secret Store veya Vault Agent gibi çözümler devreye girer.

External Secrets Operator ile kasadan çekme
Aşağıdaki örnek, uygulamanın ihtiyaç duyduğu değerin doğrudan git’te tutulmadan, kasadan senkronize edilmesini anlatır. Gerçek konfigürasyon sağlayıcıya göre değişir; hedef, secret kaynağının merkezi kasada olmasıdır.
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: app-db
spec:
refreshInterval: 1h
secretStoreRef:
name: prod-secret-store
kind: ClusterSecretStore
target:
name: app-db-secret
creationPolicy: Owner
data:
- secretKey: DB_PASSWORD
remoteRef:
key: prod/app/db
property: password
Bu yaklaşım, rotation ve erişim denetimini merkezi kasaya taşır. Kubernetes tarafında ise RBAC ile hangi namespace’in hangi secret’a erişeceği kontrol edilir.
Rotation stratejisi: kesintisiz geçiş
Rotation uygulanırken iki risk ortaya çıkar: uygulamaların yeni değeri zamanında alamaması ve eski değerin iptal edilmesiyle kesinti. Daha olgun bir tasarım için:
- Secret’ı versiyonlu yönetin (v1/v2) veya çift anahtar yaklaşımı kullanın.
- Uygulamada yeniden yükleme (reload) veya graceful restart mekanizması olsun.
- Eski değeri hemen iptal etmek yerine geçiş penceresi tanımlayın; sonra revoke edin.
Pratik kontrol listesi: CI/CD’de güvenli secret tasarımı
Aşağıdaki kontrol listesi, hızlı bir “neredeyiz?” değerlendirmesi sunar. Hedef, bir kerelik sertleştirme değil; sürdürülebilir bir süreçtir.
Pipeline tarafı
- Secrets kasadan runtime’da çekiliyor, repoda tutulmuyor.
- OIDC/federasyon varsa uzun ömürlü access key’ler kaldırılmış.
- Runner izolasyonu ve network egress sınırları tanımlı.
- Log’larda secret sızıntısını önleyen kurallar ve testler mevcut.
Uygulama ve platform tarafı
- RBAC ve namespace ayrımı ile erişim yüzeyi daraltılmış.
- Secret rotation planı, geçiş penceresi ve otomasyonları belirlenmiş.
- Audit log’lar merkezi izleme/SIEM sistemine akıyor.
Anti-pattern avcılığı
Ekibinizde düzenli aralıklarla anti-pattern taraması yapmak, güvenlik borcunu erken yakalar. Örnek taramalar:
- Repo taraması: geçmiş commit’lerde secret izleri
- Pipeline taraması: build output ve artifact içinde secret
- Cloud taraması: kullanılmayan access key, fazla yetkili role/policy
Sonuç: “secret saklamak” değil, güvenli akış tasarlamak
CI/CD’de secret yönetimi, tek bir araca indirgenemez. Asıl kazanım, kimlik tabanlı erişim, minimum yetki, rotation ve denetim izini bir araya getiren uçtan uca bir akış kurmaktır. Bu akış kurulduğunda, hem sızıntı riski azalır hem de olay anında “kim ne yaptı?” sorusuna hızlı yanıt verilebilir.
Başlangıç için en yüksek kaldıraç noktası genellikle şudur: uzun ömürlü anahtarları kaldırın, OIDC/federasyon ile kısa ömürlü yetkiye geçin ve secret’ları merkezi kasadan runtime’da tüketin. Böylece CI/CD hattınız hız üretirken güvenliği de otomatikleştiren bir sisteme dönüşür.


