# Verify a CodeB JWT locally in Python. # Signed with RS256 against the tenant JWKS. European Digital Identity # Wallet id_tokens are validated the same way. # [jwt-validation-cookbook 2026-07-23] # pip install "pyjwt[crypto]" requests import jwt, requests, time from jwt import PyJWKClient ISSUER = "https://" AUDIENCE = "" JWKS_URL = ISSUER + "/.well-known/jwks.json" # PyJWKClient caches keys in memory. First call fetches once; subsequent # calls read from cache. Force refresh on kid-miss. _jwks = PyJWKClient(JWKS_URL, cache_keys=True, lifespan=600) def verify(token: str) -> dict: signing_key = _jwks.get_signing_key_from_jwt(token).key return jwt.decode( token, signing_key, algorithms=["RS256"], audience=AUDIENCE, issuer=ISSUER, leeway=5, # seconds options={"require": ["exp", "iat", "iss", "aud", "sub"]}, ) if __name__ == "__main__": import sys claims = verify(sys.argv[1]) print("sub =", claims["sub"]) print("role =", claims.get("role", "user")) print("scope=", claims.get("scope")) # RFCs: 7519 (JWT), 7517 (JWK), 7518 (JWA).