You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda无法读取启用KMS加密的SQS队列问题排查求助

解决Lambda访问KMS加密SQS队列的权限问题

一、先排查KMS密钥策略的核心问题

你的现有KMS策略已经包含了lambda.amazonaws.com服务主体和指定IAM角色,但可能存在两个关键问题:

  • 如果${role}仅指向单个Lambda的执行角色ARN,那其他需要访问的Lambda角色会被排除在外,直接导致访问被拒;
  • 虽然策略里Resource写*是允许的,但明确指定KMS密钥ARN会更严谨,避免潜在的权限范围模糊问题。

针对多Lambda场景,推荐两种KMS策略修正方式:

方式1:直接添加所有Lambda执行角色ARN

把所有需要访问该SQS的Lambda执行角色ARN加入到Principal.AWS列表中:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Enable User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::${account}:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow services and Lambda roles to use key",
      "Effect": "Allow",
      "Principal": {
        "Service": ["sns.amazonaws.com", "lambda.amazonaws.com"],
        "AWS": [
          "arn:aws:iam::${account}:role/Lambda-Role-01",
          "arn:aws:iam::${account}:role/Lambda-Role-02",
          "arn:aws:iam::${account}:role/Lambda-Role-03"
        ]
      },
      "Action": [
        "kms:GenerateDataKey",
        "kms:Decrypt"
      ],
      "Resource": "${kmsARN}"
    }
  ]
}

方式2:用IAM组批量管理(更适合多Lambda场景)

先创建一个IAM组(比如Lambda-SQS-KMS-Access-Group),把所有需要访问的Lambda执行角色加入该组;然后修改KMS策略,允许这个IAM组访问:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Enable User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::${account}:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow services and Lambda group to use key",
      "Effect": "Allow",
      "Principal": {
        "Service": ["sns.amazonaws.com", "lambda.amazonaws.com"],
        "AWS": "arn:aws:iam::${account}:group/Lambda-SQS-KMS-Access-Group"
      },
      "Action": [
        "kms:GenerateDataKey",
        "kms:Decrypt"
      ],
      "Resource": "${kmsARN}"
    }
  ]
}

二、确认Lambda执行角色的权限配置

你的Lambda权限策略已经覆盖了SQS的核心操作和KMS权限,但需要注意两点:

  • 确保${kmsARN}是正确的KMS密钥ARN,没有拼写错误;
  • 检查Lambda执行角色的信任策略,必须允许lambda.amazonaws.com服务扮演该角色:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

如果是通过事件源映射自动触发Lambda拉取SQS消息,无需额外配置事件源的权限,它会自动使用Lambda执行角色的权限。

三、多Lambda批量授权的最佳实践

如果有大量Lambda需要访问这个加密SQS,推荐这样做:

  1. 创建一个共享的IAM权限策略,包含所有必要权限:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "sqs:ReceiveMessage",
        "sqs:DeleteMessage",
        "sqs:GetQueueAttributes"
      ],
      "Resource": "arn:aws:sqs:xxx-1:xxxx:queue"
    },
    {
      "Effect": "Allow",
      "Action": [
        "kms:GenerateDataKey",
        "kms:Decrypt"
      ],
      "Resource": "${kmsARN}"
    }
  ]
}
  1. 把这个策略附加到每个需要访问的Lambda执行角色上,或者用IAM权限边界批量管控权限范围;
  2. 结合前面提到的IAM组方式管理KMS权限,避免每次新增Lambda都要修改KMS策略。

四、Node.js代码的配置说明

不需要在代码中做任何额外的KMS配置! AWS SDK(v2或v3)会自动使用Lambda的执行角色权限处理KMS解密逻辑,只要权限配置正确,SDK会在拉取SQS消息时自动完成解密。

举个AWS SDK v3的示例代码:

import { SQSClient, ReceiveMessageCommand } from "@aws-sdk/client-sqs";

const sqsClient = new SQSClient({ region: "xxx-1" });

export const handler = async (event) => {
  const command = new ReceiveMessageCommand({
    QueueUrl: "https://sqs.xxx-1.amazonaws.com/xxxx/queue",
    MaxNumberOfMessages: 10,
    WaitTimeSeconds: 20
  });
  
  try {
    const response = await sqsClient.send(command);
    console.log("Received messages:", response.Messages);
    return response;
  } catch (error) {
    console.error("Error receiving messages:", error);
    throw error;
  }
};

最后验证步骤

  1. 等待KMS策略修改生效(通常需要1-5分钟);
  2. 确认Lambda执行角色已附加正确的权限策略;
  3. 测试Lambda拉取消息,查看CloudWatch日志是否还有KMS访问被拒的错误。

内容的提问来源于stack exchange,提问作者user1555190

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.01 02:12:47