This post is a quick capture of how to easily secure your FastAPI with any auth provider that provides JWKS.
Background: RS256
RS256 is a signing algorithm used to generate and validate JSON Web Tokens (JWTs). Unlike the common HS256 algorithm that uses the same secret string to both generate and validate JWTs, RS256 uses a private key to generate JWTs and a separate public key for validating JWTs:
RS256 generates an asymmetric signature, which means a private key must be used to sign the JWT and a different public key must be used to verify the signature. [source]
This allows you to share your public key and thus enables any service to validate JWTs (provided that the service can read the public key). This makes RS256 a great choice for distributed applications, wherein one service generates auth tokens but many services can independently validate auth tokens.
Note: You are already using asymmetric cryptographic algorithms. For example, when you access a website over HTTPS, the SSL certificate includes a public key to allow a browser to validate messages sent by the origin server, while the origin server maintains a private key used to sign messages before they are sent. Additionally, when you set up SSH key pair for the purpose of connecting to servers, this key pair consists of a private and public key. The private is kept on your machine while a public key can be stored in a ~/.ssh/authorized_keys
file on the server to validate login requests.
Background: JWKS
The JSON Web Key Set (JWKS) is a set of keys containing the public keys used to verify any JSON Web Token (JWT) issued by the authorization server and signed using the RS256 signing algorithm. [source]
The JWKS is needed by each service that will be validating tokens. It can be commonly be found at /.well-known/jwks.json
, however theoretically could be distributed in any other means (S3, AWS Parameter Store, etc).
JWKS Locations
Provider | Location | Example |
---|---|---|
Cognito | https://cognito-idp.{region}.amazonaws.com/{user_pool_id}/.well-known/jwks.json | https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Wt2sA2K9e/.well-known/jwks.json |
Auth0 | https://YOUR_DOMAIN/.well-known/jwks.json | https://example.auth0.com/.well-known/jwks.json |
FastAPI Integration
For a FastAPI application to validate a JWT signed with an RS256 algorithm, it needs to do the following:
- Load JWKS
- Retrieve token from the request
- Validate the token’s signature against the JWKS
Below, I’ve added a simple way to achieve this by taking advantage of FastAPI’s dependency injection system and pyJWT:
|
|