SNS/SQS KMS Access Denied: Cross-Service-Verschlüsselungsberechtigungen beheben
2026-05-03 · 7 Min. Lesezeit
Sie haben gerade die serverseitige Verschlüsselung für Ihre SQS-Queue aktiviert. Ein verantwortungsvoller Schritt — Daten sollten immer verschlüsselt gespeichert werden. Aber jetzt kann Ihr SNS-Topic keine Nachrichten mehr an die Queue zustellen. Die Nachrichten verschwinden lautlos, und wenn Sie die SNS-Zustellungsprotokolle prüfen, sehen Sie Folgendes:
{
"notification": {
"messageId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE",
"topicArn": "arn:aws:sns:us-east-1:123456789012:order-events"
},
"delivery": {
"statusCode": 403,
"providerResponse": "{\"ErrorCode\":\"KMS.AccessDeniedException\",\"ErrorMessage\":\"User: arn:aws:iam::123456789012:root is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:us-east-1:123456789012:key/abc123-def456\",\"sqsRequestId\":\"xxx\"}"
}
}
Oder vielleicht scheitert Ihre Lambda-Funktion beim Lesen einer verschlüsselten SQS-Queue:
[ERROR] KMSAccessDeniedException: The ciphertext refers to a customer master
key that does not exist, does not exist in this region, or you are not allowed
to access.
Diese Fehler sind frustrierend, weil die Verschlüsselungskonfiguration korrekt aussieht — die Queue ist verschlüsselt, der Schlüssel existiert und die IAM-Policies scheinen in Ordnung. Das Problem liegt darin, dass KMS-Key-Policies nach einem anderen Berechtigungsmodell funktionieren als die meisten AWS-Dienste, und Cross-Service-Verschlüsselung Berechtigungen erfordert, die nicht offensichtlich sind.
Das Problem verstehen: Warum Cross-Service-KMS fehlschlägt
Wenn Sie eine SQS-Queue mit einem KMS-Schlüssel verschlüsseln, benötigt jeder Dienst, der in die Queue schreibt oder daraus liest, die Berechtigung, diesen Schlüssel zu verwenden. Das ist ein wichtiger Unterschied zu unverschlüsselten Queues:
- SNS benötigt
kms:GenerateDataKeyundkms:Decryptzum Publizieren von Nachrichten - Lambda benötigt
kms:Decryptzum Abrufen und Lesen von Nachrichten - S3-Event-Benachrichtigungen benötigen
kms:GenerateDataKeyzum Publizieren an verschlüsselte SNS-Topics - EventBridge benötigt ähnliche Berechtigungen bei verschlüsselten Ziel-Queues
Die Berechtigungen müssen an zwei Stellen gewährt werden: in der IAM-Policy des aufrufenden Principals und in der KMS-Key-Policy selbst. Fehlt eine davon, kommt es zur AccessDeniedException.
Ursache 1: AWS-Managed Key (aws/sqs) bei Cross-Service-Kommunikation
Dies ist der häufigste Fehler, den ich in der Praxis sehe. Wenn Sie die Verschlüsselung einer SQS-Queue über die Konsole aktivieren, ist die Standardoption der AWS-verwaltete Schlüssel alias/aws/sqs. Dieser Schlüssel funktioniert einwandfrei für direkte API-Aufrufe von IAM-Benutzern und -Rollen, aber er kann nicht von AWS-Service-Principals wie sns.amazonaws.com verwendet werden.
Prüfen Sie, welchen Schlüssel Ihre Queue verwendet:
aws sqs get-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/order-queue \
--attribute-names KmsMasterKeyId \
--query 'Attributes.KmsMasterKeyId' \
--output text
Wenn dies alias/aws/sqs oder einen ARN mit alias/aws/sqs zurückgibt, ist das Ihr Problem. Sie müssen zu einem kundenverwalteten KMS-Schlüssel (CMK) wechseln, damit Sie die Key-Policy anpassen können, um anderen AWS-Diensten Zugriff zu gewähren.
Die Lösung: Kundenverwalteten Schlüssel erstellen und verwenden
# Kundenverwalteten Schlüssel erstellen
aws kms create-key \
--description "Schluessel fuer Order-Queue-Verschluesselung" \
--query 'KeyMetadata.KeyId' \
--output text
Speichern Sie die Key-ID und erstellen Sie einen Alias für einfache Referenzierung:
aws kms create-alias \
--alias-name alias/order-queue-key \
--target-key-id YOUR_KEY_ID
Aktualisieren Sie die SQS-Queue mit dem neuen Schlüssel:
aws sqs set-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/order-queue \
--attributes '{"KmsMasterKeyId":"YOUR_KEY_ID"}'
Ursache 2: KMS-Key-Policy ohne Service-Principal-Berechtigungen
Selbst mit einem kundenverwalteten Schlüssel muss die KMS-Key-Policy den AWS-Service-Principals, die mit der verschlüsselten Queue interagieren müssen, explizit Berechtigungen erteilen. Standardmäßig vertraut ein neuer KMS-Schlüssel nur dem Account-Root und den Key-Administratoren.
Prüfen Sie die aktuelle Key-Policy:
aws kms get-key-policy \
--key-id YOUR_KEY_ID \
--policy-name default \
--output text
Die Lösung: SNS-Service-Principal zur Key-Policy hinzufügen
Fügen Sie der Key-Policy ein Statement hinzu, das dem SNS-Service-Principal die Nutzung des Schlüssels erlaubt:
{
"Sid": "AllowSNSToUseKey",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:sns:us-east-1:123456789012:order-events"
}
}
}
Wenden Sie die aktualisierte Key-Policy an:
aws kms put-key-policy \
--key-id YOUR_KEY_ID \
--policy-name default \
--policy file://key-policy.json
Der Condition-Block ist sicherheitskritisch. Ohne ihn könnte jedes SNS-Topic in jedem Account Ihren Schlüssel verwenden. Begrenzen Sie die Condition immer auf spezifische Source-ARNs.
S3-Service-Principal hinzufügen (für S3-Event-Benachrichtigungen)
Wenn S3-Event-Benachrichtigungen an ein verschlüsseltes SNS-Topic oder eine SQS-Queue publizieren, fügen Sie auch den S3-Service-Principal hinzu:
{
"Sid": "AllowS3ToUseKey",
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:s3:::my-bucket"
}
}
}
Ursache 3: Lambda-Ausführungsrolle ohne kms:Decrypt
Wenn Lambda eine verschlüsselte SQS-Queue pollt, muss die Lambda-Ausführungsrolle die Berechtigung kms:Decrypt für den KMS-Schlüssel haben. Das ist unabhängig von den SQS-Berechtigungen — sqs:ReceiveMessage allein reicht nicht aus.
Prüfen Sie die Lambda-Ausführungsrolle:
# Ausführungsrollen-ARN abrufen
aws lambda get-function-configuration \
--function-name order-processor \
--query 'Role' \
--output text
# Angehängte Policies auflisten
aws iam list-attached-role-policies \
--role-name order-processor-role
# Inline-Policies prüfen
aws iam list-role-policies \
--role-name order-processor-role
Die Lösung: KMS-Berechtigungen zur Lambda-Rolle hinzufügen
Fügen Sie diese Policy zur Lambda-Ausführungsrolle hinzu:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/YOUR_KEY_ID"
}
]
}
aws iam put-role-policy \
--role-name order-processor-role \
--policy-name KMSDecryptForSQS \
--policy-document file://kms-decrypt-policy.json
Stellen Sie außerdem sicher, dass die KMS-Key-Policy ein Statement enthält, das die Lambda-Ausführungsrolle erlaubt:
{
"Sid": "AllowLambdaRoleToDecrypt",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/order-processor-role"
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "*"
}
Ursache 4: Cross-Account verschlüsselte Queue-Subscriptions
Cross-Account-Setups fügen eine weitere Komplexitätsebene hinzu. Wenn ein SNS-Topic in Account A an eine verschlüsselte SQS-Queue in Account B publiziert, benötigen Sie Berechtigungen an drei Stellen: der SNS-Topic-Policy, der SQS-Queue-Policy und der KMS-Key-Policy in Account B.
Die KMS-Key-Policy in Account B muss dem SNS-Service-Principal Zugriff gewähren, eingeschränkt durch den Source-Topic-ARN aus Account A:
{
"Sid": "AllowCrossAccountSNS",
"Effect": "Allow",
"Principal": {
"Service": "sns.amazonaws.com"
},
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "*",
"Condition": {
"ArnLike": {
"aws:SourceArn": "arn:aws:sns:us-east-1:111111111111:order-events"
}
}
}
Verifizieren Sie, dass die SQS-Queue-Policy auch dem SNS-Topic aus Account A das Senden von Nachrichten erlaubt:
aws sqs get-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/222222222222/order-queue \
--attribute-names Policy \
--query 'Attributes.Policy' \
--output text | python3 -m json.tool
Ursache 5: KMS-Schlüssel in einer anderen Region
KMS-Schlüssel sind regional. Wenn Ihre SQS-Queue in us-east-1 liegt, aber der KMS-Schlüssel-ARN auf einen Schlüssel in eu-west-1 verweist, wird die Verschlüsselung fehlschlagen. Dies kann passieren, wenn Infrastrukturkonfigurationen zwischen Regionen kopiert werden.
Verifizieren Sie, dass die Schlüssel-Region mit der Queue-Region übereinstimmt:
# Region aus dem Key-ARN prüfen
aws sqs get-queue-attributes \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/order-queue \
--attribute-names KmsMasterKeyId \
--output text
Das Key-ARN-Format ist arn:aws:kms:REGION:ACCOUNT:key/KEY_ID. Stellen Sie sicher, dass REGION mit der Region der SQS-Queue übereinstimmt.
Schritt-für-Schritt-Diagnose
Wenn Sie auf einen KMS-Access-Denied-Fehler mit SNS/SQS stoßen, folgen Sie dieser systematischen Checkliste:
- KMS-Schlüssel identifizieren, der von der Queue oder dem Topic verwendet wird
- Prüfen, ob es ein AWS-verwalteter Schlüssel ist — wenn ja, zu einem kundenverwalteten Schlüssel wechseln
- KMS-Key-Policy lesen und sicherstellen, dass die erforderlichen Service-Principals aufgeführt sind
- IAM-Policies prüfen auf der publizierenden/konsumierenden Rolle für kms:GenerateDataKey und kms:Decrypt
- Mit manuellem Publish testen, um die Lösung zu bestätigen
# SNS-Publish an die Queue testen
aws sns publish \
--topic-arn arn:aws:sns:us-east-1:123456789012:order-events \
--message '{"test": "kms-permissions-check"}' \
--output text
# Prüfen, ob die Nachricht in der Queue ankommt
aws sqs receive-message \
--queue-url https://sqs.us-east-1.amazonaws.com/123456789012/order-queue \
--max-number-of-messages 1 \
--wait-time-seconds 5
Prävention: Best Practices für verschlüsselte Queues
-
Verwenden Sie immer kundenverwaltete Schlüssel für Queues, die Nachrichten von anderen AWS-Diensten empfangen. AWS-verwaltete Schlüssel sind einfacher, können aber keine Cross-Service-Berechtigungen gewähren.
-
Nutzen Sie CloudTrail zur KMS-Überwachung. Aktivieren Sie CloudTrail-Logging für KMS-API-Aufrufe, damit Sie genau sehen können, welche Principals abgelehnt werden:
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=Decrypt \
--start-time 2026-05-03T00:00:00Z \
--max-results 20 \
--query 'Events[*].{Time:EventTime,User:Username,Error:CloudTrailEvent}' \
--output table
-
Conditions eng eingrenzen. Verwenden Sie immer
aws:SourceArnoderaws:SourceAccountConditions in Key-Policies, um unbeabsichtigten Zugriff zu verhindern. -
Infrastructure as Code verwenden. Definieren Sie KMS-Key-Policies zusammen mit den Queues und Topics in CloudFormation oder CDK. So werden die Berechtigungen immer gemeinsam deployt und in Pull Requests überprüft.
-
Verschlüsselung End-to-End testen in Ihrer CI/CD-Pipeline, bevor Sie in die Produktion deployen. Ein einfacher Integrationstest, der eine Nachricht publiziert und aus der verschlüsselten Queue empfängt, erkennt Berechtigungsprobleme, bevor sie die Produktion erreichen.
Hilfe bei KMS-Berechtigungen nötig?
Cross-Service-Verschlüsselung in AWS ist leistungsfähig, aber das Berechtigungsmodell ist wirklich komplex. Wenn Sie Stunden mit dem Debugging von KMS-Access-Denied-Fehlern verbringen oder sicherstellen möchten, dass Ihre Verschlüsselungsarchitektur von Anfang an den AWS-Best-Practices folgt, können wir helfen. Kontaktieren Sie uns für eine kostenlose AWS-Beratung — wir haben Hunderte dieser Berechtigungskonfigurationen entwirrt und können das Problem typischerweise bereits im ersten Gespräch identifizieren.
Brauchen Sie Hilfe mit Ihrer AWS-Infrastruktur?
Buchen Sie ein kostenloses 30-Minuten-Gespräch.