Files
clawbot e96d27f35c
build / build-windows-x86_64 (push) Has been cancelled
build / build-linux-x86_64 (push) Failing after 1m13s
build / build-linux-aarch64 (push) Failing after 1m8s
deploy-agent: Rust deployment automation (server + stub + signed payloads)
- Workspace: common (protocol/crypto/tarball), server (axum+rustls), stub (registration, poll, verify-before-execute)
- Ed25519 payload signing + request-signature auth on /poll, /report
- flate2/miniz_oxide pure-Rust tarball, no system deps
- CI matrix: linux musl x86_64/aarch64, windows x86_64
- Compiles clean: cargo build --workspace, 0 errors 0 warnings
2026-07-30 23:57:25 -07:00

3.3 KiB

Deploy-Agent — Build Spec

A deployment automation system: a lightweight stub agent that runs on target machines, polls a control server over HTTPS:443, downloads signed payloads, verifies signatures, and executes them. Rust everywhere.

Project root

/home/node/.openclaw/workspace/tools/deploy-agent/

Layout:

tools/deploy-agent/
├── Cargo.toml            # workspace: members = ["server", "stub", "common"]
├── common/               # shared crate: protocol types, crypto, payload format
├── server/               # control server
├── stub/                 # target-machine agent
├── payloads/             # sample payload tarballs + signing scripts
├── README.md             # architecture, threat model, build, deploy
└── justfile or Makefile  # build targets

Targets

  • Linux x86_64 (primary) — musl static, rustls
  • Linux aarch64 — musl static, rustls
  • Windows x86_64 — Win 10/11, rustls (NOTE: modern Rust 1.94 has NO win7 targets; protocol must stay OS-agnostic so a legacy win7 build can be added later without server changes)

Stub behavior (stub/)

  • Register once on first run: generate Ed25519 identity keypair, send public key + machine ID → server issues per-machine client cert (or server stores pubkey for challenge). Same ID reused on subsequent runs.
  • Poll POST /poll with machine id + auth. Server returns instruction or "no-op".
  • Instruction types (whitelist, NOT raw shell):
    • fetch-payload: download tarball from server, verify Ed25519 signature, extract
    • run-payload: execute the verified payload (a bundled script/binary per-platform)
    • report-status: return result + logs to server
  • TLS: rustls (Linux/Windows). No OpenSSL for Linux (stays static). Windows 10/11 uses rustls too.
  • Compression: flate2 with miniz_oxide backend (pure Rust, zero system deps).

Server behavior (server/)

  • axum + rustls + rustls-acme (Let's Encrypt auto-provision on :443)
  • mTLS client cert auth for stubs
  • Per-machine instruction store (JSON file or SQLite) — which machine has which payload revision
  • Endpoints:
    • POST /register — initial machine registration
    • POST /poll — authenticated stub polls for instructions
    • GET /payload/{id} — served over mTLS, stub downloads tarball
    • Admin UI or CLI to push instructions to a machine
  • Signature key: server holds Ed25519 signing key; publishes public key for payload verification

Security model (must document in README)

  1. mTLS machine auth (client certs issued at registration)
  2. Payloads signed with Ed25519 — stub verifies before ANY execution
  3. Whitelisted instruction set, NOT arbitrary remote shell
  4. All traffic over TLS 1.3 (rustls)
  5. Defense-in-depth: even a compromised server can't push unsigned payloads

Deliverables

  1. Rust workspace that compiles
  2. Stub binary for each target (Linux musl static confirmed)
  3. Server binary + Let's Encrypt provisioning
  4. Payload signing helper script
  5. README with threat model + build/run instructions
  6. .gitea/workflows/ CI to build the target matrix

Constraints

  • No system lib dependencies for Linux (musl static)
  • flate2/miniz_oxide for compression (pure Rust)
  • rustls for TLS everywhere possible
  • Ed25519 (via ed25519-dalek or ring) for signing
  • Keep protocol/format identical across all OS targets
  • This is security-sensitive: verify-before-execute is non-negotiable