AWS lambda authorizer caching
Problem
-
Make a request to an endpoint in API gateway that uses a lambda authorizer with caching enabled. This request succeeeds.
-
Make a request to a different endpoint in API gateway that uses the same lambda authorizer. This request fails with an error that looks something like this:
{ "message": "User is not authorized to access this resource" }
Why?
When a lambda authorizer has caching enabled, it uses the authorization token
(i.e. Bearer abc123
) as a key and a policy document as a value. The policy
document looks something like:
{
"principalId": "user",
"policyDocument": {
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": [
"arn:aws:execute-api:us-1:abc:123/prod/GET/v1/users",
]
}
],
"Version": "2012-10-17"
}
}
So, if the Resource
in the policy is specific to single endpoint, the
cached value will only work for that endpoint. I was using the methodArn
to
dynamically generate this policy document on each invocation, which is why I
was having my problem - the cached policy would only work for the first endpoint
I hit. I’d have to wait until the cache was invalidated before I could hit a
different endpoint… and then wait longer to be able to hit another.
Solutions
-
(bad) Disable authorizer caching. This is probably not what most people want since calls to the authorizer will likely involve calling a separate identity service.
-
Make the
Resource
s covered by the policy more lax. Ideally using wildcards in portions of the resources"Resource": "arn:aws:execute-api:us-1:abc:123/prod/*/v?/*"
or just allowing any resource to be invoked
"Resource": "*"
(which isn’t too awful since the
Action
portion of the policy is pretty restrictive).