Skip to main content

Async library to fetch JWKs for JWT tokens

Project description

pyjwt-key-fetcher

GitHub Workflow Status Code style: black PyPI PyPI - Python Version License: BSD 3-Clause

Async library to fetch JWKs for JWT tokens.

This library is intended to be used together with PyJWT to automatically verify keys signed by OpenID Connect providers. It retrieves the iss (issuer) and the kid (key ID) from the JWT, fetches the .well-known/openid-configuration from the issuer to find out the jwks_uri and fetches that to find the right key.

This should give similar ability to verify keys as for example https://jwt.io/, where you can just paste in a token, and it will automatically reach out and retrieve the key for you.

The AsyncKeyFetcher provided by this library acts as an improved async replacement for PyJWKClient.

Installation

The package is available on PyPI:

pip install pyjwt-key-fetcher

Usage

Example

import asyncio

import jwt

from pyjwt_key_fetcher import AsyncKeyFetcher


async def main():
    fetcher = AsyncKeyFetcher()
    # Token and options copied from
    # https://pyjwt.readthedocs.io/en/2.6.0/usage.html#retrieve-rsa-signing-keys-from-a-jwks-endpoint
    token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRTFRVVJCT1RNNE16STVSa0ZETlRZeE9UVTFNRGcyT0Rnd1EwVXpNVGsxUWpZeVJrUkZRdyJ9.eyJpc3MiOiJodHRwczovL2Rldi04N2V2eDlydS5hdXRoMC5jb20vIiwic3ViIjoiYVc0Q2NhNzl4UmVMV1V6MGFFMkg2a0QwTzNjWEJWdENAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vZXhwZW5zZXMtYXBpIiwiaWF0IjoxNTcyMDA2OTU0LCJleHAiOjE1NzIwMDY5NjQsImF6cCI6ImFXNENjYTc5eFJlTFdVejBhRTJINmtEME8zY1hCVnRDIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.PUxE7xn52aTCohGiWoSdMBZGiYAHwE5FYie0Y1qUT68IHSTXwXVd6hn02HTah6epvHHVKA2FqcFZ4GGv5VTHEvYpeggiiZMgbxFrmTEY0csL6VNkX1eaJGcuehwQCRBKRLL3zKmA5IKGy5GeUnIbpPHLHDxr-GXvgFzsdsyWlVQvPX2xjeaQ217r2PtxDeqjlf66UYl6oY6AqNS8DH3iryCvIfCcybRZkc_hdy-6ZMoKT6Piijvk_aXdm7-QQqKJFHLuEqrVSOuBqqiNfVrG27QzAPuPOxvfXTVLXL2jek5meH6n-VWgrBdoMFH93QEszEDowDAEhQPHVs0xj7SIzA"
    key_entry = await fetcher.get_key(token)
    token = jwt.decode(
        jwt=token,
        options={"verify_exp": False},
        audience="https://expenses-api",
        **key_entry
    )
    print(token)


if __name__ == "__main__":
    asyncio.run(main())

Options

Limiting issuers

You can limit the issuers you allow fetching keys from by setting the valid_issuers when creating the AsyncKeyFetcher, like this:

AsyncKeyFetcher(valid_issuers=["https://example.com"])

Adjusting caching

The AsyncKeyFetcher will by default cache data for up to 32 different issuers with a TTL of 3600 seconds (1 hour) each. This means that in case of key-revocation, the key will be trusted for up to 1 hour after it was removed from the JWKs.

If a previously unseen kid for an already seen issuer is seen, it will trigger a re-fetch of the JWKs, provided they have not been fetched in the past 5 minutes, in order to rather quickly react to new keys being published.

The amount of issuers to cache data for, as well as the cache time for the data can be adjusted like this:

AsyncKeyFetcher(cache_maxsize=10, cache_ttl=2*60*60)

The minimum interval for checking for new keys can for now not be adjusted.

Loading configuration from a custom path

You can change from which path the configuration is loaded from the issuer (iss). By default, the configuration is assumed to be an OpenID Connect configuration and to be loaded from /.well-known/openid-configuration. As long as the configuration contains a jwks_uri you can change the configuration to be loaded from a custom path.

You can override the config path when creating the AsyncKeyFetcher like this:

AsyncKeyFetcher(config_path="/.well-known/dataspace/party-configuration.json")

Using your own HTTP Client

The library ships with a DefaultHTTPClient that uses aiohttp for fetching the JSON data; the openid-configuration and the jwks. If you want, you can write your own custom client by inheriting from the HTTPClient. The only requirement is that it implements an async function to fetch JSON from a given URL and return it as a dictionary.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyjwt_key_fetcher-0.4.0.tar.gz (14.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyjwt_key_fetcher-0.4.0-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file pyjwt_key_fetcher-0.4.0.tar.gz.

File metadata

  • Download URL: pyjwt_key_fetcher-0.4.0.tar.gz
  • Upload date:
  • Size: 14.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.2 CPython/3.9.16 Linux/5.15.0-1033-azure

File hashes

Hashes for pyjwt_key_fetcher-0.4.0.tar.gz
Algorithm Hash digest
SHA256 d0e4c2a0b9b0fbe22c7bb388b8138fce011ad30d8cca78a017dfeba678f42903
MD5 aafff9a33fafb3e40066888f4855256c
BLAKE2b-256 0feb8bbcb21deb97c366c743a82fa3d99cb4c5b98a414f8135b401355274196b

See more details on using hashes here.

File details

Details for the file pyjwt_key_fetcher-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: pyjwt_key_fetcher-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 15.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.3.2 CPython/3.9.16 Linux/5.15.0-1033-azure

File hashes

Hashes for pyjwt_key_fetcher-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 30d7924db82918c4074f7c27c6871d3c91aa3632ba3d08cc23131ba24dec1ff3
MD5 3b702be0708c58d339ff52e92d596a8f
BLAKE2b-256 4046e675946fd788d0441e6e8c77179fdc83f35e2eba52bb00d2ae6cdb5b0b6e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page