Skip to content

Authenticate Requests from cloudformation stack to lambda

0

I am creating a custom resource with lambda as service token. This lambda is present in a different account than custom resource. I want to authenticate requests in lambda and I want to ensure that only calls from cloudformation are allowed in the lambda. How can I do it? I have already tried to use a resource policy in lambda like this to restrict calls but it doesn't work i.e. I am not able to call lambda as part of cloudformation deployment and custom resource creation.


{
  "ArnLike": {
    "AWS:SourceArn": "arn:aws:cloudformation:us-east-1:<AccountId>:stack/*"
  }
}
1 Answer
0

aws:SourceArn, aws:SourceAccount, and the other aws:Source* condition keys only apply to requests with an AWS service principal as the calling principal. The CloudFormation stack normally gets executed using an AWS IAM mechanism called Forward Access Sessions (FAS) in the security context of an IAM role in your account instead, or alternatively, using a custom IAM service role that's been passed to the CloudFormation service. In both cases, the aws:Source* keys won't be present in the request context of API calls the stack makes.

You could try using this condition test in your Lambda's resource-based policy to identify that the call is coming through CloudFormation. Note the "ForAnyValue:" prefix to the comparison operator, required when evaluating multivalued condition keys:

"Condition": {
  "ForAnyValue:StringEquals": {
    "aws:CalledVia": "cloudformation.amazonaws.com"
  }
}

This might also work, requiring further that the last service in the FAS chain is CloudFormation. Only one service can be the last one, so this key is single-valued and must be evaluated with a comparison operator without the "ForAnyValue:" prefix. However, I'm not 100% sure that some other service might not be in between in the case of your custom resource, so it's possible this variation won't work:

"Condition": {
  "StringEquals": {
    "aws:CalledViaLast": "cloudformation.amazonaws.com"
  }
}
EXPERT

answered 2 years ago

  • will the principal in this case be account:root? or role which cloudformation is using? Also its not possible to add these advanced conditions through console, right? Its not allowing me to do via cli also only possible options are SYNOPSIS

            add-permission
          --function-name <value>
          --statement-id <value>
          --action <value>
          --principal <value>
          [--source-arn <value>]
          [--source-account <value>]
          [--event-source-token <value>]
          [--qualifier <value>]
          [--revision-id <value>]
          [--principal-org-id <value>]
          [--function-url-auth-type <value>]
          [--cli-input-json | --cli-input-yaml]
          [--generate-cli-skeleton <value>]
          [--debug]
          [--endpoint-url <value>]
          [--no-verify-ssl]
          [--no-paginate]
          [--output <value>]
          [--query <value>]
          [--profile <value>]
          [--region <value>]
          [--version <value>]
          [--color <value>]
          [--no-sign-request]
          [--ca-bundle <value>]
          [--cli-read-timeout <value>]
          [--cli-connect-timeout <value>]
          [--cli-binary-format <value>]
          [--no-cli-pager]
          [--cli-auto-prompt]
          [--no-cli-auto-prompt]
    

    How to achieve this?

  • The principal is typically the IAM role under which you created the CloudFormation stack. If you explicitly specify a different role for the stack to use, it will be that IAM role. In both cases, it'll be one specific IAM role that you specify in the permissions, not requiring the entire account (via the :root principal).

  • I checked the API documentation (https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html) and unfortunately you're right, regular IAM condition clauses can't be added to the resource-based policy of a Lambda function. The only option I can think of would be to use a Service Control Policy (SCP) in AWS Organizations with a condition to block access if the call isn't coming via CloudFormation. Deny statements in SCPs do support all global context keys.

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.