GCP IAM Servis Hesabı Oluşturma ve Yönetimi
Google Cloud Platform’da güvenlik mimarisinin en kritik parçalarından biri olan servis hesapları, yanlış yapılandırıldığında ciddi güvenlik açıkları doğurabilir. Bir uygulamanın GCS bucket’ına erişmesi gerektiğinde, bir Compute Engine instance’ının Pub/Sub’a mesaj göndermesi gerektiğinde ya da CI/CD pipeline’ınızın deployment yapması gerektiğinde devreye giren bu kimlikler, insan kullanıcılardan farklı olarak makine kimliklerini temsil eder. Bu yazıda servis hesaplarını sıfırdan nasıl oluşturacağınızı, en iyi pratiklerle nasıl yöneteceğinizi ve üretim ortamında karşılaşacağınız gerçek senaryoları ele alacağız.
Servis Hesabı Nedir ve Neden Önemlidir?
Servis hesapları, GCP’de insan kullanıcıları değil uygulamaları ve sanal makineleri temsil eden özel kimlik türleridir. Bir e-posta adresi formatına sahip olurlar ([email protected]) ve bu onları hem tanımlanabilir hem de yönetilebilir kılar.
Önemli bir ayrımı baştan netleştirelim: Servis hesapları hem bir kimlik (principal) hem de bir kaynak (resource) olarak davranabilir. Bir servis hesabına rol atadığınızda onu kimlik olarak kullanıyorsunuzdur. Başka bir kullanıcıya o servis hesabını kullanma izni verdiğinizde ise onu kaynak olarak yönetiyorsunuzdur. Bu çift doğa, servis hesaplarını IAM mimarisinin en karmaşık bileşenlerinden biri yapar.
Her GCP projesinde bazı varsayılan servis hesapları otomatik olarak oluşturulur. Compute Engine default service account ve App Engine default service account bunların başında gelir. Ancak bu hesaplar genellikle fazla geniş izinlerle gelir ve üretim ortamında doğrudan kullanılmaları önerilmez.
Servis Hesabı Oluşturma
gcloud CLI ile Oluşturma
gcloud komutu servis hesabı yönetiminin temel aracıdır. Önce ortamınızı hazırlayalım:
# Aktif projenizi kontrol edin
gcloud config get-value project
# Projeyi belirleyin
gcloud config set project YOUR_PROJECT_ID
# IAM API'nin etkin olduğundan emin olun
gcloud services enable iam.googleapis.com
Şimdi bir servis hesabı oluşturalım. İyi bir isimlendirme kuralı belirlemek kritik öneme sahiptir. Ben genellikle {servis}-{ortam}-sa formatını kullanırım:
# Temel servis hesabı oluşturma
gcloud iam service-accounts create app-backend-prod-sa
--display-name="Backend Uygulama Prod Servis Hesabı"
--description="Production ortamında backend uygulaması için kullanılan servis hesabı"
--project=my-project-id
# Oluşturulan hesabı doğrulayın
gcloud iam service-accounts describe
[email protected]
Servis hesabı oluşturduktan sonra ona uygun roller atamamız gerekir. Burada en az ayrıcalık prensibini (principle of least privilege) uygulamak en kritik noktadır:
# Projeye rol atama - sadece gerekli olan Cloud Storage okuma rolü
gcloud projects add-iam-policy-binding my-project-id
--member="serviceAccount:[email protected]"
--role="roles/storage.objectViewer"
# Belirli bir bucket'a rol atama (proje geneli yerine kaynak bazlı - daha güvenli)
gcloud storage buckets add-iam-policy-binding gs://my-app-bucket
--member="serviceAccount:[email protected]"
--role="roles/storage.objectViewer"
Proje geneline rol atamak yerine kaynak bazlı atama yapmak çok daha güvenlidir. Uygulamanız sadece belirli bir bucket’a erişmesi gerekiyorsa, tüm projedeki storage’a değil sadece o bucket’a erişim verin.
Terraform ile Servis Hesabı Yönetimi
Üretim ortamlarında servis hesaplarını elle yönetmek yerine Infrastructure as Code yaklaşımıyla yönetmek gerekir. Terraform ile bir örnek görelim:
# main.tf dosyası içeriği - bash ile göstermek için cat kullanıyoruz
cat > main.tf << 'EOF'
resource "google_service_account" "app_backend" {
account_id = "app-backend-prod-sa"
display_name = "Backend Uygulama Prod Servis Hesabı"
description = "Production ortamında backend uygulaması için"
project = var.project_id
}
resource "google_storage_bucket_iam_member" "app_backend_storage" {
bucket = google_storage_bucket.app_bucket.name
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.app_backend.email}"
}
resource "google_project_iam_member" "app_backend_pubsub" {
project = var.project_id
role = "roles/pubsub.publisher"
member = "serviceAccount:${google_service_account.app_backend.email}"
}
EOF
# Terraform ile uygulama
terraform init
terraform plan
terraform apply
Servis Hesabı Anahtarları ve Güvenlik
Servis hesabı anahtarları (JSON key files) en çok yanlış kullanılan ve en büyük güvenlik risklerinden birini oluşturan bileşendir. Mümkün olduğunca anahtar kullanmaktan kaçının. Workload Identity, Compute Engine metadata server gibi alternatifleri tercih edin.
Ancak zorunlu durumlarda anahtar oluşturmanız gerekebilir:
# Servis hesabı anahtarı oluşturma (dikkatli kullanın!)
gcloud iam service-accounts keys create ~/keys/app-backend-prod-sa-key.json
--iam-account=app-backend-prod-sa@my-project-id.iam.gserviceaccount.com
--key-file-type=json
# Mevcut anahtarları listeleme
gcloud iam service-accounts keys list
--iam-account=app-backend-prod-sa@my-project-id.iam.gserviceaccount.com
# Anahtarı kullanarak authentication test etme
export GOOGLE_APPLICATION_CREDENTIALS=~/keys/app-backend-prod-sa-key.json
gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS
# Eski veya kullanılmayan anahtarı silme
gcloud iam service-accounts keys delete KEY_ID
--iam-account=app-backend-prod-sa@my-project-id.iam.gserviceaccount.com
Anahtar yönetimi için bazı kritik kurallar:
- Anahtarları asla Git repository’ye commit etmeyin.
.gitignoredosyanıza*.jsonekleyin veya daha iyisi git-secrets gibi araçlar kullanın - Secret Manager kullanın. Anahtarları environment variable veya dosya olarak değil, GCP Secret Manager’da saklayın
- Anahtar rotasyonu yapın. 90 günden uzun süre aynı anahtarı kullanmayın
- Kullanılmayan anahtarları silin. Her servis hesabının aktif anahtar sayısını minimize edin
Workload Identity Federation – Anahtarsız Authentication
Modern GCP mimarilerinde anahtar dosyası yerine Workload Identity kullanmak altın standarttır. Özellikle GKE üzerinde çalışan uygulamalar için:
# GKE cluster'da Workload Identity'yi etkinleştirme
gcloud container clusters update my-cluster
--workload-pool=my-project-id.svc.id.goog
--region=europe-west1
# Kubernetes service account ile GCP service account'u bağlama
gcloud iam service-accounts add-iam-policy-binding
[email protected]
--role roles/iam.workloadIdentityUser
--member "serviceAccount:my-project-id.svc.id.goog[my-namespace/my-ksa]"
# Kubernetes tarafında annotation ekleme
kubectl annotate serviceaccount my-ksa
--namespace my-namespace
iam.gke.io/gcp-service-account=app-backend-prod-sa@my-project-id.iam.gserviceaccount.com
Bu yaklaşımla pod’larınız herhangi bir JSON anahtar dosyası olmadan GCP servislerine erişebilir.
Servis Hesabı Taklidi (Impersonation)
Servis hesabı taklidi, bir kullanıcının veya başka bir servis hesabının geçici olarak başka bir servis hesabının kimliğini üstlenmesi işlemidir. Özellikle geliştirme ve test ortamlarında production servis hesaplarının davranışını simüle etmek için kullanılır:
# Bir kullanıcıya belirli bir servis hesabını taklit etme izni verme
gcloud iam service-accounts add-iam-policy-binding
[email protected]
--member="user:[email protected]"
--role="roles/iam.serviceAccountTokenCreator"
# Servis hesabını taklit ederek komut çalıştırma
gcloud storage ls gs://my-app-bucket
--impersonate-service-account=app-backend-prod-sa@my-project-id.iam.gserviceaccount.com
# Taklit edilen hesap için kısa süreli token oluşturma
gcloud auth print-access-token
--impersonate-service-account=app-backend-prod-sa@my-project-id.iam.gserviceaccount.com
Servis hesabı taklidi, serviceAccountTokenCreator rolüne sahip olmayı gerektirir. Bu rolü verirken dikkatli olun çünkü bir servis hesabını taklit edebilen biri, o hesabın tüm yetkilerini kullanabilir.
Servis Hesaplarını Denetleme ve İzleme
Servis hesaplarınızın ne yaptığını düzenli olarak denetlemek güvenlik açısından kritiktir. Cloud Audit Logs bu noktada en değerli kaynağınızdır:
# Belirli bir servis hesabının aktivitelerini Cloud Logging'den sorgulama
gcloud logging read
'protoPayload.authenticationInfo.principalEmail="[email protected]"'
--project=my-project-id
--limit=50
--format="json" | jq '.[].protoPayload.methodName'
# IAM policy değişikliklerini izleme
gcloud logging read
'protoPayload.serviceName="iam.googleapis.com" AND protoPayload.methodName:"SetIamPolicy"'
--project=my-project-id
--freshness=7d
# Servis hesabı anahtar oluşturma aktivitelerini izleme
gcloud logging read
'protoPayload.methodName="google.iam.admin.v1.CreateServiceAccountKey"'
--project=my-project-id
--freshness=30d
Kullanılmayan servis hesaplarını tespit etmek için IAM Recommender çok işe yarar:
# IAM Recommender'dan önerileri çekme
gcloud recommender recommendations list
--project=my-project-id
--location=global
--recommender=google.iam.policy.Recommender
--format="table(name,stateInfo.state,primaryImpact.securityProjection.details)"
# Policy Analyzer ile hangi hesabın hangi kaynağa erişebildiğini analiz etme
gcloud asset search-all-iam-policies
--scope=projects/my-project-id
--query="policy:[email protected]"
Gerçek Dünya Senaryoları
Senaryo 1: CI/CD Pipeline için Servis Hesabı
GitHub Actions üzerinde çalışan bir deployment pipeline’ı için servis hesabı kuruyorsunuz. Bu durumda Workload Identity Federation kullanarak anahtarsız bir yapı kurabilirsiniz:
# Workload Identity Pool oluşturma
gcloud iam workload-identity-pools create github-actions-pool
--project=my-project-id
--location=global
--display-name="GitHub Actions Pool"
# GitHub Actions için Provider oluşturma
gcloud iam workload-identity-pools providers create-oidc github-provider
--project=my-project-id
--location=global
--workload-identity-pool=github-actions-pool
--display-name="GitHub Provider"
--attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository"
--issuer-uri="https://token.actions.githubusercontent.com"
# CI/CD servis hesabı oluşturma ve bağlama
gcloud iam service-accounts create cicd-deploy-sa
--display-name="CI/CD Deployment Service Account"
--project=my-project-id
# Sadece belirli repository'den gelen isteklere izin verme
gcloud iam service-accounts add-iam-policy-binding
[email protected]
--role="roles/iam.workloadIdentityUser"
--member="principalSet://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/github-actions-pool/attribute.repository/my-org/my-repo"
# Deployment için gerekli roller
gcloud projects add-iam-policy-binding my-project-id
--member="serviceAccount:[email protected]"
--role="roles/run.admin"
gcloud projects add-iam-policy-binding my-project-id
--member="serviceAccount:[email protected]"
--role="roles/artifactregistry.writer"
Bu yapıyla GitHub Actions workflow’unuz herhangi bir JSON key olmadan GCP’ye deploy yapabilir.
Senaryo 2: Multi-Proje Erişimi
Büyük organizasyonlarda bir servis hesabının birden fazla projeye erişmesi gerekebilir. Standart yaklaşım, kaynak projesinde servis hesabı oluşturup hedef projelere erişim vermektir:
# Ana projede servis hesabı oluşturma
gcloud iam service-accounts create data-pipeline-sa
--project=source-project-id
--display-name="Data Pipeline Service Account"
# Hedef projedeki BigQuery'ye erişim verme
gcloud projects add-iam-policy-binding target-project-id
--member="serviceAccount:[email protected]"
--role="roles/bigquery.dataEditor"
# Hedef projedeki belirli bir dataset'e daha granüler erişim
bq add-iam-policy-binding
--member="serviceAccount:[email protected]"
--role="roles/bigquery.dataViewer"
target-project-id:my_dataset
Senaryo 3: Acil Durum – Servis Hesabını Devre Dışı Bırakma
Bir güvenlik ihlali şüphesi durumunda hızla aksiyon almanız gerekir:
# Servis hesabını hemen devre dışı bırakma
gcloud iam service-accounts disable
[email protected]
# Tüm anahtarları listeleme ve silme
for KEY_ID in $(gcloud iam service-accounts keys list
--iam-account=compromised-sa@my-project-id.iam.gserviceaccount.com
--format="value(name)"
--filter="keyType:USER_MANAGED"); do
gcloud iam service-accounts keys delete $KEY_ID
--iam-account=compromised-sa@my-project-id.iam.gserviceaccount.com
--quiet
done
# Servis hesabının son aktivitelerini audit log'dan inceleme
gcloud logging read
'protoPayload.authenticationInfo.principalEmail="[email protected]"'
--project=my-project-id
--freshness=48h
--format="json" | jq '.[].protoPayload | {method: .methodName, resource: .resourceName, time: .requestMetadata.requestAttributes.time}'
Servis Hesabı Yönetiminde En İyi Pratikler
Yıllar içinde öğrendiğim ve üretim ortamlarında uyguladığım pratikler şöyle sıralanabilir:
- Her uygulama için ayrı servis hesabı kullanın. Paylaşılan servis hesapları sorun tespitini zorlaştırır ve blast radius’u artırır
- Varsayılan servis hesaplarını kullanmayın.
[email protected]gibi hesaplar genellikle Editor rolüyle gelir, bu tehlikelidir - Anahtar dosyası yerine Workload Identity tercih edin. GKE, Cloud Run, Compute Engine üzerinde çalışan uygulamalar için anahtara gerek yoktur
- İsimlendirme kuralına uyun.
{uygulama}-{ortam}-saformatı operasyonel karmaşıklığı azaltır - Düzenli denetim yapın. IAM Recommender’ı aylık kontrol edin, kullanılmayan izinleri kaldırın
- Servis hesabı silmeyi düşünmeden önce devre dışı bırakın. Silinen hesabı geri getirmek mümkün değildir, devre dışı bırakmak geri dönüş kapısı açık bırakır
- Terraform veya Deployment Manager kullanın. Elle yapılan değişiklikler audit trail bırakmaz ve tutarsızlık yaratır
- Proje bazlı değil kaynak bazlı izin verin.
roles/storage.adminyerine belirli bucket’aroles/storage.objectAdminçok daha güvenlidir
Sonuç
GCP servis hesabı yönetimi, ilk bakışta basit görünen ama derinleştikçe nüansları ortaya çıkan bir konudur. Temel prensip her zaman aynı: uygulamanıza sadece ihtiyaç duyduğu kadar erişim verin, bu erişimi kaynak bazlı tutun ve kimlik bilgilerini (özellikle JSON key dosyalarını) mümkün olduğunca kullanmaktan kaçının.
Workload Identity Federation, bu alanda gerçek bir paradigma değişimi yaratmıştır. Artık CI/CD sistemlerinden GKE pod’larına kadar pek çok senaryo için anahtarsız authentication mümkündür. Bu imkanı kullanmamak için çok iyi bir nedeniniz olmadığı sürece, anahtar tabanlı authentication’ı legacy bir yaklaşım olarak değerlendirmenizi öneririm.
Son olarak, servis hesabı yönetimini bir kere yapıp bırakılan bir iş olarak görmemek gerekir. IAM Recommender’ı düzenli kontrol etmek, audit logları izlemek ve gereksiz izinleri temizlemek operasyonel sürecin kalıcı bir parçası olmalıdır. Güvenlik bir hedef değil, sürekli sürdürülen bir pratiktir.
