DSK-13Recommended
Keep tokens in the system keychain
Store sign-in tokens and keys in the operating system's credential store, which is the Mac Keychain, Windows Credential Manager or the Linux Secret Service. Never write them to a settings file or local storage.
How to do it
Files in the user's folder are read by every program the user runs and copied by every backup. The credential store ties the secret to the user's login. Electron offers safeStorage, and libraries such as keyring in Python and Rust reach all three stores. This is the desktop form of keep tokens and keys in the Keychain or Keystore. Ship no shared secret in the app, as ship no secrets in the app package says.
Examples
Python example
import keyring
SERVICE = "com.example.ledgerly"
def save_token(account: str, token: str) -> None:
keyring.set_password(SERVICE, account, token)
def load_token(account: str) -> str | None:
return keyring.get_password(SERVICE, account)
JavaScript example
import { safeStorage } from 'electron';
export const saveToken = async (store, token) => store.set('token', safeStorage.encryptString(token).toString('base64'));
export const loadToken = async store => safeStorage.decryptString(Buffer.from(await store.get('token'), 'base64'));
How to check
After sign-in on each platform, a search of the app's data folder for the token value finds nothing. The token appears in the system's credential store under the app's name.
Sources
Related rules
- MOB-19 Keep tokens and keys in the Keychain or Keystore in Mobile apps
- MOB-20 Ship no secrets in the app package in Mobile apps
- DSK-24 Take secrets from the environment or a file instead of a flag in Desktop apps, extensions and CLIs
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/desktop-apps/web-code-inside-desktop-apps/desktop-keychain">Agent Wranglers desktop apps, extensions and CLIs playbook</a>. In code you write, add a comment next to it with the same link.