feat(auth): git push/fetch work without a running helper (Phase 1b)#188
Merged
LiranCohen merged 3 commits intoJun 24, 2026
Merged
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>
getVaultPassword() now consults the durable secret store (OS keychain / encrypted file) between the public-reader secret and the /dev/tty prompt, so the credential helper's direct-signing fallback and the daemon auto-start are non-interactive after the first unlock. git push / git fetch succeed even when no local helper is running, and a dead or never-started helper no longer blocks pushes. Lockfiles are written atomically (temp + rename) to avoid a corrupt lockfile on a crash mid-write. Part of #186 (Phase 1b). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Base automatically changed from
feat/auth-session-core
to
fix/install-wrapper-symlink-clobber
June 24, 2026 02:56
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 1b of the auth/session/server redesign (#186). Stacked on #187 (
feat/auth-session-core) — review/merge that first.What & why
This fixes the "keep the server alive" half of the complaint. Today, when no local helper (daemon) is running,
git push/fetchcan fail or hang: the credential helper's fallback and the daemon auto-start resolve the vault password viagetVaultPassword(), which only knewGITD_PASSWORD→ public-reader → a/dev/ttyprompt. During a push, git owns stdin, so the prompt often can't run (and never could in CI), so a dead or never-started helper blocked the push.Now
getVaultPassword()also consults the durable secret store from Phase 1 (OS keychain / encrypted file), which is populated on the first unlock. So aftergitd auth login,git push/fetchsucceed without a prompt even when no helper is running — the credential helper signs a fresh DID push token directly. The helper becomes a performance optimization, not a hard dependency on the critical path.Changes
src/git-remote/tty-prompt.ts—getVaultPassword()is now async and resolves:GITD_PASSWORD→ public-reader secret → durable secret store (per profile) →/dev/ttyprompt →null.src/git-remote/credential-main.ts—awaitthe resolver in the no-daemon fallback (+ doc).src/git-remote/resolve.ts—awaitthe resolver in the daemon auto-start path.src/cli/commands/serve-lifecycle.ts—awaitthe resolver ingitd helper start.src/daemon/lockfile.ts— write lockfiles atomically (temp file + rename) so a crash mid-write can't leave a corrupt lockfile.Behavior / compatibility
POST /auth/token, no password) is unchanged and still preferred when a helper is running.GITD_PASSWORDstill wins for CI and is never persisted; the public-reader (no-identity) path is unchanged.Verification
bun run build— cleanbun run lint— clean (--max-warnings 0)bun test .spec.ts— 1803 pass, 8 skip, 0 fail (updatedtests/tty-prompt.spec.tscovers the new durable-store resolution +GITD_PASSWORDprecedence; the async signature change is type-checked across all call sites)🤖 Generated with Claude Code