Severity
Low
Summary
Track switching credential storage from machine-derived AES-256-GCM (current) to native OS keychain integration (macOS Keychain via security, Linux Secret Service via secret-tool, Windows Credential Vault).
Why
The current implementation in src/credentials.ts encrypts the credentials file with a key derived from username + hostname + app salt:
function deriveKey(): Buffer {
const { username } = userInfo();
return createHash("sha256")
.update(`${username} ${hostname()} ${APP_SALT}`)
.digest();
}
This protects against accidental disclosure (backup tools copying $HOME, file shared by mistake, etc.) — a copied credentials file is unusable on a different machine or under a different user. But anyone who has the file and can guess (username, hostname) can reconstruct the key offline. For typical username and hostname patterns, the effective entropy is on the order of 30-40 bits.
OS keychain integration would:
- Enforce per-app ACLs (other apps must prompt the user before reading).
- Require an unlocked user session on macOS.
- Eliminate the ability to brute-force key derivation from leaked file + low-entropy identifiers.
Constraints
- Single-file SEA binaries can't ship native modules like
keytar. The implementation must shell out to platform CLIs (security, secret-tool, cmdkey/PowerShell).
- Headless / CI environments may have no keychain available — must keep the encrypted-file path as fallback.
- Existing encrypted credentials files should migrate forward on first read.
Acceptance criteria
- macOS:
security add-generic-password writes the credentials; security find-generic-password -w reads them.
- Linux: detect
secret-tool presence; use it when available, fall back to encrypted file otherwise.
- Windows:
cmdkey or PowerShell-based equivalent.
- Existing encrypted file is migrated to keychain on first read, then deleted.
- A "logout" command clears both keychain entry and any leftover file.
Tracked by
Pre-0.1.1 security review. Not a regression from current behavior — current encrypted-file scheme is strictly better than the pre-0.1.0 plain-JSON approach. Tracking as future-work follow-up.
Severity
Low
Summary
Track switching credential storage from machine-derived AES-256-GCM (current) to native OS keychain integration (macOS Keychain via
security, Linux Secret Service viasecret-tool, Windows Credential Vault).Why
The current implementation in
src/credentials.tsencrypts the credentials file with a key derived fromusername + hostname + app salt:This protects against accidental disclosure (backup tools copying
$HOME, file shared by mistake, etc.) — a copied credentials file is unusable on a different machine or under a different user. But anyone who has the file and can guess(username, hostname)can reconstruct the key offline. For typical username and hostname patterns, the effective entropy is on the order of 30-40 bits.OS keychain integration would:
Constraints
keytar. The implementation must shell out to platform CLIs (security,secret-tool,cmdkey/PowerShell).Acceptance criteria
security add-generic-passwordwrites the credentials;security find-generic-password -wreads them.secret-toolpresence; use it when available, fall back to encrypted file otherwise.cmdkeyor PowerShell-based equivalent.Tracked by
Pre-0.1.1 security review. Not a regression from current behavior — current encrypted-file scheme is strictly better than the pre-0.1.0 plain-JSON approach. Tracking as future-work follow-up.