| title | subtitle | brand |
|---|---|---|
Dispatcher |
Perl machine-to-machine remote script execution over mTLS |
odcc |
A Perl machine-to-machine remote script execution system. The dispatcher host runs scripts on remote agent hosts via HTTPS with mutual certificate authentication. No SSH involved; agents expose only an explicit allowlist of permitted scripts.
Designed for infrastructure automation pipelines where a control host needs to trigger operations on a fleet of managed hosts with strong identity guarantees and a minimal attack surface.
dispatcher (control host) : CLI tool and optional HTTP API. Connects to agents, sends signed requests, collects results. Manages the private CA, agent registry, and cert lifecycle. The API server exposes run, ping, discovery, and status endpoints with an OpenAPI spec (static and live-generated).
dispatcher-agent (remote hosts) : mTLS HTTPS server on port 7443. Executes only scripts named in a per-host allowlist. No shell - arguments are passed directly to the OS. Reloads config on SIGHUP without dropping connections.
pairing : One-time certificate exchange. The agent generates a key and CSR, connects to the dispatcher on port 7444, and waits for operator approval. The dispatcher signs the CSR with its private CA and returns the cert. After pairing, all traffic uses mTLS on port 7443.
auth hook
: An optional executable called before every run and ping. Receives full
request context including token, username, script, args, and source IP.
Tokens are forwarded through the pipeline so downstream components can
independently verify authority. The hook is the policy engine - dispatcher
has no built-in ACLs.
automatic cert renewal : Certs are renewed automatically over the live mTLS connection when remaining validity drops below half the configured lifetime. No operator involvement during normal operation.
dispatcher-plugins : A companion repository providing ready-built plugins across three categories: management interfaces for the HTTP API and CLI, agent scripts covering common infrastructure tasks, and auth hooks integrating dispatcher with external identity systems. Each plugin is self-contained.
INSTALL.md
: Platform requirements, installer flags, initial setup, all configuration
options, operational reference, troubleshooting.
API.md
: HTTP API reference. All endpoints, request and response schemas, error
codes, OpenAPI spec endpoints, and the run result status store.
DOCKER.md
: Deploying dispatcher and agents in Alpine Docker containers, including
entrypoint patterns, volume mounts, and the pairing workflow in Docker.
SECURITY.md
: Security model, trust boundaries, file permissions, and operational
security guidance.
DEVELOPER.md
: Module reference, wire format, protocol details, and how to extend the
system.
Full detail is in INSTALL.md. The sequence below gets dispatcher running
between two hosts in about ten minutes.
Install and initialise the CA and dispatcher identity:
sudo ./install.sh --dispatcher
sudo dispatcher setup-ca
sudo dispatcher setup-dispatcher
sudo usermod -aG dispatcher $USER
# Log out and back in for group membership to take effectConfigure the auth hook. The dispatcher requires an auth hook to authorise
run and ping requests. For an isolated network the simplest policy is
allow-all - replace with real logic when deploying to production:
sudo cp /usr/local/lib/dispatcher/auth-hook.example /etc/dispatcher/auth-hook
sudo chmod 755 /etc/dispatcher/auth-hookEdit /etc/dispatcher/auth-hook and uncomment exit 0 near the end of the
file (the "Allow everything" example). The last executable line must be
exit 0.
If you prefer not to use a hook, remove or comment out the auth_hook line
in /etc/dispatcher/dispatcher.conf and set:
api_auth_default = allowInstall the agent:
sudo ./install.sh --agentEdit /etc/dispatcher-agent/scripts.conf to add the scripts the agent is
permitted to run. logger is available on every platform and requires no
additional setup:
logger = /usr/bin/loggerStart the agent:
sudo systemctl enable dispatcher-agent
sudo systemctl start dispatcher-agentVerify the agent configuration is valid before pairing:
sudo dispatcher-agent ping-selfOn the dispatcher host, start pairing mode:
sudo dispatcher pairing-modeOn the agent host, request pairing:
sudo dispatcher-agent request-pairing --dispatcher <dispatcher-hostname>A pairing code is displayed on both hosts. Confirm they match, then type a
in the pairing mode terminal to approve. The agent receives its signed cert
and is ready.
dispatcher ping <agent-hostname>
dispatcher run <agent-hostname> --script logger -- -t test "hello from dispatcher"The API server exposes dispatcher over HTTP on localhost:7445. Install and
start it on the dispatcher host:
sudo ./install.sh --api
sudo systemctl enable dispatcher-api
sudo systemctl start dispatcher-api
curl -s http://localhost:7445/healthThe API uses the same auth hook as the CLI. Ensure the hook is configured before starting the API - the hook is read at startup and a stale process will not pick up config changes without a restart.
Debian / Ubuntu
: apt packages, systemd service management.
Alpine Linux
: apk packages, no systemd. Run binaries directly or use Docker - see
DOCKER.md.
All dependencies are system packages on both platforms. No CPAN required.
Released under the GNU Affero General Public License v3.0 (AGPL-3.0-only).
See LICENCE for the full text.
The AGPL extends the GPL copyleft requirement to cover network use: if you run a modified version of dispatcher as a service, you must make the modified source available to users of that service.