Package Information
Available Nodes
Documentation generating…
Documentation
n8n-nodes-legacy-sftp
n8n-nodes-legacy-sftp is a standalone n8n community node for SFTP endpoints that require legacy RSA/SHA-1 SSH compatibility. It is designed for services with the same client requirements observed on Gamma Telecom SFTP:
HostKeyAlgorithms=+ssh-rsa
PubkeyAcceptedAlgorithms=+ssh-rsa
The package does not modify, patch, copy, or fork n8n's built-in FTP/SFTP node. The built-in node was used only as a reference for node UX, credential testing, binary handling, per-item execution, error handling, and connection cleanup.
Status
Version 0.1.0 provides:
- List files and directories
- Download a remote file to an n8n binary field
- private-key authentication with an optional passphrase
- strict SHA256 host-key verification, enabled by default
- modern SSH behavior by default
- explicit opt-in
ssh-rsacompatibility for the server host key - explicit opt-in RSA/SHA-1
ssh-rsacompatibility for public-key user authentication - normal encrypted n8n credential storage
- Continue On Fail behavior and paired-item output
- a credential connection test
- unit tests, a live-endpoint test, and a containerized legacy OpenSSH fixture
Upload, rename, delete, and other SFTP operations are intentionally outside the version 1 scope.
Security warning
In this context, ssh-rsa means an RSA signature using SHA-1. SHA-1 signatures are deprecated. Legacy behavior is disabled by default and should be enabled only for a known endpoint that cannot yet be upgraded.
The node never enables ssh-dss/DSA.
Keep Strict Host Key Checking enabled in production. Confirm host-key fingerprints through a trusted provider channel rather than trusting a value discovered from the same network path used for the connection.
Why ssh2
The node uses ssh2 1.17.0 directly rather than a higher-level SFTP wrapper. Direct access is required because Gamma compatibility involves two independent SSH decisions:
ConnectConfig.algorithms.serverHostKeycontrols the server host-key algorithm.- The parsed RSA authentication key and
ssh2authentication selection control the signature algorithm used for public-key user authentication.
Accepting an ssh-rsa host key alone does not solve send_pubkey_test: no mutual signature algorithm. The user-authentication request must also be signed with the legacy ssh-rsa RSA/SHA-1 algorithm when the endpoint accepts no RSA/SHA-2 signature.
ssh2 supports both paths. For RSA public-key authentication it uses the server's server-sig-algs information when available, prefers RSA/SHA-2, and can fall back to the ssh-rsa key/signature algorithm with SHA-1. The parsed key's sign(data, hashAlgorithm) implementation receives the selected hash.
This package adds an explicit policy around that behavior:
| Credential state | Server host-key policy | RSA user-authentication policy |
|---|---|---|
| Legacy compatibility disabled | Remove ssh-rsa and ssh-dss |
Reject SHA-1; allow RSA/SHA-2 |
| Legacy mode: Host Key Only | Append ssh-rsa; remove ssh-dss |
Reject SHA-1; require RSA/SHA-2 |
| Legacy mode: Host Key + User Authentication | Append ssh-rsa; remove ssh-dss |
Allow ssh2 to negotiate the ssh-rsa/SHA-1 fallback |
The implementation uses only public ssh2 APIs: Client, ConnectConfig.algorithms, authHandler, utils.parseKey(), ParsedKey.sign(), hostVerifier, and the SFTP wrapper. It does not patch ssh2 or reach into private module internals.
See docs/ssh-library-research.md for the source-level analysis and alternatives considered.
Compatibility
| Endpoint | Configuration |
|---|---|
| Modern OpenSSH or another modern RFC-compliant SFTP server | Leave legacy compatibility disabled |
| Modern server using an RSA user key | Leave legacy compatibility disabled; RSA/SHA-2 remains available |
Server offering only an ssh-rsa host key but accepting RSA/SHA-2 user authentication |
Enable legacy compatibility and select Host Key Only |
Gamma-style endpoint requiring ssh-rsa for both host key and user authentication |
Enable legacy compatibility and select Host Key + User Authentication (Gamma Compatible) |
| DSA-only endpoint | Not supported intentionally |
A live Gamma account was not available in the build environment. The repository includes a controlled OpenSSH fixture configured with both HostKeyAlgorithms ssh-rsa and PubkeyAcceptedAlgorithms ssh-rsa, plus an environment-driven live test for Gamma or another provider endpoint. A release should not claim provider certification without executing the external test against that provider.
Credential
Create a credential of type Legacy SFTP Credential.
| Field | Required | Description |
|---|---|---|
| Host | Yes | SFTP hostname or IP address |
| Port | Yes | SSH port, default 22 |
| Username | Yes | SFTP account username |
| Private Key | Yes | OpenSSH, PEM, or PuTTY PPK private key |
| Passphrase | No | Passphrase for an encrypted private key |
| Strict Host Key Checking | Yes | Reject an untrusted server key; default true |
| Trusted Host Key Fingerprints | When strict checking is enabled | One or more OpenSSH SHA256 host-key fingerprints |
| Enable Legacy RSA Compatibility | Yes | Opt-in legacy switch; default false |
| Legacy RSA Mode | When legacy compatibility is enabled | Host Key Only or Host Key + User Authentication (Gamma Compatible) |
Private keys, passphrases, host-key fingerprints, and other credential values are stored through n8n's normal encrypted credential system. The Docker example requires an explicit N8N_ENCRYPTION_KEY so stored credentials remain decryptable across container replacement.
Obtain and verify a host-key fingerprint
Use a fingerprint supplied by the SFTP provider whenever possible. To inspect the RSA host key visible from the network:
ssh-keyscan -p 22 -t rsa sftp.example.com 2>/dev/null \
| ssh-keygen -lf - -E sha256
Copy only the SHA256:... value into Trusted Host Key Fingerprints after comparing it with a provider-published or independently confirmed value. Discovery with ssh-keyscan does not itself establish trust.
Multiple fingerprints can be separated by spaces, commas, semicolons, or new lines. This supports controlled host-key rotation without disabling verification.
Gamma-style credential settings
Strict Host Key Checking: true
Trusted Host Key Fingerprints: SHA256:<provider-confirmed-value>
Enable Legacy RSA Compatibility: true
Legacy RSA Mode: Host Key + User Authentication (Gamma Compatible)
Use an RSA private key for a Gamma-style endpoint that accepts only the ssh-rsa public-key algorithm. Enabling legacy mode cannot make an Ed25519 or ECDSA user key satisfy an RSA-only authentication policy.
Operations
List
Lists a remote directory. Recursive traversal is optional, uses a configurable maximum depth from 1 to 100, and does not follow symbolic links.
Each remote entry becomes one n8n item:
{
"type": "-",
"name": "report.csv",
"path": "/outbound/report.csv",
"size": 12345,
"accessTime": "2026-07-23T10:00:00.000Z",
"modifyTime": "2026-07-23T10:01:00.000Z",
"mode": "0640",
"rights": {
"user": "rw-",
"group": "r--",
"other": "---"
},
"owner": 1000,
"group": 1000,
"longname": "-rw-r----- ... report.csv"
}
Download
Streams a remote file through n8n's binary-data helper. The default output field is data. Existing JSON and binary data on the input item are preserved.
Community Nodes installation
This package is intended for self-hosted n8n. It has a runtime dependency on ssh2, so under current n8n verification rules it is an installable unverified community node rather than an n8n Cloud verified node.
Install through the n8n user interface
After the package is published to npm:
- Open Settings > Community Nodes.
- Select Install.
- Enter
n8n-nodes-legacy-sftp. - Review and accept the community-node risk notice.
- Install the package.
- Restart n8n only if the node does not appear after installation.
The instance owner or another administrator with community-node installation permission must perform this operation.
Manual installation
Run the following as the operating-system user that runs n8n:
mkdir -p ~/.n8n/nodes
cd ~/.n8n/nodes
npm install n8n-nodes-legacy-sftp
Restart every n8n process that loads nodes. In queue mode, install the same package version on the main process and every worker.
For a locally built package before npm publication:
npm install --omit=optional
npm run build
npm pack
mkdir -p ~/.n8n/nodes
cd ~/.n8n/nodes
npm install /absolute/path/to/n8n-nodes-legacy-sftp-0.1.0.tgz
Install into an existing Docker container
For a container named n8n:
docker exec -u node n8n sh -lc \
'mkdir -p /home/node/.n8n/nodes && cd /home/node/.n8n/nodes && npm install n8n-nodes-legacy-sftp'
docker restart n8n
Persist /home/node/.n8n; otherwise the installed package and n8n encryption key can be lost when the container is replaced.
Build a custom n8n image
The repository includes a multi-stage Dockerfile and Compose example:
cp docker/.env.example docker/.env
openssl rand -hex 32
# Put the generated value in N8N_ENCRYPTION_KEY inside docker/.env.
docker compose --env-file docker/.env -f docker/docker-compose.yml build
docker compose --env-file docker/.env -f docker/docker-compose.yml up -d
docker/.env.example intentionally leaves N8N_ENCRYPTION_KEY empty. Compose refuses to start until a value is supplied. Review and pin N8N_VERSION before deployment.
The builder installs dependencies, runs the current n8n node build, packs the community node, and installs the resulting tarball into the official n8n image. Optional native ssh2 acceleration is omitted; ssh2 uses its portable JavaScript implementation.
Example workflow
Import examples/list-and-download.workflow.json. Select a Legacy SFTP Credential on both imported nodes and replace the example remote paths.
Project structure
See PROJECT_TREE.md for the complete source tree and the responsibility of each directory.
Development
Requirements:
- Node.js 22 or later
- npm 10 or later
Install and validate:
npm install --omit=optional
npm run lint
npm run typecheck
npm test
npm audit --omit=dev
npm pack --dry-run
Start a development n8n instance with hot reload:
npm run dev
Build the distributable package:
npm run build
npm pack
Integration tests
Controlled legacy OpenSSH fixture
The deterministic Docker fixture permits only:
HostKeyAlgorithms ssh-rsa
PubkeyAcceptedAlgorithms ssh-rsa
Run:
npm install --omit=optional
npm run test:legacy-container
The test performs three independent attempts:
- Modern mode must fail because the server offers only an
ssh-rsahost key. - Host Key Only must pass host-key negotiation but fail because RSA/SHA-1 user-authentication signatures remain blocked.
- Host Key + User Authentication must connect, report
ssh-rsaas the negotiated server host-key algorithm, authenticate with an RSA/SHA-1ssh-rsasignature, and list a directory.
The third attempt can succeed only when both Gamma compatibility paths are active.
Live provider endpoint
The live test is skipped unless its required environment variables are set:
export LEGACY_SFTP_TEST_HOST=sftp.example.com
export LEGACY_SFTP_TEST_PORT=22
export LEGACY_SFTP_TEST_USERNAME=account-name
export LEGACY_SFTP_TEST_PRIVATE_KEY_FILE="$HOME/.ssh/id_rsa"
export LEGACY_SFTP_TEST_HOST_KEY_FINGERPRINTS='SHA256:confirmedFingerprint'
export LEGACY_SFTP_TEST_ENABLE_LEGACY_RSA=true
export LEGACY_SFTP_TEST_LEGACY_RSA_MODE=hostKeyAndUserAuth
export LEGACY_SFTP_TEST_PATH=/
npm run test:integration
Set LEGACY_SFTP_TEST_STRICT_HOST_KEY=false only in an isolated disposable test environment. Do not use it for production validation.
Publishing
The package follows the current programmatic community-node layout and uses @n8n/node-cli for build, lint, development, prerelease validation, and release handling.
The supplied workflows perform the following:
.github/workflows/ci.ymlaudits runtime dependencies, lints, type-checks, builds, runs unit tests, runs the three-stage legacy OpenSSH fixture, and performs an npm pack dry run..github/workflows/publish.ymlverifies the version tag, injects exact repository metadata fromGITHUB_REPOSITORY, repeats the validation and compatibility gates, and publishes from GitHub Actions with npm provenance.- The source package does not invent a GitHub owner. Repository, homepage, and issue-tracker metadata are derived from the repository that actually executes the workflow.
Release sequence:
- Push the project to a public GitHub repository.
- Run the clean-checkout release gates in
VALIDATION.md. - For an existing npm package, configure npm Trusted Publishing for that repository and
.github/workflows/publish.yml. - For an initial npm publication, add a package-scoped granular npm token as the
NPM_TOKENrepository secret. After the first publication, configure Trusted Publishing and remove the token. - Run
npm run releaselocally. The current n8n CLI updates the version, changelog, commit, tag, GitHub release, and pushes; it does not publish locally by default. - The version tag triggers the publish workflow. The tag must match
package.json, with or without a leadingv.
The publish job grants only contents: read and id-token: write. It supports token-based bootstrap authentication when NPM_TOKEN exists and otherwise relies on npm Trusted Publishing/OIDC.
n8n Cloud and verified-node limitation
The package necessarily has the runtime dependency ssh2. Current n8n verified-node rules do not permit runtime dependencies, so this package is intended for self-hosted n8n as an unverified community node. The project sets n8n.strict to false, uses the official configWithoutCloudSupport ESLint profile, and disables only the no-runtime-dependencies rule for package.json. All other community-node, credential, node, import-resolution, and TypeScript lint checks remain active.
Troubleshooting
no matching host key type found or no matching host key format
Enable Legacy RSA Compatibility. The node enables ssh-rsa only and continues to reject ssh-dss/DSA.
send_pubkey_test: no mutual signature algorithm
Select Host Key + User Authentication (Gamma Compatible). Host Key Only changes only server host-key negotiation and deliberately blocks the RSA/SHA-1 user-authentication signature.
Host key verification failed
Verify the presented SHA256 fingerprint through a trusted channel. Do not copy an unverified value into the credential simply to make the connection succeed.
All configured authentication methods failed
Check the username, private key, passphrase, server-side authorized key, and selected legacy mode. Version 1 uses private-key authentication only.
Encrypted key cannot be parsed
Confirm that the passphrase is correct and that the key is in an OpenSSH, PEM, or PuTTY PPK format supported by ssh2.
Gamma-compatible mode still fails under FIPS policy
Full Gamma mode requires an RSA/SHA-1 signature. A Node.js/OpenSSL runtime configured to prohibit SHA-1 signatures can reject the operation. Use an approved isolated runtime for the legacy endpoint or require the provider to upgrade the SSH service.
Dependency security status
The package pins ssh2 1.17.0, the latest published npm release used for this implementation. NVD lists CVE-2025-70034 against that version. The corresponding GitHub advisory is currently unreviewed, provides no npm package mapping or affected/fixed range, and publishes no actionable reproducer or code location; upstream reports that no technical details were supplied.
This is recorded as an unresolved supply-chain risk rather than dismissed. Runtime dependencies are audited in CI, ssh2 is pinned exactly, and SECURITY.md requires reassessment before every release.
Validation
See VALIDATION.md for completed checks, environment limitations, and mandatory release gates.
License
MIT