ssh-executor
Execute commands on remote hosts over SSH with structured discovery protocol, vault-integrated auth, and safety guardrails for remote server administration. Use when the user asks to access remote servers, inspect state, map runtime/containers/network/data, or run single commands. Supports SSH keys Skill: ssh-executor Owner: rickkbarbosa Summary: Execute commands on remote hosts over SSH with structured discovery protocol, vault-integrated auth, and safety guardrails for remote server administration. Use when the user asks to access remote servers, inspect state, map runtime/containers/network/data, or run single commands. Supports SSH keys Tags: latest:2.4.2 Version history: v2.4.2 | 2026-07-24T02:37:04.179Z |
Rank
62
Safety
84
Downloads
1.8k
Updated
Oct 10, 2026
Version
2.4.2
Source
CLAWHUB
About
What it does, and when to use it.
Capability contract not published. No trust telemetry is available yet. 1.8K downloads reported by the source. Last updated 10/10/2026.
Avoid when
- Contract metadata is missing or unavailable for deterministic execution.
Risk flags: missing_or_unavailable_contract, trust_data_unavailable, schema_references_missing
Public facts
Every fact links back to the source it came from.
- Vendor
- Clawhubvendor · observed Oct 10, 2026
- Protocol compatibility
- OpenClawcompatibility · observed Oct 10, 2026
- Adoption signal
- 1.8K downloadsadoption · observed Oct 10, 2026
- Latest release
- 2.4.2release · observed Jul 24, 2026
- Handshake status
- UNKNOWNsecurity
Install and run
Setup complexity: low.
clawhub skill install s171q3s6m4gq09dzjg1yep0g1n84x3a1:ssh-executor- Setup complexity is classified as HIGH. You must provision dedicated cloud infrastructure or an isolated VM. Do not run this directly on your local workstation.
- Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data.
Contract: missing
curl -s "https://www.xpersona.co/api/v1/agents/clawhub-rickkbarbosa-ssh-executor/snapshot"
Documentation
CLAWHUB
152,671 characters of source documentation, loaded on request.
Extracted files
5 files captured from the source.
SKILL.md
---
name: ssh-executor
description: Execute commands on remote hosts over SSH with structured discovery, pluggable credential backends, and safety guardrails. Supports SSH key-based and password-based auth with multiple credential sources (vault, env vars, direct files). Includes 6-step discovery protocol and standardized JSON output. Host-key verification is strict by default. Cross-platform: works on Hermes Agent, OpenClaw, Claude Code, Codex, and any LLM environment with bash + python3.
metadata:
platforms: ["hermes", "openclaw", "claude-code", "codex", "generic"]
os: ["linux", "darwin"]
requires: { bins: ["bash", "python3", "base64"], optional_bins: ["ssh", "ssh-agent", "ssh-add", "ssh-keygen", "sshpass"] }
---
# SSH Executor
Execute remote commands over SSH securely. Platform-agnostic — configure once, use anywhere.
## Scope
| Use for | Don't use for |
|---------|---------------|
| Connecting to Linux servers via alias, IP, user, port | Storing/displaying credentials in chat or logs |
| Inspection commands (read-only) | Running destructive commands without user confirmation |
| Maintenance with explicit `--confirm-dangerous` | Bypassing host-key verification (strict by default) |
| Any credential backend: vault, env vars, key files, password prompts | Exposing private key contents anywhere |
### Credential Sources (Tiered)
The skill works with **any** credential source. Configure what you have — no mandatory vault dependency.
| Tier | Source | How | Example |
|------|--------|-----|---------|
| **1. Vault** | Any vault that outputs to stdout | `--vault-key <name>` + backend script | Bitwarden CLI, 1Password CLI, vault-resolver, HashiCorp Vault |
| **2. Env vars** | Environment variables | `SSH_PASS`, `SSH_SUDO_PASS`, `SSH_KEY` | CI/CD pipelines, containerized agents |
| **3. Direct** | Key files, interactive prompts | `--key <path>`, `--ssh-pass-ask`, `--sudo-pass-ask` | Local development, one-off access |
The default vault backend is **vault-resolver** (Hermes-native, Vaultwarden API). To use another vault:
```bash
# 1Password CLI
export VAULT_RESOLVER_BIN="op"
# Bitwarden CLI
export VAULT_RESOLVER_BIN="bw"
# Custom script (must accept JSON on stdin, output JSON on stdout)
export VAULT_RESOLVER_BIN="/path/to/your/vault-wrapper"
```
See `references/vault-backends.md` for setup guides for each platform.
## Platform Setup
### Hermes Agent / OpenClaw (native)
```bash
# vault-resolver is auto-detected at /opt/data/bin/vault-resolver
# Store a key:
ssh-keys.sh store my-server ~/.ssh/id_rsa
# Use:
ssh-run.sh --host my-server --vault-key my-server -- 'uptime'
```
### Claude Code / Codex / Generic LLM
```bash
# No vault — use env vars or key files:
export SSH_KEY="$(cat ~/.ssh/id_rsa)"
ssh-run.sh --host my-server --user ubuntu --key ~/.ssh/id_rsa -- 'uptime'
# Or with password (requires SSH_EXECUTOR_ALLOW_DANGEROUS=1):
SSH_EXECUTOR_ALLOW_DANGEROUS=1 SSH_PASS="<your-password>" ssh-run.sh --host my-server --user ubuntu -- 'uptime_meta.json
{
"ownerId": "kn7e7q1wce41djeky0k2zscsw184xh21",
"slug": "ssh-executor",
"version": "2.4.2",
"publishedAt": 1784860624179
}references/docker-diagnostics-without-cli.md
# Docker Diagnostics Without Docker CLI
When the remote SSH user is **not in the docker group** and **has no sudo
NOPASSWD** — but you still need to diagnose containers, networks, and services.
## Techniques
### 1. List active containers via cgroup
```bash
ls /sys/fs/cgroup/system.slice/docker-*.scope 2>/dev/null | while read f; do
id=$(echo "$f" | grep -oP "docker-\K[a-f0-9]{12}")
echo "Container ID: $id"
done
```
⚠️ Shows ALL active containers (not just running — any process in the
cgroup). Useful as a starting point.
### 2. Identify processes inside a container
```bash
# PIDs in the container
cat /sys/fs/cgroup/system.slice/docker-<FULL_ID>.scope/cgroup.procs
# What each PID executes
for pid in $(cat /sys/fs/cgroup/system.slice/docker-<ID>.scope/cgroup.procs); do
cmd=$(cat /proc/$pid/cmdline 2>/dev/null | tr "\0" " " | head -c 200)
echo "PID $pid: $cmd"
done
```
### 3. Determine the container's network_mode
Compare the process network namespace with the host's:
```bash
host_ns=$(readlink /proc/1/ns/net)
container_ns=$(readlink /proc/<PID>/ns/net)
if [ "$host_ns" = "$container_ns" ]; then
echo "network_mode: host"
else
echo "network_mode: bridge (or other)"
fi
```
### 4. Find container IPs via bridge ARP
Knowing which bridge is active (via `ip addr show`):
```bash
# List active bridges
ip addr show | grep -E "^[0-9]+: br-|^[0-9]+: docker" | grep UP
# Show ARP neighbors (active IPs)
ip neigh show dev br-<ID>
```
Example output:
```
172.18.0.5 lladdr de:9a:bb:2b:2a:32 REACHABLE
172.18.0.7 lladdr 66:1d:5b:2c:c2:08 STALE
```
**REACHABLE/STALE** IPs = active containers. **FAILED** = IP does not exist.
### 5. Discover which process listens on which port
```bash
ss -tlnp # TCP listening, with PID
ss -ulnp # UDP
```
⚠️ Without root, `ss -p` does not show the process (empty column). Use the port
as a clue and cross-reference with `/proc/PID/cmdline`.
### 6. Test TCP connectivity without tools
```bash
timeout 2 bash -c "echo > /dev/tcp/<IP>/<PORT>" 2>/dev/null && echo "OPEN"
```
Useful for quickly scanning ports on a bridge or host — **only on networks you own or have explicit authorization to probe**:
```bash
# ⚠️ Network scanning — verify authorization before running
for ip in 172.18.0.{1..10}; do
timeout 1 bash -c "echo > /dev/tcp/$ip/3306" 2>/dev/null && echo "$ip:3306 OK"
done
```
### 7. Read container configuration via docker-compose
Not every container was started with compose, but when it was:
```bash
cat /path/docker-compose.yml
```
Pay special attention to:
- `network_mode:` (host vs bridge)
- `networks:` → `driver:` (host = shares host IP)
- `ports:` (mapping)
- `extra_hosts:` (hostname resolution)
- `environment:` / `env_file:` (configuration variables)
### 8. Check internal configuration files
For services like MySQL/MariaDB, even without container access:
```bash
# Process has config args in cmdline
cat /proc/<PID>/cmdline | tr "\0" " "
# Check default config (host filesystem)
cat /etc/mysreferences/multiplexing-verification.md
# Multiplexing Verification Procedure to confirm that ControlMaster multiplexing is working correctly. ## Quick Checklist (6 steps) ### 1. Does the local socket exist? ```bash ls -la /tmp/ssh-mux-<user>@<hostname>:<port> # Ex: /tmp/[email protected]:22 ``` **Expected:** UNIX socket (`srw-------`) with the first connection's timestamp. ### 2. Does the socket timestamp stay unchanged across subsequent commands? ```bash stat -c '%Y' /tmp/ssh-mux-<user>@<host>:<port> # before ssh-run.sh --host <host> --user <user> --vault-key <key> -- 'date' stat -c '%Y' /tmp/ssh-mux-<user>@<host>:<port> # after — same value! ``` **Expected:** same epoch timestamp before and after. ### 3. Only 1 mux process for the host? ```bash ps aux | grep "[s]sh.*mux.*<host>" ``` **Expected:** exactly 1 process `ssh: /tmp/ssh-mux-... [mux]`. ### 4. Are TCP connections on the server consistent? ```bash ssh-run.sh --host <host> --user <user> --vault-key id-rsa -- 'ss -tn sport = :22' ``` **Expected:** the number of ESTABLISHED connections to the Hermes IP does not increase with each command. ### 5. Does auth.log have only 1 Accepted per window? ```bash ssh-run.sh --host <host> --user <user> --vault-key <key> \ --sudo --sudo-pass-vault <name> \ -- 'sudo grep "sshd.*Accepted.*<user>" /var/log/auth.log | tail -5' ``` **Expected:** only 1 `Accepted publickey` entry for the entire batch of commands within the ControlPersist window. ### 6. Is the JSON output clean (no vault pollution)? ```bash result=$(ssh-run.sh --host <host> --user <user> --vault-key id-rsa -- 'hostname' 2>/dev/null) echo "$result" | python3 -c "import sys,json; d=json.load(sys.stdin); print('OK:', d['stdout'].strip())" ``` **Expected:** successful parse, no "Retrieving SSH key..." messages in stdout. ## Signs that multiplexing is NOT active | Symptom | Likely cause | |---------|-------------| | Socket does not exist after command | `ssh-agent` is not running → Python backend (no ControlMaster) | | Multiple sockets with different timestamps | Different `--user` across calls → each user@host combination creates its own socket | | Socket exists but timestamp changes per command | `ControlPersist` expired between calls (>180s) | | `Permission denied (publickey)` | Wrong `--user` (local user instead of remote) | ## Quick diagnostic command ```bash # Close old socket, test 3 commands, verify ssh -o ControlPath=/tmp/ssh-mux-<user>@%h:%p -O exit <user>@<host> 2>/dev/null || true TS1=$(bash ssh-run.sh --host <host> --user <user> --vault-key <key> --control-persist 180 -- 'hostname' 2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin)['stdout'].strip())") S1=$(stat -c '%Y' /tmp/ssh-mux-<user>@<host>:<port> 2>/dev/null) TS2=$(bash ssh-run.sh --host <host> --user <user> --vault-key <key> -- 'date' 2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin)['stdout'].strip())") S2=$(stat -c '%Y' /tmp/ssh-mux-<user>@<host>:<port> 2>/dev/null) TS3=$(ba
references/remote-backup-cleanup.md
# Remote Backup Cleanup via SSH
> **⚠️ DESTRUCTIVE OPERATIONS:** All commands in this document delete data permanently.
> - **Always dry-run first** with `-ls` or `-printf` to verify what will be deleted
> - **Require explicit user confirmation** before running any command with `-delete`
> - Pass `--confirm-dangerous` AND set `SSH_EXECUTOR_ALLOW_DANGEROUS=1` when using `ssh-run.sh` for these commands
> - See `safety.md` for the full confirmation policy
Clean up old backups on remote servers using `find -mtime +N -delete`.
## Basic pattern
```bash
# With ssh-executor (requires SSH_EXECUTOR_ALLOW_DANGEROUS=1 + --confirm-dangerous):
SSH_EXECUTOR_ALLOW_DANGEROUS=1 ssh-run.sh --host <host> --user <user> --vault-key <key> \
--confirm-dangerous -- 'find /srv/backup -type f -mtime +15 -delete'
# Direct SSH (manual, no guardrails):
ssh <user>@<host> 'find /srv/backup -type f -mtime +15 -delete'
```
The `-delete` flag only works after `-type f` (prevents accidentally deleting directories).
## Permission model — common pitfall
Deleting a file does **not** require write permission on the **file** — it requires write permission (`w`) on the **directory** that contains it.
### Quick diagnosis
```bash
# View complete hierarchy permissions
namei -l /srv/backup/2026-06-13/backup_file.tar.gz
```
### Typical scenario
```
drwxr-xr-x root backup srv/backup/ # backup group has r-x, missing w
drwxr-xr-x root backup 2026-06-13/ # backup group has r-x, missing w
-rw-r--r-- root backup file.tar.gz # group read-only — irrelevant
```
Even if the **remote user** is in the `backup` group (via `groups` or `id`) and the **files** are `root:backup`, deletion fails with `Permission denied` if the directory lacks `w` for the group.
### Solutions (in order of preference)
| Approach | Requirement | Risks |
|-----------|-----------|--------|
| **sudo** | Remote user's sudo password | Simplest, but needs interaction |
| **chmod g+w on directories** | Directory owner or sudo | Permission stays open; requires directory owner |
| **Cron job as root** | Backup service runs as root | Ideal for automated routine |
| **ACL** | Filesystem with ACL support | `setfacl -m g:backup:rwx /srv/backup` |
### Real case example
A common scenario encountered in production:
- Server with backup directories owned by `root:backup`, permissions `drwxr-xr-x`
- The remote user is in the `backup` group but lacks write permission on directories
- Backup files are owned by `root:root` (or `root:backup`)
- Deletion fails without sudo because directories lack `w` for the `backup` group
This is not a file permission issue — it's a **directory write permission** issue.
The solution is sudo, `chmod g+w` on directories, ACLs, or a cron job as root.
## Useful commands
```bash
# Dry-run: list files older than 15 days with size
ssh <host> 'find /srv/backup /archive/backup -type f -mtime +15 -ls'
# Count and total size
ssh <host> 'find /srv/backup /archive/backup -type fAionUi
Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!
activepieces
AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents
cherry-studio
AI productivity studio with smart chat, autonomous agents, and 300+ assistants.
CopilotKit
The Frontend for Agents & Generative UI. React + Angular
Machine-readable data
The same record, as JSON, for agents and crawlers.
{
"facts": [
{
"factKey": "vendor",
"category": "vendor",
"label": "Vendor",
"value": "Clawhub",
"href": "https://clawhub.ai/rickkbarbosa/skills/ssh-executor",
"sourceUrl": "https://clawhub.ai/rickkbarbosa/skills/ssh-executor",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-10T02:16:13.368Z",
"isPublic": true
},
{
"factKey": "protocols",
"category": "compatibility",
"label": "Protocol compatibility",
"value": "OpenClaw",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-rickkbarbosa-ssh-executor/contract",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-rickkbarbosa-ssh-executor/contract",
"sourceType": "contract",
"confidence": "medium",
"observedAt": "2026-10-10T02:16:13.368Z",
"isPublic": true
},
{
"factKey": "traction",
"category": "adoption",
"label": "Adoption signal",
"value": "1.8K downloads",
"href": "https://clawhub.ai/rickkbarbosa/ssh-executor",
"sourceUrl": "https://clawhub.ai/rickkbarbosa/ssh-executor",
"sourceType": "profile",
"confidence": "medium",
"observedAt": "2026-10-10T02:16:13.368Z",
"isPublic": true
},
{
"factKey": "latest_release",
"category": "release",
"label": "Latest release",
"value": "2.4.2",
"href": "https://clawhub.ai/rickkbarbosa/ssh-executor",
"sourceUrl": "https://clawhub.ai/rickkbarbosa/ssh-executor",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-07-24T02:37:04.179Z",
"isPublic": true
},
{
"factKey": "handshake_status",
"category": "security",
"label": "Handshake status",
"value": "UNKNOWN",
"href": "https://www.xpersona.co/api/v1/agents/clawhub-rickkbarbosa-ssh-executor/trust",
"sourceUrl": "https://www.xpersona.co/api/v1/agents/clawhub-rickkbarbosa-ssh-executor/trust",
"sourceType": "trust",
"confidence": "medium",
"observedAt": null,
"isPublic": true
}
],
"events": [
{
"eventType": "release",
"title": "Release 2.4.2",
"description": "- Removed unused file: skill-card.md - Clarified and expanded credential source descriptions, including support for password-based login with explicit `SSH_EXECUTOR_ALLOW_DANGEROUS=1` - Updated security rules: password and sudo operations require explicit user approval, even if credentials already exist - Declared new required capability: access to environment variables for password and agent support - Documented the use of `sshpass` for password-based authentication as an optional dependency - Enhanced documentation for usage, security, and platform setup across multiple environments",
"href": "https://clawhub.ai/rickkbarbosa/ssh-executor",
"sourceUrl": "https://clawhub.ai/rickkbarbosa/ssh-executor",
"sourceType": "release",
"confidence": "medium",
"observedAt": "2026-07-24T02:37:04.179Z",
"isPublic": true
}
]
}Record generated Oct 10, 2026.
