SshNet.Agent 2026.0.0

dotnet add package SshNet.Agent --version 2026.0.0
                    
NuGet\Install-Package SshNet.Agent -Version 2026.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SshNet.Agent" Version="2026.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SshNet.Agent" Version="2026.0.0" />
                    
Directory.Packages.props
<PackageReference Include="SshNet.Agent" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SshNet.Agent --version 2026.0.0
                    
#r "nuget: SshNet.Agent, 2026.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SshNet.Agent@2026.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SshNet.Agent&version=2026.0.0
                    
Install as a Cake Addin
#tool nuget:?package=SshNet.Agent&version=2026.0.0
                    
Install as a Cake Tool

SshNet.Agent

SSH.NET Extension to authenticate via OpenSSH Agent and PuTTY Pageant

License NuGet Nuget

.NET-Ubuntu .NET-Windows NuGet

.NET Frameworks

  • .NET 4.8
  • netstandard 2.0
  • netstandard 2.1
  • .NET 8.0

Note: Only the netstandard 2.1 and .NET 8.0 builds contain support for Unix Domain Sockets to use ssh-agent on Linux.

Keys

  • ssh-ed25519
  • ecdsa-sha2-nistp256
  • ecdsa-sha2-nistp384
  • ecdsa-sha2-nistp521
  • ssh-rsa with 2048, 3072, 4096 or 8192 KeyLength
  • sk-ssh-ed25519@openssh.com (FIDO/security key)
  • sk-ecdsa-sha2-nistp256@openssh.com (FIDO/security key)

FIDO / security keys

FIDO identities (ssh-keygen -t ed25519-sk / -t ecdsa-sk) held by the agent are offered to the server automatically. The agent drives the authenticator, so touch (and, for verify-required keys, the PIN) is prompted at sign time; the private key never leaves the hardware. These identities have no SSH.NET Key, so SshAgentPrivateKey.Key is null for them; their comment is still available via SshAgentPrivateKey.Comment, which every identity carries.

RSA and legacy ssh-rsa

RSA identities are offered as rsa-sha2-512 and rsa-sha2-256 (RFC 8332). The legacy SHA-1 ssh-rsa signature algorithm is only offered when explicitly enabled: it is needed solely for servers without RFC 8332 support (OpenSSH older than 7.2), OpenSSH 8.8+ rejects it, and every offered algorithm costs one of the server's MaxAuthTries.

var agent = new SshAgent { IncludeLegacySshRsa = true };

Features

  • Auth
  • Auth with OpenSSH Certificates
  • Adding Keys
  • Adding Keys with Constraints (lifetime, confirm)
  • Adding and Removing PKCS#11 / Smartcard Keys
  • Getting Keys
  • Removing Keys
  • Removing all Keys
  • Locking and Unlocking the Agent
  • Async API

Agent Protocol Documentation

draft-miller-ssh-agent-02

Usage

OpenSSH Agent

var agent = new SshAgent();

var keyFile = new PrivateKeyFile("test.key");
agent.AddIdentity(keyFile);

var keys = agent.RequestIdentities();

using var client = new SshClient("ssh.foo.com", "root", keys);
client.Connect();
Console.WriteLine(client.RunCommand("hostname").Result);

PuTTY Pageant

var agent = new Pageant();

var keyFile = new PrivateKeyFile("test.key");
agent.AddIdentity(keyFile);

var keys = agent.RequestIdentities();

using var client = new SshClient("ssh.foo.com", "root", keys);
client.Connect();
Console.WriteLine(client.RunCommand("hostname").Result);

Pageant automatically talks to Pageant 0.77+ over its OpenSSH named pipe when one is available (real async I/O, no WM_COPYDATA 8 KB message limit), and falls back to the legacy WM_COPYDATA interface otherwise. No code change is needed.

The Pageant class is Windows only (its transports, WM_COPYDATA and the Windows named pipe, do not exist elsewhere). On Linux, PuTTY's pageant serves the standard agent protocol on a unix socket, so use SshAgent instead: pageant sets SSH_AUTH_SOCK, which new SshAgent() picks up, or pass the socket path to new SshAgent(path, null).

OpenSSH Certificates

Certificate identities held by the agent (*-cert-v01@openssh.com) are offered to the server automatically; the agent signs with the matching private key. To add a key together with its certificate, load the certificate alongside the private key:

var agent = new SshAgent();

// test.key + the certificate signed by your CA (test-cert.pub)
agent.AddIdentity(new PrivateKeyFile("test.key", null, "test-cert.pub"));

var keys = agent.RequestIdentities();

// works against servers that trust the CA (TrustedUserCAKeys)
using var client = new SshClient("ssh.foo.com", "root", keys);
client.Connect();

Minting Certificates with SshNet.Keygen

The certificate above can be produced in .NET with SshNet.Keygen, so the whole short-lived-certificate flow - mint, load into the agent, authenticate - stays in one process without shelling out to ssh-keygen:

// mint a short-lived user certificate for test.key, signed by your CA
var userKey = new PrivateKeyFile("test.key");
var certificate = new SshCertificateBuilder(userKey)
    .WithKeyId("root@example.com")
    .WithPrincipal("root")
    .WithValidity(DateTime.UtcNow, DateTime.UtcNow.AddHours(8))
    .SignWith(new PrivateKeyFile("ca"));

File.WriteAllText("test-cert.pub", certificate.ToOpenSshPublicFormat());

// load the key together with the freshly minted certificate ...
var agent = new SshAgent();
agent.AddIdentity(new PrivateKeyFile("test.key", null, "test-cert.pub"));

// ... and authenticate against a server that trusts the CA
using var client = new SshClient("ssh.foo.com", "root", agent.RequestIdentities());
client.Connect();

The same certificate can be served through an agent server, or used directly with SSH.NET without an agent.

Async

All agent operations are also available asynchronously and take an optional CancellationToken:

var agent = new SshAgent();

await agent.AddIdentityAsync(new PrivateKeyFile("test.key"), cancellationToken);
var keys = await agent.RequestIdentitiesAsync(cancellationToken);
await agent.RemoveAllIdentitiesAsync(cancellationToken);

Note: Signing during authentication stays synchronous, since SSH.NET calls it through its synchronous DigitalSignature contract.

Key Constraints

Keys can be added with the constraints known from ssh-add -t and ssh-add -c:

var agent = new SshAgent();

// the agent removes the key after 10 minutes and asks for
// confirmation on every use
agent.AddIdentity(new PrivateKeyFile("test.key"), TimeSpan.FromMinutes(10), confirm: true);

Locking and Unlocking

A locked agent hides its identities and refuses signing until it is unlocked again, like ssh-add -x/ssh-add -X:

var agent = new SshAgent();

agent.Lock("passphrase");
// agent.RequestIdentities() is empty now
agent.Unlock("passphrase");

PKCS#11 / Smartcard Keys

Keys held on a PKCS#11 token can be added to and removed from the agent, like ssh-add -s/ssh-add -e. The agent loads the key through the PKCS#11 provider (a shared library path) and unlocks the token with the PIN; the private key never leaves the token.

var agent = new SshAgent();

// ssh-add -s /usr/lib/opensc-pkcs11.so
agent.AddSmartcardIdentity("/usr/lib/opensc-pkcs11.so", "1234");

var keys = agent.RequestIdentities();

// ssh-add -e /usr/lib/opensc-pkcs11.so
agent.RemoveSmartcardIdentity("/usr/lib/opensc-pkcs11.so");

Smartcard keys can be added with the same lifetime/confirm constraints as regular keys:

agent.AddSmartcardIdentity("/usr/lib/opensc-pkcs11.so", "1234", TimeSpan.FromMinutes(10), confirm: true);

Resharper Warning

If you want to avoid the Resharper Warning "Co-variant array conversion": https://www.jetbrains.com/help/resharper/CoVariantArrayConversion.html

var agent = new Pageant();

var keyFile = new PrivateKeyFile("test.key");
agent.AddIdentity(keyFile);

var keys = agent.RequestIdentities();

using var client = new SshClient("ssh.foo.com", "root", keys.ToArray<IPrivateKeySource>());
client.Connect();
Console.WriteLine(client.RunCommand("hostname").Result);
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 is compatible.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETFramework 4.8

    • SSH.NET (>= 2026.0.0 && < 2027.0.0)
  • .NETStandard 2.0

    • SSH.NET (>= 2026.0.0 && < 2027.0.0)
  • .NETStandard 2.1

    • SSH.NET (>= 2026.0.0 && < 2027.0.0)
  • net8.0

    • SSH.NET (>= 2026.0.0 && < 2027.0.0)

NuGet packages (3)

Showing the top 3 NuGet packages that depend on SshNet.Agent:

Package Downloads
RoyalApps.RoyalTerminal.Terminal.Transport.Ssh.SshNet.Agent

Optional SSH.NET agent authentication adapter for terminal SSH transport.

RoyalApps.RoyalTerminal.Avalonia.App

Reusable RoyalTerminal Avalonia application shell with window chrome, native menus, settings, capture replay UI, and multi-session terminal workflows.

DplTools

Package Description

GitHub repositories (1)

Showing the top 1 popular GitHub repositories that depend on SshNet.Agent:

Repository Stars
duplicati/duplicati
Store securely encrypted backups in the cloud!
Version Downloads Last Updated
2026.0.0 5,178 8/14/2026
2024.2.0.5 675 7/21/2026
2024.2.0.4 144 7/16/2026
2024.2.0.4-beta 122 7/14/2026
2024.2.0.3-beta 552 5/14/2025
2024.2.0.2-beta 349 5/14/2025
2024.2.0.1 90,047 12/3/2024
2024.2.0 12,638 12/2/2024
2024.0.0.2 475 10/18/2024
2024.0.0.2-beta 449 3/25/2024
2024.0.0.1-beta 234 3/24/2024
2024.0.0-beta 219 3/16/2024
0.4.0-beta 286 11/29/2023
0.3.0-beta 218 11/29/2023
0.2.0-beta 228 11/29/2023
0.1.0-beta 707 3/7/2021