WIP: A simple cli for daily tangled use cases and AI integration. This is for my personal use right now, but happy if others get mileage from it! :)

Detect locked keychain and provide better auth error message #17

closed opened by markbennett.ca

Context#

When a Mac is locked (screen saver, sleep), the OS keychain may become temporarily inaccessible. @napi-rs/keyring's getPassword() returns undefined for a missing entry but throws for a platform failure (locked keychain, access denied).

Currently resumeSession() in api-client.ts catches all errors and calls clearCurrentSessionMetadata(). This incorrectly wipes stored credentials when the keychain is just temporarily locked, forcing the user to run tangled auth login again unnecessarily.

macOS keychain behaviour#

  • CLI tools (unsigned) do not automatically get an unlock dialog (unlike GUI apps)
  • When the screen is locked, no interactive prompts are possible; on screen unlock the login keychain typically auto-unlocks
  • The macOS security CLI tool can unlock the keychain interactively: security unlock-keychain

Tasks#

  • Export a KeychainAccessError class from src/lib/session.ts
  • Wrap getPassword() throws in loadSession() and getCurrentSessionMetadata() as KeychainAccessError (any throw is a platform error; missing entries return undefined, not an error)
  • In resumeSession() in api-client.ts: rethrow KeychainAccessError without clearing metadata; only clear metadata for other errors (invalid/stale session)
  • Add ensureAuthenticated(client) helper to src/utils/auth-helpers.ts that calls resumeSession(), on KeychainAccessError tries security unlock-keychain (macOS only, prompts on TTY), retries once, then falls back to a clear error message with manual instructions
  • Replace the 7 repeated auth check blocks in src/commands/issue.ts with await ensureAuthenticated(client)
  • Add tests for: KeychainAccessError is rethrown without clearing metadata; unlock and retry success; unlock failure falls back to error message

Notes#

On macOS, execSync('security unlock-keychain', { stdio: 'inherit' }) passes the terminal TTY through so the user is prompted for their keychain password. This only works in an interactive terminal; SSH sessions or locked screens will fall through to the error message with instructions to run security unlock-keychain manually.

Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:b2mcbcamkwyznc5fkplwlxbf/sh.tangled.repo.issue/3mek7osp4il2t