Skip to content

fix: order passless.service after gpg-agent.socket - #468

Open
AuthenticSm1les wants to merge 2 commits into
pando85:masterfrom
AuthenticSm1les:fix/systemd-gpg-agent-ordering
Open

AuthenticSm1les wants to merge 2 commits into
pando85:masterfrom
AuthenticSm1les:fix/systemd-gpg-agent-ordering

Conversation

@AuthenticSm1les

Copy link
Copy Markdown

Fixes #467.

Problem

contrib/systemd/passless.service only declares After=network-online.target, with no ordering dependency on the SSH agent. When passless forks before gpg-agent.service has started (observed on this system: passless.service started ~2.5s before gpg-agent.service, both at boot), it permanently inherits a missing/stale SSH_AUTH_SOCK, since a process's environment is a fixed snapshot taken at exec and is never refreshed later. This silently and permanently breaks the pass backend's git push (auto-commit still succeeds, so the store just accumulates unpushed commits forever with only a WARN log line as evidence) — see #467 for full repro/root-cause.

Fix

Add gpg-agent.socket to After= (ordering-only, no Wants=), so passless starts after the agent socket is live when it's present, with zero behavior change for anyone not running gpg-agent's SSH support.

Scope

Deliberately minimal/low-risk — a more complete fix would have the pass backend re-resolve SSH_AUTH_SOCK at the time of each prepare()/finalize() call instead of trusting inherited env once at startup, and/or retry once on git exit code 128. Left out of this PR to keep it easy to review; happy to follow up if maintainers want that too.

Prevents passless from forking before SSH_AUTH_SOCK is backed by a
running agent, which otherwise permanently breaks the pass backend's
git push for the life of the process (a forked process's environment
is a fixed snapshot at fork time and is never refreshed later, even
once the agent becomes available).

This is an ordering-only addition (no Wants=), so it is a no-op for
anyone not running gpg-agent's SSH support.

Fixes pando85#467
@pando85

pando85 commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Thanks for investigating this. I think the issue is real, but I’d prefer fixing it by explicitly passing the SSH agent socket ("SSH_AUTH_SOCK") to Git sync rather than depending on a specific "gpg-agent" systemd unit.

That should work across distros and with gpg-agent, ssh-agent, KeePassXC, 1Password, etc. Would you be interested in adapting the PR in that direction?

I will prepare it.

The pass backend's Git sync shells out via prs_lib, which inherits
SSH_AUTH_SOCK from the process environment as-is. That environment is a
fixed snapshot taken once at passless startup and never refreshed, so if
the agent isn't up yet (or exports its socket into the systemd user
environment only after passless has already started), push silently and
permanently breaks for the life of the process.

Rather than depending on ordering against one specific systemd unit
(gpg-agent.socket), re-resolve a live agent socket fresh before every
prepare/finalize call, checking systemd's user environment table, the
inherited process environment, and gpgconf's gpg-agent SSH socket in
turn. This is agnostic to which agent is in use (gpg-agent, ssh-agent,
KeePassXC, 1Password, ...) and self-heals if the agent starts, restarts,
or updates its socket after passless does.

Fixes pando85#467
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

passless.service can start before the SSH agent is ready, permanently breaking pass-backend Git push for the life of the process

2 participants