Tokens That Outlive the Process
A daemon that forgets every token the moment you restart it is a daemon you stop trusting. And a modern OAuth client that doesn’t do PKCE is leaving a door open for no good reason. Both of those are now fixed.
Remembering Across Restarts
AuthDeck keeps tokens in memory for speed, but memory dies with the process. So the token store now writes through to disk—atomically, with tight permissions—and reloads on startup.
Where the file lives follows the OS, not my home directory:
Linux ~/.local/share/authdeck/tokens.json (honors XDG_DATA_HOME)
macOS ~/Library/Application Support/authdeck/tokens.json
Windows %AppData%\authdeck\tokens.json
The path is overridable, but it defaults to somewhere a state file actually belongs.
Two details matter more than the path:
- Expired tokens are kept, not dropped. An expired access token still carries its refresh token. Throwing it away would force a fresh interactive login for no reason.
- A refresh pass runs on boot. Instead of waiting for the first request, the background renewer executes immediately after startup, so a token that aged out while the process was down is silently replaced.
PKCE by Default
PKCE (RFC 7636) is now on for every authorization-code provider. AuthDeck generates a code_verifier, sends its S256
challenge with the authorization request, and presents the verifier at the token exchange. For providers that refuse the
extra parameters, it can be turned off:
pkce: false # default is true
Defaulting it on is a deliberate stance. PKCE exists to stop authorization-code interception, and the “it’s only localhost” argument is weaker than it sounds—a local callback is still a public client. Secure should be the path of least resistance, not an option you remember to enable.
Persistence and PKCE are unglamorous, and that’s the point. Good defaults do the boring, correct thing quietly, and only surface when you’d otherwise be annoyed—after a restart, or after reading about a class of attack you didn’t want to think about.





