fix(auth): extend JWT TTL to 30d to match cookie - #918
Merged
Conversation
- Align TOKEN_EXPIRY with the session cookie Max-Age (COOKIE_MAX_AGE_DAYS = 30 days). The cookie shell outlived the 24h JWT, so remote WebUI kept sending a dead token, producing an endless reject-and-reconnect loop after ~24h desktop uptime. - Stop-gap until token refresh lands, then TTL returns to a short access-token lifetime; add token_lifetime_is_30_days test locking the value. - Sync the unused SESSION_EXPIRY label and stale 24h comments to 30d.
piorpua
pushed a commit
that referenced
this pull request
Aug 25, 2026
🤖 I have created a release *beep* *boop* --- ## [0.1.72](v0.1.71...v0.1.72) (2026-08-24) ### Features * **auth:** account/secret CLI and decoupled encryption root ([#917](#917)) ([0251be7](0251be7)) * **conversation:** persist plan snapshots and expose them for rehydration ([#916](#916)) ([b2f12e9](b2f12e9)) * **sidebar:** tear down agent processes on archive ([#925](#925)) ([7ac84f9](7ac84f9)) ### Bug Fixes * **auth:** extend JWT TTL to 30d to match cookie ([#918](#918)) ([ecbedfa](ecbedfa)) * **claude:** apply model selection in-band so it matches the claude CLI ([#928](#928)) ([706a2eb](706a2eb)) * **cli:** register unindexed top-level subcommands in the capability index ([#929](#929)) ([c490161](c490161)) ### Performance Improvements * slim auto-inject skill descriptions to the injection budget ([#930](#930)) ([9b7e4ce](9b7e4ce)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
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
Stop-gap for iOfficeAI/AionUi#4124. On the remote WebUI (phone), once the desktop had been up for roughly a day the Core JWT expired and was never refreshed, so every request carried a dead token and the client fell into an unrecoverable 401 / WebSocket reconnect loop.
The session cookie has a 30-day
Max-Age(COOKIE_MAX_AGE_DAYS), but the JWT inside it expired after 24h. That mismatch — a live cookie wrapping a dead token — is what triggered the loop. This bumpsTOKEN_EXPIRYfrom 24h to 30d so the token lifetime matches the cookie, closing the window.This is a stop-gap, not the fix. The real solution is a refresh-token flow (tracked separately). Once that lands,
TOKEN_EXPIRYreturns to a short access-token lifetime; the doc comment and thetoken_lifetime_is_30_daystest record this so the later change is a deliberate contract update, not a silent regression.Changes
aionui-auth/src/jwt.rs:TOKEN_EXPIRY24h → 30d with a stop-gap doc comment;sign()doc updated; newtoken_lifetime_is_30_daystest asserting both the constant andexp - iat; blacklist-test comment synced to 30d.aionui-common/src/constants.rs:SESSION_EXPIRYlabel"24h"→"30d"(currently unused; kept consistent, documented).Testing
just pushpre-push gate (migration check, lint, format, tests) passed — that is how this branch reached origin.token_lifetime_is_30_dayslocks the 30-day value.Scope / blast radius
Open-source AionUi runs the backend in Local identity mode (loopback), which skips JWT and WebSocket auth entirely — this change is inert there. It only affects deployments using the
UserSession/AionProidentity modes, i.e. the remote-WebUI path in the linked issue.Relates to iOfficeAI/AionUi#4124