Why do I get an Access Denied message for Go AWS Lambda function using Secrets Manager API when not specifying VersionStage: AWSCURRENT?

huangapple go评论92阅读模式
英文:

Why do I get an Access Denied message for Go AWS Lambda function using Secrets Manager API when not specifying VersionStage: AWSCURRENT?

问题

在调试 AWS SecretsManager Caching Go 的问题时,我回退到使用 AWS SecretsManager API,并遇到了以下错误信息:
>AccessDeniedException: User: arn:aws:sts::redacted:assumed-role/MyLambdaFunctionName-DNV2M7OYIFMX/MyLambdaFunctionName-eoFcAmXLBOV1 is not authorized to perform: secretsmanager:GetSecretValue on resource: my_secret_name

代码如下:

session := session.Must(session.NewSession(aws.NewConfig().WithRegion("us-east-1")))
secretMgr := secretsmanager.New(session)
res, err := secretMgr.GetSecretValue(
        &secretsmanager.GetSecretValueInput{
            SecretId: String("my_secret_name")
        },
    )

密钥资源策略设置如下:

{
  "Version" : "2012-10-17",
  "Statement" : [ {
    "Effect" : "Allow",
    "Principal" : {
      "AWS" : "arn:aws:iam::redacted:role/MyLambdaFunctionNameRole-DNV2M7OYIFMX"
    },
    "Action" : "secretsmanager:GetSecretValue",
    "Resource" : "*",
    "Condition" : {
      "ForAnyValue:StringEquals" : {
        "secretsmanager:VersionStage" : "AWSCURRENT"
      }
    }
  } ]
}

只要我将代码更改为包括值为 "AWSCURRENT" 的 VersionStage 参数,代码就能正确执行而没有错误:

session := session.Must(session.NewSession(aws.NewConfig().WithRegion("us-east-1")))
secretMgr := secretsmanager.New(session)
res, err := secretMgr.GetSecretValue(
        &secretsmanager.GetSecretValueInput{
            SecretId:     String("my_secret_name"),
            VersionStage: String("AWSCURRENT"),
        },
    )

根据 SecretsManager API 文档,如果未指定 VersionStage,则 VersionStage: "AWSCURRENT" 应该是默认配置:
>如果未指定 VersionStage 或 VersionId,则默认情况下会在具有 VersionStage 值为 AWSCURRENT 的版本上执行操作。

有人能解释为什么省略 VersionStage 会导致此错误消息,以及为什么它与 IAM 承担的角色有关,因为 AWS 密钥和 Lambda 函数都在同一个账户中吗?谢谢!

英文:

While debugging an issue with the AWS SecretsManager Caching Go, I reverted back to using the AWS SecretsManager API and ran into the following error message:
>AccessDeniedException: User: arn:aws:sts::redacted:assumed-role/MyLambdaFunctionName-DNV2M7OYIFMX/MyLambdaFunctionName-eoFcAmXLBOV1 is not authorized to perform: secretsmanager:GetSecretValue on resource: my_secret_name

The code is:

session := session.Must(session.NewSession(aws.NewConfig().WithRegion("us-east-1")))
secretMgr := secretsmanager.New(session)
res, err := secretMgr.GetSecretValue(
        &secretsmanager.GetSecretValueInput{
            SecretId: String("my_secret_name")
        },
    )

The secret resource policy is set as:

{
  "Version" : "2012-10-17",
  "Statement" : [ {
    "Effect" : "Allow",
    "Principal" : {
      "AWS" : "arn:aws:iam::redacted:role/MyLambdaFunctionNameRole-DNV2M7OYIFMX"
    },
    "Action" : "secretsmanager:GetSecretValue",
    "Resource" : "*",
    "Condition" : {
      "ForAnyValue:StringEquals" : {
        "secretsmanager:VersionStage" : "AWSCURRENT"
      }
    }
  } ]
}

As soon as I change the code to include the VersionStage parameter with value "AWSCURRENT", the code executes correctly without errors:

session := session.Must(session.NewSession(aws.NewConfig().WithRegion("us-east-1")))
secretMgr := secretsmanager.New(session)
res, err := secretMgr.GetSecretValue(
        &secretsmanager.GetSecretValueInput{
            SecretId:     String("my_secret_name"),
            VersionStage: String("AWSCURRENT"),
        },
    )

According the SecretsManager API documentation, VersionStage: "AWSCURRENT" appears as if it should be the default configuration if not specified:
>If you don't specify either a VersionStage or VersionId, then the default is to perform the operation on the version with the VersionStage value of AWSCURRENT.

Can anyone explain why omitting VersionStage results in this error message, and/or why it has anything to do with an IAM assumed role, since both the AWS secret and lambda function are in the same account? Thanks!

答案1

得分: 1

AWS文档中针对secretsmanager:VersionStage条件的说明如下:

> 根据请求中VersionStage参数中标识的分段标签对请求进行过滤。我们建议您不要使用此键,因为如果使用此键,请求必须传递一个分段标签与此策略进行比较。

这正是您所遇到的情况。在使用此条件时,您必须明确包含标签。文档没有解释为什么 AWSCURRENT 的 'default' 阶段不起作用。您可以在这里找到一个广泛的 GitHub 讨论线程,讨论了这个问题。结论基本上是文档的表述确实有些糟糕,但他们目前还没有理由来更新文档。

英文:

The AWS docs state for the secretsmanager:VersionStage condition:

> Filters the request based on the staging labels identified in the VersionStage parameter of a request. We recommend you do not use this key, because if you use this key, requests must pass in a staging label to compare to this policy.

Which is exactly what you experienced. You have to explicitly include the label when using this condition. It does not explain why the 'default' stage of AWSCURRENT is not working. You can find an extensive github thread discussing this issue here. The conclusion is basically that it's indeed a bit crappy how the docs formulate this, but they see no reason yet to actually update the docs.

huangapple
  • 本文由 发表于 2021年9月10日 03:34:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/69123831.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定