DAEMON MANAGEMENT
Warning
Daemon management is EXPERIMENTAL. The subcommands, service file format, and behavior may change in future releases.
swamp serve daemon manages swamp serve as a platform-native system daemon.
On macOS it registers a launchd LaunchAgent; on Linux it creates a systemd user
service.
Subcommands
enable
swamp serve daemon enableGenerates and registers a platform-native service definition with all serve flags baked in. The daemon starts immediately and will restart automatically on failure. Whether it starts on reboot depends on the service type — see Platform Details below.
✓ Daemon enabled — swamp serve will start automaticallyDaemon-specific flags
| Flag | Description |
|---|---|
--user |
Install as a per-user service (systemd --user / launchd agent). Without this flag on Linux, the unit is installed system-wide under /etc/systemd/system/. On macOS the service is always a LaunchAgent (per-user); --user is accepted but has no additional effect. |
Forwarded serve flags
All swamp serve flags are forwarded to the service definition:
| Flag | Default | Description |
|---|---|---|
--config <path> |
Path to a YAML config file (default: .swamp/serve.yaml). See Serve Flags — Config file |
|
--port <port> |
9090 |
Port for the daemon to listen on |
--host <host> |
127.0.0.1 |
Host for the daemon to bind to |
--cert-file <path> |
Path to PEM-encoded TLS certificate | |
--key-file <path> |
Path to PEM-encoded TLS private key | |
--auth-mode <mode> |
none |
Authentication mode: none (deprecated), token, or oauth |
--admins <principals> |
Comma-separated principal IDs for admin access | |
--club-api-key-file <path> |
File holding the collective API key. The service definition stores the absolute path, never the key. A daemon does not inherit the enabling shell's environment, so this is how a daemon reads its key from a file | |
--grant-reload <mode> |
manual |
Policy snapshot reload: manual or auto |
--remote-only |
(off) | Disable local (loopback) execution — all steps must declare placement (env: SWAMP_REMOTE_ONLY) |
--no-schedule |
Disable scheduled workflow execution | |
--webhook <spec> |
Register a webhook endpoint (repeatable) | |
--allowed-collectives |
Comma-separated collective slugs for OAuth admission | |
--allowed-users |
Comma-separated user identifiers for OAuth admission | |
--oauth-provider <url> |
OAuth authorization server URL | |
--oauth-client-id <id> |
OAuth client ID (env: SWAMP_OAUTH_CLIENT_ID). When set, serve never registers a client and needs the client's secret from --oauth-client-secret-file, SWAMP_OAUTH_CLIENT_SECRET_FILE, SWAMP_OAUTH_CLIENT_SECRET or a usable stored copy, or it refuses to start. When omitted, a client is registered on first start |
|
--oauth-client-secret-file <path> |
Path to a file holding the secret of the client named by --oauth-client-id. Used for this run only and never stored. Overrides SWAMP_OAUTH_CLIENT_SECRET_FILE and SWAMP_OAUTH_CLIENT_SECRET. Refused without a client ID. Requires Swamp v20261103.225037.0-sha.5911dc9c or later |
|
--keep-oauth-client-in-vault |
(off) | Leave oauth-client-id and oauth-client-secret in the user vault when moving OAuth secrets into the control-plane store (env: SWAMP_KEEP_OAUTH_CLIENT_IN_VAULT). Off by default: anything that can read that vault can read the client secret. Requires Swamp v20261103.225037.0-sha.5911dc9c or later |
--oauth-client-name <name> |
Override the OAuth client_name used during dynamic client registration. Default: swamp-serve-{repoName}-{hostname} (env: SWAMP_OAUTH_CLIENT_NAME) |
|
--groups-field <field> |
Userinfo field the collectives are read from (default: collectives) |
|
--trust-proxy |
Trust a reverse proxy's forwarding headers: the client IP, used for rate limiting, is read from the leftmost X-Forwarded-For entry instead of the connection's address, and dashboard sign-in takes the public scheme and host from X-Forwarded-Proto and X-Forwarded-Host |
|
--verify-on-enroll |
Run a fleet probe on each enrolling worker before it becomes schedulable | |
--restricted-model-types <types> |
Comma-separated behavior types whose behaviors require admin on access:* to create, run, edit, delete, delete or rename data of, or reference from a changed workflow step. A leading @ is ignored when matching. See Restricted behavior types |
|
--restricted-commands <cmds> |
Comma-separated server commands that require admin authority (e.g. datastore.namespace.list,extension.install) |
|
--trusted-hosts <hosts> |
Comma-separated hostnames or host:port entries to trust for Host header and browser Origin validation; a public address on a port other than 443 is given as host:port (env: SWAMP_TRUSTED_HOSTS) |
|
--group-refresh-interval <duration> |
4h |
How often to re-fetch IdP group memberships for active server tokens. Accepts seconds (14400), explicit units (4h, 30m), or 0 to disable. Requires --auth-mode oauth (env: SWAMP_GROUP_REFRESH_INTERVAL) |
--approve-requires-explicit-grant |
Require a grant that names approve to decide a manual approval gate. Requires --auth-mode token or oauth (env: SWAMP_APPROVE_REQUIRES_EXPLICIT_GRANT) |
|
--auto-resume |
(off) | Resume a suspended run once an approval made through serve decides its last gate (env: SWAMP_AUTO_RESUME) |
--dashboard |
(off) | Enable the web dashboard at /dashboard (env: SWAMP_DASHBOARD) |
--repo-dir <dir> |
Repository directory (env: SWAMP_REPO_DIR) |
swamp serve daemon enable does not carry SWAMP_OAUTH_CLIENT_ID into the
service definition. Pass --oauth-client-id instead.
Example with a custom port and TLS:
swamp serve daemon enable --port 8080 --cert-file cert.pem --key-file key.pem --auth-mode tokendisable
swamp serve daemon disableUnloads the running daemon and removes the service definition.
✓ Daemon disabled — service definition removedstatus
swamp serve daemon statusReports the daemon's enabled/running state, PID, and log path:
Status: running
Enabled: yes
PID: 65055
Logs: ~/Library/Logs/swampWhen no daemon is configured:
Status: not configured
Run swamp serve daemon enable to set up the daemonPlatform Details
macOS (launchd)
enable writes a LaunchAgent plist under ~/Library/LaunchAgents/. The plist
uses KeepAlive to restart the process on exit and ThrottleInterval set to 10
seconds to prevent rapid restart loops. LaunchAgents are per-user services —
they run only while the user is logged in and start again on the next login, not
on reboot itself.
Linux (systemd)
Without --user, enable writes a system-wide unit under
/etc/systemd/system/. System services start on boot and run independently of
any user session.
With --user, enable writes a user service unit under
~/.config/systemd/user/. User services run only while the user has an active
login session. To make a user service start on boot without logging in, enable
lingering: loginctl enable-linger $USER.
Both use Restart=always with RestartSec=10.
Swamp data and config directories
Swamp loads every extension — including extensions already pulled into the
repository — through an embedded runtime under the Swamp data directory:
SWAMP_HOME when set, otherwise ~/.swamp resolved from HOME (or
USERPROFILE).
Every Swamp process needs a swamp-club.com credential to start — see
Swamp Account Requirement. The
daemon reads the credential that swamp auth login stores in auth.json, and
the cached proof in auth_verified.json, from the Swamp config directory,
resolved in this order:
| Priority | Directory |
|---|---|
| 1 | $SWAMP_CONFIG_DIR |
| 2 | $SWAMP_HOME/config |
| 3 | $XDG_CONFIG_HOME/swamp |
| 4 | ~/.config/swamp |
enable sets both SWAMP_HOME and SWAMP_CONFIG_DIR in the generated service
definition — Environment= lines in the systemd unit, EnvironmentVariables
entries in the launchd plist. Each is the absolute path of that directory as
resolved in the environment of the user who ran enable, so the daemon reads
the same credentials that user is signed in with. Sign in as that user before
running enable.
A daemon that does not own the config directory, such as a system service running as root, reads the credential and proof but never writes to the directory. A running serve renews its proof once it is over 7 days old and holds the renewed proof in memory. The proof on disk is kept fresh by the signed-in user's own Swamp runs; if that user runs nothing for 14 days, it expires and the daemon must reach swamp-club.com when it next starts.
swamp worker daemon enable sets SWAMP_CONFIG_DIR the same way. A worker
daemon enabled by a version without the account requirement lacks it. When it
finds no credential at all, it passes through its serve as a
remote worker;
re-run swamp worker daemon enable as the signed-in user to give it the user's
credential. Serve daemons already set SWAMP_CONFIG_DIR and need no change.
A running daemon is checked when it starts, not on every request.
A service definition written by hand must set SWAMP_HOME or HOME. When none
of SWAMP_HOME, HOME, or USERPROFILE is set, extension loading is disabled
and Swamp logs a warning beginning
Extension loading is unavailable: no swamp data directory found (none of SWAMP_HOME, HOME, or USERPROFILE is set).
Scheduled workflows that use pulled or user extension types then fail with
Unknown model type.
Warning
Setting SWAMP_HOME without SWAMP_CONFIG_DIR moves the config directory to
$SWAMP_HOME/config. The daemon then cannot find the auth.json that
swamp auth login wrote, fails to start in any --auth-mode, and is
restarted every 10 seconds. A hand-written service definition that sets
SWAMP_HOME must also set SWAMP_CONFIG_DIR to the directory holding those
credentials (~/.config/swamp by default):
Environment=SWAMP_HOME=/opt/swamp
Environment=SWAMP_CONFIG_DIR=/home/alice/.config/swampVersions from 20260921.211448.0 up to, but not including, 20260930.184839.0
set only SWAMP_HOME, so a token or oauth daemon they installed cannot start.
Re-run swamp serve daemon enable to rewrite the service definition.
File Permissions
Service definition files are written with 0600 permissions. This is because
the service definition may contain webhook secrets or other sensitive flags
passed to swamp serve. To avoid embedding literal secrets in the service
definition, use the @env=, @file=, or @vault= indirection prefixes — see
Serve Flags: Secret indirection.