Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

SSH Agent Harness

LLM 驱动的 SSH 命令生成/执行框架,仅本机 Web 控制台。 支持本机 Ollama(deepseek-r1)或任意 OpenAI 兼容端点(DeepSeek/vLLM/Azure), 以 Harness 架构把「模型 + 工具 + 上下文 + 评估 + 护栏」组合成安全可审计的运维助手。

架构

┌─────────────────────────────────────────────────────────────┐
│                 SSH Agent Harness(纯 Web)                 │
├─────────────────────────────────────────────────────────────┤
│  Web 控制台(FastAPI + React SPA)                          │
├─────────────────────────────────────────────────────────────┤
│  Generator (deepseek-r1)   │  命令生成 + CoT / 多轮修复     │
├─────────────────────────────────────────────────────────────┤
│  Tool Execution Layer      │  SSH / SFTP 传输 / 文件        │
├─────────────────────────────────────────────────────────────┤
│  Context & Memory          │  会话 / 服务器工作空间 / 指纹    │
├─────────────────────────────────────────────────────────────┤
│  Evaluator / Guardrails    │  安全分级 / 审批门控 / 审计    │
└─────────────────────────────────────────────────────────────┘

安装

从 PyPI 安装(自带前端控制台,装完直接可用):

pip install ssh-agent-harness
ssh-agent-web            # 浏览器打开 http://127.0.0.1:8000

开发(源码 + 热更新):

conda activate python312
pip install -e ".[dev]"

打包与发布(本地构建、TestPyPI、正式 PyPI)见 docs/packaging-and-release.md。

也可使用本机模型:先 ollama serve,再 ollama pull deepseek-r1:1.5b; 或通过环境变量指向外部 OpenAI 兼容端点(key 只走 env,勿入库):

export LLM_PROVIDER=openai LLM_MODEL=deepseek-chat LLM_API_KEY=***
# 可选:LLM_BASE_URL=https://api.deepseek.com

启动

唯一入口是 Web 控制台 ssh-agent-web(ssh_agent_harness/api/__main__.py:main):

ssh-agent-web --db ./data/agent.db
# 或显式参数:
ssh-agent-web --host 127.0.0.1 --port 8000 --db ./data/agent.db --approval-timeout 900

⚠️ 只能用 ssh-agent-web 启动。不要用 uvicorn 直启 app (python -m uvicorn ssh_agent_harness.api.app:app)——它不解析 --db, 会落到用户默认库并触发启动清理(误伤在飞任务)。

参数 默认值 说明
--host 127.0.0.1 绑定地址;默认只监听回环
--port 8000 监听端口
--db settings.storage.db_path SQLite 路径
--approval-timeout 900.0 审批等待秒数;超时后审批置 expired、任务判 denied
--static 包内自带的 SPA 覆盖内置前端目录;源码开发时指向 web/dist,安装版无需传

交互式 API 文档:http://127.0.0.1:<port>/docs。

日志:启动时按 settings.yaml 的 logging 段装配(控制台 + 轮转文件,默认 ~/.ssh-agent-harness/ssh-agent.log,format: json 每行一条;~ 自动展开)。

前端 dev / 构建

前端控制台源码位于 web/(React 18 + TypeScript + Vite 5 + Ant Design 5 + react-query 5):

# dev 双进程:只起本后端(纯 API),前端 dev server 另行启动并把 /api 反代到后端
ssh-agent-web --port 8000
npm run dev --prefix web        # vite dev server(5173),/api 反代到 127.0.0.1:8000

# build 单进程:前端产出 dist,后端同一进程托管 SPA 与 /api
npm run build --prefix web      # 产出 web/dist(不入库)
ssh-agent-web --port 8000 --static web/dist

后端未开 CORS,dev 模式请走 vite 的 /api 反向代理,勿让前端跨源直连。

配置

  • config/settings.yaml:主设置(LLM provider、SSH、safety、storage/SQLite 路径)。
  • 服务器清单存 SQLite hosts 表(经 Web 控制台「服务器管理」页增删改;DB 密码明文=已知接受风险,API 永不回显 password)。
  • LLM provider 生效优先级:UI 控制台配置 > env LLM_* > settings.yaml。
    • UI:「模型配置」可切 Ollama / DeepSeek API / 自定义端点,选择存 SQLite(密钥明文为已知风险、响应永不回显)。
    • env:LLM_PROVIDER / LLM_MODEL / LLM_BASE_URL / LLM_API_KEY(或 DEEPSEEK_API_KEY)。
    • LLM_TIMEOUT(env)可覆盖读超时(默认 600s)。
    • 注意 config.py 以 YAML init 注入 Settings,OLLAMA__* 风格 env 覆盖不生效,请用 LLM_*。
  • Safety:rm -rf 类黑名单为硬 DENY(审批不可越过);systemctl stop 等触发确认门;kill/pkill 默认直接放行。

Web 功能

  • 提交任务:智能模式(默认)/ 快速模式,可设 dry-run、修复轮数(rounds)、步进循环。
  • 审批弹窗:危险命令挂起,弹窗内批准/拒绝;超时自动拒绝。
  • 服务器管理:YAML ∪ DB 合并视图,CRUD + 连通性测试。
  • 服务器工作空间(知识库):按服务器维护规范与事实,供探测轮注入。
  • 任务记录:执行记录(sessions)与审计轨迹、run 详情时间线、按 run 撤销工作空间事实。

run 状态机

queued → generating → [awaiting_approval ⇄ running] → succeeded | failed | denied | cancelled (dry-run 不经审批;cancel 优先于并发完成;重启时未终结的 run 在启动清理中置 failed)

多轮修复(rounds)

POST /api/runs 请求体 rounds(1-10,缺省 1)大于 1 时启用反馈回路:每轮执行完毕, 把命令及其 stdout/stderr 组成观察回灌给模型,模型判定任务是否完成——输出 TASK_COMPLETE 是确认成功的唯一通道;未完成则给出修正命令,下一轮继续执行;轮尽仍未确认 → 终态 failed (verdict=exhausted)。dry-run 同样适用。verdict 词表 complete|exhausted|no-progress|repair-failed,null = 终态未落判定。

安全边界

  • 默认仅监听 127.0.0.1,且无任何鉴权:能访问该端口即可完整操作服务器,勿暴露到公网。
  • 明文密码为已知风险:DB 服务器的密码明文存于 SQLite,且 PUT /api/hosts 请求体明文传输(仅回环缓解)。
  • cancel 不打断在飞命令:只阻止后续命令执行并落终态 cancelled,已发出的 SSH 命令会跑完。
  • 安全黑名单硬 DENY:rm -rf /、mkfs、dd of=/dev/* 等被 gate 直接拒绝,审批无法越过。
  • 审批超时即 denied:等待 --approval-timeout 秒无人决策 → 审批 expired、任务 denied。
  • 同一数据库文件同时只允许运行一个 ssh-agent-web 实例:启动清理会把库内全部非终态 run 置 failed;多实例请各自指定独立 --db。
  • dry-run 不落库:只生成不执行,也不写 session 历史。
  • 服务器/审批响应一律脱敏:不回显密码与私钥内容。

API 速览

方法与路径 说明
GET /api/version 版本号
GET /api/llm 当前生效模型 + provider 目录(presets)+ api_key_set;永不回显密钥
PUT /api/llm {provider, model, api_key?, adapter_type?, base_url?} 切换模型(UI 配置存 SQLite,优先于 env/settings)
DELETE /api/llm 清除 UI 切换,回落 env/settings
GET /api/hosts 服务器清单(读 SQLite hosts 表,脱敏)
POST /api/hosts 新建 DB 服务器(同名 shadow YAML 服务器,DB 字段优先)
PUT /api/hosts/{name} 更新 DB 服务器;YAML 服务器 403
DELETE /api/hosts/{name} 删除 DB 服务器行;YAML 服务器 403
POST /api/hosts/{name}/test 连通性探测,返回 {reachable, latency_ms, error}
GET /api/sessions?host=&status=&limit=&offset= 执行历史,新→旧
GET /api/sessions/{id} 会话详情 + 按时间正序的审计轨迹
DELETE /api/sessions/{id} 删除会话及其审计
POST /api/runs {task, host, dry_run?, rounds?, step?} 提交后台任务 → 202
GET /api/runs?limit=&offset= run 列表(新→旧,全状态)
GET /api/runs/{id} 轮询:status / current_step / commands / results
POST /api/runs/{id}/cancel 取消活跃 run;终态或未知 → 409
GET /api/approvals?run_id=&status=pending 待审批收件箱(仅支持 pending)
POST /api/approvals/{id}/decide {decision: approve|deny} 首次决策生效并唤醒任务;重复 decide 409
GET/PUT/DELETE /api/knowledge/... 服务器工作空间(规范与事实)读写与撤销

测试与门禁

# 后端单测(无需 Ollama/SSH)
conda run -n python312 --no-capture-output python -m pytest -m "not integration" -q

# 类型检查(strict)
mypy ssh_agent_harness

# 前端门禁
npm run typecheck --prefix web
npm run build --prefix web

提交门槛 = 上述四项全绿。集成测试(需 Ollama + 数据库中配置的真实服务器): conda run -n python312 --no-capture-output python -m pytest -m integration -v。

目录结构(纯 Web)

ssh_agent_harness/
├── api/            # Web 后端 FastAPI 包(app/run_manager/routes/schemas/deps/__main__)
├── core/           # orchestrator/step_loop/multi_turn/llm 工厂/host_loader/run_persistence/...
├── tools/          # ssh_pool(asyncssh)/paramiko fallback/command_executor
├── harness/        # safety + confirmation(含 Web 挂起审批) + evaluator/rollback/protocol
├── storage/        # session_store(SQLite) + run_store(runs/approvals) + host_store
└── config.py       # pydantic-settings Settings
web/                # React18+TS+Vite+AntD5 控制台(dist 不入库;打包前由 scripts/build_frontend.py 拷入包内 static/)
tests/              # 最小 Web 测试集(api smoke / web entry / config)
docs/superpowers/   # 黄金路径手册等
config/             # settings.yaml(服务器在 DB,经 Web 服务器管理页维护)

License

MIT

Metadata

Release files for ssh-agent-harness 0.1.0rc1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ssh-agent-harness 0.1.0rc1
File Size Uploaded Provenance
ssh_agent_harness-0.1.0rc1.tar.gz 727.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for ssh-agent-harness 0.1.0rc1
File Interpreter ABI Platform
ssh_agent_harness-0.1.0rc1-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / ssh_agent_harness-0.1.0rc1.tar.gz

Download URL ssh_agent_harness-0.1.0rc1.tar.gz
Size 727.6 kB
Tags Source
SHA-256 checksum
How to use checksums
fd1f70d2cc56ac80f072d4ed3e88a9cbd8ced72051c9e7ecfff59d3e606ddf6d
BLAKE2b-256 checksum
How to use checksums
662c4d04cbd0205f0f4556a117e7b25f128e0fb98f9ca74335b889fda11b0c0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / ssh_agent_harness-0.1.0rc1-py3-none-any.whl

Download URL ssh_agent_harness-0.1.0rc1-py3-none-any.whl
Size 692.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d2c609333515b43d4e2903b53c74c829bfc0c7cc6480d15bb282ae15d98c7173
BLAKE2b-256 checksum
How to use checksums
15578fb1a985e510ea4afda0fbe2e2724d11612cbc9b788001ce2aebe0f78378
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Security for ssh-agent-harness 0.1.0rc1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page