I'm trying to implement authorization in my cloudfront distribution. It has worked so far until I ran into size limitation. I'm now running into the cloudfront error message Max allowed: 1048576
, which is roughly ~1MB. But after installing the authlib
package the total size is around 6MB. My method for validating tokens look roughly like this:
from authlib.jose import JsonWebToken
jwk = get_jwk()
claims_options = {
"iss": {"essential": True, "value": ISSUER},
"aud": {"essential": True, "value": AUDIENCE}
}
jwt = JsonWebToken()
claims = jwt.decode(token, jwk, claims_options=claims_options)
claims.validate()
The whole thing works beautifully until the size limitation.
My ideas to get around this are:
Perhaps there are more alternatives, but these are the ones I could come up with which are desirable in descending order. Requesting assistance on either of these options or perhaps totally different solution.
The problem with authlib
package is that a significant part of its size is cryptography
dependency, which has compiled dependencies on its own. Here are few thought on how it can be approached.
One option to consider is trying out a more lightweight package like pyjwt
. According to the documentation, pyjwt requires cryptography
dependency if you want to encode or decode tokens using certain digital signature algorithms like RSA or ECDSA. This means that with a lightweight version of pyjwt
(without cryptography
dependency) you can use the HS256 algorithm, but not RSA or ECDSA. Without cryptography
, pyjwt
library should be below size limit.
I’m not an cryptography expert, but as I understand HS256-based JWT could be subject to a brute force or a dictionary attack. Therefore, it is recommended to use RS256 or ES256 algorithms instead, which are possible only with cryptography
.
An interesting solution on how to use recommended algorithm is shown in this repository, where
Lambda@Edge simply makes a request to another API that does not have such harsh limit on its size and can use cryptography
without compromising security.
Another way to delegate jwt decoding would be to invoke a separate Lambda function. Current size quotas for a standard Lambda's deployment package is 50 MB for zipped archive and 250 MB for unzipped package, so you can easily use cryptography
with authlib
or pyjwt
there. Please mind that invoking Lambda this way would be synchronous. You probably would also have to add "lambda:InvokeFunction"
permission.
import json
from boto3 import client as boto3_client
lambda_client = boto3_client('lambda')
def lambda_handler(event, context):
# ...
response = lambda_client.invoke(
FunctionName="another_lambda_",
InvocationType='Event', # or 'RequestResponse' for sync request/response
Payload=json.dumps(your_payload)
)
# ...