95 lines
3.7 KiB
Markdown
95 lines
3.7 KiB
Markdown
# VPS Control contributor guide
|
|
|
|
## Purpose and architecture
|
|
|
|
VPS Control monitors and performs a deliberately small set of administrative
|
|
actions on systemd-based Linux VPS hosts. `agent/` is a Rust daemon installed on
|
|
each VPS. `control-plane/backend/` is the Go API and polling service,
|
|
`control-plane/frontend/` is the React UI, and PostgreSQL is the only durable
|
|
metrics/audit store. Browsers never contact agents directly.
|
|
|
|
## Security invariants
|
|
|
|
- DO NOT add arbitrary command execution.
|
|
- DO NOT expose the agent publicly by default.
|
|
- DO NOT disable authentication for convenience.
|
|
- DO NOT store plaintext credentials in source control or the database.
|
|
- DO NOT allow arbitrary systemd service names.
|
|
- DO NOT mutate unmanaged firewall rules.
|
|
- DO NOT write unbounded logs, local state, or queues.
|
|
- DO NOT add heavyweight Agent dependencies without a measured justification.
|
|
- Never pass user input to `sh -c`, `bash -c`, `eval`, or equivalent APIs.
|
|
- Agent subprocess arguments are separate argv values and must be validated.
|
|
- Sensitive values must be redacted from logs and audit records.
|
|
|
|
Any privileged operation requires:
|
|
|
|
1. input validation;
|
|
2. allow-listing;
|
|
3. an audit event;
|
|
4. a bounded timeout;
|
|
5. explicit error handling.
|
|
|
|
The v1 agent is unprivileged. Read-only commands are permitted by the systemd
|
|
sandbox. Fail2Ban and systemd writes require narrowly scoped sudoers/polkit rules
|
|
installed by an administrator; firewall mutation is intentionally disabled until
|
|
the separately reviewed helper/rollback subsystem is enabled.
|
|
|
|
## Repository layout
|
|
|
|
- `agent/`: Rust daemon, unit tests, systemd packaging.
|
|
- `control-plane/backend/`: Go API, auth/RBAC, polling, audit, migrations.
|
|
- `control-plane/frontend/`: React/Vite UI.
|
|
- `docs/`: architecture, security, deployment, development.
|
|
- `scripts/`: lifecycle script for the agent.
|
|
- `examples/`: safe configuration examples.
|
|
|
|
Keep module ownership narrow. JSON API fields use `snake_case`; URLs are under
|
|
`/v1` on the agent and `/api/v1` on the control plane. Errors are JSON objects
|
|
with an `error` string and an optional stable `code`.
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
# Agent
|
|
cargo fmt --manifest-path agent/Cargo.toml --check
|
|
cargo clippy --manifest-path agent/Cargo.toml --all-targets -- -D warnings
|
|
cargo test --manifest-path agent/Cargo.toml
|
|
cargo build --manifest-path agent/Cargo.toml --release
|
|
|
|
# Control-plane backend
|
|
cd control-plane/backend && gofmt -w . && go vet ./... && go test ./...
|
|
|
|
# Frontend
|
|
cd control-plane/frontend && npm ci && npm run lint && npm run typecheck
|
|
npm test -- --run && npm run build
|
|
|
|
# Deployment
|
|
docker compose -f control-plane/docker-compose.yml config
|
|
docker compose -f control-plane/docker-compose.yml build
|
|
```
|
|
|
|
Ordinary tests must not require root, nftables, Fail2Ban, WireGuard, or a live
|
|
PostgreSQL instance. Put host-dependent tests behind explicit integration tags.
|
|
|
|
## Resource and coding rules
|
|
|
|
The agent targets <=30 MiB idle RSS, a 64 MiB systemd limit, near-zero idle CPU,
|
|
and negligible disk writes. Prefer `/proc` and `/sys`, collect expensive data
|
|
on demand, bound request bodies/concurrency/timeouts, and do not cache history on
|
|
the VPS. Production logging is `info` to journald and successful polls are not
|
|
logged.
|
|
|
|
Rust must be formatted, clippy-clean, avoid `unsafe` unless documented, and keep
|
|
blocking OS work out of async executor threads. Go handlers must enforce auth and
|
|
RBAC before reading request bodies for mutations. React code must be typed and
|
|
must not bypass the backend.
|
|
|
|
## Release process
|
|
|
|
CI lints, tests, builds both Linux agent targets, emits
|
|
`vps-agent-linux-{amd64,arm64}` plus `SHA256SUMS`, validates Compose, and builds
|
|
containers. Release publication is a manual approval step. Update the changelog,
|
|
version, checksums/signature, compatibility notes, and rollback instructions.
|
|
|