In vielen Microsoft-Entra-ID-Tenants, die ich betreue, wuchern die Conditional-Access-Richtlinien mit der Zeit zu einem regelrechten Dickicht zusammen. Irgendwann weiß niemand mehr genau, wer wann welche Regel geändert hat, welche Anpassungen tatsächlich beabsichtigt waren und ob die Dokumentation noch zum Ist-Zustand passt. An dieser Stelle hilft mir „Conditional Access as Code“ in der Praxis weiter. Dabei behandle ich CA-Policies wie Software-Code. Sie werden exportiert, versioniert, im Review geprüft und automatisiert über eine Pipeline ausgerollt. Damit werden Änderungen nachvollziehbar, die Qualität steigt, und mit Schattenänderungen direkt im Portal ist Schluss.
Der Export mit Microsoft Graph PowerShell bildet den Ausgangspunkt
Zuerst gilt es, alle vorhandenen Conditional-Access-Policies strukturiert zu erfassen. Dafür nutze ich das Microsoft Graph PowerShell SDK. Voraussetzung sind die Rolle Security Administrator oder Global Administrator sowie die Berechtigung Policy.Read.All. Mit den folgenden Befehlen exportiere ich sämtliche Policies als JSON:
# PowerShell 7, Microsoft.Graph-Modul installiert
gc
Connect-MgGraph -Scopes "Policy.Read.All"
Get-MgIdentityConditionalAccessPolicy | ConvertTo-Json -Depth 10 > .\ConditionalAccessPolicies.json
Das läuft zuverlässig, Details dazu stehen in meinem Beitrag Microsoft 365 automatisieren mit dem Microsoft Graph PowerShell SDK: Der Alltag nach AzureAD und MSOnline. Die JSON-Datei gehört idealerweise direkt ins Git-Repository. Dann wird jede Änderung an den Richtlinien zu einem Commit, und Pull Requests sowie Code-Reviews werden möglich. Niemand kann das Produktivsystem mehr unbemerkt umstellen, während die Dokumentation still und leise veraltet.
Mit Conditional Access as Code durchläuft jede Änderung Review und Drift-Kontrolle
Sobald der JSON-Export als maßgebliche Quelle (Single Source of Truth) dient, prüfe ich Richtlinienänderungen im Git-Repo wie jede andere Codeänderung. Jeden Pull Request lesen Kollegen gegen. Riskante Fehler, etwa zu großzügige Ausnahmen oder versehentlich deaktivierte Regeln, fallen dadurch früh auf. Über den Git-Diff kann ich zudem jederzeit nachvollziehen, wann und warum eine Policy angepasst wurde. Um Drift zwischen Repo und Tenant zu erkennen, exportiere ich die Richtlinien regelmäßig neu und vergleiche das Ergebnis mit dem Haupt-Branch. Dafür eignet sich zum Beispiel ein zeitgesteuerter Job in Azure Pipelines oder GitHub Actions.
Aus meinen Projekten weiß ich, dass sich die Drift-Erkennung schnell bezahlt macht. Viele Änderungen werden „mal eben schnell“ im Portal erledigt. Durch den regelmäßigen Abgleich mit dem Repo fallen solche Abweichungen sofort auf, und ich kann gezielt nachhaken.
Eine Pipeline mit Workload Identity Federation rollt die Richtlinien getestet aus
Neue oder geänderte Conditional-Access-Policies sollen nicht per Mausklick, sondern automatisiert in den Tenant gelangen. Ich setze dafür Pipelines ein, die sich per Workload Identity Federation bei Entra ID anmelden. Ein Client Secret braucht es dann nicht mehr, was das Risiko durch statische Zugangsdaten senkt. In Azure DevOps oder GitHub Actions binde ich PowerShell-Skripte ein, die die Policy-Änderungen über Graph einspielen (API-Dokumentation).
Besonders wichtig ist mir, dass Richtlinien zunächst im Report-only-Modus ausgerollt werden. So lässt sich ablesen, wie die Policy wirken würde, ohne im Produktivbetrieb etwas zu blockieren. Aktiviert wird sie erst, wenn ich Logs und Testergebnisse ausgewertet habe. Für automatisierte Tests gibt es Community-Tools wie Maester, die Policies auf Best Practices und Kompatibilität prüfen. Vor dem Rollout ist eine solche Prüfung ausgesprochen hilfreich.
Die Entra-Audit-Logs zeigen, wer eine Richtlinie geändert hat
Auch wenn alles als Code verwaltet wird, kommt man um die klassische Protokollierung nicht herum. Im Entra Admin Center → Überwachung & Integrität → Auditprotokolle (Kategorie: Richtlinie) sehe ich für Conditional Access, wer welche Policy wann geändert, erstellt oder gelöscht hat. Macht ein Rollout Probleme oder tauchen ungeplante Änderungen auf, lässt sich hier am schnellsten klären, wer verantwortlich ist. Zusätzlich kann man die Audit-Logs nutzen, um automatisiert auf Policy-Änderungen zu reagieren, zum Beispiel mit Benachrichtigungen.
Die folgende Übersicht zeigt, wie die Bausteine von Conditional Access as Code in der Praxis ineinandergreifen, vom Tenant über das Review bis zum Deployment:
flowchart LR
Entra["Entra ID Tenant"] --> Export["Export Policies (Graph PowerShell)"]
Export --> Git["Git Repository"]
Git --> Review["Pull Request Review"]
Review --> Pipeline["Pipeline Deployment"]
Pipeline --> Entra
Pipeline --> Test["Report-only, Testing"]
Git --> Drift["Drift Detection"]
Abbildung: CA as Code mit Export, Review, Deployment und Drift-Erkennung im Überblick.
Weniger Wildwuchs bringt spürbar mehr Qualität ins Richtlinienmanagement
Conditional Access as Code ist kein Selbstzweck. Mir hilft der Ansatz, endlich Ordnung und Nachvollziehbarkeit in das Richtlinienmanagement zu bringen und die Qualität zu verbessern. Davon profitieren auch kleinere Umgebungen, denn versehentliche Änderungen und veraltete Dokumentation werden deutlich seltener. Export mit Microsoft Graph PowerShell, Versionskontrolle im Git-Repo und Deployment per Pipeline mit Workload Identity Federation gehören in vielen Projekten bereits zum Alltag. Wer noch ganz am Anfang steht, findet in meinem Beitrag Conditional Access in Microsoft Entra ID: Die ersten Richtlinien, die jeder Tenant braucht weitere Tipps für den Einstieg und kann danach mit Conditional Access as Code direkt den nächsten Schritt gehen.


