# SSH/SFTP Integration Audience: operators and maintainers configuring SSH/SFTP sources or destinations. The SSH backend uses native SSH and SFTP libraries. It does not call `ssh`, `scp`, or `rsync`. ## Dependencies Runtime SSH support uses: - `golang.org/x/crypto/ssh` - `golang.org/x/crypto/ssh/agent` - `golang.org/x/crypto/ssh/knownhosts` - `github.com/pkg/sftp` Exact versions are pinned in `go.mod`. ## Config Contract Required fields: - `backend: ssh` - `host` - `path` Optional fields: - `user`: defaults to the current OS user when available. - `port`: defaults to `22`. - `ssh_key_file`: private key path. - `known_hosts`: OpenSSH known-hosts file path. - `host_key_policy`: `strict`, `accept-new`, or `off`; defaults to `accept-new`. ## Authentication Authentication methods are attempted in this order: 1. SSH agent identities when `SSH_AUTH_SOCK` is set. 2. The private key configured by `ssh_key_file`. Password authentication is not configured in YAML. If neither an agent nor key file is available, opening the backend fails. ## Host Key Policy - `strict`: requires a matching known host key. - `accept-new`: accepts and persists an unknown host key, but rejects changed known keys. - `off`: disables host key checking. When `known_hosts` is omitted and checking is enabled, the adapter uses the current user's default OpenSSH `known_hosts` path when available. During dry runs, accepted unknown host keys are not persisted. ## Storage Behavior The configured `path` is the backend root. All source discovery, destination paths, reads, writes, state files, and deletes operate on logical paths below that root. The adapter rejects symlink ancestors for reads and writes. Reads require regular files. Writes create parent directories and prefer atomic temp-file-plus-rename writes when requested. Walk output is sorted through the shared storage walker. Managed cleanup and normal replacement delete only managed output paths plus `.distributor.json`. Merge publication retains omitted managed paths and may overwrite existing managed paths. Forced replacement deletes the bounded destination bundle path. ## Boundaries The SSH backend does not configure passwords, jump hosts, shell commands, `rsync`, host-key bypass warnings beyond command output, or broad recursive deletion outside the destination bundle path. ## Tests Before changing this integration, inspect and run: ```sh go test ./internal/adapters/ssh ``` Live SSH tests are opt-in and gated by environment variables in the adapter test package.