Skip to content

Soul

The agent on a managed host — a single static Go binary with no runtime dependencies. It applies Destiny through core modules and works in two modes with the same set of modules.

  • pull (daemon). The agent runs as a systemd service, initiates a long-lived gRPC stream to Keeper over mTLS itself, and applies the tasks Keeper delivers over that stream. No inbound ports need to be opened on the host.
  • push (one-shot over SSH). No permanent daemon: Keeper delivers the binary and modules to the host over SSH and triggers a one-time apply. Modules are cached on the host by SHA-256.

The same binary and the same set of modules work in both modes — applying a task does not depend on whether it is a daemon or a one-shot.

  • The agent’s SID (Soul ID) equals the host’s FQDN. The SID must resolve and be a valid lower-case FQDN.
  • Onboarding goes through a CSR: on soul init the agent generates a private key and a CSR — the private key never leaves the host. In exchange for a one-time bootstrap token, Keeper signs and returns the agent’s mTLS identity, which is laid out into the state directory.
  • On the bidi stream (EventStream) the authority on identity is the client mTLS certificate; the SID in messages is used as an echo for logs.

The agent collects the Soulprint — a typed set of facts about the system (OS family, distribution and version, architecture, package manager and init system, kernel, CPU, memory, network). These facts are:

  • available in scenarios for targeting and templating (for example, picking the package manager by OS family);
  • read directly by core modules (core.pkg.* / core.service.* rely on the collected pkg_mgr / init_system).

Configuration is applied by core modules — steps of the form core.<module>.<state> statically built into the binary (for example core.pkg.installed, core.file.present). The catalog of built-in modules is in Modules. Custom modules plug in as separate plugins (a subprocess over gRPC-over-stdio) and are cached on the host by SHA-256.

CommandWhat it does
soul initonboarding: generates a key + CSR, exchanges the bootstrap token for an mTLS identity
soul runstarts the daemon: holds the EventStream to Keeper and applies tasks (pull mode)
soul versionthe binary version

The bootstrap token for soul init is passed via the SOUL_BOOTSTRAP_TOKEN environment variable (preferred — it does not show up in ps/history) or from stdin.

The agent is a single static binary: the host needs no interpreters, runtimes, or third-party dependencies (unlike agentless tools that require a Python/SSH harness). All it needs is network access to Keeper (outbound, to the bootstrap and EventStream ports) and the privileges to apply Destiny.

The agent is installed from the soul-stack-soul package, a binary release, or a source build. Onboarding (registering the host, issuing the token, soul init, starting the daemon) is in Install from packages → Agent onboarding.