Skip to content

Configuration reference

In plain terms: Meet Waffle.

config.example.toml in the repository is the configuration contract. This page describes each table in it. A test (configuration reference covers every section of the contract) fails if the contract grows a table this page does not describe, so the two cannot drift apart.

Three rules apply throughout, and none of them have exceptions:

  • Configuration is strict. Unknown or invalid keys are an error. There is no permissive fallback, and adding one would be a defect.
  • Secrets are never values. config.toml holds secret:// references only; real values live in the encrypted store.
  • Profiles are trust boundaries, not personality presets. A profile fixes the system prompt, model, tools, and sandbox together.

Providers are deliberately absent from the example: a fresh install may omit provider, model, and default-model configuration entirely until waffle provider add validates the first connection on the host. Prefer that command over hand-editing — it probes upstream and commits the encrypted credential and the config change as one transaction.

Optional standalone local chat service (socket). Managed deployments normally receive /run/waffle/chat.sock from systemd socket activation instead. Setting this does not change client behaviour: waffle chat stays in direct mode unless --socket or WAFFLE_CHAT_SOCKET selects a socket explicitly.

Every ancestor of the socket path is checked for ownership and mode; the socket itself is 0600.

Waffle Desk (enabled, plus skill-import roots and permitted Git hosts). Disabled by default, and a disabled Desk cannot enable itself. Desk shares the loopback gateway.status_listen address rather than adding a listener.

See Waffle Desk.

Authorises Desk requests proxied by a same-host tailscale serve, using allowlisted Tailscale identity headers. Those requests may address only /desk/ and /api/v1/desk/*. Funnel requests are always rejected, and this never moves the bind address — /status and /healthz stay loopback-only in every configuration.

Durable-memory behaviour, principally write_gate (auto, notify, or review) and the injection budget. Under review, durable writes queue for approval through waffle candidates.

Writes derived from untrusted content are queued regardless of this setting.

Self-development: approval (manual, ci, or auto-patch), verification steps, protected paths, and required_checks. Under ci, every required check must have completed successfully for the exact candidate SHA; missing, pending, or stale checks fail closed.

Every upgrade resolves one commit SHA and builds it in an isolated detached worktree, so the configured checkout is never modified.

The scoped GitHub App backing Git credentials for workspaces: app_id, installation_id, private_key (a secret:// reference), and base_url for GitHub Enterprise. Register it with the narrowest permissions the tools you use require.

The host-side broker the sandbox authenticates to (listen). It issues scoped wk_ session tokens with a 24-hour TTL; expired tokens stop authorising the proxy, git-credential, and API faces and are swept from memory. Real credentials never cross into the sandbox.

Top-level agent settings: default_profile and the base system prompt.

The owner-interactive profile: system prompt, model, sandbox mode (host or docker), and which child profiles it may spawn. This is the profile waffle chat uses unless --profile selects another.

Tool policy for main — allow and deny lists. A profile can tighten its group’s policy and can never widen it.

Example restricted profile: docker sandbox, read and fetch only.

Tool policy for researcher, including the filesystem roots its file tools may reach.

Example restricted profile: docker sandbox, read-only critique.

Tool policy for reviewer.

The Telegram gateway: enabled, a secret:// bot token, and the maximum attachment size. Pairing binds your own account; anyone else receives a code and nothing more.

Sandbox execution: working directory, the filesystem roots the built-in file tools may reach, PID limits, and the enforcer. On a non-Linux host running Docker mode, runner_binary must be an absolute path to a static linux build matching the container’s GOARCH.

Tool policy can deny a tool by name but cannot widen the filesystem boundary.

See The sandbox queue.

A named search connection: type, an api_key reference, and result limits.

The search connection used when none is named.

Spend and throughput ceilings: tokens per day, requests per hour, and tunnel bytes per session.