DEV Community

Cover image for Day 45: Locking down Lambda with IAM Least Privilege
Eric Rodríguez
Eric Rodríguez

Posted on

Day 45: Locking down Lambda with IAM Least Privilege

Building features is fun; securing them is mandatory. For the past few weeks, my Serverless AI Financial Agent has been running smoothly, but under the hood, my Lambda function's execution role was a security nightmare. It had AmazonDynamoDBFullAccess and AmazonSNSFullAccess.

If a bad actor managed to exploit a vulnerability in my code, they would inherit those permissions and could wipe out my entire AWS account or rack up a massive SNS bill.

The Strategy: Granular Inline Policies
Today, I ripped out all AWS-managed FullAccess policies. Instead of giving the Lambda the master keys, I provided a highly scoped JSON policy that restricts actions to the exact Amazon Resource Names (ARNs) it needs.

Here is what the lockdown looks like:

JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:PutItem",
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:UpdateItem"
],
"Resource": [
"arn:aws:dynamodb:eu-north-1:ACCOUNT_ID:table/FinanceAgent-Transactions",
"arn:aws:dynamodb:eu-north-1:ACCOUNT_ID:table/FinanceAgent-Cache"
]
},
{
"Effect": "Allow",
"Action": "sns:Publish",
"Resource": "arn:aws:sns:eu-north-1:ACCOUNT_ID:FinanceAgent-Alerts"
}
]
}

The Timezone Gotcha
As a bonus, the transition to Summer Time in Spain (CEST / UTC+2) broke my 9:00 AM daily EventBridge triggers. Since AWS servers run on UTC, I had to update my Python backend to dynamically check datetime.utcnow().hour == 7 to ensure my local timezone delivery remained consistent. Never trust server time without a local offset!

Top comments (0)