feat(auth): durable vault-unlock secret to stop repeated password prompts (Phase 1)#187
Merged
LiranCohen merged 2 commits intoJun 24, 2026
Conversation
…mpts Resolve the vault password through one path (explicit -> GITD_PASSWORD -> public-reader -> durable secret store -> prompt) and persist a freshly entered secret per profile in a durable store: the OS keychain (macOS security, Linux secret-tool) when available, otherwise a machine-keyed AES-256-GCM encrypted file under ~/.enbox/secrets/. After the first unlock, commands restore the session without re-prompting for the vault password. GITD_SECRET_BACKEND=keychain|file|none pins or disables the backend. A cached secret that is later rejected is cleared automatically to avoid lock-out; gitd auth logout / reset drop the stored secret. Part of #186 (Phase 1). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 of the auth/session/server redesign (#186). Stacked on #185 (
fix/install-wrapper-symlink-clobber), which contains the session/helper subsystem being reworked.What & why
gitd asked for the vault password on essentially every command because each one unlocked its own agent via an ad-hoc
getPassword()(env → TTY prompt) with no durable cache. This PR introduces a single resolution path and a durable per-profile secret store, so after the first unlock the session is restored without re-prompting — the first concrete fix for "asked for the vault password repeatedly" and a session that survives across separate processes.Changes
src/auth/secret-store.ts— durable per-profile secret store: OS keychain (macOSsecurity, Linuxsecret-tool) when available, otherwise a machine-keyed AES-256-GCM encrypted file under~/.enbox/secrets/(mode 0600).GITD_SECRET_BACKEND=keychain|file|nonepins/disables the backend.src/auth/vault-password.ts— one resolution path: explicit →GITD_PASSWORD→ hidden public-reader secret → durable store → interactive prompt (TTY raw / piped), tracking the source.rememberVaultSecretcaches only freshly entered (tty/explicit) secrets — neverenv.forgetVaultSecretclears them.src/cli/main.ts— both connect sites resolve via the new path and cache on a verified unlock; a rejected cached secret is cleared automatically so a stale secret can't lock you out. (Removes the old inlinegetPassword.)src/cli/commands/auth.ts—auth logincaches the new secret;auth logout/auth resetdrop it.src/cli/identity-wizard.ts— first-run wizard caches the secret too.Behavior / compatibility
GITD_PASSWORDstill wins for CI/non-interactive use and is not persisted.Verification
bun run build— clean (zero TS errors)bun run lint— clean (--max-warnings 0)bun test .spec.ts— 1802 pass, 8 skip, 0 fail (incl. 17 new tests intests/secret-store.spec.tsandtests/vault-password.spec.tscovering round-trip, encryption-at-rest, resolution precedence, cache-only-fresh-secrets, and forget)🤖 Generated with Claude Code