feat: harden JWT auth with claim validation, JWKS, clock-skew, token refresh#212
Open
queentiffany1111-cloud wants to merge 1 commit into
Open
Conversation
…refresh (RiftCore00#197) - Validate iss and aud claims against AUTH_ISSUER/AUTH_AUDIENCE env vars - Add clock-skew tolerance (±30s, configurable via AUTH_CLOCK_SKEW_MS) - Add JWKS endpoint support (http+https) with TTL caching and RSA/EC key support - Explicitly reject alg:none tokens before jwt.verify - Pre-validate iss claim to ensure correct error ordering over aud check - Restrict allowed algorithms to HS256, RS256, ES256 - Add token_refresh message handler in server.js; updates client identity on success - Make wss connection callback async to support await verifyConnection - Add auth-hardening.test.js and refresh.test.js test suites - All 173 tests pass, lint clean
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.
Summary
Hardens the JWT authentication layer (src/auth.js) to close several security gaps present in the original implementation and adds a
token-refresh protocol to src/server.js so long-lived WebSocket connections (e.g. fleet-tracking clients) can rotate their credentials
without disconnecting.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Problem
The previous verifyConnection implementation only checked JWT signature and expiry. This left four concrete vulnerabilities and one
operational gap:
"none" or swap to a different algorithm family to bypass signature verification.
HMAC secret (e.g. an internal SSO) would be unconditionally accepted by the gateway.
received Token has expired on tokens that were nominally still valid.
provider (Auth0, Keycloak, AWS Cognito) require JWKS-based key rotation using RSA or EC public keys.
in live tracking streams.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Changes
src/auth.js
including none.
error message "Invalid token: unsupported algorithm".
manually before calling jwt.verify to ensure the correct error is returned (the jsonwebtoken library checks aud before iss internally,
which would produce misleading errors).
AUTH_CLOCK_SKEW_MS.
Supports both https:// and http:// transports. Keys are converted to Node.js KeyObject via crypto.createPublicKey({ format: "jwk", key:
jwk }) — no new dependencies added. HMAC (AUTH_SECRET) flow is preserved as the default when AUTH_JWKS_URI is not set.
is returned on background refresh errors to avoid auth outages during transient JWKS endpoint failures.
src/server.js
The server verifies the new token, updates actualClientId in-place, and replies with { type: "token_refresh_ok" }. On failure it returns
{ type: "error", payload: { message: "..." } } and keeps the connection open. actualClientId is promoted from const to let to allow
identity updates on refresh.
src/validator.js
MESSAGE_SIZE_LIMITS.
tests/auth-hardening.test.js (new)
Covers all new hardening paths:
tests/refresh.test.js (new)
Integration tests against a live createServer instance:
Testing
Test Files: 21 passed | 1 skipped (22)
Tests: 173 passed | 15 skipped (188)
The 15 skipped tests are PostgreSQL integration tests that require a live database — skipped by design in CI without a DB. All auth,
server, refresh, and hardening tests pass. npm run lint passes with zero errors.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Out of Scope
closes #197