Task: Implement JWT refresh

Table of Contents

This page documents a task in the JWT refresh story. It captures the goal, current status, acceptance, and any notes or results.

Goal

Close the loop on JWT auth with refresh + telemetry, so long-running sessions don't expire silently.

Status

Field Value
State DONE
Parent story JWT refresh
Now Completed 2026-03-21.
Waiting on None.
Next None.
Last touched 2026-03-21

Acceptance

  • Configurable lifetimes via iam.token.access_lifetime_seconds + party_selection_lifetime_seconds + max_session_seconds + refresh_threshold_pct.
  • iam.v1.auth.refresh NATS endpoint + validate_allow_expired() in JWT authenticator.
  • ores_iam_auth_events_tbl TimescaleDB hypertable with hourly + daily continuous aggregates (90-day raw, 3-year daily retention).
  • make_request_context() returns std::expected with explicit token_expired / unauthorized (no more silent fallback).
  • error_reply() helper sends X-Error NATS headers.
  • 48 domain handler files updated to handle the new std::expected return type.
  • account_handler + auth_handler hot-reload token settings on system_setting_changed.
  • Shell: nats_session::authenticated_request validates X-Error; on token_expired refreshes + retries once; max_session_exceeded throws.
  • Qt: ClientManager QTimer fires at 80% of token lifetime; sessionExpired signal connects to MainWindow → warning dialog + re-login.

Plan

Captured during execution; cleared into the parent story on close.

Notes

Builds on the RS256 + JWT-in-claims work from sprint 14; the telemetry hypertable is the load-bearing addition.

Result

JWT refresh works end-to-end; auth telemetry persisted.

Emacs 29.1 (Org mode 9.6.6)