[Hands-On] AWS Lambda function URL with AWS IAM Authentication type
Tags: lambda, serverless, security, tutorial
Published: 2023-10-31 23:11:41

In this article, I am going to cover how to secure the AWS lambda function URL using AWS_IAM auth followed by how authenticated IAM users can access the lambda function via function URL.

If you are not aware of what the AWS Lambda function URL is then please refer to my video on [How to configure the AWS Lambda function URL](https://youtu.be/NIk5ut7_5sM).

_What does AWS_IAM Authentication type mean when enabled for AWS Lambda function URL?_

It means that only authenticated IAM users or roles can invoke the lambda function via the function URL. If they are not authenticated or do not have the necessary permissions then they will not be able to invoke or access the lambda function via URL and they will be greeted with an error message like Forbidden with status code 403.

## Hands-On
Login to the AWS Management Console to get started.

### Lambda Function
Navigate to Lambda Management Console and create the lambda function with the configuration as shown below.


![Create lambda function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jw0idjv8kinkzxeo5y1e.png)<figcaption>Create lambda function</figcation>

As a part of the Execution role, the first option will create a role with basic permissions which will allow the lambda function to create and write the logs to cloudwatch.

Expand the _Advance Settings_ — to enable function URL along with _AWS_IAM_ as auth type as shown in below screenshot and click on _Create function_. You can also enable the function URL after creating the function.

![Enable function URL](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bvug6skixzcfordadg7d.png) <figcaption>Enable function URL</figcaption>

### IAM User
The next step would be to create an IAM user. I am creating the new IAM user just to demonstrate things end-to-end but you can also experiment with an existing IAM user.

Navigate to _IAM Management Console_ → Click _Users_ from left panel → _Create User_. Follow through the on-screen steps. Do not add/attach any permissions to that IAM user.

Now, if we were to access the lambda function via the function URL when the AWS_IAM Authentication type is enabled, we would require AWS security credentials. So let’s generate the access key & secret access key for the given IAM user.

Open the IAM user → Security credentials → Scroll down to _Access keys_ → _Create access key_. As the next step, let’s try to invoke the lambda function via the function URL using the generated security credentials with Postman.

![Configure security credentials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yu8j89zd9wsc3k3xuy9c.png)<figcaption>Configure security credentials</figcaption>

Open Postman → Copy & paste the lambda function URL. Under _Authorization_ → Select _AWS Signature_ → Fill the _Access Key_ & _Secret key_ values with IAM user credentials (Generated in the previous step). Under Advanced configuration, enter the appropriate region (in my case it’s us-east-1) and the service name will be lambda because we are accessing/invoking the lambda service. Finally, click on Send to invoke and it will greet you with 403 forbidden because the IAM user does not have permission to access the said lambda function via the function URL.

The next step would be to provide the permission. There are two ways to provide permission which is either via Identity-based policy or resource-based policy and I will show you both. The basic difference between Identity-based policy and resource-based policy is that identity-based policies are directly attached to IAM users, groups, or roles, and in this case, we will attach it to IAM user that we have created, whereas resource-based policies are directly attached to resources which defines who can access that resource and in our case the resource is Lambda function where we will define who can access this lambda function via function URL.

Ideally, to successfully invoke the function via URL, the said entity must have _InvokeFunctionUrl_ permission.

#### Permission via Identity-based policy

Navigate to _IAM Management Console_ → _Policies_ (from left panel) → _Create policy_ → Select _JSON view_. Copy & paste the below policy and create it. _Make sure to replace the ARN with the ARN of your lambda function_. Post policy creation, attach the policy to the IAM user.

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunctionUrl"
            ],
            "Resource": [
                "arn:aws:lambda:your-region:your-acc-id:function:your-lambda-fun"
            ]
        }
    ]
}
```
The above policy says - to allow the InvokeFunctionUrl action on the particular lambda function that is defined as a part of the Resource to the IAM user or identity to which this policy will be attached.

As a next step, open Postman and invoke the function URL again. This time, it will return status code 200 along with “Hello from lambda!” as a response.

### Permission via Resource-based policy
In this section, we will configure the resource-based policy. It is something that is attached to the resource (i.e. lambda function). As a first step, please remove the policy that you have attached to the IAM user.

Open the lambda function → _Configurations_ → _Permissions_ → Scroll down to _Resource-based policy statements_ → _Add permissions_. Configure the policy as shown below.

![Resource-based policy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hzv196m32jm0mq0tntcp.png)<figcaption>Resource-based policy</figcaption>

Replace the _Principal_ with the IAM user ARN → Save and test it again. You should be able to successfully invoke the lambda function via the function URL.

### Generating & using temporary security credentials

We were able to invoke the lambda function via the function URL successfully using the IAM user security credentials (i.e. access and secret key), but the keys might get exposed and misused, which is a risk. So, the more promising way is to use temporary credentials which basically expire after a certain time. To do that, we are going to use AWS Security Token Service (AWS STS) to create and use temporary credentials and it is very simple to generate. Follow the below steps (Assuming AWS CLI is already installed).

- Open terminal
- Execute `aws configure` & configure the access key, access secret key & region
- To generate temporary credentials, execute `aws sts get-session-token --duration-seconds 900`

The above command will generate the temporary credentials (looks like below), which will be valid for 900 seconds.


![AWS temporary credentials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vizjxv5oi6fnobgj7hj3.png)<figcaption>AWS temporary credentials</figcaption>

As a next step, open Postman. Replace the _AccessKey_ & _SecretKey_ with the new values. Also, paste the _sessionToken_ in the relevant field under _Advanced configuration_.

![Postman temporary credentials configuration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/22310pq5e6eb5f8x4syc.png)<figcaption>Postman temporary credentials configuration</figcaption>

If you invoke the URL now, then you will be able to access the lambda function successfully with status code 200. After 15 minutes, these credentials will no longer be valid and need to be regenerated.

I hope you learned something new today. If you like to follow along with me step by step then you can refer to this video.

{% embed https://youtu.be/A-AEO103i98 %}

You might also like reading about [how to Whitelist IP addresses for Lambda function URLs](https://medium.com/srcecde/whitelist-ip-addresses-for-lambda-function-urls-8f69c8285e0a).

If you have any questions, comments, or feedback please leave them below. A reaction & a follow is appreciated :) [Subscribe to my channel](https://www.youtube.com/srcecde?sub_confirmation=1) for more.