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

70 lines
3.3 KiB
Markdown

# 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