# 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