Skip to main content

Secure server management agent for Storm Developments infrastructure

Project description

Storm Pulse Agent

CI License: MIT Typed: mypy strict

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

  1. Agent connects outbound to the dashboard. Nginx terminates mTLS.
  2. Sends a register message (including its available commands list), then pushes metrics every 15s (CPU, memory, disk, load, containers).
  3. Dashboard sends HMAC-signed commands. Agent verifies signature, nonce, and expiry before executing.
  4. 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.

Install from PyPI:

pip install storm-pulse-agent

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 garage init [--config PATH] [--garage-config PATH] [--force]
stormpulse logging init [--config PATH]
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. Auto-detects Garage installations and running Docker containers and offers to enable integration / log shipping.

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.

garage init -- Detects a Garage S3 node and appends a [garage] section to an existing stormpulse.toml. Auto-detects container name from docker-compose.yml. Use --force to overwrite an existing [garage] section.

logging init -- Detects running Docker containers and appends [[log_groups]] blocks for each, using source_type = "docker" and the docker_raw parser. Skips containers already present in the config. See Log Shipping for details.

Configuration

Run stormpulse init to generate a config interactively - see the Setup Guide. 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)
garage enabled Enable Garage S3 integration (optional, default: absent)
garage container_name Docker container name for Garage (e.g. garaged)
garage config_path Path to Garage config file
garage state_push_interval_seconds How often to refresh Garage state (default: 30)

Documentation

Develop

git clone https://git.stormdevelopments.ca/official-public/storm-pulse.git && cd storm-pulse
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
mypy .          # strict
make fitness    # architecture + security invariants

License

MIT - see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

storm_pulse_agent-0.1.8.tar.gz (159.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

storm_pulse_agent-0.1.8-py3-none-any.whl (157.0 kB view details)

Uploaded Python 3

File details

Details for the file storm_pulse_agent-0.1.8.tar.gz.

File metadata

  • Download URL: storm_pulse_agent-0.1.8.tar.gz
  • Upload date:
  • Size: 159.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for storm_pulse_agent-0.1.8.tar.gz
Algorithm Hash digest
SHA256 b893bfa498280c661d531fb8c78f7cd9517862feca02935db70eab8cd2cee66f
MD5 f1bd9100b84c0a3d90c888670d7adec9
BLAKE2b-256 d39f18dc5c3ecaef8c56f84091bc45d422199717dc8228c376c0289e565268e7

See more details on using hashes here.

File details

Details for the file storm_pulse_agent-0.1.8-py3-none-any.whl.

File metadata

  • Download URL: storm_pulse_agent-0.1.8-py3-none-any.whl
  • Upload date:
  • Size: 157.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for storm_pulse_agent-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 bae85eafd5a0a11cca801a1a929293944dd084f7e35122058318f34f9694bdfe
MD5 ac84488a0cba5519afbd438081bef3b1
BLAKE2b-256 9a6478889bf44cac765365d9d07a19b580cf16136f9a4e23f4dafb8f61520439

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page