Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/auth/secure-credential-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ export class SecureCredentialStore {
*/
private async initializeKeychain(): Promise<void> {
try {
// On Linux without a display session, libsecret's D-Bus call to the Secret
// Service blocks the Node.js event loop indefinitely — the keyring daemon is
// running but locked, and the GUI unlock dialog never appears in SSH/headless
// environments. Since @napi-rs/keyring uses native N-API (not async I/O),
// Promise.race cannot interrupt it. Bail out early instead.
if (process.platform === 'linux' && !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY) {
this.keychainAvailable = false;
logger.debug('Skipping OS keychain: Linux without display (headless/SSH) — using encrypted file storage');
return;
}

// Dynamically import keyring
const keyring = await import('@napi-rs/keyring');
this.Entry = keyring.Entry;
Expand Down
Loading