我一直在与Serverless (the framework)合作,遇到了一个问题。这可能取决于我对AWS的最低了解以及它的架构,但也许有人可以为我指明正确的方向。
我用Terraform创建了一个S3存储桶,它利用AWS的KMS为存储桶提供了Server Side Encrpytion。从CLI上载到此存储桶可以正常工作,但是当使用由无服务器创建的Lambda时,它会返回并显示“访问被拒绝”。
无服务器的yaml有权上传到S3,我已经在关闭SSE的情况下对其进行了测试,并且工作正常。
我不了解的是如何为AWS指定密钥。我以为将它添加到服务的顶部可能有效(但无济于事)。
这是Yaml文件:
service:
name: lambdas
awsKmsKeyArn: [KEY GOES HERE]
custom:
serverless-offline:
port: 3000
bucket:
name: evidence-bucket
serverSideEncryption: aws:kms
sseKMSKeyId: [ KEY GOES HERE]
provider:
name: aws
runtime: nodejs12.x
region: eu-west-2
iamRoleStatements:
- Effect: Allow
Action:
- s3:ListBucket
- s3:PutObject
- s3:PutObjectAcl
Resource: "arn:aws:s3:::${self:custom.bucket.name}/*"
- Effect: Allow
Action:
- kms:Encrypt
- kms:Decrypt
- kms:DescribeKey
Resource: "[KEY GOES HERE]"
functions:
storeEvidence:
handler: handler.storeEvidence
environment:
BUCKET: ${self:custom.bucket.name}
events:
- http:
path: store-evidence
method: post
我需要其他插件吗?关于使用无服务器创建存储桶,但不使用SSE使用现有存储桶,有很多信息?如何解决此“访问被拒绝”消息?
答案 0 :(得分:0)
尝试一下:
iamRoleStatements:
- Effect: Allow
Action:
- s3:*
Resource: "arn:aws:s3:::${self:custom.bucket.name}/*"
- Effect: Allow
Action:
- kms:*
Resource: "[KEY GOES HERE]"
如果这行得通,则说明您缺少某些操作。然后,这是一个痛苦的过程,需要寻找丢失的动作,或者如果您高兴的话,只需留下* s。
答案 1 :(得分:0)
正如评论中的jarmod所说,您缺少kms:GenerateDataKey。在这里,我将向您展示添加到您上面显示的现有Yaml中的确切需求:
# ...
provider:
name: aws
runtime: nodejs12.x
region: eu-west-2
iamRoleStatements:
- Effect: Allow
Action:
- s3:ListBucket
- s3:PutObject
- s3:PutObjectAcl
Resource: "arn:aws:s3:::${self:custom.bucket.name}/*"
- Effect: Allow
Action:
- kms:Encrypt
- kms:Decrypt
- kms:DescribeKey
- kms:GenerateDataKey # <------ this is the new permission
Resource: "[KEY GOES HERE]"
#...
值得注意的是,如果您的代码从字面上仅使用s3:PutObject进行上传,则无需添加Encrypt,DescribeKey权限。参见:https://aws.amazon.com/premiumsupport/knowledge-center/s3-access-denied-error-kms/
如果您的代码涉及分段上传,则确实需要kms:DescribeKey,kms:Encrypt和更多权限(例如kms:ReEncrypt *,kms:GenerateDataKey * ...)查看详细信息:https://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html