Skip to content

feat(identity-webhook): composite app_*_* token exchange#6

Open
eliteprox wants to merge 13 commits into
mainfrom
feat/composite-app-token-exchange
Open

feat(identity-webhook): composite app_*_* token exchange#6
eliteprox wants to merge 13 commits into
mainfrom
feat/composite-app-token-exchange

Conversation

@eliteprox

@eliteprox eliteprox commented Jul 11, 2026

Copy link
Copy Markdown

Summary

Test plan

  • cd identity-webhook && npm test

Summary by CodeRabbit

  • New Features
    • Added optional OIDC token-exchange environment settings.
    • Added support for underscore-delimited composite API keys (app_<24hex>_<secret>), including updated exchange credential formats.
  • Bug Fixes
    • Hardened OIDC issuer/JWKS discovery and verification (issuer normalization, stricter discovery response validation, tighter verification claims).
    • Improved Authorization: Bearer <token> parsing to be scheme-based (case-insensitive) and return empty when missing.
    • Refined composite token exchange caching to prevent stale inflight overwrites.
  • Documentation
    • Updated environment variable examples and OIDC guidance for JWKS override/discovery fallback and verification requirements.

Replace the incorrect default {issuer}/.well-known/jwks.json with
issuer-relative OIDC discovery (openid-configuration → jwks_uri).
Validate discovery issuer, wrap JWKS fetch errors with the URL, and
keep OIDC_JWKS_URI as an explicit override. Unit tests cover discovery
and leave api_key mode unchanged.
Accept Bearer app_<24hex>_<secret> when OIDC_TOKEN_EXCHANGE_BASE_URL is set:
RFC 8693 exchange at the app-scoped token endpoint, then jwtVerify the minted
access token (same JWKS discovery path as livepeer#62). Secret segment is opaque
(operator prefixes allowed); reject cs_ / _cs_ client-secret shapes. Harden
cache keys (salted HKDF) and log sanitization. Document exchange env vars.
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 578b6a53-3f25-4fe5-821d-6b0c50b20be4

📥 Commits

Reviewing files that changed from the base of the PR and between be32152 and d1d816e.

📒 Files selected for processing (2)
  • identity-webhook/verifiers.mjs
  • identity-webhook/verifiers.test.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
  • identity-webhook/verifiers.test.mjs

📝 Walkthrough

Walkthrough

The update changes bearer and composite API-key parsing, strengthens OIDC issuer discovery and JWKS resolution, enforces JWT claims, and improves exchange-cache handling. Tests cover validation, retries, malformed responses, exchange behavior, and resolver errors. OIDC configuration documentation is updated.

Changes

Identity verification updates

Layer / File(s) Summary
Bearer token extraction validation
identity-webhook/protocol.mjs, identity-webhook/protocol.test.mjs
Bearer extraction now requires a case-insensitive Bearer scheme and returns an empty token for bare inputs.
Composite API-key parsing and exchange flow
identity-webhook/verifiers.mjs, identity-webhook/legacy-env.test.mjs, identity-webhook/verifiers.test.mjs
Composite credentials use app_<24hex>_<secret>, with updated parsing, rejection cases, exchange requests, identity assertions, and promise-stable cache behavior.
OIDC discovery and JWKS resolution
identity-webhook/verifiers.mjs, identity-webhook/verifiers.test.mjs, .env.example, README.md
Issuer normalization, discovery consistency checks, JWKS validation, required JWT claims, resolver checks, retry behavior, warning messages, and OIDC configuration documentation were updated.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant createOidcVerifier
  participant discoverJwksUri
  participant fetchImpl
  participant JWKSResolver
  createOidcVerifier->>discoverJwksUri: resolve normalized issuer
  discoverJwksUri->>fetchImpl: fetch OIDC discovery document
  fetchImpl-->>discoverJwksUri: return validated jwks_uri
  createOidcVerifier->>fetchImpl: fetch JWKS document
  fetchImpl-->>JWKSResolver: provide JWKS JSON
  JWKSResolver-->>createOidcVerifier: return signing-key resolver
Loading
🚥 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 The title clearly summarizes the main change: composite app__ token exchange support in identity-webhook.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ 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 feat/composite-app-token-exchange

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Clear the in-flight discovery promise on failure so later verifies can
retry, and wrap createLocalJWKSet errors with the JWKS URL.
Move the OIDC discovery docs off normalizeIssuer and align the non-ok
HTTP error message with response.ok (2xx).
Trim issuers, reject blank jwtIssuer, require jwks to be a jose key
function, and align JWKS non-ok HTTP errors with response.ok.
Wrap createRemoteJWKSet URL construction so Invalid URL failures retain
the offending jwks_uri / OIDC_JWKS_URI in the verify warn log.

@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 `@identity-webhook/verifiers.mjs`:
- Around line 147-150: Update the JWT verification flow around normalizeIssuer
and createOidcVerifier so the normalized issuer is passed to verifyJwtBearer
instead of the original jwtIssuer. Ensure the same normalized value is used
consistently for discovery acceptance and JWT issuer validation, including the
code path covering lines 163–195.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 98362a45-c5c9-4a91-813d-e770f1e8172c

📥 Commits

Reviewing files that changed from the base of the PR and between a036e9d and 04a898c.

📒 Files selected for processing (5)
  • .env.example
  • README.md
  • identity-webhook/legacy-env.test.mjs
  • identity-webhook/verifiers.mjs
  • identity-webhook/verifiers.test.mjs

Comment thread identity-webhook/verifiers.mjs
* fix(identity-webhook): resolve JWKS via OIDC discovery

Replace the incorrect default `{issuer}/.well-known/jwks.json` with
issuer-relative OIDC discovery (`openid-configuration` → `jwks_uri`),
while keeping `OIDC_JWKS_URI` as an explicit override.

Validate discovery issuer, trim/reject blank issuers, require `jwks` to be
a jose key function, and clear the in-flight discovery promise on failure
so later verifies can retry. Wrap JWKS fetch, `createLocalJWKSet`, and
malformed JWKS URL errors with the offending URL for clearer verify logs.

Also update issuer examples in docs and unit tests; api_key mode remains
unchanged.
Expire stale composite-exchange inflight cache entries, require Bearer
scheme, reject non-origin token-exchange URLs, expand JWT algs to
RS256/ES256, require exp with 60s clock skew, and normalize OIDC issuer
consistently for discovery and jwtVerify.
export function bearerToken(authorization) {
const value = (authorization ?? "").trim();
return value.replace(/^Bearer\s+/i, "").trim();
const m = /^Bearer\s+(.+)$/i.exec((authorization ?? "").trim());
…e races

Allow jwtVerify to match iss with or without a trailing slash after
issuer normalization, and only clear/set composite-exchange cache
entries when they still reference the same inflight promise.
@sonarqubecloud

Copy link
Copy Markdown

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.

2 participants