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.6.0.tar.gz (13.9 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.6.0-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pyjwt_key_fetcher-0.6.0.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.9.18 Linux/6.2.0-1011-azure

File hashes

Hashes for pyjwt_key_fetcher-0.6.0.tar.gz
Algorithm Hash digest
SHA256 4d260b9bffc2f832bb9a468f290acb0ce80579b377219963a29a3d32012389b1
MD5 b92e1e80d97597b2d9770f4f9bebb703
BLAKE2b-256 bf7285a2806676a5ee7fd6fe24312b449c1a291e41c7a5b8869d671075e0a3aa

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pyjwt_key_fetcher-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 15.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.6.1 CPython/3.9.18 Linux/6.2.0-1011-azure

File hashes

Hashes for pyjwt_key_fetcher-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 97f787545ce195cfa53148e7b86f88d7c5056e61a50cd47898f4387f7ac42e25
MD5 efe47134636b360ac1fd3458d64877e5
BLAKE2b-256 4d3689f252fa53dfbb9ac06893d1bd8e02d5ff36d6ba7876809f5f7bd18a4dd9

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