Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to store a JWT token locally on computer?

I'm building a custom command line tool using node. The user will need to be able to sign in and persist their session. I have done this using node and passport before for a web app using localStorage, but how should I go about storing the users JWT with a cli tool.

like image 204
Derek Dawson Avatar asked Oct 19 '25 12:10

Derek Dawson


1 Answers

  • If it's an OAuth2 or OIDC access_token then even though it's a JWT you should treat it as an opaque blob because OAuth2 and OIDC clients are not the intended audience for access_token (they're meant to pass it as-is verbatim to the remote Protected Resource).
    • I note that OAuth2 and ODIC allow access_token to be anything - including non-JWT tokens, such as a short opaque "reference token" value.
    • This means that you can write the JWT (in its Base64-encoded format) directly to a file on-disk and read it back as you like. Because it's Base64 you don't need to worry about file encoding too much (e.g. both 7-bit ASCII vs UTF-8 are fine).
  • If it's an ODIC id_token then you could Base64-decode it and store the decoded raw JSON in a file if you intend to use each individual Claim stored within in your client. Note that if you do store the raw JSON to a file you must use UTF-8 unless you want difficulties down the line.

Each platform has a preferred location for per-user temporary data:

  • On Windows, you should store this in a subdirectory of %LOCALAPPDATA% (C:\Users\me\AppData\Local), e.g. %LOCALAPPDATA%\YourCompany\YourProduct\Jwt.json.
    • If security is important you should encrypt this file at-rest using DPAPI: DPAPI encrypts files using a secret key that's part of the user's profile - you just pass the cleartext into the Win32 function and it returns the encrypted ciphertext which you then write to disk. Make sure you're careful about the binary encoding of any text you read and write, of course. DPAPI can be used on a per-user (roaming between machines) or per-machine (multiple users, but only on the same machine) basis.
  • Windows also has the Credential Manager API, but it's not well-suited to storing large blobs: https://learn.microsoft.com/en-us/windows/desktop/secauthn/kinds-of-credentials
  • On macOS you'll want to use the Keychain API: https://developer.apple.com/documentation/security/keychain_services
  • On Linux, there is no system-provided secret-storage mechanism ( https://dzone.com/articles/storing-secrets-in-linux ), but most approaches seem to write secrets to disk and then set chmod on the file to prevent access by other users. You could also encrypt the file with a custom password that the user must enter whenever your program runs.
    • As with Windows, you should still save this data under the user's home directory (~/) and not the shared /tmp directory. The convention on Linux for application-specific data is to use a hidden (dot-prefixed) home subdirectory, e.g. ~/.yourCompany/yourProduct or just ~/.yourProduct.
like image 95
Dai Avatar answered Oct 21 '25 02:10

Dai