`keyfile` config is ignored by `InteractiveSSHClient` SSH config `IdentityFile` entries used instead, causing unrelated keys to be tried
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Quiet
- Tech stack
- python
- Domain
- authentication, backend
Research direction
Start in dvc_ssh/client.py at InteractiveSSHClient.public_key_auth_requested() and trace how options.client_keys and the parsed SSH config are used during interactive authentication. Reproduce the two-key scenario, then verify that only the explicitly configured keyfile is attempted while SSH config fallback still works when no explicit key is set.
Written by the indexing model from the issue text.
Description
Labels: bug
dvc-ssh version: 4.3.0
asyncssh version: 2.23.0
Description
When keyfile is configured for an SSH remote, DVC correctly passes it to asyncssh.connect() as client_keys. However, when the key requires a passphrase (triggering the interactive auth path), InteractiveSSHClient.public_key_auth_requested() ignores options.client_keys and instead reads IdentityFile entries directly from the SSH config file:
# dvc_ssh/client.py — public_key_auth_requested()
config = options.config
client_keys = cast("Sequence[FilePath]", config.get("IdentityFile", ()))
This means any IdentityFile entries inherited from a Host * block in ~/.ssh/config are tried as well, including keys that are unrelated to the configured remote (e.g. a git commit signing key). This produces unexpected passphrase prompts for keys the user never intended to use with DVC.
Steps to reproduce
- Have two keys in
~/.ssh/configunderHost *, e.g.id_ed25519(auth) andid_ed25519_signing(git signing key) - Configure a DVC SSH remote with
keyfilepointing to onlyid_ed25519:dvc remote modify --local myremote keyfile ~/.ssh/id_ed25519 - Run
dvc pull
Expected: only ~/.ssh/id_ed25519 is tried; no prompt for id_ed25519_signing
Actual: both keys are tried; user is prompted for the passphrase of id_ed25519_signing
Root cause
public_key_auth_requested() sources its key list from options.config.get("IdentityFile") (the parsed SSH config) rather than from options.client_keys (the explicit client_keys argument passed to asyncssh.connect()). The explicitly configured keyfile is therefore only respected for the initial non-interactive auth attempt, not for the interactive passphrase-prompting fallback.
Suggested fix
In public_key_auth_requested(), prefer options.client_keys when it is set, falling back to SSH config only when no explicit keys are configured:
# Prefer explicitly configured client_keys over SSH config discovery
client_keys = list(options.client_keys) if options.client_keys else None
if not client_keys:
client_keys = cast("Sequence[FilePath]", config.get("IdentityFile", ()))
if not client_keys:
client_keys = [
os.path.expanduser(os.path.join("~", ".ssh", path))
for path, cond in _DEFAULT_KEY_FILES
if cond
]
Workaround
Remove unintended keys from Host * in ~/.ssh/config so they are not picked up by asyncssh's config parsing.
- Dominant language
- Python
- Stars
- 2
- Forks
- 6
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from treeverse/dvc-ssh
-
Difficulty 4/5 3-5 days Newbie friendliness 42/100
-
awaiting response
Difficulty 4/5 3-5 days Newbie friendliness 28/100
-
awaiting response
Difficulty 3/5 1-2 days Newbie friendliness 45/100
-
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
Difficulty 4/5 3-5 days Newbie friendliness 30/100
All issues in treeverse/dvc-ssh
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100