Compare commits

..

1 Commits

Author SHA1 Message Date
Bas Nijholt
77857d49ad fix: Explicitly disable SSH agent when using dedicated keys (#176)
Some checks failed
CI / browser-tests (push) Has been cancelled
CI / lint (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
TOC Generator / TOC Generator (push) Has been cancelled
Update README.md / update_readme (push) Has been cancelled
CI / test (macos-latest, 3.11) (push) Has been cancelled
CI / test (macos-latest, 3.12) (push) Has been cancelled
CI / test (macos-latest, 3.13) (push) Has been cancelled
CI / test (ubuntu-latest, 3.11) (push) Has been cancelled
CI / test (ubuntu-latest, 3.12) (push) Has been cancelled
CI / test (ubuntu-latest, 3.13) (push) Has been cancelled
asyncssh defaults to querying SSH_AUTH_SOCK even when client_keys are
provided. If the agent socket is stale or broken (common with forwarded
agents in Docker/NAS environments), this causes a ConnectionResetError
that crashes the connection before the dedicated key is even tried.

Set agent_path=None when dedicated compose-farm keys exist so asyncssh
skips the agent entirely. The agent fallback path (when no dedicated
keys exist) is unchanged.
2026-02-19 20:40:15 -08:00
2 changed files with 4 additions and 2 deletions

View File

@@ -191,6 +191,7 @@ def ssh_connect_kwargs(host: Host) -> dict[str, Any]:
# If dedicated key exists, force use of it and ignore agent
# This avoids issues with stale/broken forwarded agents in Docker
kwargs["client_keys"] = [str(key_path)]
kwargs["agent_path"] = None # Prevent asyncssh from using SSH_AUTH_SOCK
elif agent_path:
# Fallback to agent if no dedicated key
kwargs["agent_path"] = agent_path

View File

@@ -217,6 +217,7 @@ class TestSshConnectKwargs:
result = ssh_connect_kwargs(host)
assert result["client_keys"] == [str(key_path)]
assert result["agent_path"] is None
def test_includes_both_agent_and_key(self, tmp_path: Path) -> None:
"""Prioritize client_keys over agent_path when both available."""
@@ -229,8 +230,8 @@ class TestSshConnectKwargs:
):
result = ssh_connect_kwargs(host)
# Agent should be ignored in favor of the dedicated key
assert "agent_path" not in result
# Agent must be explicitly disabled so asyncssh doesn't use SSH_AUTH_SOCK
assert result["agent_path"] is None
assert result["client_keys"] == [str(key_path)]
def test_custom_port(self) -> None: