fix(keycardai-oauth): migrate JOSE handling from authlib to joserfc - #195
Merged
Conversation
authlib.jose is deprecated and emits an AuthlibDeprecationWarning on import, surfacing to every SDK user. Migrate JWT signing/verification and JWK handling to joserfc (authlib 's recommended replacement, already in the dependency tree). - decode_and_verify_jwt: import key via joserfc, decode with explicit algorithms, return .claims - get_jwks_key: return import_key(jwk).as_pem() - create_client_assertion / key export: joserfc encode + import_key - derive key type from the JWS algorithm so PEM imports do not emit joserfc's implicit-key SecurityWarning - drop the direct authlib dependency (remains transitively via fastmcp)
Contributor
📦 Release PreviewThis analysis shows the expected release impact: 📈 Expected Version Changes📋 Package Details[
{
"package_name": "keycardai-oauth",
"package_dir": "packages/oauth",
"has_changes": true,
"current_version": "0.21.0",
"next_version": "0.21.1",
"increment": "PATCH"
}
]📝 Changelog PreviewThis comment was automatically generated by the release preview workflow. |
…e diff Address review feedback on the joserfc migration: - _key_type_for_algorithm now raises on an unrecognized algorithm instead of silently defaulting to RSA (a genuine mismatch previously failed later at key import / the algorithms=[...] gate; now it fails explicitly). - Hand-restore uv.lock to a minimal authlib->joserfc swap. Regenerating under a newer uv had added unrelated python_full_version markers to transitive deps (aiologic, onnxruntime deps, sympy). joserfc was already present transitively, so only the oauth entry changes. Verified consistent with uv sync --frozen.
Contributor
📦 Release PreviewThis analysis shows the expected release impact: 📈 Expected Version Changes📋 Package Details[
{
"package_name": "keycardai-oauth",
"package_dir": "packages/oauth",
"has_changes": true,
"current_version": "0.21.0",
"next_version": "0.21.1",
"increment": "PATCH"
}
]📝 Changelog PreviewThis comment was automatically generated by the release preview workflow. |
This PR promotes joserfc to a first-class dependency, so it must not ship on a vulnerable floor. joserfc 1.6.4 is affected by: - GHSA-gg9x-qcx2-xmrh (HIGH): HS256/384/512 verify accepts empty/nil HMAC key - GHSA-wphv-vfrh-23q5 (MODERATE): b64=false RFC7797 JWS payload-size bypass 1.6.8 fixes both (superset of the two Socket bot PRs #189/#190, which target 1.6.7 and 1.6.8). Root uv.lock resolves to 1.6.8; tests pass. Neither advisory affects our own code path (we verify RS256), but a correct floor matters for downstream consumers.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Contributor
📦 Release PreviewThis analysis shows the expected release impact: 📈 Expected Version Changes📋 Package Details[
{
"package_name": "keycardai-oauth",
"package_dir": "packages/oauth",
"has_changes": true,
"current_version": "0.21.0",
"next_version": "0.21.1",
"increment": "PATCH"
}
]📝 Changelog PreviewThis comment was automatically generated by the release preview workflow. |
Larry-Osakwe
marked this pull request as ready for review
July 20, 2026 02:57
mnoble
approved these changes
Jul 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Kim flagged that the SDK emits an
AuthlibDeprecationWarningon import:authlib.josefires this unconditionally at import time, so everykeycardai-oauthuser sees it whether or not they touch JWTs. This migrates our JOSE usage to joserfc (authlib author's recommended replacement, already in our dependency tree via authlib itself).Changes
utils/jwt.pydecode_and_verify_jwt: import the verification key viajoserfc.jwk.import_key, decode with explicitalgorithms=[...], return.claims.get_jwks_key: returnimport_key(jwk).as_pem()._key_type_for_algorithmso PEM imports pass an explicit key type (RS/PS→RSA, ES→EC, Ed→OKP, HS→oct).server/private_key.py: key export viaimport_key(pem, "RSA").as_dict(); client-assertion signing viajose_jwt.encode(...), dropping the intermediatecryptography.load_pem_private_keyhop.tests/.../test_jwt.py: retargeted mocks (jose_jwt/import_key,.claims,.as_pem()) and reworked the real-crypto token factory to sign with joserfc.pyproject.toml: dropped the directauthlibdependency, addedjoserfc.Two gotchas designed around (verified empirically)
joserfc.jwt.decoderequires a Key object, not a PEM string, so the key is imported insidedecode.SecurityWarningwhen importing a PEM without an explicit key type, which would just trade one warning for another. Deriving the key type from the algorithm silences it.Verification
python -W error, confirming both the authlib deprecation warning and the joserfc SecurityWarning are gone.Caveat
authlibremains inuv.lockas a transitive dependency offastmcp-slim, not from our code. The warning is eliminated from the corekeycardai-oauthimport path. Users onkeycardai-fastmcpmay still hit it from fastmcp's own internalauthlib.joseusage — that's upstream's issue to fix.Parity note for reviewers
joserfc does not auto-validate
expon decode; neither did the old authlib call path, so no behavior change there. joserfc is stricter on some structural validation, which is a net positive.