Skip to main content

Documentation Index

Fetch the complete documentation index at: https://www.integrate.io/docs/llms.txt

Use this file to discover all available pages before exploring further.

Use this guide when Integrate.io ETL needs to land output files on a Windows file share (SMB or CIFS) that you do not want to expose to the public internet. The Windows host runs OpenSSH Server, opens an outbound reverse SSH tunnel to Integrate.io, and accepts writes from your package over standard SFTP. No inbound firewall rules are required. If your Windows host has a public IP and whitelisting Integrate.io’s IP range is an option, you can skip the reverse stage and connect directly over SFTP. See Connecting to SFTP and the IP list.

How it works

  1. OpenSSH Server runs on a Windows host that has access to the SMB share (either the file server itself, or a jump host that has write rights to the share over the network).
  2. The Windows host opens an outbound reverse SSH tunnel to an Integrate.io bastion. The tunnel exposes the host’s local SFTP port back to the Integrate.io worker.
  3. The package uses a standard SFTP destination component pointed at the tunnel endpoint, with a dedicated, chrooted SFTP user that has write access to a single output subfolder.

Pre-flight

  • Windows 10/11 or Windows Server 2019+ (OpenSSH Server ships in-box).
  • Local administrator rights on the Windows host.
  • Access to the Integrate.io app to create the SFTP connection and the reverse tunnel endpoint.
  • A writable location on the file share. If the OpenSSH host is not itself the file server, the SFTP user must have network write rights to the UNC path.

1. Install OpenSSH Server on Windows

Open PowerShell as Administrator and run:
# Install the OpenSSH Server feature
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

# Bind sshd to loopback only. The reverse tunnel does not need sshd reachable from the LAN.
$cfg = "C:\ProgramData\ssh\sshd_config"
Add-Content $cfg "`nListenAddress 127.0.0.1:22`nPasswordAuthentication no`nPubkeyAuthentication yes"

# Start sshd and have it come back on every boot
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic

2. Create a dedicated SFTP user

Create a non-admin local user that exists only to serve this connection.
$pw = Read-Host -AsSecureString "Password for integrateio-sftp (use a random 22+ character string)"
New-LocalUser -Name "integrateio-sftp" -Password $pw -PasswordNeverExpires
Do not add this user to any group beyond the default Users.

3. Prepare the chroot and grant write access

OpenSSH on Windows requires the ChrootDirectory to be owned by SYSTEM or BUILTIN\Administrators and not writable by the SFTP user. The pattern below puts the chroot at a parent folder and grants write only on a child subfolder, so the user can create files but cannot escape or tamper with the chroot itself.
# Chroot root, owned by Administrators (must not be writable by integrateio-sftp)
New-Item -ItemType Directory -Path "C:\integrateio-sftp" -Force | Out-Null
icacls "C:\integrateio-sftp" /inheritance:r
icacls "C:\integrateio-sftp" /grant:r "SYSTEM:(OI)(CI)F" "BUILTIN\Administrators:(OI)(CI)F"

# Writable output subfolder
New-Item -ItemType Directory -Path "C:\integrateio-sftp\out" -Force | Out-Null
icacls "C:\integrateio-sftp\out" /grant:r "integrateio-sftp:(OI)(CI)M"
If output needs to land on a separate file server reached over UNC, you have two options:
  • Symlink the output subfolder to the UNC target (New-Item -ItemType SymbolicLink ...) and make sure integrateio-sftp has share and NTFS write rights on the file server.
  • Run a post-job step on Windows that moves files from C:\integrateio-sftp\out to the UNC target. This avoids granting the SFTP user direct network rights.

4. Lock sshd to the SFTP user

Append a Match User block at the end of C:\ProgramData\ssh\sshd_config so the SFTP user is restricted to internal-sftp inside the chroot. Other users are unaffected.
Match User integrateio-sftp
    ForceCommand internal-sftp
    ChrootDirectory C:\integrateio-sftp
    AllowTcpForwarding no
    PermitTunnel no
    X11Forwarding no
Save the file with LF line endings, not CRLF. Edit in VS Code (status bar, bottom-right) rather than Notepad. Reload sshd:
Restart-Service sshd

5. Open the reverse SSH tunnel from Windows

Two keypairs are involved, in opposite directions:
KeypairGenerated onPrivate key onPublic key goes to
Tunnel authWindows hostWindows hostIntegrate.io (Settings, SSH Public Keys)
SFTP authIntegrate.io (created with the SFTP connection)Integrate.io workerWindows host (C:\Users\integrateio-sftp\.ssh\authorized_keys)
For a quick smoke test, run the tunnel command shown in the Integrate.io connection screen in a foreground PowerShell window. For production, set it up as a Scheduled Task that starts on boot. The full PowerShell walkthrough is here: Reverse SSH Tunnel from Windows (PowerShell).

6. Install the SFTP public key on Windows

Once the SFTP connection is created in Integrate.io (next step), it produces a public key for the worker. Paste that key into the SFTP user’s authorized_keys:
$sshDir = "C:\Users\integrateio-sftp\.ssh"
New-Item -ItemType Directory -Path $sshDir -Force | Out-Null
Set-Content -Path "$sshDir\authorized_keys" -Value "<paste the SFTP public key from Integrate.io>" -Encoding ASCII

# OpenSSH on Windows is strict about ACLs on authorized_keys
icacls "$sshDir\authorized_keys" /inheritance:r
icacls "$sshDir\authorized_keys" /grant:r "SYSTEM:F" "integrateio-sftp:R"
If integrateio-sftp is in the Administrators group, the key file location is C:\ProgramData\ssh\administrators_authorized_keys instead. Keep the SFTP user out of Administrators so the standard location applies.

7. Create the SFTP connection in Integrate.io

In the Integrate.io app, follow Connecting to SFTP, with these field values:
  • Access type: Reverse SSH tunnel.
  • Hostname: 127.0.0.1 (the worker connects through the tunnel).
  • Port: 22 (the loopback port sshd is bound to on Windows).
  • Username: integrateio-sftp.
  • Authentication method: Public key. Copy the SFTP public key shown in the connection form into Windows as in Step 6.
  • Bastion host and Bastion forwarding port: the values shown on the connection screen. These are the endpoint the Windows host targets when it opens the reverse tunnel in Step 5.
Click Test connection. If it fails, see the failure table below before changing anything.

8. Build the package

Add an SFTP destination component to your package and set:
  • Connection: the SFTP connection from Step 7.
  • Target path: a path inside the writable subfolder, for example /out.
  • Filename pattern: how each output part should be named, for example orders-{job_id}-{part}.csv.
  • File format: CSV, JSON, Parquet, and so on.
For a smoke test, build a one-row package that writes test.csv to /out and confirm the file appears in C:\integrateio-sftp\out on Windows.

Common failure modes

SymptomLikely causeFix
Tunnel connects, SFTP auth failsACLs on authorized_keys are too permissive, or the file is in the wrong location for the user.Reapply icacls from Step 6. If the user is in Administrators, move the key to C:\ProgramData\ssh\administrators_authorized_keys.
Job runs but writes no filesNTFS ACLs on the output subfolder do not grant Modify to integrateio-sftp, or the path lands at the chroot root (which is read-only by design).Reapply icacls from Step 3 and write into /out, not /.
Permission denied writing to UNC pathThe SFTP user has no rights on the file server share.Either grant share and NTFS rights on the file server, or use a post-job move step on Windows.
sshd will not startPort 22 already in use by another service, or sshd_config has a syntax error.Open Event Viewer, Applications and Services, OpenSSH, Operational.
Test connection times outReverse tunnel is not running, or the bastion port does not match.Re-run the ssh -R command from Step 5 and confirm the port matches the connection form.
Bad ownership or modes for chroot directoryC:\integrateio-sftp is writable by the SFTP user.Re-run the ACL commands in Step 3. The chroot root must be owned by SYSTEM or Administrators and not writable by integrateio-sftp.

Tear-down

  • Stop the reverse-tunnel PowerShell window (or disable the Scheduled Task).
  • In Integrate.io, delete the SFTP connection and remove the tunnel public key under Settings, SSH Public Keys.
  • On Windows:
Stop-Service sshd
Set-Service -Name sshd -StartupType Disabled
Remove-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Remove-LocalUser -Name "integrateio-sftp"
Remove-Item -Recurse -Force "C:\integrateio-sftp"
Last modified on May 29, 2026