Home > Mobile >  How to add a Secret Manager read resource policy to my lambda resourse with SAM CLI template
How to add a Secret Manager read resource policy to my lambda resourse with SAM CLI template

Time:11-01

I have a lambda function created from the SAM CLI template and it needs to call on the secret key manager to grab a third-party secret key. Since I want everything saved in a public GitHub I try to keep exposed information to a minimum which is why my initial secret that is added to the manager is blank and in theory I'd just update the value manually every time I re-create this SAM. The problem my lambda function doesn't have permission to call on getSecretValue(). I tried many different ways to add a policy but nothing worked.

Is there another way to get the ARN of my Secretkey recourse so I can pass it to the lambda Policies?

This is the error I get in cloudwatch when running a GET on the lambda (#### being placeholders)

"User: arn:aws:sts::######:assumed-role/FunctionRole-######/getAllItemsFunction-###### is not authorized to perform: secretsmanager:GetSecretValue on resource: Secretkey because no identity-based policy allows the secretsmanager:GetSecretValue action"
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Description",
  "Transform": ["AWS::Serverless-2016-10-31"],
  "Resources": {
    "getAllItemsFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Handler": "src/handlers/get-all-items.getAllItemsHandler",
        "Runtime": "nodejs14.x",
        "Architectures": ["x86_64"],
        "MemorySize": 128,
        "Timeout": 100,
        "Description": "Description",
        "Policies": [
          {
            "AWSSecretsManagerGetSecretValuePolicy": {
              "SecretArn": {
                "Ref": "Secretkey"
              }
            }
          }
        ],
        "Events": {
          "Api": {
            "Type": "Api",
            "Properties": {
              "Path": "/",
              "Method": "GET"
            }
          }
        }
      }
    },
    "Secretkey": {
      "Type": "AWS::SecretsManager::Secret",
      "Properties": {
        "Description": "Secret key from API that keeps API secure from outside calls",
        "SecretString": "{\"secret\": \"\"}"
      }
    }
  },
  "Outputs": {
    "WebEndpoint": {
      "Description": "API Gateway endpoint URL for Prod stage",
      "Value": {
        "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
      }
    }
  }
}

CodePudding user response:

The fix to my problem was I had the wrong SecretId name used in getSecretValue({ SecretId: NAME_HERE }).

lambda_functon.js

// I only had "Secretkey" before. Had to switch it to "Secretkey-ksjsnKDNSkGk"
const { SecretString } = await client.getSecretValue({ SecretId: "Secretkey-ksjsnKDNSkGk" }).promise();

To find the proper name go to AWS Secret Manager -> Secrets -> Select your secret -> View details for "Secret Name"

my secret name was that NAME-#### for example Secretkey-ksjsnKDNSkGk

I received two different errors which made this hard to troubleshoot.

Locally it said CATCH_ERROR: ResourceNotFoundException: Secrets Manager can't find the specified secret.

Remotely it returned "User: arn:aws:sts::######:assumed-role/FunctionRole-######/getAllItemsFunction-###### is not authorized to perform: secretsmanager:GetSecretValue on resource: Secretkey because no identity-based policy allows the secretsmanager:GetSecretValue action"

I found my solution by Navigating to my CloudFormation stack and viewing the Template that AWS created based on the template I feed it via (template.yaml or template.json). It specified all the resources created and the roles for each resource. This clearly showed me that my template file was correct and the lambda has access to the specified ARN so its very helpful to checkout.

To find Navigate to CloudFormations -> Select your Stack -> Select template -> Toggle "View processed template" -> Find your resource name/role in the file. You will usually see RESOURCE_NAME which is what you created and RESOURCE_NAME_ROLE which was automatically created for me based on the policies I have my resources in the template.yaml / template.json file. This will show you if your policies are created correctly.

At that point, I realized it was something else hence investigated the Secret Manager Resource itself and saw the name mismatch

CodePudding user response:

AWS documentation can be found here: https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html

  • Related