|
|
||
|---|---|---|
| .forgejo/workflows | ||
| .venv | ||
| config | ||
| storm_pulse_agent.egg-info | ||
| stormpulse | ||
| tests | ||
| .gitignore | ||
| pyproject.toml | ||
| README.md | ||
Storm Pulse Agent
Secure server management agent for Storm Developments. Connects outbound to a Django dashboard over WebSocket with mTLS, pushes system metrics, and executes whitelisted deploy commands. Zero listening ports.
How It Works
- Agent connects outbound to the dashboard. Nginx terminates mTLS.
- Sends a
registermessage (including its available commands list), then pushes metrics every 15s (CPU, memory, disk, load, containers). - Dashboard sends HMAC-signed commands. Agent verifies signature, nonce, and expiry before executing.
- Commands run via
subprocess.run(shell=False)against a strict whitelist. Custom commands can be added via config with optional overridable parameters (regex-validated). No shell injection possible.
Read the Protocol Specification for exact information.
Security
Five layers, each independent:
- Network -- No inbound ports. Agent initiates all connections.
- Transport -- mTLS with per-agent certs from a private CA.
- Application -- HMAC-SHA256 + nonce + expiry on every command.
- Execution -- Whitelisted commands only. Absolute paths.
shell=False. Config placeholders from local config only; runtime params are regex-validated. - OS -- Dedicated user. Systemd sandboxing.
See the Security Architecture wiki page for the full design.
Setup
Requires Python 3.12+. Three runtime deps: websockets, psutil, cryptography.
For full setup instructions (system user, permissions, systemd, firewall), see the Setup Guide.
CLI
stormpulse enroll ENDPOINT AGENT_ID TOKEN [--creds-dir DIR] [--force]
stormpulse init [--creds-dir DIR] [--force]
stormpulse run [CONFIG]
stormpulse status [CONFIG]
stormpulse --version
enroll -- One-time enrollment. Generates an EC P-256 keypair, sends a CSR to the dashboard, writes the signed cert + CA cert + HMAC key to /etc/stormpulse/. The private key never leaves the machine.
init -- Interactive setup wizard. Generates config, creates systemd service, sets permissions. Run after enrollment.
run -- Starts the agent. Connects to the dashboard, sends heartbeats and metrics, executes commands. Reconnects automatically with exponential backoff.
status -- Local inspection. Shows version, agent ID, config path, dashboard URL, certificate expiry, nonce DB entry count, and whether the agent process is running. No network required.
Configuration
See config/stormpulse.example.toml for all options. Key settings:
| Section | Field | Description |
|---|---|---|
agent |
id |
Unique identifier for this server |
agent |
pulse_token |
UUID from the Server record in the dashboard |
agent |
disabled_commands |
List of command names to remove from the registry (optional) |
dashboard |
url |
WebSocket URL (wss://...) |
project |
project_dir |
Absolute path to the deployed project |
project |
compose_file |
Absolute path to docker-compose.yml |
project |
env_file |
Absolute path to .env file (optional, passed as --env-file to docker compose) |
commands.* |
Custom commands (optional, see example config) |
Documentation
- Setup Guide -- Full install, enrollment, systemd, permissions
- Customize Commands -- How to disable existing commands, or whitelist new commands
- Protocol Specification -- Message formats, envelope structure, versioning
- Security Architecture -- Threat model, five security layers
Develop
git clone <repo-url> && cd storm-pulse
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest # 395 tests
mypy . # strict
License
MIT