nw/sftp-bundle
Symfony bundle that adds SFTP file access via phpseclib, providing a configurable client service for secure remote file operations such as listing, uploading, downloading, and deleting files from Symfony applications.
Architecture fit. Despite being scored in a Laravel/PHP package context, nw/sftp-bundle is a Symfony bundle, not a Laravel package. Its value proposition is a DI extension that reads a nw_sftp config block, builds an SFTP client service from it, and exposes it for autowiring. Inside a Laravel application none of that machinery is usable: no ServiceProvider, no auto-discovery, no facade, no publishable config. What you actually inherit is a single thin service class wrapping phpseclib-style SFTP calls — roughly a few hundred lines of glue. That is both the risk and the opportunity: the portable surface area is small enough to vendor or re-implement in a day.
Integration feasibility. Moderate-to-low as a dependency, high as a copy-and-adapt. Installing it pulls a Symfony framework-bundle constraint chain into a Laravel composer.json, which is the wrong direction for the dependency graph and a likely source of conflicts. A viable path exists — composer require with Symfony packages as dev-only, then bind the underlying client class as a Laravel singleton and feed it config('filesystems.disks.sftp') — but at that point you are maintaining a fork without calling it one.
Technical risk.
phpseclib (likely v2-era) clashes with PHP 8.1+/8.3 and modern Laravel; resolution may require --ignore-platform-reqs, which is a smell.league/flysystem-sftp-v3 with first-class Storage integration.Key questions for the requester. What does the SFTP integration actually need — one-off nightly export, or a general-purpose storage driver? Is key-based auth with host-key pinning required by compliance? Which Laravel and PHP versions are in scope? Are we willing to own a vendored fork, and who signs up for CVE triage on phpseclib? Is a subprocess-based sftp/rsync shell wrapper acceptable instead of a PHP library?
Verdict: technically usable as reference code, not as an adopted dependency. Recommend evaluating flysystem-sftp-v3 first; fall back to vendoring this class only if its specific behavior (e.g., remote file listing semantics) is load-bearing.
Stack fit. Poor as a drop-in. Laravel's filesystem abstraction already models exactly this problem, and league/flysystem-sftp-v3 (phpseclib 3 under the hood) plugs into the Storage facade, Storage::disk('sftp')->put(...), retry helpers, and Laravel's testing fakes. Adopting nw/sftp-bundle would mean bypassing the abstraction and hand-rolling what the framework gives free — no upsides at this star/activity level.
Migration path. Three options, in preference order:
sftp disk via flysystem-sftp-v3, move credentials to config/filesystems.php + .env, and route calls through Storage. Est. 0.5–1 day.app/Support/Sftp/, strip the Symfony config/DI code, keep only transfer methods, bind it in a ServiceProvider reading a dedicated config/sftp.php. Est. 1–2 days including tests.Compatibility. Verify hard before committing: PHP constraint, phpseclib major version, and whether the bundle's Extension class references Symfony classes at runtime or only at container-build time. If the latter, path 3 becomes fractionally more viable but path 1 still wins. Confirm SFTP key formats and whether StrictHostKeyChecking-equivalent behavior is configurable.
Sequencing.
docker SFTP container (e.g., atmoz/sftp), prove connectivity with flysystem-sftp-v3, capture auth matrix (password vs key vs key+passphrase).SftpClientInterface, add typed exceptions, retry/timeout config, and host-key pinning.Maintenance. Effectively a fork on day one. Upstream has not shipped in ~5 years; you will track phpseclib security advisories yourself and patch a vendored copy. Budget a few hours per quarter for dependency review, more if a CVE lands in phpseclib. License is MIT — permissive and clean for vendoring, which is the one genuine point in its favor.
Support. None meaningful. Three stars, zero dependents, one maintainer, no issue triage. Internal ownership must be explicit and named in the ADR; "the package team" is not an answer.
Scaling. Synchronous, request-scoped connections with no pooling. Fine for scheduled batch transfers (nightly exports, report drops). Unsuitable for high-concurrency or per-request transfers — connection setup dominates and SFTP servers commonly cap concurrent sessions. Large files: confirm whether transfers stream or buffer; a naive wrapper that reads into memory will OOM on multi-GB files. Throughput is bounded by the SFTP server and network, not the client, so horizontal scaling of the web tier does nothing for you.
Failure modes to instrument. Connection/auth timeouts (network policy, key rotation, expired credentials); partial writes / truncated remote files with no atomic rename; host-key verification disabled by default → silent MITM; silent success on non-zero server status codes; no backoff, so transient blips become user-visible failures; remote directory full or permission drift. Mitigations: transfer to .tmp then rename, checksum verification, bounded retries with jitter, alerting on consecutive failures, and credential-expiry monitoring.
Ramp-up. Very low technical complexity — the client surface is a handful of methods a mid-level developer reads in an hour. The real ramp-up cost is operational, not code: teaching the team that this component is unsupported, that they own its security posture, and that the SFTP server is an external dependency with its own change windows. That onboarding burden is disproportionate to the ~200 lines of code involved and is the strongest argument for using the framework-native option instead.
Bottom line for the roadmap: low effort, low strategic value, non-trivial long-tail ownership cost. Adopt only if a specific behavioral requirement in this bundle cannot be met by flysystem-sftp-v3; otherwise treat it as documentation of an approach and move on.
How can I help you explore Laravel packages today?