feat(first-boot): keep login keychain unlocked on headless targets#30
Conversation
Mac Mini dev servers can't use GUI auto-login (iCloud + TouchID accounts disallow it), so the login keychain starts locked every reboot. Without this setting, once unlocked it would re-lock after idle timeout, which breaks claude-wrapper's Keychain-backed service account token fetch. Set lock-on-sleep + no idle timeout so that once the admin unlocks the keychain (console login or manual unlock), it stays unlocked until the next sleep — matching typical headless build-server operation. Discovered during Phase 4 verification on MIMOLETTE: claude-wrapper appeared broken (op: failed to DecodeSACredentials) until the login keychain was manually unlocked. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
PR Review - feat(first-boot): keep login keychain unlocked on headless targets Scope: Single block added to import_external_keychain_credentials() in scripts/server/first-boot.sh (lines 485-495). Summary Clean, focused fix for a real operational problem (idle keychain re-locking breaking claude-wrapper). No blocking issues found. Observations -u flag semantics are non-obvious (maintenance note) security set-keychain-settings -l -u: the -u flag in the security(1) man page is documented as 'lock keychain after timeout interval', which reads as enabling idle lock rather than disabling it. The intended behavior (no idle timeout) is actually achieved by omitting -t, so -u without -t effectively sets the lock-after-timeout mechanism with no timeout value, producing the 'no-timeout' result seen in show-keychain-info. The comment correctly describes the outcome but could confuse a future reader who looks up the flag. A brief inline note tying -u to the 'no -t means no timeout' behavior would help. No functional concern. The manual verification on MIMOLETTE confirms the correct setting is applied. Placement is appropriate The block sits after unset op_service_token (line 480), so no credential is live in memory when the security call runs. Placing keychain configuration at the end of import_external_keychain_credentials is logical. Error handling is appropriate collect_warning on failure is correct. This is a configuration enhancement, not a critical gate. first-boot.sh continues normally if the call fails, which is the right tradeoff for a non-essential setting. Idempotency security set-keychain-settings is idempotent; repeated provisioning runs are safe. Security tradeoff is documented Removing idle timeout is a deliberate reduction in keychain security for operability on a headless build server. The comment explains why (no GUI auto-login, iCloud/TouchID accounts) and limits scope (lock-on-sleep is preserved). Adequate. VERDICT: PASS |
- prep-airdrop.sh: only echo "Provisioning..." when token is present (previously printed before the nil-check, creating misleading output when the dev Keychain lacks the token) — closes #28 - first-boot.sh: clarify -u flag semantics for security set-keychain-settings — the no-timeout behavior comes from omitting -t, not from -u alone — closes #31 - CLAUDE.md: note that opp is a local shell function from dotfiles, not a standard macOS/Homebrew tool — closes #29 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- prep-airdrop.sh: only echo "Provisioning..." when token is present (previously printed before the nil-check, creating misleading output when the dev Keychain lacks the token) — closes #28 - first-boot.sh: clarify -u flag semantics for security set-keychain-settings — the no-timeout behavior comes from omitting -t, not from -u alone — closes #31 - CLAUDE.md: note that opp is a local shell function from dotfiles, not a standard macOS/Homebrew tool — closes #29 Co-authored-by: Claude Code Bot <claude-code@smartwatermelon.github> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
Follow-up to #27. Mac Mini dev servers can't use GUI auto-login (iCloud + TouchID accounts disallow it), so the login keychain starts locked every reboot. Without the idle-timeout setting, even after a manual unlock it would re-lock during idle and break `claude-wrapper`'s Keychain-backed token fetch.
Adds `security set-keychain-settings -l -u login.keychain-db` to the end of `import_external_keychain_credentials` so once the admin unlocks the keychain (console login or manual `security unlock-keychain`), it stays unlocked until sleep.
How this was discovered
During Phase 4 verification on MIMOLETTE after #27 merged, `claude-wrapper` appeared broken with `op: failed to DecodeSACredentials: unexpected end of JSON input`. Root cause was the login keychain being locked — `security find-generic-password` silently returned empty.
Test plan
🤖 Generated with Claude Code