feat(agentex-ui): accept RSA (RS256) private_key_jwt keys#367
Merged
Conversation
erichwoo-scale
force-pushed
the
erichwoo/agentex-ui-private-key-jwt-rsa
branch
from
July 16, 2026 21:47
59a5dc5 to
ffee3f0
Compare
declan-scale
approved these changes
Jul 16, 2026
The bespoke private_key_jwt signer was ES256/P-256 only. Sign the RFC 7523 client_assertion with `jose` (importJWK + SignJWT) instead of hand-rolled WebCrypto, so an app can authenticate with an EC (ES256/384/512) or RSA (RS256/384/512, incl. PS*) private JWK. - Replaces base64url + importEs256Key + jwsSigningFor + the manual JWT assembly with jose, which validates the JWK against its alg and handles every key type natively (no silent-wrong-alg edge cases). - signingAlgForJwk derives the alg (explicit JWK `alg`, else EC by curve / RSA → RS256) for both the login key import and the refresh assertion. - jose is promoted from a transitive dep (via @auth/core) to a direct one. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
erichwoo-scale
force-pushed
the
erichwoo/agentex-ui-private-key-jwt-rsa
branch
from
July 16, 2026 21:58
ffee3f0 to
523e62e
Compare
erichwoo-scale
enabled auto-merge (squash)
July 16, 2026 21:58
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
Brings agentex-ui's bespoke
private_key_jwtsigner back on par with@scale/oneauth-nextjsand, in the process, replaces the hand-rolled WebCrypto assertion code withjose. The signer was ES256/P-256 only; an app configured with an RSAOIDC_PRIVATE_KEY_JWKcouldn't sign the client assertion. It now signs with EC (ES256/384/512) or RSA (RS256/384/512, incl. PS*), alg derived from the key.Purely additive — the ES256 path is behaviorally unchanged.
What changed
Single file,
agentex-ui/auth.ts(+josepromoted to a direct dependency):jose—importJWK+SignJWTreplacebase64url,importEs256Key,jwsSigningFor, and the manual JWT assembly (~55 lines → ~10).josevalidates the JWK against itsalgand handles every key type natively, so there are no silent-wrong-alg edge cases to guard by hand.signingAlgForJwkderives the alg — explicit JWKalg, else EC by curve (ES256/384/512) / RSA → RS256 — for both the login-key import and the refresh assertion. RS384/RS512/PS256 are supported by declaringalgon the JWK.josewas already in the tree transitively (it's what@auth/coreuses); this makes it a direct dep.Everything else was already at parity (agentex-ui set the original bar):
getSessionTokenBFF, token-stripped session, fail-loud misconfig guards, top-level-await key resolution, OIDC-discovery-driven endpoints.Verification
tsc --noEmit,next lint(0 warnings), Prettier, andnext build— all clean.Test plan
OIDC_PRIVATE_KEY_JWKclients still log in and refresh (ES256, unchanged).OIDC_PRIVATE_KEY_JWK(registered withprivate_key_jwt+ matching public JWK) → login + refresh succeed (RS256 assertion accepted).alg: RS384/PS256→ assertion carries that alg.OIDC_PRIVATE_KEY_JWK→ clear error (jose rejects), not a silent wrong-alg.client_secret_postpath unaffected.🤖 Generated with Claude Code
Greptile Summary
This PR adds RSA (
RS256and family) support toagentex-ui'sprivate_key_jwtsigner by replacing ~55 lines of hand-rolled WebCrypto JWT assembly withjose'simportJWK+SignJWT. The ES256/P-256 path is preserved exactly;signingAlgForJwkadds EC-curve and RSA-key-type detection for the algorithm negotiation.signingAlgForJwkrespects an explicitalgfield in the JWK, falls back to curve-based EC alg (ES256/384/512), or defaults toRS256for bare RSA keys (PSS variants requirealgto be declared on the JWK, which is documented in the PR).importClientPrivateKeyand theSignJWTflow replaceimportEs256Key,jwsSigningFor, and the manualbase64urlheader/payload/signature construction — delegate alg validation and signing tojoseentirely.joseis promoted from a transitive dependency (via@auth/core) to a direct one at^6.0.0.Confidence Score: 5/5
Safe to merge — the change is purely additive, the EC/ES256 path is behaviorally unchanged, and the new RSA path delegates all alg validation to jose rather than adding bespoke string-matching that could be wrong.
The replaced code was simple enough that the rewrite is easy to audit line-by-line. signingAlgForJwk correctly checks jwk.alg first, EC curve second, and RSA last. The SignJWT builder covers iss/sub/aud/jti/iat/exp identically to the old manual assembly. No logic regressions visible.
No files require special attention — both changed files are straightforward.
Important Files Changed
Reviews (3): Last reviewed commit: "feat(agentex-ui): accept EC/RSA private_..." | Re-trigger Greptile