#14211: feat: Add Stateful SSH Plugin with Auto-Key Detection
size: XL
Cluster:
OpenClaw Plugin Enhancements
## 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
#2556: fix(plugin-install): handle existing plugins and filter workspace deps
by longmaba · 2026-01-27
76.8%
#23574: security: P0 critical remediation — plugin sandbox, password hashin...
by lumeleopard001 · 2026-02-22
76.7%
#20424: Fix plugin extension path traversal in discovery/install
by markmusson · 2026-02-18
75.3%
#11096: fix(plugins): require explicit trust for workspace and external plu...
by T1mn · 2026-02-07
75.3%
#8821: Security: Holistic capability-based sandbox (replaces pattern-match...
by tonioloewald · 2026-02-04
75.1%
#6405: feat(security): Add HTTP API security hooks for plugin scanning
by masterfung · 2026-02-01
74.8%
#18003: feat(infra): Adaptive SSH Environment Wrapper (ARE)
by stakeswky · 2026-02-16
74.0%
#7346: Security: add hardening module and secure-bot extension
by AlphonseC · 2026-02-02
74.0%
#20402: Pr/load openclaw plugins async
by ramarnat · 2026-02-18
73.9%
#21964: Security: harden gateway and plugin trust boundaries
by Elormyevu · 2026-02-20
73.8%