Are you guys as frustrated with AWS as I am? (IAM - get it? Its punny...)
Checkout this IAM policy which — just a few months ago — was 100% valid and worked fine.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt123456",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:ca-central-1:99999:function:test",
"arn:aws:lambda:us-east-1:99999:function:test",
"arn:aws:lambda:us-east-2:99999:function:test",
"arn:aws:lambda:us-west-1:99999:function:test",
"arn:aws:lambda:us-west-2:99999:function:test"
]
}
]
}
If you paste this 2017 valid policy into the IAM console editor today, you will be told that:
This policy does not grant any permissions. To grant access, policies must have an action that has an applicable resource or condition
Now as you can see for yourself, there are 5 very specific "applicable resources" being given. So what gives here? What did those AWS boys and girls do to all of our existing IAM Lambda policies? And are we still secure as a result?
Life in 2018
So imagine that you just created a new Lambda fn, and you want to grant a single user permission to be able to run THAT specific fn and no other. If you start from scratch and use the new console, this is all that you are allowed to validly construct that comes close:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "*"
}
]
}
So we have a big problem here, don't we? That tiny asterisk means this policy can run ANY Lambda fn in the entire account (a fact I have proven). Since you can no longer specify a Resource in the permission Lambda:InvokeFunction, this permission is pretty useless for our use case.
But wait! There is another Lambda permission, called Lambda:Invoke, and with this permission you CAN specify a specific resource in the console editor like so:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "lambda:Invoke",
"Resource": "arn:aws:lambda:us-east-1:99999:function:test"
}
]
}
Well that looks pretty good doesn't it?! I mean, perhaps AWS just changed the name of the permission from InvokeFunction to Invoke. Heck, thats not so bad and certainly not worth this record long question on SO right? Heh, yeah, well don't do what I did and get all lubed up thinking you're about to score. Welcome to this new hell:
Error: User: arn:aws:iam::99999:user/PersistentDumbass is not authorized to perform: lambda:InvokeFunction on resource: arn:aws:lambda:us-east-1:99999:function:test
WHAT?
Ok, for one, we didn't call a function in the AWS SDK called "InvokeFunction", we called "Invoke". Second, we DID attach this policy to our user. Third, we waited an hour to make sure this wasn't a propagation issue and also checked the relatively useless AWS Service Health Dashboard - which is all green, all the time even when us-east-1 is down. Netflix.
SO wunderkinds, I summon thee to wade through AWS's now obsolete documentation and poor nomenclature choices to create an answer for "the current way" we are supposed to permission ONE user to invoke ONE, SPECIFIC function.
s3:ListObjects
when there is in fact no such action -- the permission for listing objects iss3:ListBucket
. A similar set of crossed wires may be occurring here. – Michael - sqlbot