Vault access tokens expire (~10min); consumers hit 401s after container
recreates. Now: refresh_token persisted at login and rotated on every
refresh (Vaultwarden semantics); 401 on an authed call refreshes once
and retries; if refresh is unavailable, full relogin (password+TOTP
injected by the sm shims from the TSGCOO vault-account env) is attempted
before failing. cmdLogin passes the TOTP seed again (regression).
QA: corrupted access_token -> TSGCOO sm read self-healed end-to-end.
Ticket: https://projects.knownelement.com/issues/832
The login grant requested offline_access but the issued refresh_token
was parsed and discarded: every access token died with the ~1h
Vaultwarden TTL, and consumers (all lanes) hit HTTP 401 on sync until
a human re-logged in.
- persist refresh_token in state (0600, same file)
- add refresh grant (grant_type=refresh_token, rotated token saved)
- on 401 for authed calls: refresh once, retry the request
- persistTokens() keeps the rest of the state intact
Build verified in golang:1.23-alpine (vet + gofmt clean). After
deploy, one `sm login` issues a refresh token (~30d, rotated on use)
and sessions self-heal from then on.