Relationships
#1391 serve daemon enable is ungated — it reports success, then the account gate fires inside the detached daemon, which crash-loops invisibly
Opened by magistr · 7/24/2026
Summary
swamp serve daemon enable has no account/scope gate. It writes the launchd/systemd unit, forwards --auth-mode into the unit's argv, and reports success. The gate then fires inside the detached child on every start, so the daemon crash-loops with an authentication error the user never sees on their terminal. The command's own documented example is the failing invocation.
Where (source)
src/cli/commands/serve.ts:486-510—daemonEnableCommand.action(). NorequireAuthenticated, norequireScope; it resolves the service mode, callsscheduler.enable(...), and renders success at :509.src/cli/commands/serve.ts:279-281—collectServeExtraArgsforwards--auth-modeintoextraArgs, which is baked into the unit.src/cli/commands/serve.ts:960-963— the gate, reached only when the daemon process actually runsserve.src/cli/commands/serve.ts:482-485— the documented example:swamp serve daemon enable --cert-file cert.pem --key-file key.pem --auth-mode token
Repro
Not executed here, because running it installs a real launchd/systemd unit on the host. The path is simple to confirm by inspection, and equally simple to confirm live on a throwaway machine:
# with no swamp-club credentials present
swamp serve daemon enable --auth-mode token --port 8080
# -> reports success
# the daemon then fails on every start; visible only in the service log:
# Error: swamp serve is a team feature that requires a free swamp-club.com account.
launchctl print gui/$(id -u)/<service label> # macOS
journalctl -u swamp-serve # linuxCompare running the same configuration in the foreground, which fails immediately and visibly:
swamp serve --auth-mode token --admins user:alice --no-schedule
# -> Error: swamp serve is a team feature that requires a free swamp-club.com account.(That foreground behavior I did verify directly.)
Two amplifiers
- System-mode units run as a different user.
AuthRepositoryresolves its config dir fromSWAMP_HOME/XDG_CONFIG_HOME/HOME(paths.ts:284-300). A system-mode unit running as root reads root's config, not the invoking user's, so a perfectly logged-in operator installs a daemon that cannot see their credentials and fails the gate anyway. SWAMP_API_KEYis not inherited. launchd and systemd units do not inherit the invoking shell's environment, so collective-token operators fail identically unless the key is written into the unit explicitly.
Both mean the gate can fail in the daemon even when it passes interactively, which makes the failure look like a swamp bug rather than a missing account.
Impact
The user gets a success message and a service that never runs. Nothing on the terminal indicates authentication is involved; the diagnosis requires knowing to read the service log. For the system-mode and env-var cases above, the same command succeeds in the foreground and fails as a daemon, which is a genuinely confusing signal.
Expected
- Run the same
requireAuthenticated/requireScopechecks indaemon enable, before writing the unit, using the resolved--auth-mode. Failing at install time is the whole point of an install-time command. - For system mode, warn when the unit will run as a user whose config dir differs from the invoking user's, since the credential will not be visible there.
- If the daemon does start and hit the gate, that failure should be distinguishable in the service log from a crash (it currently exits like any other error).
Environment
- Source
main@10943ef. Gate shipped ina519305(#1934), 2026-07-23; installed stable20260722.210030.0-sha.7ff1e2f0predates it, so this is latent until the next release. - macOS 14 (launchd) and Linux (systemd) both affected by inspection.
Closed
No activity in this phase yet.