Lambda无法访问KMS密钥。

8
当我运行我的lambda代码时,我收到以下错误信息:
密文引用了一个不存在的客户主密钥,在此区域不存在,或者您无权访问。
我大多数情况下按照 this 创建堆栈使用aws-sam-cli,并且模板的相关部分位于代码下方。
相关代码如下:
const ssm = new AWS.SSM();
const param = {
    Name: "param1",
    WithDecryption: true
};
const secret = await ssm.getParameter(param).promise();

模板.yaml文件的相关部分如下:
KeyAlias:
    Type: AWS::KMS::Alias
    Properties:
      AliasName: 'param1Key'
      TargetKeyId: !Ref Key
Key:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Id: default
        Statement:
        - Effect: Allow
          Principal:
            AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
          Action:
          - 'kms:Create*'
          - 'kms:Encrypt'
          - 'kms:Describe*'
          - 'kms:Enable*'
          - 'kms:List*'
          - 'kms:Put*'
          - 'kms:Update*'
          - 'kms:Revoke*'
          - 'kms:Disable*'
          - 'kms:Get*'
          - 'kms:Delete*'
          - 'kms:ScheduleKeyDeletion'
          - 'kms:CancelKeyDeletion'
          Resource: '*'
          Sid: Allow root account all permissions except to decrypt the key
        Version: 2012-10-17

LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ../
      Handler: app.lambda
      Runtime: nodejs8.10
      Policies:
      - DynamoDBReadPolicy:
          TableName: !Ref Table
      - KMSDecryptPolicy:
          KeyId: !Ref Key
      - Statement:
         - Action:
           - "ssm:GetParameter"
           Effect: Allow
           Resource: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/param1"

KMSDecryptPolicy不能允许使用该密钥吗?我错过了什么吗?谢谢!

编辑:将模板更改为以下内容可行,但如果可能的话,我真的很想在lambda定义中使用KMSDecryptPolicy

LambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: ../
      Handler: app.lambda
      Runtime: nodejs8.10
      Policies:
      - DynamoDBReadPolicy:
          TableName: !Ref Table
      - KMSDecryptPolicy:
          KeyId: !Ref Key
      - Statement:
         - Action:
           - "ssm:GetParameter"
           Effect: Allow
           Resource: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/param1"

Key:
    Type: AWS::KMS::Key
    Properties:
      KeyPolicy:
        Id: default
        Statement:
        - Effect: Allow
          Principal:
            AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
          Action:
          - 'kms:Create*'
          - 'kms:Encrypt'
          - 'kms:Describe*'
          - 'kms:Enable*'
          - 'kms:List*'
          - 'kms:Put*'
          - 'kms:Update*'
          - 'kms:Revoke*'
          - 'kms:Disable*'
          - 'kms:Get*'
          - 'kms:Delete*'
          - 'kms:ScheduleKeyDeletion'
          - 'kms:CancelKeyDeletion'
          Resource: '*'
          Sid: Allow root account all permissions except to decrypt the key
        - Sid: 'Allow use of the key for decryption by the LambdaFunction'
          Effect: Allow
          Principal:
            AWS: !GetAtt LambdaFunctionRole.Arn
          Action:
          - 'kms:Decrypt'
          Resource: '*'        
        Version: 2012-10-17

谢谢你的解决方案,但能否将其作为答案发布,并简要描述一下你所做的更改?这样阅读起来会更容易理解你所做的更改。 - Federico
对我来说,解决方案是按照 https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-setting-up-vpc.html#sysman-setting-up-vpc-create 中提到的创建所需的端点。 - Federico
可能是一个愚蠢的问题,但上面的模板不是一个循环引用吗? - Ben Lamm
是的,事实上那样做是行不通的。 - Matteo
1个回答

5
问题本身就包含了答案。改变之处在于,与其只在lambda角色中授予KMS权限(基于身份的方式),现在还在密钥策略中授予权限给lambda角色(基于资源的方式)。
以下是AWS官方关于此问题的资源- https://docs.aws.amazon.com/kms/latest/developerguide/iam-policies.html 根据这个资源,所有KMS CMK都有一个密钥策略,并且必须使用它来控制对CMK的访问。单独使用IAM策略无法允许访问CMK,尽管您可以将它们与CMK的密钥策略结合使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接