GCP Cloud Storage Erişim Kontrolü ve İzin Yönetimi
Google Cloud Storage ile çalışırken en sık karşılaşılan sorunların başında “kim neye erişebilir?” sorusu geliyor. Yanlış yapılandırılmış bir bucket, ya kritik verileri dışarıya açık bırakır ya da geliştirici ekibini günlerce bloke eder. Bu yazıda GCP Cloud Storage erişim kontrolünü, IAM ile ACL arasındaki farkları ve gerçek dünya senaryolarında nasıl doğru izin yönetimi yapacağını ele alacağız.
Erişim Kontrolü Temel Kavramları
GCP Cloud Storage’da erişim kontrolü iki ana mekanizma üzerine kurulu:
- IAM (Identity and Access Management): Bucket ve proje seviyesinde çalışır. Politikalar kimlik bazlıdır ve “bu kullanıcı bu bucket’a ne yapabilir?” sorusunu yanıtlar.
- ACL (Access Control Lists): Nesne (object) seviyesinde çalışır. Daha ince taneli kontrol sağlar ama yönetimi karmaşıklaşabilir.
Modern GCP ortamlarında IAM önerilen yöntemdir. ACL, eski uygulamalar için hâlâ destekleniyor ancak yeni projelerde IAM ile başlamak çok daha sağlıklı.
Bir de “Uniform bucket-level access” diye bir kavram var. Bu mod etkinleştirildiğinde ACL’ler tamamen devre dışı kalır ve tüm erişim kontrolü IAM üzerinden yönetilir. Ciddi ortamlarda bu modu açık tutmanı tavsiye ederim; iki farklı sistemi aynı anda yönetmek baş ağrısı yaratır.
IAM Rolleri ve İzin Seviyeleri
GCP’de üç seviyede IAM politikası tanımlayabilirsin:
- Proje seviyesi: Tüm bucket’ları etkiler. Geniş kapsamlı, dikkatli kullan.
- Bucket seviyesi: Sadece ilgili bucket’ı etkiler.
- Nesne seviyesi: Tek bir dosyayı etkiler (yalnızca ACL ile, IAM desteklemez).
Temel Storage IAM Rolleri
- roles/storage.objectViewer: Nesneleri okuyabilir, listeleyebilir. CI/CD pipeline’larında artefakt okumak için ideal.
- roles/storage.objectCreator: Nesne oluşturabilir ama silemez. Log yazma servislerine vermek için uygun.
- roles/storage.objectAdmin: Nesneler üzerinde tam yetki. Silme dahil her şey.
- roles/storage.legacyBucketReader: Bucket meta verisini okuyabilir, nesneleri listeler.
- roles/storage.legacyBucketWriter: Yukarıdakilere ek olarak nesne oluşturabilir.
- roles/storage.legacyBucketOwner: Bucket üzerinde tam kontrol, ACL yönetimi dahil.
- roles/storage.admin: Hem bucket hem nesne yönetimi için tam yetki. Production’da kimseye vermekten kaçın.
gcloud CLI ile Temel İşlemler
Önce mevcut bir bucket’ın IAM politikasını görmekle başlayalım:
# Bucket IAM politikasını görüntüle
gcloud storage buckets get-iam-policy gs://my-production-bucket
# Daha okunabilir JSON formatında
gcloud storage buckets get-iam-policy gs://my-production-bucket
--format="json"
Bir kullanıcıya bucket üzerinde okuma yetkisi vermek için:
# Belirli bir kullanıcıya objectViewer rolü ver
gcloud storage buckets add-iam-policy-binding gs://my-production-bucket
--member="user:[email protected]"
--role="roles/storage.objectViewer"
# Servis hesabına objectCreator rolü ver
gcloud storage buckets add-iam-policy-binding gs://my-production-bucket
--member="serviceAccount:[email protected]"
--role="roles/storage.objectCreator"
# Bir grubu ekle (Google Workspace grubu)
gcloud storage buckets add-iam-policy-binding gs://my-production-bucket
--member="group:[email protected]"
--role="roles/storage.objectViewer"
Yetki kaldırmak için:
# Kullanıcının yetkisini kaldır
gcloud storage buckets remove-iam-policy-binding gs://my-production-bucket
--member="user:[email protected]"
--role="roles/storage.objectViewer"
Uniform Bucket-Level Access
Bu modu yeni oluşturduğun bucket’larda hemen etkinleştir:
# Yeni bucket oluştururken uniform access aç
gcloud storage buckets create gs://my-new-bucket
--location=europe-west1
--uniform-bucket-level-access
# Mevcut bucket'ta etkinleştir
gcloud storage buckets update gs://my-existing-bucket
--uniform-bucket-level-access
# Durumu kontrol et
gcloud storage buckets describe gs://my-existing-bucket
--format="json(iamConfiguration)"
Dikkat: Bu modu etkinleştirdikten sonra 90 gün içinde kapatabilirsin. 90 gün geçince kalıcı oluyor. Üretim ortamına geçmeden önce test ortamında dene.
Gerçek Dünya Senaryosu 1: CI/CD Pipeline İzinleri
Bir e-ticaret şirketinde çalıştığını düşün. Geliştirme ekibinin kullandığı CI/CD sistemi (Jenkins veya GitHub Actions) deployment artefaktlarını bir GCS bucket’ına yazıyor. Uygulama sunucuları ise bu artefaktları okuyor. İzinleri minimum yetki prensibine göre şöyle yapılandırabilirsin:
# CI/CD servis hesabı - sadece yazabilsin
gcloud storage buckets add-iam-policy-binding gs://cicd-artifacts-bucket
--member="serviceAccount:[email protected]"
--role="roles/storage.objectCreator"
# Uygulama sunucuları - sadece okuyabilsin
gcloud storage buckets add-iam-policy-binding gs://cicd-artifacts-bucket
--member="serviceAccount:[email protected]"
--role="roles/storage.objectViewer"
# DevOps ekibi grubu - tam yönetim (silme dahil)
gcloud storage buckets add-iam-policy-binding gs://cicd-artifacts-bucket
--member="group:[email protected]"
--role="roles/storage.objectAdmin"
# Mevcut politikayı doğrula
gcloud storage buckets get-iam-policy gs://cicd-artifacts-bucket
Bu yapıda CI/CD sistemi artefakt yazabiliyor ama silemez. Uygulama sunucusu okuyabiliyor ama değiştiremez. Sadece DevOps ekibi temizlik yapabilir. Gayet temiz bir yapı.
Gerçek Dünya Senaryosu 2: Farklı Ortamlar için İzin Yönetimi
Çoğu şirkette dev, staging ve production ortamları var. Her ortam için ayrı bucket ve ayrı izin politikası olmalı:
#!/bin/bash
# setup-storage-permissions.sh
PROJECT_ID="my-company-project"
ENVIRONMENTS=("dev" "staging" "prod")
for ENV in "${ENVIRONMENTS[@]}"; do
BUCKET="gs://myapp-${ENV}-data"
echo "Configuring permissions for ${ENV} environment..."
# Uniform access aç
gcloud storage buckets update "${BUCKET}"
--uniform-bucket-level-access
--project="${PROJECT_ID}"
# Geliştirici erişimi - sadece dev'de tam yetki
if [ "${ENV}" == "dev" ]; then
gcloud storage buckets add-iam-policy-binding "${BUCKET}"
--member="group:[email protected]"
--role="roles/storage.objectAdmin"
--project="${PROJECT_ID}"
else
# staging ve prod'da geliştiriciler sadece okuyabilir
gcloud storage buckets add-iam-policy-binding "${BUCKET}"
--member="group:[email protected]"
--role="roles/storage.objectViewer"
--project="${PROJECT_ID}"
fi
# Uygulama servis hesabı her ortamda aynı
APP_SA="app-${ENV}@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud storage buckets add-iam-policy-binding "${BUCKET}"
--member="serviceAccount:${APP_SA}"
--role="roles/storage.objectAdmin"
--project="${PROJECT_ID}"
echo "Done for ${ENV}"
done
Bu script’i bir kez çalıştırınca tüm ortamlar tutarlı bir izin yapısına kavuşuyor.
Koşullu IAM Politikaları (IAM Conditions)
GCP’nin güzel özelliklerinden biri, IAM politikalarına koşul ekleyebilmek. Mesela belirli bir prefix’e sahip nesnelere erişimi sınırlandırabilirsin:
# Sadece "reports/" prefix'li nesnelere erişim ver
gcloud storage buckets add-iam-policy-binding gs://company-data-bucket
--member="serviceAccount:[email protected]"
--role="roles/storage.objectViewer"
--condition='title=reports-only,description=Only reports folder access,expression=resource.name.startsWith("projects/_/buckets/company-data-bucket/objects/reports/")'
Bu özellikle çok kiracılı (multi-tenant) mimarilerde işe yarıyor. Her müşteri kendi klasörüne erişebilir, başkasının verisini göremez.
Signed URL ile Geçici Erişim
Bazen dış kullanıcılara ya da sistemlere geçici erişim vermek gerekiyor. Bunu IAM olmadan, signed URL ile yapabilirsin:
# 1 saatlik geçerli signed URL oluştur (indirme için)
gcloud storage sign-url gs://my-private-bucket/confidential-report.pdf
--duration=1h
--private-key-file=/path/to/service-account-key.json
# 24 saatlik yükleme URL'i
gcloud storage sign-url gs://my-upload-bucket/incoming/new-file.csv
--duration=24h
--method=PUT
--private-key-file=/path/to/service-account-key.json
--headers="Content-Type:text/csv"
Signed URL’ler denetim (audit) kaydına girmez, bu yüzden hassas veriler için dikkatli kullan. Kısa süreli tut, uzun süreli erişim gerekiyorsa IAM tercih et.
Public Erişim Yönetimi
Production bucket’larında public erişimi kapatmak kritik. GCP bunu proje seviyesinde engelleyebilir:
# Proje seviyesinde tüm public erişimi engelle
gcloud resource-manager org-policies set-policy
--project=my-project
iam_policy.json
# Belirli bir bucket'ta public erişimi kontrol et
gcloud storage buckets describe gs://my-bucket
--format="json(iamConfiguration.publicAccessPrevention)"
# Public erişimi bucket seviyesinde engelle
gcloud storage buckets update gs://my-sensitive-bucket
--no-public-access-prevention=false
# Public erişim engellini etkinleştir
gcloud storage buckets update gs://my-sensitive-bucket
--public-access-prevention
Yanlışlıkla “allUsers” ya da “allAuthenticatedUsers” olarak açılmış bucket’ları tespit etmek için:
# Projede public erişime açık bucket'ları listele
for bucket in $(gcloud storage ls); do
policy=$(gcloud storage buckets get-iam-policy "$bucket" --format="json" 2>/dev/null)
if echo "$policy" | grep -q "allUsers|allAuthenticatedUsers"; then
echo "UYARI: Public erisim tespit edildi: $bucket"
fi
done
Bu scripti haftalık cron job olarak çalıştırmak güzel bir güvenlik önlemi.
Servis Hesabı Anahtar Yönetimi
Servis hesapları GCS erişiminde en çok kullanılan kimlik türü. Ama anahtar dosyalarını yanlış yönetmek büyük güvenlik açığı oluşturur.
# Servis hesabı oluştur
gcloud iam service-accounts create storage-app-sa
--display-name="Storage Application Service Account"
--project=my-project
# Anahtar oluştur (mümkünse bu yöntemden kaçın, Workload Identity kullan)
gcloud iam service-accounts keys create ~/sa-key.json
[email protected]
# Mevcut anahtarları listele
gcloud iam service-accounts keys list
[email protected]
# Eski anahtarı iptal et
gcloud iam service-accounts keys delete KEY_ID
[email protected]
GKE veya Cloud Run kullanıyorsan Workload Identity tercih et. Anahtar dosyası olmadan servis hesabı yetkilerini kullanabilirsin. Anahtar dosyaları çalınabilir, kaybolabilir, versiyon kontrolüne yanlışlıkla commit edilebilir. Workload Identity bu risklerin hepsini ortadan kaldırır.
Audit Logging ile Erişim Takibi
Kimin neye eriştiğini izlemek compliance açısından zorunlu. GCS için data access audit loglarını etkinleştir:
# Proje için audit log politikasını görüntüle
gcloud projects get-iam-policy my-project
--format="json(auditConfigs)"
# Audit logging'i etkinleştirmek için policy dosyası oluştur
cat > audit-policy.json << 'EOF'
{
"auditConfigs": [
{
"service": "storage.googleapis.com",
"auditLogConfigs": [
{
"logType": "DATA_READ"
},
{
"logType": "DATA_WRITE"
},
{
"logType": "ADMIN_READ"
}
]
}
]
}
EOF
# Politikayı uygula
gcloud projects set-iam-policy my-project audit-policy.json
Logları Cloud Logging üzerinden sorgulayabilirsin:
# Son 1 saatteki GCS okuma işlemlerini listele
gcloud logging read
'resource.type="gcs_bucket" AND protoPayload.methodName="storage.objects.get"'
--limit=50
--freshness=1h
--project=my-project
--format="table(timestamp,protoPayload.authenticationInfo.principalEmail,protoPayload.resourceName)"
Bu sorgu ile kimin hangi nesneyi ne zaman okuduğunu görebilirsin. Güvenlik olayı sonrasında forensic analiz için bu loglar altın değerinde.
Terraform ile Erişim Yönetimi
Infrastructure as Code yaklaşımını benimsediysen Terraform ile GCS izinlerini yönetmek hem tutarlılık sağlar hem de değişiklikleri versiyon kontrolüne alır:
# Terraform konfigürasyonunu oluştur
cat > storage-iam.tf << 'EOF'
# Bucket IAM binding
resource "google_storage_bucket_iam_binding" "app_viewer" {
bucket = "my-production-bucket"
role = "roles/storage.objectViewer"
members = [
"serviceAccount:[email protected]",
"group:[email protected]",
]
}
resource "google_storage_bucket_iam_member" "cicd_creator" {
bucket = "my-production-bucket"
role = "roles/storage.objectCreator"
member = "serviceAccount:[email protected]"
}
EOF
# Plan kontrol et
terraform plan
# Uygula
terraform apply
google_storage_bucket_iam_binding ile google_storage_bucket_iam_member arasındaki farka dikkat et. binding kullandığında o roldeki tüm üyelerin listesini Terraform yönetir, manuel eklenen biri varsa sonraki apply’da silinir. member sadece belirtilen üyeyi yönetir, diğerlerine dokunmaz.
Yaygın Hatalar ve Çözümleri
Hata 1: “Permission denied” alınıyor ama IAM doğru görünüyor
En sık karşılaşılan durum. Olası nedenler:
- IAM propagation gecikmesi (birkaç dakika sürebilir, 2-3 dakika bekle)
- Proje seviyesinde kısıtlayıcı bir organizasyon politikası var
- Uniform bucket-level access açıkken nesne seviyesinde ACL ayarlanmaya çalışılıyor
# IAM politikasını kontrol et
gcloud storage buckets get-iam-policy gs://my-bucket
# Organizasyon politikalarını kontrol et
gcloud resource-manager org-policies list
--project=my-project
# Servis hesabının yetkilerini doğrula
gcloud iam service-accounts get-iam-policy
[email protected]
Hata 2: Public olmaması gereken bucket herkese açık
# Hemen kapat
gcloud storage buckets update gs://accidentally-public-bucket
--public-access-prevention
# allUsers ve allAuthenticatedUsers yetkilerini temizle
gcloud storage buckets remove-iam-policy-binding gs://accidentally-public-bucket
--member="allUsers"
--role="roles/storage.objectViewer"
Hata 3: Çok geniş proje seviyesi yetkiler
Geliştiricilere proje seviyesinde roles/storage.admin verilmişse bu tüm bucket’ları etkiler. Bunu bucket seviyesine indirgemek için proje politikasından çıkar, her bucket için ayrıca ekle.
Erişim Kontrolü Best Practice’leri
- Minimum yetki prensibini uygula. Her kimliğe sadece işini yapması için gerekli minimum yetki ver. Bir servis okuma yapıyorsa
objectVieweryeterli,objectAdminverme. - Servis hesaplarını amaçlarına göre ayır. Tek bir “tüm işleri yapan” servis hesabı yerine her uygulama veya fonksiyon için ayrı servis hesabı oluştur.
- Kullanıcılara değil gruplara yetki ver. Bireysel email adreslerine yetki vermek, kişi değişince sorun çıkarır. Google Workspace grupları üzerinden yönet.
- Uniform bucket-level access’i her zaman aç. Hem daha güvenli hem daha yönetilebilir.
- Public erişimi organizasyon politikasıyla engelle. Bucket seviyesinde bırakma, proje veya organizasyon seviyesinde merkezi olarak kapat.
- Audit logları mutlaka etkinleştir. Sonradan ne olduğunu anlayamazsan sorun çözemezsin.
- IAM politikalarını Terraform ile yönet. Manuel değişiklikler drifta yol açar, IaC ile tutarlılığı sağla.
- Signed URL sürelerini kısa tut. 1 saatten fazla gerekiyorsa IAM ile kalıcı erişim ver.
Sonuç
GCP Cloud Storage erişim kontrolü ilk bakışta karmaşık görünse de temel prensipleri oturtunca oldukça mantıklı bir yapısı var. IAM ve ACL arasında tercih yapmak durumundaysan modern projelerde her zaman IAM ve uniform bucket-level access ile başla. Servis hesaplarına minimum yetki ver, kullanıcıları gruplar üzerinden yönet, audit loglarını aç ve her şeyi Terraform ile kodla.
Güvenlik olaylarının büyük çoğunluğu yanlış yapılandırılmış erişim kontrollerinden kaynaklanıyor. “Çalışıyor mu?” diye test ettiğinde yeter değil, “fazla mı açık?” diye de sorgulamanı tavsiye ederim. Özellikle production ortamlarında her birkaç ayda bir IAM politikalarını gözden geçirmek, eski çalışanların servis hesaplarını ve gereksiz yetkileri temizlemek güvenlik hijyeninin temel parçası.
