Repository navigation
Start the native helper from its own directory - #1169
Merged
theoephraim merged 2 commits intoOct 1, 2026
Merged
Conversation
JayOfTheKeyboard
added a commit
to JayOfTheKeyboard/JayOfTheKeyboard
that referenced
this pull request
Sep 30, 2026
Contributor
There was a problem hiding this comment.
Important
Handle an empty XDG_CONFIG_HOME before changing the helper cwd, or the Rust helper can select the install directory as its key store.
Reviewed changes in commit 675409cd, covering the native-helper spawn options, every production helper and daemon launch path, user config path normalization, unit coverage, and the locked-cwd binary smoke test.
- Helper working directory: Native helper processes and detached daemons now start from the resolved helper directory so Bun can spawn them when the caller cwd is inaccessible.
- Config path preservation: Relative
XDG_CONFIG_HOMEvalues are made absolute for both JS path consumers and child-process environments. - WSL launch paths: Helper probes,
wslpath, and PowerShell daemon startup receive the same cwd and environment handling. - Regression coverage: Unit tests pin spawn options and config resolution, while a conditional binary smoke test exercises an inaccessible cwd with a bundled helper.
azure/gpt-5.6-sol | 𝕏
Contributor
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes since the prior Pullfrog review, focused on the empty XDG_CONFIG_HOME correction and its regression coverage.
- Normalized empty config paths: Dropped an empty
XDG_CONFIG_HOMEfrom native-helper child environments so the helper uses the same default config location asgetUserVarlockDir(), with a focused unit test covering the behavior.
azure/gpt-5.6-sol | 𝕏
Bun's spawn fails with EACCES when the caller's cwd cannot be entered, which happens when varlock runs as a service user via runuser from a private home directory. Start the helper, and the WSL tools that start its daemon, from the helper's directory. A relative XDG_CONFIG_HOME is the only thing that tied the helper to the caller's cwd, so it is now resolved to an absolute path: in getUserVarlockDir, which builds the daemon's socket and pid paths, and in the env passed to the helper.
getUserVarlockDir treats an empty value as unset, but the Rust helper read it as the relative path "varlock", which now resolved under the helper's install directory.
theoephraim
force-pushed
the
fix-native-helper-spawn-cwd
branch
from
October 1, 2026 19:27
062c8b7 to
ea3ff2e
Compare
@varlock/ci-env-info
varlock
@varlock/native-helper-darwin
@varlock/native-helper-linux-arm64
@varlock/native-helper-linux-x64
@varlock/native-helper-win32-x64
@varlock/google-secret-manager-plugin
commit: |
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.

The standalone binary fails to start its native helper when varlock runs from a directory the current user cannot enter:
I hit this on a production host. A secret-rotation script ran
runuser -u <service-user> -- varlock cache clear --yesfor each service identity.runuserkeeps the caller's cwd, here a home directory with mode 750, so the clear failed for all six identities. WithcacheTtl=forever, the services kept the old credential until the cache files were deleted by hand. Reproduced in a clean container, the same command exits 1 with the error above.The cause is in Bun 1.3.14, which the binary is built with (
packageManager: [email protected]). Itschild_processspawn fails with EACCES when the parent's cwd cannot be entered, even for/bin/true. Bun 1.4.2 and Node both spawn fine from the same cwd.Change
getNativeBinarySpawnOptions()inbinary-resolver.tsstarts the helper from its own directory, which anyone who can run it can enter. It is used for every spawn of the helper (runNativeBinary,spawnNativeBinaryAsync, decrypt via the daemon, the detached daemon) and for the two WSL tools that start the Windows daemon (wslpath,powershell.exe). The daemon also stops holding the caller's directory open for its lifetime.A relative
XDG_CONFIG_HOMEwas the only thing tying the helper to the caller's cwd. It is now resolved to an absolute path, both ingetUserVarlockDir()(which builds the daemon's socket and pid paths) and in the env passed to the helper, so keys and the daemon socket stay where they were. An emptyXDG_CONFIG_HOMEis dropped from the helper's env, sincegetUserVarlockDir()treats it as unset and the helpers would otherwise read it as a relative path.This only covers the helper. Other spawns from the binary, including the child of
varlock run, still use the caller's cwd, which is correct for them, but they hit the same Bun bug from a cwd that cannot be entered. Upgrading Bun would fix those too.Test
getNativeBinarySpawnOptionsreturns the helper's directory and resolves a relativeXDG_CONFIG_HOME;getUserVarlockDirreturns an absolute path for one.binary.test.ts): enters a temp directory, removes access to it (chmod 000 .), runscache clearwithVARLOCK_DEBUG=1and a scratchXDG_CONFIG_HOME, and checks that the helper was spawned and did not fail. On main it fails with the EACCES above. It needs the helper next to the binary, and the smoke-test workflow builds with--skip-native, so there it is skipped rather than passing without spawning anything. Skipped on Windows and as root.I ran the smoke test locally against a binary built with Bun 1.3.14 with the Rust helper bundled, and also by hand in a Debian container as a service user via
runuserfrom a mode 750 directory.cache clearnow exits 0.