Library / SDK
ronf/asyncssh avatar
ronf/asyncssh

AsyncSSH: Asynchronous SSHv2 Client and Server for Python

AsyncSSH is a Python package which provides an asynchronous client and server implementation of the SSHv2 protocol on top of the Python asyncio framework.

1,763 stars187 forksPythonEPL-2.0

At a glance

What is it?
AsyncSSH is a Python library for building asynchronous SSHv2 clients and servers on asyncio. It supports commands, SFTP, SCP, forwarding, multiple sessions, and several authentication methods.
Who is it for?
Adopt AsyncSSH when an application needs SSH connections or an SSH server inside Python asyncio, especially for concurrent sessions, file transfer, or forwarding. Do not choose it for a simple synchronous script unless introducing an event loop is acceptable.
Can I use it commercially?
Yes, with conditions. EPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • ronf/asyncssh1,763 ★ · +2
Star history
Repository2026-10-172026-11-07
ronf/asyncssh1.8k1.8k

2 Stars in the last 21 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

AsyncSSH client and server scope for Python applications

AsyncSSH addresses applications that need SSH without blocking an event loop while network operations are in progress. It is intended for Python developers building network clients, automation services, file-transfer workflows, remote gateways, and SSH servers. The package implements both an asynchronous client and an asynchronous server. It is not merely a wrapper around the OpenSSH command-line program, so applications can use SSH through a Python API and keep unrelated asyncio tasks progressing while a connection waits for authentication, command output, or transferred data.

The documented feature set extends beyond remote command execution. The README lists shell, command, and subsystem channels, multiple simultaneous sessions on one SSH connection, and multiple SSH connections in one event loop. It also describes local and remote TCP/IP forwarding, UNIX domain socket forwarding, dynamic forwarding through SOCKS, and X11 forwarding. This puts AsyncSSH in consideration for network plumbing as well as shell automation.

File transfer is another substantial part of the package. The README documents SFTP version 3 with OpenSSH extensions. It also describes experimental support for SFTP versions 4 through 6 when specifically requested. SCP is supported, including third-party remote-to-remote copies. These are meaningful distinctions when comparing AsyncSSH with a small command-execution wrapper, since they determine whether the library can handle transfer workflows directly.

The documented operating model is Python 3.10 or later with asyncio. The repository's `pyproject.toml` requires Python `>= 3.10` and lists classifiers for Python 3.10 through 3.14. It declares dependencies on `cryptography >= 48.0.1` and `typing_extensions >= 4.0.0`. The README's prerequisite section says Python 3.10 or later and cryptography 39.0 or later are needed for AsyncSSH 2.0 or later, but the current `pyproject.toml` declares the stricter cryptography minimum. For dependency resolution, `pyproject.toml` is the specific packaging source to follow.

AsyncSSH connection and command data flow

The README's client example establishes the basic flow. An application calls `asyncssh.connect()`, enters the returned connection through an asynchronous context manager, starts a command with `conn.run()`, and awaits the result. Passing `check=True` makes command failure handling part of that call. Reading `result.stdout` then exposes the command's standard output to the Python program.

This structure makes the network operations asynchronous at the application boundary. The code is awaiting SSH operations instead of synchronously blocking the main thread. It also allows an application to schedule other asyncio tasks around the connection. The README explicitly lists support for multiple SSH connections in one event loop and multiple sessions on one connection, which are consequences of this programming model.

The server side is exposed as a Python library rather than documented as a packaged SSH daemon. The `examples/` directory contains callback clients and servers, chat and math servers, redirect examples, listening clients, and local and remote forwarding clients and servers. These filenames point to several service patterns: processing a callback, accepting incoming clients, redirecting streams, or configuring forwarding. The exact server callback signatures are not reproduced in the README, so an application should consult the API documentation before selecting a server design.

Based on the repository layout, implementation code, examples, documentation, and tests are kept in distinct areas. The `tests/` directory is especially relevant when adapting AsyncSSH to a particular host system, authentication mechanism, or forwarding configuration. The package also includes type information through `py.typed`, while the presence of `mypy.ini` shows that static typing is considered in the repository tooling.

Installing AsyncSSH and running the first remote command

The README gives a direct PyPI installation command. After installation, its shortest client example connects to `localhost`, runs `echo "Hello!"`, and prints standard output. The connection will require whatever credentials and host verification the local SSH environment expects, because the example does not provide a username, key, password, port, or custom `known_hosts` path.

Install the base package with:

bash
pip install asyncssh

The project defines optional extras for specific integrations. They include `bcrypt`, `fido2`, `ifaddr`, `gssapi`, `pkcs11`, `pyOpenSSL`, and `pywin32`. For example, the README gives this command for installing several optional packages on UNIX:

bash
pip install 'asyncssh[bcrypt,fido2,gssapi,ifaddr,pkcs11,pyOpenSSL]'

Use only the extras required by the application. Installing every optional package can add platform dependencies that are irrelevant to a particular deployment. For example, `pkcs11` maps to `python-pkcs11` and is relevant to PIV security tokens, while `pyOpenSSL` enables X.509 certificate authentication according to the README.

The first client can follow the example published in `README.rst`:

python
import asyncio, asyncssh, sys

async def run_client():
    async with asyncssh.connect('localhost') as conn:
        result = await conn.run('echo "Hello!"', check=True)
        print(result.stdout, end='')

try:
    asyncio.get_event_loop().run_until_complete(run_client())
except (OSError, asyncssh.Error) as exc:
    sys.exit('SSH connection failed: ' + str(exc))

When the local SSH server accepts the connection and the command succeeds, `echo` produces `Hello!` followed by a newline, and `end=''` prevents `print` from adding another one. Failure can produce an `OSError` or `asyncssh.Error`, which the example converts into a nonzero process exit with an error message.

Modern asyncio applications would normally use a synchronous entry point such as `asyncio.run()` to execute an asynchronous function. The README example instead uses `asyncio.get_event_loop().run_until_complete()`, so newcomers should use that form only when it fits their existing program structure.

Authentication choices and host verification dependencies

AsyncSSH supports public-key, password, and keyboard-interactive authentication. The README also describes user-based and host-based public-key authentication. For applications integrated into existing UNIX environments, it documents access to keys managed by `ssh-agent`, including agent forwarding on clients and servers. On Windows, the README describes support for keys managed by PuTTY's Pageant agent through the `pywin32` extra.

Hardware-backed and certificate-based credentials are also represented. The README lists OpenSSH-compatible support for U2F and FIDO2 security keys, PKCS#11 access for PIV security tokens, and X.509 certificates defined by RFC 6187. OpenSSH's `ssh-keysign` mechanism is listed for accessing host keys. These features depend on the appropriate platform, cryptographic backend, and optional package, so availability should be checked for the target environment rather than inferred from the feature list.

AsyncSSH has partial support for OpenSSH-style configuration files. It also supports OpenSSH-style `known_hosts` and `authorized_keys` files. Partial configuration support is a meaningful deployment boundary: an application migrating from OpenSSH cannot assume that every directive or matching rule behaves identically. The README links to dedicated configuration, `known_hosts`, and `authorized_keys` documentation, which is the relevant starting point for checking those rules.

The README identifies ML-KEM and SNTRUP post-quantum key exchange support, with `liboqs` installed separately. It also mentions `libnettle` for UMAC cryptographic hashes. These optional algorithm paths mean that a successful base installation does not prove every advertised algorithm is available. Deployment environments should verify the exact key exchange, encryption, MAC, and authentication path they intend to permit or require.

Limitations in server deployment and advanced file transfer

AsyncSSH is a library, not a documented replacement for every use of the OpenSSH command-line client. It is a poor fit for a short synchronous script that only runs a command and has no existing asyncio event loop. Using AsyncSSH in that case introduces coroutines, connection context management, exception handling, and event-loop scheduling without providing a feature the script needs. The README does not present a synchronous convenience API or a separate AsyncSSH command-line client.

The server implementation also needs an operational boundary. The repository includes chat, math, callback, redirect, listening, and forwarding examples, but the README does not describe a packaged, hardened SSH daemon. A service built with AsyncSSH must define its own host-key handling, authentication policy, account isolation, forwarding permissions, logging, and process boundaries. The existence of server examples does not answer those deployment questions.

SFTP versions 4 through 6 are described as experimental when requested. That status should be considered before standardizing a transfer workflow on those versions. SCP support is also more limited than a general object-storage integration because it remains tied to SSH server behavior and path semantics. The README does not claim that AsyncSSH removes differences among SCP or SFTP implementations on remote systems.

There is a packaging version to resolve as well. The README says cryptography 39.0 or later is needed for AsyncSSH 2.0 or later, but `pyproject.toml` requires `cryptography >= 48.0.1`. An installer relying on current package metadata will receive the stricter requirement. Existing environments should check their installed versions before following README-level prerequisite advice.

AsyncSSH versus integration with the OpenSSH executable

The main alternative is to invoke OpenSSH through Python subprocess APIs or use it directly for administration. These approaches have a different architecture. OpenSSH is an external SSH implementation with its own process model, configuration handling, authentication tools, forwarding behavior, and command interface. Python can capture that process's standard streams and return code, but the surrounding program does not receive AsyncSSH's in-process channel objects or Python-level server implementation.

AsyncSSH instead implements SSHv2 behavior in Python on top of asyncio. That design is appropriate when one application must coordinate many connections within a single event loop, maintain multiple sessions on a connection, expose SSH services to Python callbacks, or connect forwarding behavior to application logic. The `examples/gather_results.py` filename indicates an example around gathering results, while forwarding and callback examples show other service patterns. Their full code should be consulted for implementation details.

OpenSSH integration may be simpler for a single administrative command, especially when existing scripts already depend on its exact configuration and authentication behavior. AsyncSSH is more relevant when SSH is part of a concurrent Python service, but its API also puts more connection handling in application code. The deciding factor is therefore not simply SSH performance or feature count. It is whether the application needs an embedded asyncio protocol implementation or can treat SSH as an external command.

Maintenance status, licensing, and dependency upgrades

The repository is not archived, and the last push was on 2026-10-10. No GitHub releases are listed, so the repository does not establish a release cadence through that channel. The current `pyproject.toml` classifies AsyncSSH as `Development Status :: 5 - Production/Stable`, while the README describes prerequisites for AsyncSSH 2.0 or later. Installed environments should use package metadata and the project's documentation site when determining an exact version's behavior.

The repository includes `tests/`, `tox.ini`, `mypy.ini`, and a pre-commit configuration. Those are concrete project files for compatibility checks, but the README excerpt does not prescribe one universal upgrade command. A maintainer can use the repository's configured tooling after reviewing those files rather than inventing separate test or lint invocations.

The package license is `EPL-2.0 OR GPL-2.0-or-later` in both `README.rst` and `pyproject.toml`. The README states that the Eclipse Public License version 2.0 accompanies the distribution and that the GNU General Public License version 2.0 or later is available as a secondary license when the EPL conditions are satisfied. This identifies the declared licensing options but does not replace a legal review of how the library is distributed or incorporated.

Upgrade risk extends beyond the main package. AsyncSSH depends on `cryptography` and `typing_extensions`, while optional functionality brings in `bcrypt`, `fido2`, `ifaddr`, `gssapi`, `python-pkcs11`, `pyOpenSSL`, and `pywin32`. Algorithms based on ML-KEM or SNTRUP require `liboqs`, and UMAC support requires `libnettle` according to the README. An upgrade should therefore be checked against the authentication method, certificate type, forwarding feature, operating system, or key exchange used in production.

Editorial conclusion

Adopt AsyncSSH when an application needs SSH connections or an SSH server inside Python asyncio, especially for concurrent sessions, file transfer, or forwarding. Do not choose it for a simple synchronous script unless introducing an event loop is acceptable. Check Python compatibility, authentication requirements, optional dependencies, host-key policy, and remote SSH compatibility before adopting it.

Frequently asked questions

What is AsyncSSH used for?

AsyncSSH provides asynchronous SSHv2 client and server functions for Python applications running on asyncio. Its documented features include remote commands, SFTP, SCP, forwarding, multiple sessions, and several authentication methods.

How do you install AsyncSSH?

The README gives `pip install asyncssh` for the base package. The current `pyproject.toml` requires Python `>= 3.10`, `cryptography >= 48.0.1`, and `typing_extensions >= 4.0.0`, with optional extras for specific integrations.

Does AsyncSSH support SFTP and SSH forwarding?

Yes. The README documents SFTP version 3 with OpenSSH extensions, experimental SFTP versions 4 through 6 when requested, SCP, TCP/IP forwarding, UNIX domain socket forwarding, dynamic SOCKS forwarding, and X11 forwarding.

Which authentication methods does AsyncSSH support?

The README lists public-key, password, and keyboard-interactive authentication. It also describes OpenSSH-format keys, X.509 certificates, `ssh-agent`, Pageant, PKCS#11 tokens, FIDO2 security keys, and OpenSSH's `ssh-keysign`, subject to platform and dependency availability.

Does AsyncSSH fully support OpenSSH configuration files?

No. The README describes OpenSSH-style configuration-file support as partial. It separately documents `known_hosts` and `authorized_keys` support, but does not claim complete option-by-option OpenSSH compatibility.

How do I run a first command with AsyncSSH?

The README example enters `asyncssh.connect('localhost')` as an asynchronous context manager, runs `conn.run('echo "Hello!"', check=True)`, and prints `result.stdout`. It catches `OSError` and `asyncssh.Error` and exits with an SSH failure message.

Official sources

  1. Issues
  2. License: EPL-2.0
  3. README
  4. ronf/asyncssh on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ronf-asyncssh.svg)](https://hysenlabs.com/projects/ronf-asyncssh)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/ronf-asyncssh.svg)](https://hysenlabs.com/projects/ronf-asyncssh)

Was this useful?