2

Is it possible to grant AWS services (e.g. API gateway, Secrets Manager) permission to invoke a Lambda function using only IAM roles? Normally this is done in the function's policy (resource-based policy), but I wonder if this is the only way. The advantage of using IAM is that one policy can allow multiple Lambdas to be executed, without the overhead of managing one policy per function. (Note that I am not asking about Lambda IAM +execution roles+, which determine permissions as the function executing.)

Documentation on the Lambda Permissions Model suggests that IAM roles can be used in place of Lambda function policies:

Instead of using a Lambda function policy, you can create another IAM role that grants the event sources (for example, Amazon S3 or DynamoDB) permissions to invoke your Lambda function. However, you might find that resource policies are easier to set up and they make it easier for you to track which event sources have permissions to invoke your Lambda function.

In my digging, however, I have not been able to achieve the advertised effect. I've tried to grant two two services permission to invoke Lambdas: API gateway and Secrets Manager. In both cases, I found these services require access to be granted within the function policy, not an IAM role.

Service 1: Secrets Manager

I am rotating RDS credentials in Secrets Manager. Normally, Secrets Manager creates Lambdas to perform the rotation once you configure the secret's rotation schedule, but in my case I did not like the long custom names of the Lambda functions and created my own. I attempted to grant Secrets Manager permission to invoke any Lambda using IAM roles, so I created the following role:

Trust relationship:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowApiGatewayToAssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Permissions:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowInvokeAnyLambda",
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": "*"
        }
    ]
}

At the time of this writing, the AWS console does not have a way set a custom Lambda for rotating RDS credentials, so I used the CLI:

$ aws secretsmanager rotate-secret --secret-id 'rds/my-db/account' --rotation-lambda-arn 'arn:aws:lambda:us-east-1:xxxxxxxxxxxx:function:rotate-rds-secret' --rotation-rules AutomaticallyAfterDays=1

An error occurred (AccessDeniedException) when calling the RotateSecret operation: Secrets Manager cannot invoke the specified Lambda function. Ensure that the function policy grants access to the principal secretsmanager.amazonaws.com

So it looks like Secrets Manager does not use this IAM role to invoke the Lambda. And there does not seem to be a way to configure Secrets Manager to use a specific IAM role.

Service 2: API Gateway

I am using API Gateway to call my Lambda function. API Gateway has two different integration types which support invoking a Lambda: (1) Lambda function and (2) AWS Service (https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-lambda.html).

When using Lambda function integration, it's the same story as with Secrets Manager—you need to use function policies to grant API Gateway invoke access. But with AWS Service integration, you actually specify which IAM role API Gateway should use to invoke the Lambda. This makes sense to me, because how would a service like API Gateway know which IAM role to use to invoke a Lambda? Yet there is no way to choose an IAM role when using the Lambda function integration. Or is there...


Cross-posted on: https://forums.aws.amazon.com/message.jspa?messageID=844660#844660

mxxk
  • 163
  • 2
  • 7
  • 1
    It sounds like you are looking for a [service-linked role](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-service-linked-role). – Michael - sqlbot Apr 24 '18 at 03:18
  • 1
    Thanks @Michael. I looked at service-linked roles, but according to [AWS services that work with IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html), neither Secrets Manager nor API Gateway support them. – mxxk Apr 24 '18 at 07:52
  • @mxk what is the advantage to using an IAM role over a resource policy / function policy? I'm just curious. – Carlos Macasaet May 20 '18 at 00:47
  • 1
    @CarlosMacasaet, one benefit which comes to mind of an IAM role versus a function policy is when you use the same IAM role for multiple Lambda functions. When making a change to this IAM role, all Lambdas receive the update, rather than having to change each function's policy manually. – mxxk May 20 '18 at 21:30
  • 1
    Try add the permission to the function via the AWS CLI: ```aws lambda add-permission --region --function-name --statement-id 1 --principal secretsmanager.amazonaws.com --action lambda:InvokeFunction``` – damolp Oct 08 '18 at 06:20
  • Hey @damolp, `aws lambda add-permission` adds entries to the policy attached to the Lambda itself (a _resource-based policy_). While your example would allow the function to be called by Secrets Manager, I'm specifically looking for a way to use a single IAM policy to do apply this policy to _multiple_ Lambdas at once, specifically to save me from having to repeat `aws lambda add-permission` for each function. – mxxk Oct 08 '18 at 18:30
  • Try and add ```"Principal": { "Service": "secretsmanager.amazonaws.com" }``` to the Permission statement then? – damolp Oct 09 '18 at 02:36
  • @damolp `This policy contains the following error: Has prohibited field Principal For more information about the IAM policy grammar, see AWS IAM Policies` – nachonachoman Jan 12 '20 at 20:59

1 Answers1

0

If I understood correctly. You are looking for IAM role to use in LambdaProxy integration. LambdaProxy does allow to use IAM role. Here is a snippet that I use:

Resources:
  APILambdaInvokeRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - "apigateway.amazonaws.com"
            Action:
              - "sts:AssumeRole"
  APILambdaInvokePolicy:
    Type: AWS::IAM::Policy
    Properties:
      PolicyName: LambdaInvokePolicy
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: "lambda:InvokeFunction"
            Resource: "*"
      Roles:
        - !Ref APILambdaInvokeRole
titus
  • 404
  • 6
  • 17