title: In 2018, what is the correct way to allow invocation of a single lambda function?
body: <p>Are you guys as frustrated with AWS as I am? <em>(IAM - get it? Its punny...)</em></p>
  
  <p>Checkout this IAM policy which — just a few months ago — was 100% valid and worked <strong>fine</strong>.</p>
  
  <pre><code>{
      "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"
              ]
          }
      ]
  }
  </code></pre>
  
  <p>If you paste this <strong>2017 valid</strong> policy into the IAM console editor today, you will be told that:</p>
  
  <blockquote>
    <p>This policy does not grant any permissions. To grant access, policies
    must have an action that has an applicable resource or condition</p>
  </blockquote>
  
  <p>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?</p>
  
  <hr>
  
  <h2>Life in 2018</h2>
  
  <p>So imagine that you just created a new Lambda fn, and you want to grant a <em>single user</em> permission to be able to run <em>THAT specific fn and no other</em>. If you start from scratch and use the new console, this is all that you are allowed to validly construct that comes close:</p>
  
  <pre><code>{
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": "lambda:InvokeFunction",
              "Resource": "*"
          }
      ]
  }
  </code></pre>
  
  <p>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.</p>
  
  <p>But wait! There is another Lambda permission, called Lambda:Invoke, and with this permission you <strong>CAN</strong> specify a specific resource in the console editor like so:</p>
  
  <pre><code>{
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "VisualEditor0",
              "Effect": "Allow",
              "Action": "lambda:Invoke",
              "Resource": "arn:aws:lambda:us-east-1:99999:function:test"
          }
      ]
  }
  </code></pre>
  
  <p>Well that looks pretty good doesn't it?! I mean, perhaps AWS just changed the name of the permission from InvokeFunction to Invoke. <em>Heck, thats not so bad and certainly not worth this record long question on SO right?</em> 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:</p>
  
  <blockquote>
    <p>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</p>
  </blockquote>
  
  <p><strong><em>WHAT?</em></strong></p>
  
  <p>Ok, for one, we <em>didn't</em> call a function in the <a href="https://aws.amazon.com/sdk-for-browser/" rel="noreferrer">AWS SDK</a> called "InvokeFunction", we called <a href="https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#invoke-property" rel="noreferrer">"Invoke"</a>. 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 <a href="https://status.aws.amazon.com" rel="noreferrer">AWS Service Health Dashboard</a> - which is all green, all the time even when us-east-1 is down. Netflix.</p>
  
  <p>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.</p>