Bir banka iştiraki SaaS müşterimiz, AKS cluster’ını PCI DSS denetimi için hardening yapmak istedi. Mevcut cluster: 28 node, 340 pod, root-as-default container’lar, network policy yok, secret’lar plaintext envar olarak. 4 ay süren hardening sonunda: Pod Security Standards (restricted), Cilium Network Policy (deny-by-default), Workload Identity, Defender for Containers. Bu yazı o projeden notlar.
Tehdit Modeli
AKS cluster’ında düşülen güvenlik açıkları:
- Container escape: Privileged container kernel’a erişiyor, host’a bulaşıyor
- Lateral movement: Bir pod compromise olunca tüm cluster pod’larına erişiyor (network policy yok)
- Credential leak: Service principal credentials secret olarak, container içinden okunuyor
- Image vulnerability: Out-of-date base image, CVE’li paketler
- Excessive RBAC: Cluster-admin role çok kişiye verilmiş
- Sensitive data exposure: ConfigMap’lerde DB password
Pod Security Standards
Kubernetes 1.25+’da PodSecurityPolicy (PSP) deprecated. Yerine Pod Security Standards: namespace seviyesinde 3 profil: privileged, baseline, restricted.
| Profil | Kullanım |
|---|---|
| Privileged | Sistem workload (CSI driver, network plugin) |
| Baseline | Çoğu uygulama (ortalama güvenlik) |
| Restricted | Hardened uygulamalar (PCI/HIPAA) |
Banka uygulamalarında restricted şart. Namespace label ile enforce:
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
Restricted profil enforce edildiğinde:
- runAsNonRoot: true (root user yasak)
- readOnlyRootFilesystem: true (root FS read-only)
- allowPrivilegeEscalation: false (sudo yok)
- capabilities drop ALL
- seccompProfile: RuntimeDefault
- hostNetwork, hostPID, hostIPC: false
Bu kuralları sağlamayan pod deploy denenince admission controller block ediyor.
Container Hardening
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: registry.example.com/api:v2026.04
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
readOnlyRootFilesystem true ise uygulamanın yazma ihtiyaç duyduğu yerler emptyDir mount ile.
Network Policy: Deny-by-Default
Default’ta tüm pod’lar birbirine erişebilir. Network policy ile mikrosegmentasyon:
# Deny all egress (default)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# API pod'una sadece gateway pod'undan erişim
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-gateway
namespace: production
spec:
podSelector:
matchLabels:
app: api
ingress:
- from:
- podSelector:
matchLabels:
app: gateway
ports:
- port: 8080
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- port: 5432
- to: # DNS izni
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- port: 53
protocol: UDP
API pod’u sadece gateway’den ingress alır, sadece postgres + DNS’e egress yapar. Compromise olsa bile etki sınırlı.
Workload Identity: Secret-less Azure Auth
Eski yöntem: Service principal credentials secret olarak pod’a env. Compromise riski yüksek. Modern yaklaşım: Workload Identity. Pod, Azure AD federated identity ile direkt Azure kaynaklarına erişiyor, secret yok.
# AKS cluster Workload Identity enable
az aks update -g rg-banka-saas -n aks-prod
--enable-oidc-issuer
--enable-workload-identity
# Federated credential
az identity federated-credential create
--name api-federated
--identity-name id-api
--resource-group rg-banka-saas
--issuer $(az aks show -g rg-banka-saas -n aks-prod --query oidcIssuerProfile.issuerUrl -o tsv)
--subject system:serviceaccount:production:api-sa
# Service account
apiVersion: v1
kind: ServiceAccount
metadata:
name: api-sa
namespace: production
annotations:
azure.workload.identity/client-id: "550e8400-e29b-41d4-a716-446655440000"
---
# Pod
spec:
serviceAccountName: api-sa
containers:
- name: api
env:
- name: AZURE_CLIENT_ID
value: "550e8400-e29b-41d4-a716-446655440000"
Pod içinde DefaultAzureCredential() ile Key Vault, Storage, Cosmos DB’ye direkt auth, hiçbir secret yok.
Image Security: Scan + Signing
Azure Container Registry (ACR) image scan ile her push’ta CVE tarama. Defender for Containers ile findings:
# ACR image scan sonuç
az acr task run
--registry myregistry
--name image-scan
--image api:v2026.04
# Critical CVE varsa pipeline fail
az security assessment list
--resource-id /subscriptions/.../registries/myregistry/repositories/api/manifests/v2026.04
--query "[?status.code=='Unhealthy']"
Image signing (Notation + Cosign) ile sadece signed image deploy izinli. Unsigned image admission controller’da block.
Defender for Containers
Defender for Containers etkin: runtime threat detection (cryptominer, suspicious network call, container escape attempt), advisory + block. Sentinel’e log akar, SOC ekibi alarm alır.
Azure Policy ile Compliance Enforcement
# PCI DSS initiative atama
az policy assignment create
--name pci-dss-aks
--policy-set-definition "/providers/Microsoft.Authorization/policySetDefinitions/PCI_DSS_v4"
--scope /subscriptions/.../resourceGroups/rg-banka-saas
--enforcement-mode Default
Non-compliant resource’lar dashboard’da görünür, deny-by-policy ile yeni non-compliant resource oluşturulamaz.
Sahada Düşülen Üç Tuzak
- Hardening’i tek seferde uygulamak: Restricted profil aktif edilince mevcut pod’lar fail. Aşamalı: önce audit mode (sadece log), sonra warn, en son enforce.
- Network policy testi yapmamak: Yanlış selector ile prod pod’lar konuşamıyor. Önce dev/staging’de test, sonra prod.
- Workload Identity’yi tüm cluster’da değil tek namespace’te tutmak: Bazı namespace eski secret + service principal modelde kalıyor. Cluster genelinde migrate.
CloudSpark olarak AKS hardening, Pod Security Standards uygulama, Workload Identity migration, Network Policy tasarımı ve PCI DSS uyum projeleri için danışmanlık veriyoruz.



