← Back to PRs

#14211: feat: Add Stateful SSH Plugin with Auto-Key Detection

by schmiereck open 2026-02-11 17:54 View on GitHub →
size: XL
## Summary This PR adds a comprehensive **Stateful SSH Plugin** for OpenClaw that enables persistent SSH session management with automatic key detection, similar to standard SSH clients. ## Features ### Core Functionality - ✅ **Persistent SSH Sessions**: Maintain shell state (working directory, environment variables) across multiple commands - ✅ **Automatic Key Detection**: Parse `~/.ssh/config` and auto-detect SSH keys - ✅ **Host-Specific Keys**: Support different keys for different servers - ✅ **Multiple Host Patterns**: Support `Host server1 server2 192.168.1.10` in SSH config - ✅ **Wildcard Patterns**: Support `Host *.local` patterns - ✅ **Fallback to Default Keys**: Auto-search standard locations if no config match ### Tools Provided 1. **open_ssh_session**: Open persistent SSH connection 2. **execute_ssh_command**: Run commands in existing session (state preserved) 3. **close_ssh_session**: Close session cleanly 4. **list_ssh_sessions**: List all active sessions ### Session Management - ✅ Configurable session limits (default: 5) - ✅ Auto-cleanup of idle sessions (default: 10 minutes) - ✅ Graceful shutdown with cleanup handlers - ✅ Command timeout protection (default: 30 seconds) ## Use Cases **Before** (stateless, no key management): Connect to 192.168.1.10 as user 'deploy' using password 'secret', run 'cd /app && pwd && ls', then disconnect Problem: Each command starts fresh, cd doesn't persist **After** (stateful with auto-key): Connect to production-server and run these commands: - cd /app - pwd - ls Then close the session. Benefits: - Session persists, cd works across commands - Hostname resolves via ~/.ssh/config - SSH key auto-detected from config - Clean session management ## SSH Config Example ```ssh-config Host production-server prod 10.0.1.50 HostName 10.0.1.50 User deploy IdentityFile ~/.ssh/id_ed25519_production Host *.staging IdentityFile ~/.ssh/id_ed25519_staging ``` All three work: production-server, prod, 10.0.1.50 ## Technical Details - Library: ssh2 (Node.js) - Pattern: Plugin object with register method (matches memory-core) - Sandboxing: Tools disabled in sandboxed contexts for security - Path Expansion: Supports ~, $HOME, ${HOME} in IdentityFile paths ## Files Added - extensions/stateful-ssh/index.ts - Plugin registration - extensions/stateful-ssh/src/session-manager.ts - Core session management - extensions/stateful-ssh/src/ssh-tools.ts - Tool definitions - extensions/stateful-ssh/package.json - Dependencies (ssh2) - extensions/stateful-ssh/openclaw.plugin.json - Plugin metadata - Documentation: README.md, TESTING.md, AUTO-KEY-DETECTION.md, SSH-CONFIG-SUPPORT.md ## Testing Tested on: - Raspberry Pi (ARM64) with multiple SSH targets - Docker container environment - Multiple concurrent sessions - Hostname resolution via SSH config - Auto-key detection from standard locations ## Breaking Changes None - this is a new plugin that doesn't affect existing functionality. ## Related Issues Addresses common user requests for: - Persistent SSH sessions for deployment workflows - Automatic SSH key management - Standard SSH client behavior in OpenClaw --- Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR introduces a new `extensions/stateful-ssh` plugin that registers four SSH-related tools (`open_ssh_session`, `execute_ssh_command`, `close_ssh_session`, `list_ssh_sessions`) plus a lifecycle service to clean up sessions on shutdown. The core implementation is an `SSHSessionManager` built on `ssh2` that maintains a persistent shell per session, serializes command execution via a per-session promise queue, and optionally auto-detects private keys from `~/.ssh/config` (including wildcard and multi-host patterns) or common default key locations. The workspace package is added to `pnpm-lock.yaml` with required dependencies. <h3>Confidence Score: 5/5</h3> - This PR looks safe to merge with the previously-raised issues addressed in the current head commit. - The current head commit resolves the prior critical items (no process exit on signals, tool sandbox gating, prompt/command timeout cleanup, host wildcard escaping, dependency declaration, and API type consistency). The remaining changes add a new isolated extension package and lockfile entries; the core tool registration and session manager logic align with existing plugin/tool infrastructure (tool factories may return arrays and are handled by `resolvePluginTools`). - extensions/stateful-ssh/src/session-manager.ts (runtime behavior under unusual SSH server prompt/close semantics), pnpm-lock.yaml <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs