Skip to content

chore(auth): bump jsonwebtoken 9→10 + dedupe harness + ES256 coverage - #15

Merged
InstaZDLL merged 2 commits into
mainfrom
chore/auth-tests-followups
May 30, 2026
Merged

chore(auth): bump jsonwebtoken 9→10 + dedupe harness + ES256 coverage#15
InstaZDLL merged 2 commits into
mainfrom
chore/auth-tests-followups

Conversation

@InstaZDLL

@InstaZDLL InstaZDLL commented May 30, 2026

Copy link
Copy Markdown
Owner

Summary

Three follow-ups bundled — same area (auth tests + crypto deps), so single review surface.

Supersedes Dependabot #13 which only bumped the version string without fixing the v10 breaking changes (CryptoProvider feature gate) or DCO sign-off. I'll close #13 when this lands.

1. jsonwebtoken 9 → 10

  • v10 split the crypto backend behind a CryptoProvider indirection (rustls pattern). Exactly one of rust_crypto / aws_lc_rs must be enabled or every signature verify panics at runtime.
  • Picked rust_crypto — pure Rust, matches rustls-tls on reqwest, no native deps.
  • v10's defaults include use_pem (~20 KB pem + asn.1 parser). Production code reads keys via from_rsa_components(n, e) off the JWKS — PEM is only needed by the test harness for signing. Cargo feature unification per build target lets us re-enable use_pem as a dev-dep override, keeping the release binary lean.

2. Dedupe inline harness in tests/auth.rs

  • The mock-JWKS server + signing helpers lived inline in tests/auth.rs AND in tests/jwks_harness.rs (used by tests/jwt_middleware.rs).
  • tests/auth.rs now does mod jwks_harness; like the other consumer. Single source of truth.
  • -170 LOC in tests/auth.rs.

3. ES256 / elliptic-curve coverage

  • build_cached_key in src/auth.rs has separate branches for RSA and EllipticCurve, but only RSA was tested. A future refactor could silently break the EC path until a real Better Auth deploy with ES256 keys failed.
  • New JwksHarness::spawn_es256() mirrors spawn() against a P-256 keypair. Per-test keygen ~1 ms (vs ~50 ms RSA), so the sweep is essentially free.
  • 4 new ES256 tests: happy path, wrong-key reject, unknown-kid reject, cross-algorithm reject (RS256 token against ES256 JWKS).
  • New HarnessAlg enum + JwksHarness::header_with_kid(&self) so a test that switches algos doesn't thread the algorithm manually.

Deps

Dep Type Why
jsonwebtoken runtime bumped 9 → 10, default-features=false + rust_crypto
jsonwebtoken dev override re-add use_pem for the test harness
p256 = "0.13" (features: ecdsa, pkcs8) dev ES256 keypair generation

No new runtime deps.

Test plan

  • cargo check --all-targets
  • cargo fmt --all --check
  • cargo clippy --all-targets -- -D warnings
  • cargo test --test auth (17 passed — 13 RS256 + 4 ES256)
  • CI runs the full suite against Postgres (jwt_middleware + the 1.b.5 battery)

Summary by CodeRabbit

Notes de version

  • New Features

    • Ajout du support ES256 en plus de RS256 pour la vérification JWT.
  • Chores

    • Mise à jour de la dépendance JWT vers une version plus récente avec backend crypto optimisé; ajustements des dépendances de test pour le parsing PEM et génération ECDSA.
  • Tests

    • Réécriture des tests pour utiliser un harness partagé, couverture étendue (ES256, cas d’échec, cache et détections d’algorithme).

Review Change Stack

Three follow-ups in one PR — same area (auth tests + crypto deps),
same review surface.

1. **jsonwebtoken 9 → 10** (supersedes Dependabot #13)
   - v10 splits the crypto backend behind a `CryptoProvider` (same
     pattern rustls uses). Exactly one of `rust_crypto` / `aws_lc_rs`
     must be enabled or every signature verify panics. We pick
     `rust_crypto` — pure Rust, matches the `rustls-tls` feature
     we use on reqwest, no OpenSSL / aws-lc native deps to ship.
   - v10's default features include `use_pem` (~20 KB of pem +
     simple_asn1). Production code uses `from_rsa_components(n, e)`
     off the JWKS — PEM is only needed by the test harness for
     signing. Cargo's feature unification per build target lets us
     re-enable `use_pem` as a dev-dep override, keeping the release
     binary lean.
   - Dependabot's #13 only bumped the version string; it didn't
     fix the broken feature config OR sign-off the commits. This
     commit does both, so we close #13 in favour of this PR.

2. **Dedupe inline harness in tests/auth.rs**
   - The mock JWKS server + sign-and-mint helpers lived inline in
     tests/auth.rs AND in the shared tests/jwks_harness.rs that
     tests/jwt_middleware.rs uses. tests/auth.rs now does
     `mod jwks_harness;` like the other consumer — single source of
     truth for the harness, future API tweaks touch one file.
   - Net: -170 LOC in tests/auth.rs.

3. **ES256 / elliptic-curve coverage**
   - `build_cached_key` in src/auth.rs has separate branches for
     `AlgorithmParameters::RSA` and `AlgorithmParameters::EllipticCurve`,
     but only the RSA branch had tests. A future refactor could
     silently break the EC path without anyone noticing until a
     real Better Auth deploy with ES256 keys failed verify.
   - New `JwksHarness::spawn_es256()` mirrors `spawn()` against a
     P-256 keypair. Per-test keygen is ~1 ms (vs ~50 ms for the
     RSA path) so the EC sweep is essentially free.
   - 4 new tests on the EC branch: happy path, wrong-key reject,
     unknown-kid reject, cross-algorithm reject (RS256 token against
     ES256 JWKS — confused-deputy defense).
   - New `HarnessAlg` enum + `JwksHarness::header_with_kid(&self)`
     so a test that switches algorithms doesn't have to thread the
     algorithm through manually; the harness knows.

Deps:
- p256 = "0.13" (dev-dep, features = ["ecdsa", "pkcs8"]) for the
  ES256 keypair generation.
- No new runtime deps.

Test plan:
- cargo check --all-targets ✅
- cargo fmt --all --check ✅
- cargo clippy --all-targets -- -D warnings ✅
- cargo test --test auth (17 passed, 13 RS256 + 4 ES256) ✅
- CI will run the rest against Postgres.

Signed-off-by: InstaZDLL <github.105mh@8shield.net>
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 354b9ebe-41af-4da7-b7aa-03576b512eec

📥 Commits

Reviewing files that changed from the base of the PR and between fbc84b8 and 9b1839b.

📒 Files selected for processing (1)
  • tests/auth.rs

📝 Walkthrough

Walkthrough

Mise à jour de jsonwebtoken v9→v10 (rust_crypto backend), ajout de p256 en dev, refactor du harness de tests (JwksHarness) pour supporter RS256/ES256, et migration + extension des tests JWT (RS256 migrés, suite ES256 ajoutée).

Changes

JWT Upgrade and Multi-Algorithm Test Support

Layer / File(s) Summary
Upgrade jsonwebtoken and add crypto/EC dependencies
Cargo.toml
jsonwebtoken passe de v9 à v10 avec default-features = false et backend rust_crypto en runtime; dev-dependencies activent use_pem; ajout de p256 pour tests EC.
Harness multi-algorithm infrastructure (HarnessAlg, spawn methods)
tests/jwks_harness.rs
Ajout public de HarnessAlg { Rs256, Es256 }, refactor des spawn() en spawn_rs256(advertise_alg) et nouvelle spawn_es256(), et adaptation des imports jwk/p256.
Harness instance methods and serve() refactoring
tests/jwks_harness.rs
serve(...) accepte l'algorithme, JwksHarness expose alg, ajout de header_with_kid(&self, kid), extraction de build_rsa_jwks(...), et documentation mise à jour.
Existing RS256 tests migrated to JwksHarness API
tests/auth.rs
Réécriture des tests RS256 pour utiliser JwksHarness et helpers (mint, verifier, good_claims(TEST_SUB)) ; jwks_unreachable utilise JwtVerifier::with_client.
ES256 test suite (validation, rejection, cross-algorithm)
tests/auth.rs
Ajout de tests ES256 : validation, signature mismatch, kid inconnu, et rejet cross-algorithm (assertion AlgorithmMismatch/KeyNotFound selon le cas).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🔐 De JWT v9 à v10 on grimpe,
Le cryptage Rust chante et nous imprime,
RS et ES, deux algos en piste,
Le harness tourne — les tests résistent,
🎭 clés signées, erreurs bien tristes.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Le titre décrit avec précision les trois changements principaux : bump de jsonwebtoken 9→10, déduplication du harness, et couverture ES256.
Linked Issues check ✅ Passed Le PR répond complètement aux objectifs de l'issue #13 : upgrade jsonwebtoken v9→v10, activation du backend crypto_provider via rust_crypto, et gestion des features par l'absence de defaults en runtime et re-enable de use_pem en dev.
Out of Scope Changes check ✅ Passed Tous les changements (Cargo.toml, tests/auth.rs, tests/jwks_harness.rs) sont directement liés aux trois objectifs déclarés : bump, déduplication du harness, et ES256 coverage.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/auth-tests-followups

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/auth.rs`:
- Around line 326-357: The test es256_jwk_rejects_rs256_token currently expects
AuthError::KeyNotFound or AlgorithmMismatch but the spawn_es256 harness reuses
TEST_KID so verify_token() resolves the kid and returns
AuthError::AlgorithmMismatch; update the test to assert exclusively for
AuthError::AlgorithmMismatch, update the header comment to reflect that the kid
is shared and the mismatch comes from header.alg vs cached.algorithm, and remove
or adjust any lines referencing KeyNotFound; target the test function
es256_jwk_rejects_rs256_token, the JwksHarness::spawn_es256 setup, and the
verify_token()/AuthError matching to make this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 01ad42d0-5724-474e-8946-0d8989289382

📥 Commits

Reviewing files that changed from the base of the PR and between 7d14bb8 and fbc84b8.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock, !Cargo.lock, !*.lock
📒 Files selected for processing (3)
  • Cargo.toml
  • tests/auth.rs
  • tests/jwks_harness.rs

Comment thread tests/auth.rs
CR caught an overly-permissive assertion. The disjunction
`AuthError::KeyNotFound | AuthError::AlgorithmMismatch` was hiding
which path the verifier actually took — and the `KeyNotFound`
branch is unreachable because both harnesses publish their JWK
under the same `TEST_KID`. The verifier's `resolve_kid` finds the
cached EC key, then the explicit
`if header.alg != cached.algorithm` cross-check fires on
`RS256 != ES256` and returns `AlgorithmMismatch`.

Test now asserts exclusively `AlgorithmMismatch`. The doc-comment
is rewritten to call out the shared-kid setup + the alg cross-check
path, so the next reader doesn't have to reverse-engineer it.

Verified by `cargo test --test auth es256_jwk_rejects_rs256_token`
— still passes, confirming the empirical path.

Signed-off-by: InstaZDLL <github.105mh@8shield.net>
@InstaZDLL
InstaZDLL merged commit 470e896 into main May 30, 2026
8 checks passed
@InstaZDLL
InstaZDLL deleted the chore/auth-tests-followups branch May 30, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant