Search code examples
pythonflaskjwtmulti-tenantflask-jwt-extended

Is there a way to have tenant specific JWT token


I am currently developing a SPA application (angular) with a Python/Flask API in the back-end.

The application will support multiple tenants and I struggle a bit with the security concept. I am currently using jwt-extended

An issued JWT token would be valid for all tenants (I can of course get the user form the token and then check if the user should have access or not to that tenant), but I would perfere to have JWT token that are tenant specific (so that the user get blocked by the @jwt_required).

My idea would be to have different JWT_SECRET_KEY per tenant (so like append the tenant to my key) and then check the validity of the token per tenant (tenant would be identified by the url, either as subdomain or as parameter)

By default, the key is the on the app level (with app.config('JWT_SECRET_KEY') but it looks like you can overwrite the key encode/decode functions in flask_jwt_extended.JWTManager. I am however not sure which functions I have to override for my @jwt_required to work a I would like (so to use a custoim key in the decoding that would be generated as a concatenate of my key + tenant)

If my concept does not make sense / if there is a better and/or simpler way to achieve this, please let me know.


Solution

  • It was in the end pretty easy to generate tenant specific JWT (I concatenate the key with the tenant extracted from the URL in the example below).

    You only need to define a customDecodeKey / customEncode Key method:

    def customEncodeKey(arg1):
        return app.config['JWT_SECRET_KEY'] + request.path.split('/')[1]
    
    def customDecodeKey(arg1, arg2):
        return app.config['JWT_SECRET_KEY'] + request.path.split('/')[1]
    

    and then "register" it with jwt:

    jwt = JWTManager(app)
    jwt.decode_key_loader(customDecodeKey)
    jwt.encode_key_loader(customEncodeKey)