PyJWT は jwt.encode() と jwt.decode() で JSON Web Token のエンコードとデコードを行い、PyJWKClient で JWKS エンドポイントから署名鍵を取得します。非対称アルゴリズムは crypto extra で提供され、これを指定すると pyca/cryptography がインストールされます。これを入れた 2.15.1 は、HS、RS、PS、ES の各ファミリー、ES256K、EdDSA を扱えましたが、より新しい Ed25519 と Ed448 という名前には対応しておらず、NotImplementedError: Algorithm not supported が送出されました。
検証のデフォルトは厳格です。algorithms を指定しない jwt.decode() は It is required that you pass in a value for the "algorithms" argument で失敗し、署名のない alg: none トークンは、algorithms=["none"] を指定しても検証を通りませんでした。また、PEM や OpenSSH の公開鍵を HS256 のシークレットとして使うと InvalidKeyError で拒否されました。ES256 は P-256 に結び付けられており、P-384 の鍵で署名すると曲線の不一致で失敗しました。
一方、利用者に任されている部分もあります。exp は任意なので、options 引数の require に列挙しない限り、これを含まないトークンはいつまでもデコードできます。また、leeway のデフォルトはゼロなので、時刻が数秒ずれたサーバー同士でも有効期限の判定が食い違います。短い HMAC シークレットも InsecureKeyLengthWarning が出るだけで受け入れられ、この警告はログの中で見落としがちです。シークレットは JWT シークレットチェッカーで確認してください。
ES256 署名は、JWS が求める 64 バイトの生の r‖s 形式です。署名を DER のまま組み込んだトークン(たとえば KMS の署名呼び出しの結果を使ったもの)は、汎用的な Signature verification failed で失敗します。トークンを JWT デバッガーに貼り付けて署名の長さを確認し、DER ⇄ 生形式の変換ツールで変換してください。
サンプルでは、アルゴリズム、発行者、オーディエンスを固定し、exp を必須にして、30 秒の時刻のずれを許容しています。これらが、別のサービスから受け取ったトークンに対して jwt.decode() を安全に呼び出すための 4 つの設定です。