Upgrading to v0.26.12
Цей вміст ще не доступний вашою мовою.
v0.26.12 fixes a session-token disclosure present since the v0.25 line, and makes
Rodauth’s active-session table load-bearing on every authenticated request in full
authentication mode. There is no schema migration and no dependency change, so rollback is
a tag swap.
Upgrading from a release earlier than v0.26.11? Work forward through the guides for the releases you are skipping, then return here. From v0.22 or v0.23, start with v0.24.0. From anywhere in the v0.26 line, complete v0.26.6 and then v0.26.11. Each of those carries configuration work this guide assumes is already done.
Before You Start
Section titled “Before You Start”- Back up Redis/Valkey and, in
fullmode, the authentication database. - Record your current tag:
docker compose exec app ots version(or yourOTS_IMAGE_TAG). - Note your
AUTHENTICATION_MODE. Most of this guide applies only tofull(see Simple or Full if you are unsure which mode you run). - In
fullmode, note how your authentication database is reached — direct, pooler, or failover pair — and who is paged when it goes down. Step 1 depends on it.
What Changes
Section titled “What Changes”| Area | Change | Action required? |
|---|---|---|
| Response headers | Router 404/500 fallbacks no longer replay other requests’ Set-Cookie |
Yes — decide on a session sweep |
| Full-mode sessions | Every authenticated request checks the active-session row; an unreachable authdb refuses the request | Yes — verify authdb availability |
| Session deadlines | Inactivity 24h → 72h, now enforced per request; 30-day lifetime enforced per request | No, but expect sign-outs |
| Account deletion | Full-mode Settings deletion posts to /auth/close-account |
Only if you filter paths at a proxy |
| Colonel API | details.cache removed, refresh=1 ignored, pagination.capped added |
Only if you script the Colonel API |
| Audit log | Preview and no-change rows carry dry_run: true and outcome: 'no_change' |
Only if you consume LOG_AUDIT_SYSLOG |
| New config | RODAUTH_ADMIN_URL (optional, outbound links only) |
No |
The Upgrade Checklist
Section titled “The Upgrade Checklist”Steps 1 and 2 are ordered by dependency: an authdb that cannot answer will refuse every signed-in request, which looks like the site being down, so establish that first.
-
Only in
fullmode — confirm the authentication database is highly available. Every authenticated request now runs one indexedSELECTonaccount_active_session_keys, plus a throttledlast_usewrite at most once per 300 seconds per session. When the database cannot answer, the request is refused. Before this release an authdb outage left existing sessions working from Redis; it no longer does. Check connection-pool headroom for your request rate, and add an alert on[active_session_gate] authdb unreachable. -
Pull
v0.26.12and restart. No migration runs. Existing sessions signed in before v0.26.10 carry no join key, are deliberately exempt from the new gate, and age out on their own, so nobody is mass-logged-out on deploy. -
Decide whether to revoke sessions. Before this release, a
404or500served by the router fallback could return session cookies committed on earlier requests, to whoever hit that miss. Your access logs hold the fallback-response volume that tells you how exposed you were. To clear it:ots sessions revoke-all <customer>per account, or have users sign out everywhere. -
Only if a proxy, WAF, or path allowlist sits in front of the app: confirm
POST /auth/close-accountreaches it. Full-mode account deletion moved there;/api/account/destroyremains the simple-mode path. -
Only if you script the Colonel API: the Organizations list no longer sends a
details.cacheblock and acceptsrefresh=1without acting on it. Treat a response carryingpagination.capped: trueas “there may be more”, not as a complete list. -
Only if you consume the audit syslog stream: exclude rows carrying
dry_run: trueoroutcome: 'no_change'from operator-action counts. These markers are now applied uniformly;email/sync_provider_feedbackpreviews carrydry_runfor the first time.
Verify
Section titled “Verify”- Sign in, then revoke that session from
/account/settings/security/sessionsin another browser. The first browser should be signed out on its next request, not at expiry. - In
fullmode, stop the authentication database on a staging tier. Requests should be refused and the log should readauthdb unreachable ... (fail closed), not a revocation. Start it again; the same browser should work without signing in. curl -sI https://<host>/definitely-not-a-routetwice from two different clients. Neither response should carry aSet-Cookiebelonging to the other.- If you set
RODAUTH_ADMIN_URL, open a customer in the Colonel console — the Rodauth account should render as a link rather than plain text.
Config Mapping Reference
Section titled “Config Mapping Reference”New configuration
# Base URL of the standalone Rodauth Admin instance. Optional, credential-free,# and never requested from — the Colonel console only renders outbound links.# Only meaningful in full auth mode; unset renders those links as plain text.RODAUTH_ADMIN_URL=http://127.0.0.1:9292Changed behavior
# Unchanged default (on). What changed is its reach. Before v0.26.12 the flag# controlled whether Rodauth tracked sessions at all (rows, join-key stamp,# /auth/active-sessions routes), but nothing outside those routes consulted the# rows, and the settings card was hidden by a hardcoded `false` regardless. It# now also gates per-request revocation enforcement, the two session deadlines,# and (for the first time) whether the Active Sessions card is shown.## Parsed as ENV['AUTH_ACTIVE_SESSIONS_ENABLED'] != 'false' — only the exact# lowercase string 'false' disables it. 'False', '0', 'no' and 'off' leave it ON.AUTH_ACTIVE_SESSIONS_ENABLED=trueThe 72-hour inactivity deadline and the 30-day lifetime deadline are constants in
Onetime::ActiveSessionGate. There is no environment variable for either.
Troubleshooting
Section titled “Troubleshooting”Every signed-in user is refused, and sign-in fails too
Section titled “Every signed-in user is refused, and sign-in fails too”The authentication database is unreachable. Look for
[active_session_gate] authdb unreachable. This is the fail-closed path, not a
revocation. Restore the database; sessions are honored again without a re-login.
Users are signed out after a weekend away
Section titled “Users are signed out after a weekend away”The 72-hour inactivity deadline is now enforced on every request rather than swept on the sessions page. Expected. The 30-day lifetime deadline behaves the same way.
Session revocation still doesn’t take effect
Section titled “Session revocation still doesn’t take effect”AUTH_ACTIVE_SESSIONS_ENABLED is set to false, or the mode is not full. With the flag
off this affects user-driven revocation only; ots sessions revoke-all and the other
operator-driven paths still work.
Account deletion from Account Settings still fails
Section titled “Account deletion from Account Settings still fails”In full mode it now posts to /auth/close-account. Confirm that path reaches the app
through your proxy.
The Organizations list shows fewer rows than expected
Section titled “The Organizations list shows fewer rows than expected”Search is bounded now. Check pagination.capped in the response — true means the result
stopped short deliberately. Narrow the search rather than paging for the rest.
Log lines about last_use refresh on active-session row failed
Section titled “Log lines about last_use refresh on active-session row failed”The write that keeps a session alive is failing. If it persists, live sessions will be signed out at the 72-hour deadline. Treat it as a database write-path problem, not a session problem.
Rollback
Section titled “Rollback”There is no migration, so rolling back is pinning OTS_IMAGE_TAG=v0.26.11 and restarting.
RODAUTH_ADMIN_URL is inert on the older tag and can be left set.