Skip to content

fix(auth): cap CLI JWT refresh to original 30-day lifetime#129

Merged
ohong merged 2 commits into
mainfrom
codex/fix-infinite-token-renewal-vulnerability
Jun 11, 2026
Merged

fix(auth): cap CLI JWT refresh to original 30-day lifetime#129
ohong merged 2 commits into
mainfrom
codex/fix-infinite-token-renewal-vulnerability

Conversation

@ohong

@ohong ohong commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Motivation

  • The existing sliding refresh allowed CLI JWTs to be repeatedly reissued and chained past their original 30-day lifetime, making stolen or post-deletion tokens renewable indefinitely.
  • The goal is to retain the usability improvement (transparent token rotation for interactive users) while restoring an absolute cap on credential lifetime so refreshes cannot extend tokens forever.

Description

  • Added an oiat (original issued-at) claim and extended createCliToken to accept an optional originalIat so refreshed tokens preserve the original issuance anchor via oiat and do not push the absolute expiry forward.
  • Changed token creation to compute exp as the minimum of the normal 30-day expiry and the absolute expiry derived from oiat, and added the oiat field into the payload.
  • Updated verifyCliTokenWithRefresh to compute originalIat and absoluteAgeSeconds and only mint a refreshed token when the token is past the refresh threshold and still within the original 30-day lifetime, passing originalIat through when creating the refreshed token.
  • Added a unit test does not extend lifetime beyond the original 30 days in apps/web/__tests__/unit/cli-auth.test.ts to assert refreshed tokens cannot be chained past the initial 30-day window.

Testing

  • Added unit coverage in apps/web/__tests__/unit/cli-auth.test.ts that verifies refresh behavior and the new non-chainable lifetime guard.
  • Attempts to run the test file locally were blocked by the environment: pnpm -C apps/web vitest __tests__/unit/cli-auth.test.ts failed due to an unsupported package manager specification and cd apps/web && bun x vitest __tests__/unit/cli-auth.test.ts failed with npm registry access (HTTP 403), so tests could not be executed in this runner.
  • The change is minimal and focused to preserve existing routes and behavior while restoring a bounded token lifetime; unit tests were added to cover the regression.

Codex Task

@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
straude Ready Ready Preview, Comment Jun 11, 2026 6:37am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@ohong, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 54 minutes and 42 seconds. Learn how PR review limits work.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f067464d-60b2-4c56-af88-93c4ee47dfc4

📥 Commits

Reviewing files that changed from the base of the PR and between f88fdf7 and 1f30f82.

📒 Files selected for processing (2)
  • apps/web/__tests__/unit/cli-auth.test.ts
  • apps/web/lib/api/cli-auth.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-infinite-token-renewal-vulnerability

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.

ohong and others added 2 commits June 10, 2026 23:36
The previous assertion expected second?.refreshedToken to be null, but a
token past its 30-day cap is rejected outright (verify returns null), so
the optional chain yielded undefined. Decode the refreshed token's exp and
assert it equals the original expiry, then assert rejection past 30 days.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ohong ohong force-pushed the codex/fix-infinite-token-renewal-vulnerability branch from 2c571f6 to 1f30f82 Compare June 11, 2026 06:36
@ohong

ohong commented Jun 11, 2026

Copy link
Copy Markdown
Owner Author

Merged. Caps CLI JWT refresh to the original 30-day lifetime so a leaked token can't be chained indefinitely via the sliding refresh. createCliToken now carries an oiat (original issued-at) claim and anchors exp to min(now+30d, oiat+30d); verifyCliTokenWithRefresh propagates oiat through each rotation, so every refreshed token expires at the original 30-day mark rather than 30 days from the refresh. I rewrote the regression test to assert the actual security property — it decodes the refreshed token and confirms its exp equals the original token's exp, then confirms the token is rejected outright past 30 days. (The original assertion checked second?.refreshedToken against null, but a token past its cap is rejected entirely, so the optional chain returned undefined and CI failed.) CI green.

@ohong ohong merged commit 3bdd736 into main Jun 11, 2026
4 of 5 checks passed
@ohong ohong deleted the codex/fix-infinite-token-renewal-vulnerability branch June 11, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant