Skip to content

doc #1753 sftp: prefer ~/.ssh/config over ssh_keyfile in credentials.conf - #1757

Open
robjarawan wants to merge 1 commit into
MetPX:developmentfrom
robjarawan:docs/sftp-ssh-config
Open

robjarawan wants to merge 1 commit into
MetPX:developmentfrom
robjarawan:docs/sftp-ssh-config

Conversation

@robjarawan

Copy link
Copy Markdown
Contributor
What

Closes #1753 as documentation, per the discussion there.

ssh_keyfile in credentials.conf is used by ordinary sftp transfers and silently ignored
by accelerated ones. Transfers over accelThreshold are handed to scp, which reads
~/.ssh/config and cannot see credentials.conf. The symptom is a configuration that works
until a file crosses the threshold, so it presents as "large files fail" rather than as a
credential problem.

Settings in ~/.ssh/config are read by both paths: scp natively, and paramiko because
Sftp.credentials() looks the host up in ~/.ssh/config itself and takes HostName,
User, Port and IdentityFile from it.

Change

Adds a SFTP and ~/.ssh/config section to sr3_credentials.7.rst documenting a Host
stanza with no credentials.conf entry as the way to configure sftp, and points to it from
the ssh_keyfile entry under Credential Details.

It also records two things that are easy to lose an afternoon to:

  • a port belongs in the stanza, not the URL. A port in the URL is not passed to scp
    correctly, so an accelerated transfer to sftp://user@host:2222/ fails while an ordinary
    transfer to the same URL succeeds.
  • ~/.ssh/config is only consulted when the credential does not already answer the question
    (transfer/sftp.py:285-286). An entry carrying a user and a password takes precedence and
    the stanza is not read, so omitting the entry is the reliable way to have it apply.

Documentation only. No code changes.

Verified

Every statement in the new section was run against a real sftp server on unmodified
development, not reasoned about. Lab account whose authorized_keys holds only a
deliberately odd named key, so nothing succeeds by accident, plus a second sshd on 2222 for
the port case. 2 MB file, accelThreshold 1M, md5 compared against the source on the
successful runs.

setup ordinary accelerated
ssh_keyfile in credentials.conf works fails, Permission denied (publickey)
ssh_config stanza, no credentials.conf entry works works
ssh_config stanza with Port 2222, alias in URL works works
port in the URL, key in credentials.conf works fails, 2222:/path: No such file

RST checked with docutils. The only diagnostics are the pre-existing |today| and
|release| substitutions that sphinx supplies at build time.

Not included

The French docs/source/fr/Reference/sr3_credentials.7.rst carries the matching
ssh_keyfile entry and is not updated here. I would rather that was done by someone who
writes French properly than guessed at, but I can attempt it if you would prefer it in the
same change.

Two unrelated defects turned up while testing this and are filed separately, both with
reproductions and no patch: #1755 (accelerated sftp fails when baseUrl contains a path) and
#1756 (accelerated transfers break on filenames containing spaces, across all five
accelerated call sites).

Fork CI

Run on my fork first: robjarawan#136 - 32 pass, 6 fail.

The six failures are runner flakiness, not this change. The clearest evidence is that the
duplicate workflow runs on the same commit disagree with themselves:

dynamic_flow on ubuntu-22.04     2 pass, 1 fail
dynamic_flow on ubuntu-24.04     2 pass, 1 fail
flakey_broker on ubuntu-22.04    2 pass, 1 fail
flakey_broker on ubuntu-24.04    2 pass, 1 fail
Maintenance test on ubuntu-22.04 1 pass, 1 fail
Maintenance test on ubuntu-24.04 1 pass, 1 fail

Every job that failed also passed on another run of the same commit. The same jobs are
also currently failing on untouched development upstream.

This branch changes one .rst file and a changelog line, with no python or config touched,
so the flow tests cannot be reached by it.

A passing dynamic_flow run: https://github.com/robjarawan/sarracenia/actions/runs/30972432267/job/92199482505

…ials.conf

Ordinary sftp transfers go through paramiko, which sarracenia configures from
credentials.conf. Transfers over accelThreshold are handed to scp, which reads
~/.ssh/config and cannot see credentials.conf. A key given as ssh_keyfile is
therefore used by ordinary transfers and silently missing from accelerated ones,
so a working config starts failing once a file crosses the threshold.

Settings in ~/.ssh/config are read by both paths, scp natively and paramiko via
the lookup in Sftp.credentials(), so document a Host stanza with no
credentials.conf entry as the way to configure sftp.

Also documents that a port belongs in the stanza rather than the URL, since a
port in the URL is not passed to scp correctly, and notes that ~/.ssh/config is
only consulted when the credential does not already supply a user and a secret.
@robjarawan robjarawan added the Documentation Primary deliverable of this item is documentation label Aug 5, 2026
@robjarawan robjarawan self-assigned this Aug 5, 2026
@andreleblanc11

Copy link
Copy Markdown
Member

The changes are good. Just need french changes as well.

Comment on lines +154 to +158
Sarracenia only consults ``~/.ssh/config`` when the credential does not already answer
the question: when no user is known, or when neither a key nor a password was supplied.
A ``credentials.conf`` entry carrying a user and a password takes precedence and the
stanza is not read. Omitting the entry is the reliable way to have ``~/.ssh/config``
apply.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sure how this works, I think .ssh/config is always used, I don't know which overrides which (does credentials.conf override .ssh/config or is it the other way around?)

@robjarawan

robjarawan commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

I verified every claim in this doc change against sftp.py and flow/__init__.py. The two-path model and the port-in-stanza guidance check out. Three amendments before merge.

First, the subscriber stanza problem is real and the doc needs a warning. options.sendTo is overwritten by msg['baseUrl'] (flow/__init__.py:2259), so on a subscriber the stanza Host must match the publisher's announced hostname, or there must be a matching credentials.conf entry. Aliasing local config alone has no effect on downloads, so please scope the wording that way.

Second, the precedence note must read user plus a secret. Per sftp.py:285-286 the stanza lookup is skipped when a user plus a keyfile or password is known, so a user plus ssh_keyfile suppresses it too, not just user plus password.

Third, IdentitiesOnly yes affects scp only. Sarracenia reads just HostName, User, Port, IdentityFile (sftp.py:288-296), first IdentityFile only, so please note both.

French translation stays a follow-up. The port-mangling wording is accurate for both get and put paths.

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

Labels

Documentation Primary deliverable of this item is documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Accelerated SFTP transfers ignore ssh_keyfile

3 participants