IAM Policy Struktur verstehen: Effect, Action, Resource und Condition erklärt
Wer zum ersten Mal eine IAM-Policy in JSON öffnet, sieht vier Schlüsselelemente — Effect, Action, Resource und Condition — und fragt sich, wie diese zusammenspielen. Ein falsch gesetztes Effect: Allow auf der falschen Resource kann in Produktion zu ungewolltem Zugriff führen, der erst Wochen später auffällt.
TL;DR: IAM Policy Grundstruktur auf einen Blick
| Element | Pflichtfeld? | Zweck | Typischer Wert |
|---|---|---|---|
Effect | Ja | Erlauben oder verweigern | Allow oder Deny |
Action | Ja | Welche API-Operationen | s3:GetObject, ec2:Describe* |
Resource | Ja (meistens) | Auf welche Ressourcen | ARN oder * |
Condition | Nein | Kontextabhängige Bedingungen | IP-Bereich, MFA, Tag-Werte |
Wie eine IAM Policy grundsätzlich funktioniert
Eine IAM-Policy ist eine JSON-Dokument-Sammlung von Statements. Jedes Statement beschreibt eine Zugriffsregel. AWS wertet alle anwendbaren Statements aus und folgt dabei einer festen Prioritätslogik: Ein explizites Deny überschreibt immer jedes Allow — unabhängig davon, wie viele Allow-Statements existieren.
Stell dir eine IAM-Policy wie einen Türsteher mit einer Whitelist und einer Blacklist vor. Die Blacklist gewinnt immer — selbst wenn dein Name auf der Whitelist steht.
Der Standard-Zustand ist implizites Deny: Ohne ein explizites Allow ist jede Aktion verweigert. Das ist kein Konfigurationsfehler, sondern das beabsichtigte Sicherheitsmodell.
- Anfrage eingehend: Ein Principal (User, Role, Service) sendet eine API-Anfrage.
- Explizites Deny prüfen: AWS prüft zuerst alle anwendbaren Policies auf
Deny-Statements. Wird eines gefunden, endet die Auswertung sofort mit Verweigerung. - Explizites Allow prüfen: Nur wenn kein Deny vorliegt, wird nach einem passenden
Allowgesucht. - Implizites Deny: Kein passendes Allow gefunden — Zugriff verweigert.
Die vier IAM Policy Elemente im Detail
Effect: Die Grundentscheidung
Effect akzeptiert genau zwei Werte: Allow oder Deny. Kein dritter Wert existiert. Ein Statement ohne Effect ist ungültig.
Das Wichtigste, das in der Praxis oft falsch verstanden wird: Ein Deny-Statement in einer Identity-based Policy kann durch eine Resource-based Policy nicht überschrieben werden. Explizites Deny ist final — mit einer Ausnahme: AWS-Root-Account-Aktionen und bestimmte Service-linked Roles verhalten sich anders. Für normale IAM-Operationen gilt: Deny gewinnt immer.
{
"Effect": "Deny",
"Action": "s3:DeleteBucket",
"Resource": "*"
}
Action: Die API-Operationen
Action definiert, welche AWS-API-Operationen das Statement betrifft. Das Format ist immer service:Operation, zum Beispiel s3:GetObject oder ec2:DescribeInstances. Wildcards (*) sind erlaubt — sowohl für den gesamten Service (s3:*) als auch für Teilmuster (s3:Get*).
Mehrere Actions werden als JSON-Array angegeben:
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::mein-bucket/*"
}
Die exakten Action-Strings sind im AWS Service Authorization Reference dokumentiert. Erfundene Action-Namen werden von AWS stillschweigend ignoriert — kein Fehler, kein Zugriff.
Resource: Der Geltungsbereich
Resource legt fest, auf welche AWS-Ressourcen das Statement angewendet wird. Ressourcen werden über ARNs (Amazon Resource Names) identifiziert. Das Format ist:
arn:aws:<service>:<region>:<account-id>:<resource>
Praktische Beispiele:
# Spezifischer S3-Bucket (global, keine Region/Account nötig)
arn:aws:s3:::mein-bucket
# Alle Objekte in einem S3-Bucket
arn:aws:s3:::mein-bucket/*
# Spezifische Lambda-Funktion
arn:aws:lambda:us-east-1:123456789012:function:MeineFunktion
# Alle Ressourcen (Wildcard)
*
Wichtig: Nicht alle Actions unterstützen Resource-Level-Permissions. Viele List*- und Describe*-Aktionen erfordern "Resource": "*", weil sie keiner einzelnen Ressource zugeordnet werden können. Das ist eine dokumentierte Einschränkung des jeweiligen Services — prüfe den Service Authorization Reference für den konkreten Fall.
Condition: Kontextabhängige Zugriffssteuerung
Condition ist optional, aber mächtig. Es erlaubt, ein Statement nur dann anzuwenden, wenn bestimmte Kontextbedingungen erfüllt sind — etwa eine bestimmte Quell-IP, aktives MFA, ein bestimmter Tag-Wert oder ein Zeitfenster.
Die Struktur ist immer dreischichtig: Condition → Operator → Schlüssel → Wert.
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mein-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
}
Dieses Statement erlaubt s3:GetObject nur, wenn die Anfrage aus dem IP-Bereich 203.0.113.0/24 kommt. Alle anderen Anfragen fallen auf implizites Deny zurück.
Mehrere Bedingungen innerhalb desselben Condition-Blocks werden mit logischem AND verknüpft. Mehrere Werte innerhalb eines Condition-Keys werden mit logischem OR verknüpft.
- Condition-Block: Enthält einen oder mehrere Condition-Operatoren.
- Operator: Definiert den Vergleichstyp, z.B.
StringEquals,IpAddress,Bool,DateLessThan. - Condition Key: Der Kontextwert, der geprüft wird, z.B.
aws:SourceIp,aws:MultiFactorAuthPresent. - Wert: Der erwartete Wert für den Vergleich.
Ein vollständiges Statement-Beispiel
Hier ein realistisches Beispiel: Eine Rolle darf S3-Objekte nur lesen, wenn MFA aktiv ist und die Anfrage aus einem bestimmten VPC-Endpoint kommt.
🔽 Vollständiges IAM Statement Beispiel anzeigen
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "S3LesenNurMitMFAUndVPCEndpoint",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::mein-sicherer-bucket",
"arn:aws:s3:::mein-sicherer-bucket/*"
],
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
},
"StringEquals": {
"aws:SourceVpce": "vpce-0123456789abcdef0"
}
}
}
]
}
Beachte: s3:ListBucket wird auf den Bucket-ARN selbst angewendet (arn:aws:s3:::mein-sicherer-bucket), während s3:GetObject auf Objekte innerhalb des Buckets (arn:aws:s3:::mein-sicherer-bucket/*) angewendet wird. Beide ARNs im Resource-Array sind notwendig.
Häufige Fehler in der Praxis: Symptom, Fehldiagnose, echte Ursache
Ein typisches Szenario aus der Praxis: Eine Lambda-Funktion bekommt einen AccessDenied-Fehler beim Lesen aus S3, obwohl die Execution Role ein s3:GetObject Allow auf dem Bucket hat.
Fehldiagnose: 'Die Policy ist falsch geschrieben' — also wird die Policy neu erstellt, mit identischem Inhalt. Fehler bleibt.
Echte Ursache: Der S3-Bucket hat eine Bucket Policy mit einem expliziten Deny auf s3:GetObject für alle Principals außer einem bestimmten VPC-Endpoint. Die Identity-based Policy der Lambda-Rolle erlaubt den Zugriff, aber die Resource-based Policy (Bucket Policy) verweigert ihn explizit. Explizites Deny in der Bucket Policy gewinnt.
Der Diagnosepfad:
# Bucket Policy prüfen
aws s3api get-bucket-policy \
--bucket mein-sicherer-bucket \
--query Policy \
--output text
# IAM Policy Simulation für spezifische Aktion
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/MeineLambdaRole \
--action-names s3:GetObject \
--resource-arns arn:aws:s3:::mein-sicherer-bucket/test.txt
simulate-principal-policy berücksichtigt Identity-based Policies, aber nicht alle Resource-based Policies vollständig — prüfe die Bucket Policy immer separat. Das ist der Punkt, an dem viele Diagnosen zu früh aufhören.
IAM Policy Struktur mit der AWS CLI validieren
Bevor eine Policy deployed wird, lässt sie sich lokal auf syntaktische Korrektheit prüfen und simulieren.
# Policy-Dokument auf syntaktische Fehler prüfen (beim Erstellen)
aws iam create-policy \
--policy-name TestPolicy \
--policy-document file://policy.json
# Bestehende Policy-Version abrufen
aws iam get-policy-version \
--policy-arn arn:aws:iam::123456789012:policy/MeinePolicy \
--version-id v1
# IAM Access Analyzer für Policy-Validierung
aws accessanalyzer validate-policy \
--policy-document file://policy.json \
--policy-type IDENTITY_POLICY
validate-policy über IAM Access Analyzer gibt strukturierte Warnungen und Fehler zurück — deutlich hilfreicher als das generische 'MalformedPolicyDocument' beim Deployment.
Nächste Schritte und weiterführende Ressourcen zur IAM Policy Struktur
Das Verständnis der vier Grundelemente ist der Einstieg. In der Praxis kommen schnell komplexere Szenarien hinzu: Permissions Boundaries, Service Control Policies (SCPs) in AWS Organizations, und das Zusammenspiel von Identity-based und Resource-based Policies. Die offizielle AWS IAM Policy Dokumentation und der Service Authorization Reference sind die verlässlichsten Quellen für exakte Action-Namen und Resource-Level-Support.
Für tiefere Einblicke in IAM-Fehlerdiagnose empfiehlt sich auch der Beitrag über IAM Access Analyzer und Permissions Boundaries auf diesem Blog.
Glossar: Schlüsselbegriffe der IAM Policy Struktur
| Begriff | Bedeutung |
|---|---|
| Statement | Ein einzelner Zugriffsregelblock innerhalb einer Policy. Eine Policy kann mehrere Statements enthalten. |
| Principal | Die Entität (User, Role, Service), auf die eine Policy angewendet wird. In Identity-based Policies implizit; in Resource-based Policies explizit angegeben. |
| ARN | Amazon Resource Name — eindeutiger Bezeichner für AWS-Ressourcen im Format arn:aws:service:region:account:resource. |
| Condition Key | Ein Kontextvariable wie aws:SourceIp oder aws:MultiFactorAuthPresent, die in Condition-Blöcken ausgewertet wird. |
| Implizites Deny | Der Standardzustand in AWS IAM: Jede Aktion ist verweigert, solange kein explizites Allow existiert. |
Kommentare
Kommentar veröffentlichen