Skip to content

Conversation

@ericallam
Copy link
Member

@ericallam ericallam commented Nov 19, 2025

This PR fixes #2678 by correctly signing the JWT token returned when triggering a task with the parent preview branch's API key if the environment has a parentEnvironment.

@changeset-bot
Copy link

changeset-bot bot commented Nov 19, 2025

⚠️ No Changeset found

Latest commit: e551b4a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

Walkthrough

This change refactors JWT signing key extraction across the API routes and authentication services. A new helper function extractJwtSigningSecretKey is introduced that centralizes key sourcing logic with parent environment fallback. The responseHeaders function signature in the trigger route is simplified by removing the optional triggerClient parameter and consolidating conditional JWT generation logic. Environment variable references are replaced with the new extractor function across multiple batch route handlers. Debug logging is added to JWT-related operations.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • The new extractJwtSigningSecretKey helper function implements straightforward fallback logic (parentEnvironment.apiKey with environment.apiKey as default)
  • Changes follow a consistent pattern across multiple files (replacing environment.apiKey references)
  • Function signature modification in responseHeaders simplifies the API by removing an optional parameter
  • Verify the parent environment fallback logic in extractJwtSigningSecretKey handles all intended authentication scenarios
  • Confirm that removing the triggerClient parameter from responseHeaders doesn't affect behavior in the idempotency response path or other call sites
  • Check that the new centralized key extraction is applied consistently across all JWT generation points

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is empty; the author provided no content against the required template with sections for Testing, Changelog, and Checklist. Add a description following the repository template, including: closes issue reference, testing steps, changelog entry describing the JWT generation fix, and completion of the contributing guide checklist.
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title clearly summarizes the main change: fixing JWT token generation for preview branches after triggering a run, with direct reference to the issue being fixed.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/issue-2678

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bee59de and e551b4a.

⛔ Files ignored due to path filters (7)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • references/issue-2687/.env.example is excluded by !references/**
  • references/issue-2687/README.md is excluded by !references/**
  • references/issue-2687/package.json is excluded by !references/**
  • references/issue-2687/src/repro.ts is excluded by !references/**
  • references/issue-2687/src/trigger/task.ts is excluded by !references/**
  • references/issue-2687/trigger.config.ts is excluded by !references/**
📒 Files selected for processing (5)
  • apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts (4 hunks)
  • apps/webapp/app/routes/api.v1.tasks.batch.ts (2 hunks)
  • apps/webapp/app/routes/api.v2.tasks.batch.ts (2 hunks)
  • apps/webapp/app/services/apiAuth.server.ts (1 hunks)
  • apps/webapp/app/services/realtime/jwtAuth.server.ts (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
apps/webapp/app/services/realtime/jwtAuth.server.ts (2)
packages/trigger-sdk/src/v3/index.ts (1)
  • logger (41-41)
apps/webapp/app/services/apiAuth.server.ts (1)
  • AuthenticatedEnvironment (41-44)
apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts (2)
apps/webapp/app/services/apiAuth.server.ts (1)
  • ApiAuthenticationResultSuccess (50-60)
apps/webapp/app/services/realtime/jwtAuth.server.ts (1)
  • extractJwtSigningSecretKey (95-99)
apps/webapp/app/routes/api.v2.tasks.batch.ts (1)
apps/webapp/app/services/realtime/jwtAuth.server.ts (1)
  • extractJwtSigningSecretKey (95-99)
apps/webapp/app/routes/api.v1.tasks.batch.ts (1)
apps/webapp/app/services/realtime/jwtAuth.server.ts (1)
  • extractJwtSigningSecretKey (95-99)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (8)
apps/webapp/app/services/apiAuth.server.ts (1)

239-240: LGTM! Debug logging aids troubleshooting.

The debug log will help diagnose JWT validation issues.

apps/webapp/app/routes/api.v1.tasks.batch.ts (1)

167-167: LGTM! Correctly uses parent environment's API key for preview branches.

The change from environment.apiKey to extractJwtSigningSecretKey(environment) ensures JWTs are signed with the parent environment's key when dealing with preview branches, which is the core fix for this PR.

apps/webapp/app/routes/api.v2.tasks.batch.ts (1)

182-182: LGTM! Consistent fix applied to v2 route.

Same fix as v1 batch route - correctly uses extractJwtSigningSecretKey(environment) to handle preview branches.

apps/webapp/app/services/realtime/jwtAuth.server.ts (2)

42-42: LGTM! Debug logging aids troubleshooting.

The debug log will help diagnose JWT validation issues during development and production.


95-99: LGTM! Clean helper centralizes key extraction logic.

The extractJwtSigningSecretKey helper correctly implements the fallback pattern (parent environment's key for preview branches, own key otherwise) and matches the existing pattern at line 39.

apps/webapp/app/routes/api.v1.tasks.$taskId.trigger.ts (3)

14-14: LGTM! Correct import for the new helper.


146-149: LGTM! Debug logging aids troubleshooting.

The debug log will help diagnose authentication and response header issues.


177-200: Verify whether the behavioral change to always-on JWT is intentional or an oversight.

The behavioral change is confirmed. The trigger endpoint extracts triggerClient from request headers (line 66) but does NOT pass it to the responseHeaders function, unlike batch routes which do. This results in the trigger endpoint always generating JWT for all clients, whereas batch routes conditionally generate it only when triggerClient === "browser".

However, the practical impact appears minimal because client SDKs handle the JWT header gracefully with conditional logic and fallback client-side JWT generation. But this architectural inconsistency should be addressed explicitly—either make trigger conditional like batch routes, or update batch routes to match trigger's behavior, depending on your API design intent.


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 and usage tips.

@matt-aitken matt-aitken merged commit 6464eee into main Nov 19, 2025
31 checks passed
@matt-aitken matt-aitken deleted the fix/issue-2678 branch November 19, 2025 13:42
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.

3 participants