fix(keyring): persist OAuth tokens across Homebrew upgrades

Disable KeychainTrustApplication to prevent macOS Keychain from tying
access control to the specific binary hash. This allows tokens to
survive across Homebrew upgrades where the binary hash changes.

Users may see a one-time keychain access prompt after upgrade.

Fixes #86

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
salmonumbrella 2026-01-19 19:24:50 -08:00 committed by Peter Steinberger
parent 548fdd20c4
commit 0a7dd586af
2 changed files with 10 additions and 3 deletions

View File

@ -173,8 +173,14 @@ func openKeyring() (keyring.Keyring, error) {
}
cfg := keyring.Config{
ServiceName: config.AppName,
KeychainTrustApplication: runtime.GOOS == "darwin",
ServiceName: config.AppName,
// KeychainTrustApplication is intentionally false to support Homebrew upgrades.
// When true, macOS Keychain ties access control to the specific binary hash.
// Homebrew upgrades install a new binary with a different hash, causing the
// new binary to lose access to existing keychain items. With false, users may
// see a one-time keychain prompt after upgrade (click "Always Allow"), but
// tokens survive across upgrades. See: https://github.com/steipete/gogcli/issues/86
KeychainTrustApplication: false,
AllowedBackends: backends,
FileDir: keyringDir,
FilePasswordFunc: fileKeyringPasswordFunc(),

View File

@ -17,10 +17,11 @@ import (
var errKeyringOpenBlocked = errors.New("keyring open blocked")
// keyringConfig creates a keyring.Config for testing.
// KeychainTrustApplication is false to match production config (see store.go).
func keyringConfig(keyringDir string) keyring.Config {
return keyring.Config{
ServiceName: config.AppName,
KeychainTrustApplication: runtime.GOOS == "darwin",
KeychainTrustApplication: false,
AllowedBackends: []keyring.BackendType{keyring.FileBackend},
FileDir: keyringDir,
FilePasswordFunc: fileKeyringPasswordFunc(),