Search code examples
amazon-web-servicesgoaws-lambdaamazon-iamaws-secrets-manager

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


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!


Solution

  • 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.