AKS-Plattform: Security policy¶
Diese Seite beschreibt die Guardrails, die den Cluster und die Workloads darauf schützen: Azure Policy for Kubernetes, die Kyverno- Policies, network policies, namespace-Quotas, Image-Regeln und den Ausnahmeprozess. Workload-Teams begegnen diesen Regeln bei jedem Deployment.
Referenzdesign, dein Deployment kann abweichen
Die Zuweisungen auf der Azure-Seite stammen aus Terraform. Die Policies im Cluster (Kyverno, network policies, Quotas) stammen
aus den Manifesten, die in das Plattform-GitOps-Repository migriert wurden; die im Terraform-Repository verbliebenen Kopien sind
deprecated und dienen hier als Referenz für ihren Inhalt. Effekte (Audit oder Enforce) ändern sich pro Umgebung
und mit der Zeit. Frag dein Plattform-Team nach dem aktuellen Stand.
Defence in depth¶
| Stufe | Kontrolle |
|---|---|
| Azure | Azure-Policy-Zuweisungen auf der Ressourcengruppe, Defender for Cloud (optional), Diagnoseeinstellungen, Alerts |
| Cluster | Privater API-Server, nur Entra ID, managed identities, gehärtete Node Pools, Upgrade-Strategie |
| Admission | Azure-Policy-Add-on (Gatekeeper) für die eingebauten Initiativen von Microsoft, Kyverno für plattformdefinierte Validierung und Mutation |
| Runtime | Network policies, workload identity, Key Vault, TLS am Gateway |
Azure Policy und Defender¶
Der Azure-Policy-layer weist einer Ressourcengruppe diese eingebauten Definitionen zu (siehe den Hinweis zum Policy-Scope unter Architektur):
| Zuweisung | Effekt in der Referenzkonfiguration |
|---|---|
| Kubernetes cluster pod security baseline standards for Linux workloads | Variable azure_policy_baseline_effect, Audit in beiden Umgebungen. Der Kommentar sagt, nach einer Validierungsphase auf Deny zu wechseln. |
| Pod security restricted standards for Linux workloads (nur Production) | Audit |
| Kubernetes clusters should not allow container privilege escalation | Deny |
| Kubernetes clusters should be accessible only over HTTPS | Deny |
| Containers should not share host process ID or IPC namespace | Deny |
| Eigene Zuweisungen | Eine Map in der Konfiguration, standardmäßig leer (zum Beispiel „AKS must use a private API server“) |
Namespaces, die in den Referenzdateien von diesen Zuweisungen ausgenommen sind: kube-system, gatekeeper-system, azure-arc, kyverno,
gateway-system, monitoring.
Das Design sagt, die Baseline wird in Production durchgesetzt und in Non-production auditiert. Die Konfigurationsdateien setzen in
beiden Audit, prüfe also den tatsächlichen Effekt, bevor du dich darauf verlässt.
Optionale Schalter des layers, alle in den Referenzdateien aus:
| Schalter | Was er tut |
|---|---|
deploy_defender |
Defender-for-Cloud-Pläne Containers, KeyVaults und CloudPosture auf subscription-Ebene und einen Security Contact |
deploy_diagnostic_settings |
Diagnoseeinstellungen für die aufgelisteten Ressourcen an einen Log Analytics workspace |
deploy_security_alerts |
Eine Action Group mit E-Mail-Empfängern und Scheduled Query Alert Rules auf Log Analytics |
Defender for Containers wird auf Azure Local als nicht unterstützt beschrieben (AKS auf Azure Local).
Kyverno-Policies¶
Kyverno ist die empfohlene Policy-Engine für Admission-Regeln: YAML statt Rego, Validierung, Mutation und Generierung in einem Tool und Policy Reports als Kubernetes-Ressourcen. Es wird vom GitOps-Repository deployt und ist optional. Bis es deployt ist, liefert Azure Policy die Pod-Security-Baseline.
Der Policy-Lebenszyklus lautet: Entwurf (pull request, von Plattform und Security geprüft), dann Audit in Non-production, dann Enforce in Non-production nach 7 Tagen ohne neue Verstöße, dann Enforce in Production nach 14 stabilen Tagen. Alle Beförderungen sind pull requests.
Pod-Security- und Image-Kontrollen¶
| Kontrolle | Non-production | Production | Engine |
|---|---|---|---|
| Privilegierte Container blockieren | Enforce | Enforce | Azure Policy und Kyverno |
| hostPath, hostNetwork, hostPID, hostIPC blockieren | Enforce | Enforce | Azure Policy und Kyverno |
| Privilege Escalation blockieren | Enforce | Enforce | Azure Policy und Kyverno |
| Resource Requests und Limits verlangen | Enforce | Enforce | Kyverno |
| Freigegebene Registries verlangen | Enforce | Enforce | Kyverno |
runAsNonRoot verlangen |
Audit | Enforce | Kyverno |
| Alle Capabilities entfernen | Audit | Enforce | Kyverno |
seccomp RuntimeDefault verlangen |
Audit | Enforce | Kyverno |
Den tag latest blockieren |
Audit | Enforce | Kyverno |
| Read-only Root File System | Audit | Audit | Kyverno |
Die Tabelle ist das Design. Die Kyverno-Manifeste im Repository tragen alle validationFailureAction: Audit; der
Unterschied zwischen Production und Non-production soll über Umgebungswerte im GitOps-Repository gesetzt werden.
Freigegebene Registries sind die Container Registry der Organisation (*.azurecr.io) und mcr.microsoft.com.
Kyverno kann Pods auch mutieren, damit Teams sichere Defaults nicht selbst setzen müssen: runAsNonRoot, keine Privilege Escalation,
seccomp RuntimeDefault, alle Capabilities entfernen. Das Repository enthält Mutations-Policies für Non-root, entfernte Capabilities
und seccomp.
Image-Regeln (Design)¶
| Anforderung | Non-production | Production |
|---|---|---|
| Images nur aus freigegebenen Registries | Enforce | Enforce |
| Vulnerability Scan, critical und high | Warnen | Blockieren (high, sofern nicht akzeptiert) |
| Image-Signierung und SBOM | Nicht erforderlich | Empfohlen, künftig |
Images werden von der Kubelet-Identität mit der Rolle AcrPull gezogen, sodass im Cluster keine Pull Secrets gespeichert sind.
Network policies¶
Jeder Anwendungs-namespace bekommt default deny für Ingress und Egress, und danach explizite Freigaben aus dem Basissatz:
| Policy | Effekt |
|---|---|
default-deny-all |
Blockiert gesamten Ingress und Egress |
allow-dns |
Egress zu kube-dns |
allow-ingress-from-gateway |
Ingress vom Gateway-namespace zu Anwendungs-Pods |
allow-egress-to-private-endpoints |
Egress zum Subnet der private endpoints auf den Ports 443, 5432 und 6379 |
allow-prometheus-scrape |
Ingress von den Prometheus-Pods im Monitoring-namespace auf den Ports 9090, 8080, 9394 |
Teams ergänzen eigene Policies für Aufrufe zwischen namespaces und für spezifischen Egress. NetworkPolicy steuert den East-West-Traffic im Cluster; eine Firewall (sofern vorhanden) steuert den North-South-Traffic und den Traffic zwischen spokes.
Note
Die Policy für private endpoints enthält den CIDR des private-endpoint-Subnets des Clusters und unterscheidet sich daher pro Umgebung.
Der Load Test ergänzt eigene Policies für den namespace load-testing und für die Zielports (Load testing).
Namespace-Baseline¶
Jeder Team-namespace bekommt aus dem GitOps-Repository eine Resource Quota und eine Limit Range.
| Einstellung | Non-production-Overlay | Production-Overlay |
|---|---|---|
| Requests CPU / Memory | 8 / 16 GiB | 2 / 4 GiB |
| Limits CPU / Memory | 16 / 32 GiB | 4 / 8 GiB |
| Pods | 100 | 30 |
| Basis-Defaults | 4 CPU / 8 GiB Requests, 8 CPU / 16 GiB Limits, 50 Pods, 10 Services, 10 Persistent Volume Claims, 20 Secrets, 20 Config Maps |
Container-Defaults aus der Limit Range: Request 100m CPU und 128 MiB, Limit 500m CPU und 512 MiB; Minimum 50m und 64 MiB, Maximum 4 CPU und 8 GiB pro Container, 8 CPU und 16 GiB pro Pod.
Prüfe das Production-Overlay
In den deprecated Overlays ist die Production-Quota kleiner als die Non-production-Quota. Das kann gewollt sein (kleine anfängliche namespaces) oder ein vertauschter Wert. Maßgeblich sind die Werte im GitOps-Repository.
Namespaces werden nur über GitOps erstellt; das Erstellen mit kubectl wird für Nicht-Plattform-Subjects per Admission Policy
blockiert (Design). Jeder neue namespace wird mit der Quota, der Limit Range, der Default-deny network policy und
den Role Bindings bereitgestellt. Das Design macht diese Labels verpflichtend:
| Label | Zweck |
|---|---|
<labelDomain>/team |
Team-Zuständigkeit |
<labelDomain>/environment |
dev, test, accp oder prod |
<labelDomain>/type |
application oder platform |
<labelDomain>/data-classification |
public, internal, confidential oder restricted |
<labelDomain>/security-tier |
standard oder high |
<labelDomain>/cost-center |
Kostenverfolgung |
Ein Owner-Kontakt und die Art, wie der namespace erstellt wurde, sind verpflichtende Annotations. Die Kyverno-Policy im Repository prüft nur die Labels Team und Environment, der genaue verpflichtende Satz hängt also von der Version des GitOps-Repositorys ab.
Secrets im Cluster¶
| Regel | Durchsetzung (Design) |
|---|---|
| Keine Klartext-Secrets in Git | Pre-Commit-Scanning und serverseitiger Push-Schutz |
| Key Vault gegenüber Kubernetes Secrets bevorzugen | Leitfaden |
| Keine Secrets in Config Maps | Kyverno, Audit |
Nur die Secret-Typen Opaque und TLS |
Kyverno, Audit |
Rotation übernehmen die Rotation Policies von Key Vault, und die Anwendung liest den aktuellen Wert mit dem SDK.
Policy-Ausnahmen¶
Eine Ausnahme nimmt einen Workload für begrenzte Zeit von einer Policy aus.
- Das Team öffnet im Plattform-GitOps-Repository einen pull request, der eine
PolicyExceptionergänzt (eine Liste in den Umgebungs- werten). Die Beschreibung nennt die Begründung. - Das Security-Team prüft und genehmigt. Das Plattform-Team merged, und Argo CD deployt sie.
- Vierteljährliches Review: mit Begründung verlängern oder entfernen.
| Regel | Detail |
|---|---|
| Ablauf | Jede Ausnahme hat ein Ablaufdatum, höchstens 90 Tage, mit erneuter Genehmigung verlängerbar |
| Scope | Ein namespace und Workload, nie clusterweit |
| Metadaten | Owner, Genehmiger, Grund, Risiko, kompensierende Maßnahmen, Ticket-Referenz |
| Nachverfolgung | Policy Reports zeigen, welche Workloads unter einer Ausnahme laufen |
Siehe auch Policies und Ausnahmen für die Azure-Policy-Ausnahmen der MCP- Plattform selbst.