This guide explains how to configure and use SSH agents with libssh-node, including 1Password, YubiKey, and system agents.
An SSH agent holds your private keys in memory and provides them to SSH clients when needed. This allows you to:
- Avoid typing passwords repeatedly
- Keep private keys secure (never written to disk)
- Use hardware security keys (YubiKey)
- Centralize key management (1Password)
libssh-node auto-detects these agents in priority order:
- 1Password SSH Agent - Commercial password manager with SSH key support
- YubiKey Agent - Hardware security key
- System SSH Agent - Standard ssh-agent or ssh-pageant
-
Install 1Password 8 or later
-
Enable SSH agent in 1Password settings:
- Open 1Password
- Go to Settings → Developer
- Enable "Use the SSH agent"
- Enable "Display key names when authorizing connections"
-
Add SSH keys to 1Password:
- Click the "+" button
- Select "SSH Key"
- Import existing key or generate new one
- Install 1Password
- Enable SSH agent in settings
- Configure socket path:
# Add to ~/.bashrc or ~/.zshrc
export SSH_AUTH_SOCK=~/.1password/agent.sockimport { SSHSession } from 'libssh-node';
const session = new SSHSession({
host: 'example.com',
user: 'username',
autoDetectAgent: true // Will detect 1Password automatically
});
await session.connect();
await session.authenticate({ useAgent: true });import { AgentDetector } from 'libssh-node';
const agent = AgentDetector.detect1Password();
if (agent) {
console.log('1Password agent found:', agent.socketPath);
} else {
console.log('1Password agent not available');
}- Install yubikey-agent:
# macOS
brew install yubikey-agent
# Linux
go install github.com/FiloSottile/yubikey-agent@latest- Start the agent:
yubikey-agent -setup- Configure shell:
# Add to ~/.bashrc or ~/.zshrc
export SSH_AUTH_SOCK="${HOME}/.yubikey-agent.sock"import { SSHSession } from 'libssh-node';
const session = new SSHSession({
host: 'example.com',
user: 'username',
autoDetectAgent: true // Will detect YubiKey automatically
});
await session.connect();
await session.authenticate({ useAgent: true });import { AgentDetector } from 'libssh-node';
const agent = AgentDetector.detectYubiKey();
if (agent) {
console.log('YubiKey agent found:', agent.socketPath);
} else {
console.log('YubiKey agent not available');
}- Start ssh-agent:
eval "$(ssh-agent -s)"- Add keys:
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_ed25519- Make permanent (add to ~/.bashrc or ~/.zshrc):
if [ -z "$SSH_AUTH_SOCK" ]; then
eval "$(ssh-agent -s)"
fiWindows 10/11 includes OpenSSH with ssh-agent:
- Start the service:
Get-Service -Name ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent- Add keys:
ssh-add $HOME\.ssh\id_rsaimport { SSHSession } from 'libssh-node';
const session = new SSHSession({
host: 'example.com',
user: 'username',
autoDetectAgent: true // Will use SSH_AUTH_SOCK
});
await session.connect();
await session.authenticate({ useAgent: true });import { AgentDetector } from 'libssh-node';
// Get the best available agent
const agent = AgentDetector.detect();
if (agent) {
console.log(`Using ${agent.type} agent at ${agent.socketPath}`);
}import { AgentDetector } from 'libssh-node';
const agents = AgentDetector.detectAll();
console.log(`Found ${agents.length} agent(s):`);
agents.forEach(agent => {
console.log(` - ${agent.type}: ${agent.socketPath}`);
});import { SSHSession, AgentDetector } from 'libssh-node';
const agents = AgentDetector.detectAll();
// Let user choose
const selectedAgent = agents[0]; // or user selection
const session = new SSHSession({
host: 'example.com',
user: 'username',
agentSocket: selectedAgent.socketPath,
autoDetectAgent: false // Disable auto-detection
});
await session.connect();
await session.authenticate({ useAgent: true });If you have an agent at a custom location:
const session = new SSHSession({
host: 'example.com',
user: 'username',
agentSocket: '/custom/path/to/agent.sock',
autoDetectAgent: false
});
await session.connect();
await session.authenticate({ useAgent: true });- Check if agent is running:
echo $SSH_AUTH_SOCK-
For 1Password:
- Check settings → Developer → SSH agent is enabled
- Restart 1Password
-
For YubiKey:
- Check yubikey-agent is running
- Verify socket path exists
-
For system agent:
- Run
ssh-add -lto list keys - Start agent if needed:
eval "$(ssh-agent -s)"
- Run
- Check key is added to agent:
ssh-add -l- Verify key is authorized on server:
# On remote server
cat ~/.ssh/authorized_keys- Check key permissions:
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pubExplicitly specify the agent:
const session = new SSHSession({
host: 'example.com',
user: 'username',
agentSocket: '/specific/agent.sock',
autoDetectAgent: false
});Disable auto-detection and specify the agent:
import { AgentDetector } from 'libssh-node';
const onePasswordAgent = AgentDetector.detect1Password();
const session = new SSHSession({
host: 'example.com',
user: 'username',
agentSocket: onePasswordAgent.socketPath,
autoDetectAgent: false
});- Use Agent Forwarding Carefully: Only forward to trusted servers
- Lock Screen: Agents remain active when screen is locked
- Key Management: Regularly rotate SSH keys
- Hardware Keys: Use YubiKey for highest security
- Timeout: Configure agent timeout to auto-lock
// 1Password can hold multiple keys
// It will prompt which key to use
const session = new SSHSession({
host: 'example.com',
user: 'username',
autoDetectAgent: true
});
await session.connect();
await session.authenticate({ useAgent: true });
// 1Password will show a prompt to select key// YubiKey requires physical touch and may require PIN
const session = new SSHSession({
host: 'example.com',
user: 'username',
autoDetectAgent: true
});
await session.connect();
await session.authenticate({ useAgent: true });
// YubiKey will prompt for touch/PINimport { SSHSession, AgentDetector } from 'libssh-node';
const session = new SSHSession({
host: 'example.com',
user: 'username',
autoDetectAgent: true
});
await session.connect();
// Try agent first
const agent = AgentDetector.detect();
if (agent) {
try {
await session.authenticate({ useAgent: true });
console.log('Authenticated with agent');
} catch (err) {
console.log('Agent auth failed, falling back to password');
await session.authenticate({
username: 'username',
password: 'password'
});
}
} else {
// No agent, use password
await session.authenticate({
username: 'username',
password: 'password'
});
}class SSHConfig {
static async getAgentInfo(): Promise<AgentInfo | null> {
const agents = AgentDetector.detectAll();
// Prefer 1Password for better UX
const onePassword = agents.find(a => a.type === 'onepassword');
if (onePassword) return onePassword;
// Then YubiKey for security
const yubikey = agents.find(a => a.type === 'yubikey');
if (yubikey) return yubikey;
// Finally system agent
const system = agents.find(a => a.type === 'system');
if (system) return system;
return null;
}
static async createSession(config: ConnectionConfig): Promise<SSHSession> {
const agent = await this.getAgentInfo();
return new SSHSession({
host: config.ssh.host,
port: config.ssh.port,
user: config.ssh.user,
agentSocket: agent?.socketPath,
autoDetectAgent: !agent // Only auto-detect if we didn't find one
});
}
}