Running the server
The server is one Rust binary, zupflow, serving the API, the hosted Connect page and the background workers, with its data in one SQLite file.
cd servercargo build --release --locked -p zupflow-server./target/release/zupflowA plain build leaves out the development-only crates (the contract fixture server and Taskboard).
Sign-in: local or oidc
Section titled “Sign-in: local or oidc”ZUPFLOW_IDENTITY is required, with no default.
local: one person, one machine
Section titled “local: one person, one machine”No sign-in: every Console request is one built-in owner. Because that trusts anyone who can reach the port, the server refuses to start with it on anything but a loopback address, and answers only requests addressed to localhost, 127.0.0.1 or [::1].
local exists only in builds with the local-identity feature, on by default. Build with --no-default-features for a deployment, so it can’t be turned on.
oidc: a team
Section titled “oidc: a team”The Console signs in through any OpenID Connect provider with the authorization code flow and PKCE, and the server verifies the provider’s ID token.
ZUPFLOW_IDENTITY=oidcZUPFLOW_OIDC_ISSUER=https://auth.example.comZUPFLOW_OIDC_AUDIENCE=<the Console's client ID>ZUPFLOW_SECRET_KEY=$(openssl rand -base64 32)The provider’s client for the Console must be public (no secret), allow the redirect URI {Console origin}/sign-in/callback, and answer its token endpoint cross-origin.
The secret key
Section titled “The secret key”ZUPFLOW_SECRET_KEY (32 bytes, base64) keys what must not be guessable from the database: API keys and idempotency fingerprints are stored as an HMAC under it, and the key that seals credentials is derived from it. With oidc it’s required and lives outside the database.
The Console
Section titled “The Console”The Console is a static build. Build it with the API’s URL and the sign-in provider’s origins, and serve it from any static host:
VITE_ZUPFLOW_API_URL=https://api.example.com \VITE_ZUPFLOW_OIDC_ORIGINS=https://auth.example.com \pnpm --filter @zupflow/console buildSet ZUPFLOW_CONSOLE_ORIGIN on the server to the origin it’s served from. Whatever serves it must also send Content-Security-Policy: frame-ancestors 'none' and X-Frame-Options: DENY.
Health
Section titled “Health”GET /health answers when the process is up, GET /ready when it can serve. Logs are JSON lines; runs and tool calls log their transitions and latencies, never inputs, outputs, arguments or credentials.