Registry / auth-security / pyjwt-key-fetcher

pyjwt-key-fetcher

JSON →
library0.8.0pypypi✓ verified 87d ago

PyJWT Key Fetcher is an async Python library designed to fetch JSON Web Key Sets (JWKS) for JWT token verification. It automatically retrieves issuer configurations (e.g., from OpenID Connect discovery endpoints) to locate JWKS URIs and fetch the correct public keys. This library acts as an improved async replacement for `PyJWKClient` from PyJWT. The current version is 0.8.0, and it maintains a relatively active release cadence with several updates per year.

pip install pyjwt-key-fetcher
INSTALL
IMPORT
SIG · PYJWT-KEY-FETCHER
P
pyjwt-key-fetcher
auth-securitypythonv0.8.0
Install
5.5s avg
Import
736ms
Disk
51MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.8.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.920 runs
installs and imports cleanly · install 0.0s · import 0.768s · 50.4MB
glibc
py 3.103.920 runs
installs and imports cleanly · install 5.5s · import 0.704s · 54MB
51MB installed
● package 51MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

AsyncKeyFetcher
from pyjwt_key_fetcher import AsyncKeyFetcher
Provider
from pyjwt_key_fetcher.provider import Provider
from pyjwt_key_fetcher.openid_provider import OpenIDProvider
Class was renamed from OpenIDProvider to Provider in v0.3.0 for generic JWT provider support.

This example demonstrates how to use `AsyncKeyFetcher` to retrieve a signing key from a JWT's issuer, and then use that key with `PyJWT` to decode and verify the token. It includes `valid_issuers` for security and explicitly passes `audience` and `issuer` to `jwt.decode` for full validation.

import asyncio import jwt from pyjwt_key_fetcher import AsyncKeyFetcher async def main(): # Example token from PyJWT documentation for demonstration # In a real app, this would come from an Authorization header token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRTFRVVJCT1RNNE16STVSa0ZETlRZeE9UVTFNRGcyT0Rnd1EwVXpNVGsxUWpZeVJrUkZRdyJ9.eyJpc3MiOiJodHRwczovL2Rldi04N2V2eDlydS5hdXRoMC5jb20vIiwic3ViIjoiYVc0Q2NhNzl4UmVMV1V6MGFFMkg2a0QwTzNjWEJWdENAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vZXhwZW5zZXMtYXBpIiwiaWF0IjoxNTcyMDA2OTU0LCJleHAiOjE1NzIwMDY5NjQsImF6cCI6ImFXNENjYTc5eFJlTFdVejBhRTJINmtEME8zY1hCVnRDIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.PUxE7xn52aTCohGiWoSdMBZGiYAHwE5FYie0Y1qUT68IHSTXwXVd6hn02HTah6epvHHVKA2FqcFZ4GGv5VTHEvYpeggiiZMgbxFrmTEY0csL6VNkX1eaJGcuehwQCRBKRLL3zKmA5IKGy5GeUnIbpPHLHDxr-GXvgFzsdsyWlVQvPX2xjeaQ217r2PtxDeqjlf66UYl6oY6AqNS8DH3iryCvIfCcybRZkc_hdy-6ZMoKT6Piijvk_aXdm7-QQqKJFHLuEqrVSOuBqqiNfVrG27QzAPuPOxvfXTVLXL2jek5meH6n-VWgrBdoMFH93QEszEDowDAEhQPHVs0xj7SIzA" fetcher = AsyncKeyFetcher(valid_issuers=["https://dev-87evx9ru.auth0.com/"]) try: key_entry = await fetcher.get_key(token) # The fetched key_entry can then be used with PyJWT's decode function decoded_token = jwt.decode( jwt=token, options={"verify_exp": False}, # Set to True for production audience="https://expenses-api", issuer="https://dev-87evx9ru.auth0.com/", **key_entry ) print("Successfully decoded token:", decoded_token) except Exception as e: print(f"Error decoding token: {e}") if __name__ == "__main__": asyncio.run(main())
Debug
Known issues
breakingMajor refactoring in v0.3.0 renamed all explicit OpenID Connect references to be more generic. This includes `get_openid_configuration` to `get_configuration`, `OpenIDProvider` to `Provider`, and `JWTOpenIDConnectError` exceptions.
fix
Update method/class names (e.g., `fetcher.get_configuration()` instead of `fetcher.get_openid_configuration()`, `Provider` instead of `OpenIDProvider`). Refer to the v0.3.0 changelog for all renamed symbols.
affects: <0.3.0
breakingThe type definition `OpenIDConfigurationTypeDef` was removed in v0.8.0. You should now use `ConfigurationTypeDef` instead.
fix
Replace `OpenIDConfigurationTypeDef` with `ConfigurationTypeDef` in type hints or direct references.
affects: <0.8.0
gotchaThe `AsyncKeyFetcher` uses caching with a default TTL (Time To Live) of 3600 seconds (1 hour) for JWKS data. This means key revocations might not take effect immediately, as the old key could remain in the cache. New `kid` values will trigger a re-fetch if not seen in 5 minutes.
fix
Adjust caching parameters (`cache_maxsize`, `cache_ttl`) during `AsyncKeyFetcher` initialization to match your security requirements and acceptable latency for key revocation propagation. E.g., `AsyncKeyFetcher(cache_ttl=600)` for 10-minute cache.
affects: All versions
gotchaWhile `pyjwt-key-fetcher` retrieves the correct signing key, `jwt.decode()` from PyJWT still requires explicit `audience` and `issuer` parameters for full validation, especially when dealing with OIDC tokens. Failing to provide these can lead to tokens being accepted that shouldn't be.
fix
Always pass `audience` and `issuer` to `jwt.decode()` after fetching the key, ensuring they match the expected values for your application. E.g., `jwt.decode(..., audience=my_app_aud, issuer=expected_issuer, **key_entry)`.
affects: All versions
Errors
Common errors & fixes
AttributeError: 'AsyncKeyFetcher' object has no attribute 'get_openid_configuration'
Attempting to call a method that was renamed in version 0.3.0.
fix
The method `get_openid_configuration` was renamed to `get_configuration` in v0.3.0. Use `await fetcher.get_configuration(token)` instead.
TypeError: object of type 'AsyncKeyFetcher' is not awaitable
Forgetting to use `await` with an asynchronous method or directly instantiating an async class without `async with` or `await` where expected.
fix
Ensure all calls to `AsyncKeyFetcher` methods (like `get_key`, `get_configuration`) are prefixed with `await`. Also, `AsyncKeyFetcher` itself is not awaitable; you instantiate it directly and then call its async methods.
jwt.exceptions.InvalidAudienceError: Invalid audience
The audience claim in the JWT does not match the `audience` parameter provided to `jwt.decode()`, or no `audience` was provided.
fix
Ensure the `audience` parameter passed to `jwt.decode()` exactly matches the `aud` claim in the JWT. For production, never set `verify_aud=False`.
jwt.exceptions.InvalidIssuerError: Invalid issuer
The issuer claim in the JWT does not match the `issuer` parameter provided to `jwt.decode()`, or no `issuer` was provided.
fix
Ensure the `issuer` parameter passed to `jwt.decode()` exactly matches the `iss` claim in the JWT. For production, never set `verify_iss=False`.
Upgrade
Version history
0.8.0latest on PyPI · released Aug 7, 2024
Audit
Dependencies
PyJWTrequiredCore JWT encoding/decoding, this library provides key fetching for it.
aiohttprequiredUsed internally for asynchronous HTTP requests to fetch configurations and JWKS.
cryptographyoptionalRequired by PyJWT for RSA/ECDSA algorithms commonly used with JWKS.
Agent activity
18 hits · last 30 days
node
14
OpenAI (training)
1
Resources
pyjwt-key-fetcher — pip install pyjwt-key-fetcher · libregistry