-
-
Notifications
You must be signed in to change notification settings - Fork 247
Description
We've considered using a JWT as a relatively long-lived server-to-server API key (for a handful of first and second-party servers) that specifies permitted endpoints/restrictions/etc, on which we'd use blacklisting. We've also considered various short-lived client authorization uses where we don't really need to worry about blacklisting.
I'm not sure how much it would matter in reality, but I would be a little more comfortable using JWTs for both purposes if it was trivial to specify separate secrets for each use case. This would:
- reduce the number (probably by at least a few orders of magnitude) of tokens floating around that could be used to attempt brute-force recovery of the secret used to sign the API-key tokens
- enable us to rotate more heavily-used auth secrets without having to temporarily break integrations and redistribute API-keys
One approach might be using the existing config vars when the decorators are used normally, and adding support for explicitly passing one or more secrets to the decorator. I think this could be reasonably intuitive:
API_KEY_SECRET = os.getenv("API_KEY_SECRET")
AUTH_SECRET = os.getenv("AUTH_SECRET")
@jwt_required(API_KEY_SECRET)
@route("/partner_api")
def partners(self):
...
@jwt_required(AUTH_SECRET)
@route("/account")
def account(self):
...
A more robust version might be for the decorators to accept your config objects, along with a factory that'll generate a config object as you do currently (with defaults from app.config), but override any user-supplied values.