or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

http-tunneling.mdindex.mdkey-management.mdport-forwarding.mdsftp-operations.mdssh-agents.mdssh-client.mdssh-server.md

ssh-agents.mddocs/

0

# SSH Agents

1

2

Comprehensive SSH agent integration supporting OpenSSH, Windows Pageant, and Cygwin agents for secure key management and authentication.

3

4

## Capabilities

5

6

### BaseAgent Class

7

8

Abstract base class defining the SSH agent interface.

9

10

```javascript { .api }

11

/**

12

* Abstract base class for SSH agents

13

* Provides standard interface for key management and signing operations

14

*/

15

class BaseAgent {

16

/**

17

* Get list of identities (keys) available in the agent

18

* @param callback - Callback receiving array of available keys

19

*/

20

getIdentities(callback: IdentitiesCallback): void;

21

22

/**

23

* Sign data using a key from the agent

24

* @param pubKey - Public key to use for signing

25

* @param data - Data to sign

26

* @param options - Optional signing options

27

* @param callback - Callback receiving signature

28

*/

29

sign(pubKey: ParsedKey, data: Buffer, options?: SignOptions, callback?: SignCallback): void;

30

sign(pubKey: ParsedKey, data: Buffer, callback: SignCallback): void;

31

}

32

33

interface SignOptions {

34

hash?: string;

35

}

36

37

type IdentitiesCallback = (err: Error | null, keys?: ParsedKey[]) => void;

38

type SignCallback = (err: Error | null, signature?: Buffer) => void;

39

```

40

41

### OpenSSHAgent Class

42

43

OpenSSH SSH agent implementation for Unix-like systems.

44

45

```javascript { .api }

46

/**

47

* OpenSSH SSH agent implementation

48

* Connects to SSH agent via Unix domain socket

49

*/

50

class OpenSSHAgent extends BaseAgent {

51

/**

52

* Create OpenSSH agent instance

53

* @param socketPath - Path to SSH agent socket (default: SSH_AUTH_SOCK env var)

54

*/

55

constructor(socketPath?: string);

56

57

/**

58

* Get connection stream to SSH agent

59

* @param callback - Callback receiving agent connection stream

60

*/

61

getStream(callback: StreamCallback): void;

62

}

63

64

type StreamCallback = (err: Error | null, stream?: Duplex) => void;

65

```

66

67

**Usage Examples:**

68

69

```javascript

70

const { OpenSSHAgent } = require('ssh2');

71

72

// Connect to default SSH agent

73

const agent = new OpenSSHAgent();

74

75

// List available keys

76

agent.getIdentities((err, keys) => {

77

if (err) throw err;

78

79

console.log('Available keys:');

80

keys.forEach((key, index) => {

81

console.log(`${index}: ${key.type} ${key.comment || '(no comment)'}`);

82

});

83

84

// Sign data with first key

85

if (keys.length > 0) {

86

const data = Buffer.from('Hello, SSH agent!');

87

agent.sign(keys[0], data, (err, signature) => {

88

if (err) throw err;

89

console.log('Signature:', signature.toString('base64'));

90

});

91

}

92

});

93

94

// Connect to specific agent socket

95

const customAgent = new OpenSSHAgent('/custom/path/to/agent.sock');

96

```

97

98

### PageantAgent Class

99

100

Windows Pageant SSH agent implementation.

101

102

```javascript { .api }

103

/**

104

* Windows Pageant SSH agent implementation

105

* Communicates with Pageant via Windows messaging

106

*/

107

class PageantAgent extends OpenSSHAgent {

108

constructor();

109

}

110

```

111

112

**Usage Example:**

113

114

```javascript

115

// Windows Pageant agent (Windows only)

116

const { PageantAgent } = require('ssh2');

117

118

const agent = new PageantAgent();

119

120

agent.getIdentities((err, keys) => {

121

if (err) {

122

console.error('Pageant not available or no keys loaded');

123

return;

124

}

125

126

console.log(`Found ${keys.length} keys in Pageant`);

127

});

128

```

129

130

### CygwinAgent Class

131

132

Cygwin SSH agent implementation for Cygwin environments.

133

134

```javascript { .api }

135

/**

136

* Cygwin SSH agent implementation

137

* Handles Cygwin-specific agent communication

138

*/

139

class CygwinAgent extends OpenSSHAgent {

140

constructor();

141

}

142

```

143

144

### AgentProtocol Class

145

146

Low-level SSH agent protocol implementation for creating custom agents.

147

148

```javascript { .api }

149

/**

150

* SSH agent protocol implementation

151

* Handles SSH agent wire protocol for client and server modes

152

*/

153

class AgentProtocol extends EventEmitter {

154

/**

155

* Create agent protocol instance

156

* @param isClient - true for client mode, false for server mode

157

*/

158

constructor(isClient: boolean);

159

}

160

```

161

162

#### Client Mode Methods

163

164

```javascript { .api }

165

/**

166

* Request identities from agent (client mode)

167

* @param callback - Callback receiving available keys

168

*/

169

getIdentities(callback: IdentitiesCallback): void;

170

171

/**

172

* Request signature from agent (client mode)

173

* @param pubKey - Public key to use for signing

174

* @param data - Data to sign

175

* @param options - Optional signing options

176

* @param callback - Callback receiving signature

177

*/

178

sign(pubKey: ParsedKey, data: Buffer, options?: SignOptions, callback?: SignCallback): void;

179

sign(pubKey: ParsedKey, data: Buffer, callback: SignCallback): void;

180

```

181

182

#### Server Mode Methods

183

184

```javascript { .api }

185

/**

186

* Send failure response (server mode)

187

* @param reqId - Request ID to respond to

188

*/

189

failureReply(reqId: number): void;

190

191

/**

192

* Send identities response (server mode)

193

* @param reqId - Request ID to respond to

194

* @param keys - Array of available keys

195

*/

196

getIdentitiesReply(reqId: number, keys: ParsedKey[]): void;

197

198

/**

199

* Send signature response (server mode)

200

* @param reqId - Request ID to respond to

201

* @param signature - Signature data

202

*/

203

signReply(reqId: number, signature: Buffer): void;

204

```

205

206

### AgentContext Class

207

208

Helper class for iterating through agent keys during authentication.

209

210

```javascript { .api }

211

/**

212

* Helper for iterating through SSH agent keys

213

* Simplifies multi-key authentication attempts

214

*/

215

class AgentContext {

216

/**

217

* Create agent context wrapper

218

* @param agent - SSH agent instance to wrap

219

*/

220

constructor(agent: BaseAgent);

221

222

/**

223

* Initialize key list from agent

224

* @param callback - Callback with initialization result

225

*/

226

init(callback: InitCallback): void;

227

228

/**

229

* Move to next available key

230

* @returns true if next key available, false if at end

231

*/

232

nextKey(): boolean;

233

234

/**

235

* Get current key

236

* @returns Current key or null if none available

237

*/

238

currentKey(): ParsedKey | null;

239

240

/**

241

* Get current position in key list

242

* @returns Current key index

243

*/

244

pos(): number;

245

246

/**

247

* Reset to first key

248

*/

249

reset(): void;

250

251

/**

252

* Sign data with current key

253

* @param data - Data to sign

254

* @param options - Optional signing options

255

* @param callback - Callback receiving signature

256

*/

257

sign(data: Buffer, options?: SignOptions, callback?: SignCallback): void;

258

sign(data: Buffer, callback: SignCallback): void;

259

}

260

261

type InitCallback = (err: Error | null) => void;

262

```

263

264

**Usage Example:**

265

266

```javascript

267

const { OpenSSHAgent, AgentContext } = require('ssh2');

268

269

const agent = new OpenSSHAgent();

270

const agentCtx = new AgentContext(agent);

271

272

agentCtx.init((err) => {

273

if (err) throw err;

274

275

console.log('Trying agent keys...');

276

277

function tryNextKey() {

278

const key = agentCtx.currentKey();

279

if (!key) {

280

console.log('No more keys to try');

281

return;

282

}

283

284

console.log(`Trying key: ${key.type} ${key.comment || '(no comment)'}`);

285

286

// Simulate authentication attempt

287

const authData = Buffer.from('authentication challenge');

288

agentCtx.sign(authData, (err, signature) => {

289

if (err) {

290

console.log('Key failed, trying next...');

291

if (agentCtx.nextKey()) {

292

tryNextKey();

293

} else {

294

console.log('All keys exhausted');

295

}

296

} else {

297

console.log('Authentication successful!');

298

}

299

});

300

}

301

302

if (agentCtx.currentKey()) {

303

tryNextKey();

304

}

305

});

306

```

307

308

### createAgent Function

309

310

Utility function to create appropriate agent instance based on environment.

311

312

```javascript { .api }

313

/**

314

* Create appropriate SSH agent instance

315

* Auto-detects agent type based on environment and input

316

* @param agent - Agent socket path, existing agent instance, or 'pageant'

317

* @returns Appropriate agent instance

318

*/

319

function createAgent(agent: string | BaseAgent): BaseAgent;

320

```

321

322

**Usage Examples:**

323

324

```javascript

325

const { createAgent } = require('ssh2');

326

327

// Auto-detect from environment

328

const agent1 = createAgent(process.env.SSH_AUTH_SOCK);

329

330

// Use specific socket path

331

const agent2 = createAgent('/tmp/ssh-agent.sock');

332

333

// Use Pageant on Windows

334

const agent3 = createAgent('pageant');

335

336

// Use existing agent instance

337

const existingAgent = new OpenSSHAgent();

338

const agent4 = createAgent(existingAgent);

339

340

// Use in SSH client

341

const conn = new Client();

342

conn.connect({

343

host: 'example.com',

344

username: 'user',

345

agent: createAgent(process.env.SSH_AUTH_SOCK),

346

agentForward: true

347

});

348

```

349

350

## Integration with SSH Client

351

352

Using SSH agents with the SSH client for automatic key-based authentication.

353

354

```javascript { .api }

355

// Client configuration with agent

356

interface ClientConfigWithAgent {

357

agent?: string | BaseAgent;

358

agentForward?: boolean;

359

allowAgentFwd?: boolean;

360

}

361

```

362

363

**Client Integration Examples:**

364

365

```javascript

366

const { Client, OpenSSHAgent } = require('ssh2');

367

368

// Method 1: Use environment variable

369

const conn1 = new Client();

370

conn1.connect({

371

host: 'server.com',

372

username: 'user',

373

agent: process.env.SSH_AUTH_SOCK,

374

agentForward: true // Forward agent to remote server

375

});

376

377

// Method 2: Create agent explicitly

378

const agent = new OpenSSHAgent();

379

const conn2 = new Client();

380

conn2.connect({

381

host: 'server.com',

382

username: 'user',

383

agent: agent,

384

agentForward: true

385

});

386

387

// Method 3: Use specific agent socket

388

const conn3 = new Client();

389

conn3.connect({

390

host: 'server.com',

391

username: 'user',

392

agent: '/custom/agent/socket'

393

});

394

395

// Method 4: Pageant on Windows

396

const conn4 = new Client();

397

conn4.connect({

398

host: 'server.com',

399

username: 'user',

400

agent: 'pageant'

401

});

402

```

403

404

## Agent Events

405

406

SSH agents emit events for connection and operation status.

407

408

```javascript { .api }

409

interface AgentEvents {

410

/**

411

* Emitted when agent connection is established

412

*/

413

'connect': () => void;

414

415

/**

416

* Emitted when agent connection ends

417

*/

418

'end': () => void;

419

420

/**

421

* Emitted when agent connection is closed

422

*/

423

'close': () => void;

424

425

/**

426

* Emitted when agent error occurs

427

*/

428

'error': (err: Error) => void;

429

}

430

```

431

432

## Type Definitions

433

434

### Agent-Related Types

435

436

```javascript { .api }

437

interface ParsedKey {

438

type: string;

439

comment?: string;

440

public: Buffer;

441

private?: Buffer;

442

443

// Key methods

444

getPrivatePEM(): string;

445

getPublicPEM(): string;

446

getPublicSSH(): Buffer;

447

sign(data: Buffer, hashAlgo?: string): Buffer | Error;

448

verify(data: Buffer, signature: Buffer, hashAlgo?: string): boolean | Error;

449

}

450

451

// Agent detection helper

452

function isAgent(obj: any): obj is BaseAgent;

453

```

454

455

## Environment Variables

456

457

SSH agents typically use environment variables for configuration:

458

459

- **SSH_AUTH_SOCK**: Path to SSH agent socket (Unix/Linux/macOS)

460

- **SSH_AGENT_PID**: Process ID of SSH agent (for cleanup)

461

462

```javascript

463

// Check if agent is available

464

if (process.env.SSH_AUTH_SOCK) {

465

console.log('SSH agent available at:', process.env.SSH_AUTH_SOCK);

466

const agent = new OpenSSHAgent(process.env.SSH_AUTH_SOCK);

467

} else {

468

console.log('No SSH agent configured');

469

}

470

```

471

472

## Platform Support

473

474

- **Unix/Linux/macOS**: OpenSSHAgent via Unix domain sockets

475

- **Windows**: PageantAgent via Windows messaging, OpenSSHAgent via named pipes

476

- **Cygwin**: CygwinAgent with Cygwin-specific socket handling

477

478

```javascript

479

// Platform-specific agent selection

480

const { platform } = require('os');

481

482

let agent;

483

switch (platform()) {

484

case 'win32':

485

agent = new PageantAgent();

486

break;

487

case 'linux':

488

case 'darwin':

489

case 'freebsd':

490

agent = new OpenSSHAgent();

491

break;

492

default:

493

agent = createAgent(process.env.SSH_AUTH_SOCK);

494

}

495

```