SWAMP SERVE
swamp serve turns a Swamp repository into a remote API. This page explains the
architectural decisions behind the server, the security constraints it enforces,
and how admin access is managed.
Architecture
A swamp serve instance is a single process that holds a Swamp repository and
exposes it over a WebSocket API. Clients connect to run model methods, execute
workflows, query data, and manage access. Workers connect to receive dispatched
steps for remote execution.
The server is the single source of truth. It owns the datastore, resolves vault secrets, stores model definitions, and manages the policy snapshot. Clients and workers are stateless — they issue requests and receive responses but hold no durable state.
This is a deliberate centralization. A Swamp repository is a coherent unit: definitions reference each other, workflows chain model outputs, and vault secrets are scoped to the repo. Distributing this state would introduce consistency problems that the current model avoids by not having them.
Hard refusals
swamp serve refuses to start in certain configurations. These are not warnings
— they are hard failures that prevent the server from binding.
Off-loopback without TLS and authentication. If --host is set to anything
other than 127.0.0.1 or ::1, the server requires both --cert-file /
--key-file and --auth-mode other than none. This is not configurable.
The reasoning is straightforward: swamp serve is a control plane. It accepts
arbitrary model method execution, workflow runs, and vault reads. An
unauthenticated, unencrypted control plane on the network is arbitrary remote
execution — anyone who can reach the port can run any command. The hard refusal
prevents this misconfiguration from reaching production.
On loopback, the risk model is different. The server is only reachable from the local machine, where the user already has access to the repository. TLS and authentication add friction without meaningful security benefit in this context.
That said, --auth-mode none is deprecated. The loopback exception made sense
as a convenience for early adoption, but in practice it creates a gap between
local and production setups. Workflows, grants, and token-scoped permissions
behave differently under none than under token or oauth — issues that
surface only at deployment time. Requiring authentication everywhere, including
loopback, closes that gap and makes local development a reliable predictor of
production behavior.
Admin materialization
The --admins flag lists principal IDs that receive full admin access. On every
server start, the server materializes a grant of admin on access:* for each
listed principal. This grant implies all actions on all resources.
Materialization is reconciled on every boot. If a principal is removed from
--admins, its materialized grant is removed on the next start. If a new
principal is added, it receives the grant on the next start. The config is the
source of truth — not the grant store.
This design serves two purposes.
Bootstrap. When a server starts for the first time with --auth-mode token,
someone needs to be able to mint the first token and create the first grants.
The --admins flag provides that bootstrap identity without requiring a
separate setup step.
Recovery. If an admin accidentally revokes their own access or corrupts the
grant store, restarting the server with the correct --admins flag restores
admin access. The config always wins.
Policy snapshot and reload
Grants and group memberships are compiled into a policy snapshot — a precomputed
structure that the server evaluates on every access check. The snapshot is
rebuilt on swamp access reload or automatically on every change when
--grant-reload auto is active.
The default manual reload mode is a safety mechanism. Grant changes are staged
until an admin deliberately applies them. A bad grant — an overly broad allow, a
deny that locks out the admin — does not take effect until reload. This gives
the admin a chance to review and revoke before applying.
The auto mode removes this safety net in exchange for convenience. Teams that
trust their grant-creation workflow and want immediate effect use auto. Teams
that prefer a review step use manual.
Deny-wins evaluation
When both allow and deny grants match a request, deny wins. This is not configurable.
The alternative — most-specific-wins or last-writer-wins — creates reasoning problems at scale. With deny-wins, a compliance team can create a deny grant that blocks access to sensitive resources, and no amount of allow grants from other teams can override it. The deny is a hard boundary.
This makes the system predictable: if you see a deny grant, you know it applies regardless of what else exists. See the authorization reference for the full evaluation model.
Related
- swamp serve how-to guides — practical setup and operations
- Authorization — the grant model reference
- Serve Flags — full flag and environment variable reference
- Remote Execution — how workers connect and execute steps