Sparkey
安装 / 下载方式
TotalClaw CLI推荐
totalclaw install skilldb:sanjeevneo~sparkeycURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/skilldb%3Asanjeevneo~sparkey/file -o sparkey.mdGit 仓库获取源码
git clone https://github.com/openclaw/skills/commit/7d7787b16c153a705795374738cac88229525b38---
name: sparkey
description: Time-limited, self-destructing SSH access for AI agents. Four-layer defense-in-depth: certificate TTL, OS account expiry, command-restricted dispatch, and automated cleanup. Zero session artifacts survive.
license: MIT
homepage: https://github.com/sanjeevneo/sparkey
files:
- scripts/*
metadata: {"openclaw":{"requires":{"bins":["ssh-keygen","useradd","userdel","usermod","passwd","pkill","getent"],"anyBins":["at","systemd-run"]}},"clawdbot":{"requires":{"bins":["ssh-keygen","useradd","userdel","usermod","passwd","pkill","getent"]}}}
---
# Temporary SSH Access for AI Agent Support
Defense-in-depth temporary SSH access for AI agents — combines certificate TTL, OS account expiration, command-restricted dispatch, and automated cleanup. Zero session artifacts survive — all agent accounts, keys, certificates, dispatch shells, and cleanup timers are destroyed on session end or TTL expiry. The CA private key is a persistent operator-side credential requiring separate protection (see Security Considerations).
**Platform:** Linux (requires standard user-management tools).
## Prerequisites
Scripts check for required tools at startup and report what is missing. Install them on common distributions:
**Debian / Ubuntu:**
```bash
sudo apt-get update && sudo apt-get install -y openssh-client coreutils passwd at e2fsprogs procps
```
**Alpine Linux:**
```bash
apk add openssh-keygen bash shadow coreutils util-linux procps at e2fsprogs
```
**RHEL / CentOS / Fedora:**
```bash
sudo dnf install -y openssh-clients coreutils shadow-utils at e2fsprogs procps-ng
```
| Tool | Package (Debian) | Package (Alpine) | Required |
| ---- | ---------------- | ----------------- | -------- |
| `ssh-keygen` | `openssh-client` | `openssh-keygen` | Yes |
| `useradd` / `userdel` | `passwd` | `shadow` | Yes |
| `passwd` | `passwd` | `shadow` | Yes |
| `pkill` | `procps` | `procps` | Yes |
| `getent` | `libc-bin` | `musl-utils` | Yes |
| `at` | `at` | `at` | One of `at` or `systemd-run` |
| `shred` | `coreutils` | `coreutils` | Optional (falls back to `rm`) |
| `chattr` | `e2fsprogs` | `e2fsprogs` | Optional (for immutable authorized\_keys) |
If a required tool is missing, the script exits with an error listing missing dependencies. Optional tools produce warnings but do not block execution.
### Target Host Requirements
The target server (the machine the agent will SSH into) must have:
- **sshd running** and reachable on port 22 (or a configured port)
- **`~/.ssh/` directory** for the user whose `authorized_keys` will receive the agent's public key (the agent's one-liner creates this if missing)
- For CA-based access: `TrustedUserCAKeys` configured in `/etc/ssh/sshd_config` pointing to the CA public key
If the target is a fresh container or VM, install and start sshd first:
```bash
# Alpine
apk add openssh && ssh-keygen -A && rc-service sshd start
# Debian/Ubuntu
apt-get install -y openssh-server && systemctl start sshd
```
## When to Use
- An AI agent needs temporary shell access to diagnose or remediate a remote server
- You require auditable, time-boxed access that self-revokes
- You need to restrict what the agent can execute — no arbitrary commands
- You want zero persistent credentials once the session ends
## Agent-Initiated Access Flow (Recommended)
When an AI agent determines it needs shell access, it briefly states its intent: *"I need shell access to [target] to [reason]. I'll generate a temporary key — you decide where it goes. What username should I connect as?"* Then:
1. **Verify target is reachable** — `nc -z -w 2 TARGET 22` (or equivalent). If the port is closed, stop and inform the user: *"Port 22 is not open on [target]. Please start sshd, then I'll continue."*
2. **Check for existing session** — look for stale keys in `/tmp/agent_access_key*`. If found, test connectivity (`ssh -i /tmp/agent_access_key ... 'echo ok'`). If the key still works, skip to step 7. If expired or revoked, shred stale keys and continue.
3. **Generate keypair locally** — Ed25519, stored in `/tmp/` with a session-tagged comment.
4. **Ask for the connect username** — default to the current user on the target, not root. Ask: *"What username should I connect as? (default: your current user)"*. If the task requires root, inform the user: *"This task requires root. Please add the key to root's authorized_keys (or use `sudo`)."*
5. **Present public key with expiry** — provide a one-liner with `expiry-time` for crash safety. The one-liner creates `~/.ssh/` if absent and is tailored to the target username:
```
mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo 'expiry-time="YYYYMMDDHHMMSS" ssh-ed25519 AAAA... agent-session-SID' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
```
`expiry-time` (OpenSSH 8.2+) ensures the key is server-rejected after the timestamp, even if the agent crashes and never cleans up.
**Important:** The one-liner must run as the target user so `~/.ssh/` resolves to the correct home directory. If adding the key for a different account (e.g., root), either `su - root` first or use the absolute path (e.g., `/root/.ssh/authorized_keys`).
6. **User adds the key** — the user decides where and how to grant access (maintains control).
7. **Verify connection** — connect as the agreed username: `ssh -i /tmp/agent_access_key USER@TARGET 'echo ok'`
8. **Schedule dead-man cleanup** — immediately after connecting, schedule automatic key removal on the target:
```bash
echo "sed -i '/agent-session-SID/d' ~/.ssh/authorized_keys" | at now + 4 hours
```
This fires independently of the agent. If the agent finishes early, it cancels the job and cleans up itself.
9. **Run fast recon** — OS, key packages, `screen`/`tmux` availability. Under 10 seconds.
10. **Create shared session** — start a `screen` or `tmux` session on the target so the user can attach and observe in real time.
11. **Work** — run diagnostics, remediation, or other tasks within the granted scope.
12. **Clean up** — remove the public key from `authorized_keys`, cancel the `at` job, destroy the local keypair.
### Crash Safety (Simple Mode)
Two independent mechanisms protect against agent crashes:
| Safeguard | Fires without agent? | Mechanism |
|-----------|---------------------|-----------|
| `expiry-time` in authorized_keys | Yes | Server-side — OpenSSH rejects the key after the timestamp |
| Scheduled `at` job | Yes | Runs on target's scheduler — removes the key entry on timer |
If the agent crashes and restarts, it reuses the stale keys from `/tmp/` (step 2) rather than re-provisioning, avoiding repeated user interaction.
This flow requires no script transfer to the target and leaves no persistent artifacts. For stronger guarantees (certificate TTL, command restriction, scheduled cleanup), layer the CA-based workflow below on top.
### Observability
After establishing access, the agent should create a shared terminal session:
```bash
# On the target — agent creates a named session
screen -dmS agent-work
screen -S agent-work -X multiuser on
screen -S agent-work -X acladd root
# User attaches to watch
screen -x agent-work
```
If `screen` is unavailable, `tmux` works similarly:
```bash
tmux new-session -d -s agent-work
# User attaches:
tmux attach -t agent-work
```
The agent should check for `screen`/`tmux` availability during initial recon and install if needed (with user permission).
## Architecture: Defense in Depth
Four independent expiration and restriction mechanisms ensure no single failure leaves access open:
| Layer | Mechanism | What It Does |
|-------|-----------|--------------|
| 1 | **SSH Certificate TTL** | Cryptographically enforced expiry (`-V +Nh`) — server rejects expired certs |
| 2 | **OS Account Expiration** | `useradd --expiredate` — login denied after date |
| 3 | **Forced Command / Safe Dispatch** | Exact command-name matching, path-restricted arguments, no `eval` |
| 4 | **Scheduled Cleanup** | `at` or `systemd-run` ti