Configuration reference
SysKnife reads configuration from three places, in lowest-to-highest priority:
- Built-in defaults — compiled into
sysknife-brainandsysknife-core ~/.config/sysknife/config.toml— optional, user-owned- Environment variables — always win
Set whatever's stable for your install in config.toml; override with env
vars when you need to (CI runs, ad-hoc experiments, distro packagers).
config.toml reference
Path: $XDG_CONFIG_HOME/sysknife/config.toml, falling back to
~/.config/sysknife/config.toml. The daemon and CLI read this on every
startup; the GUI reloads it after the wizard finishes.
# ─── [daemon] ────────────────────────────────────────────────────────
[daemon]
# Unix socket path the daemon listens on. CLI / shell connect here.
socket = "/run/sysknife/daemon.sock"
# SQLite database path for the local audit log.
# Production deployments should switch to [storage] backend = "postgres"
# (see below).
database = "/var/lib/sysknife/daemon.sqlite"
# ─── [llm] ───────────────────────────────────────────────────────────
[llm]
provider = "ollama" # ollama | anthropic | openai | gemini |
# groq | deepseek | mistral | xai
model = "qwen3:8b" # provider-specific model identifier
ollama_url = "http://localhost:11434"
anthropic_url = "https://api.anthropic.com"
max_turns = 10 # planning loop turn limit (>= 1)
# Optional: override the auto-detected thinking mode for Ollama.
# Default: auto-detect from the model name (qwen3 / qwq / deepseek-r → true).
# Set to `false` on CPU-only hosts running thinking models — thinking
# traces exceed Ollama's internal request timeout on 4 vCPUs.
# ollama_think = false
# ─── [storage] ───────────────────────────────────────────────────────
# Audit-log backend. Default (absent or backend = "sqlite") uses the
# local rusqlite store at [daemon].database. Production deployments
# should set backend = "postgres" — the SQLite path dies with the host.
[storage]
backend = "postgres"
url = "postgres://sysknife:${PG_PASSWORD}@db.example.com:5432/audit?sslmode=verify-full"
[storage.pool]
max_connections = 8
acquire_timeout_secs = 10
statement_cache_capacity = 100 # set to 0 for transaction-mode poolers
# ─── [policy] ────────────────────────────────────────────────────────
# Per-action risk-level overrides. Map from action name → risk level
# ("Low" | "Medium" | "High"). Validated at startup; unknown action
# names or attempted downgrades are fatal — overrides may only RAISE
# the minimum role required, never lower it.
[policy.risk_overrides]
InstallFlatpak = "High" # require Admin in this org (default: Medium/Dev)
# ─── [audit.forward] ─────────────────────────────────────────────────
# Optional SIEM forwarding. Best-effort — never blocks daemon execution.
# Phase 1 ships RFC 5424 syslog over UDP; CEF and NDJSON-over-TCP
# arrive in follow-up PRs.
[audit.forward.syslog]
host = "siem.internal:514"
facility = 1 # 1 = user-level (default)
The transaction database is the durable audit record. Safety-fence JSONL,
journald watermarks, and UDP syslog forwarding are operational signals and may
be unavailable or lossy. PostgreSQL migrations run automatically at daemon
startup; backup and restore requirements are documented in
storage-cloud.md.
Environment variables
Env vars always win over config.toml. Useful for CI runs, distro
packagers, and ad-hoc experiments. Variable names mirror the config
file's section.field path.
| Variable | Default | What it sets |
|---|---|---|
SYSKNIFE_LISTEN_URI | unix://$XDG_RUNTIME_DIR/sysknife/daemon.sock (falls back to unix:///tmp/sysknife-$UID.sock if XDG_RUNTIME_DIR is unset; production systemd unit sets unix:///run/sysknife/daemon.sock) | Daemon socket / vsock URI |
SYSKNIFE_DATABASE_PATH | $XDG_STATE_HOME/sysknife/daemon.sqlite (falls back to ~/.local/state/sysknife/daemon.sqlite; production systemd unit sets /var/lib/sysknife/daemon.sqlite) | SQLite audit log path |
SYSKNIFE_LLM_PROVIDER | auto-detect | LLM provider name (8 supported) |
SYSKNIFE_LLM_MODEL | provider default | Model identifier |
SYSKNIFE_OLLAMA_URL | http://localhost:11434 | Ollama base URL |
SYSKNIFE_OLLAMA_THINK | auto-detect | true / false thinking-mode override |
SYSKNIFE_ANTHROPIC_URL | https://api.anthropic.com | Anthropic base URL |
SYSKNIFE_BRAIN_MAX_TURNS | 10 | Planning loop turn limit |
SYSKNIFE_MAX_RPM | 20 | Rate limit (requests / 60s sliding window) |
SYSKNIFE_AUDIT_KEY_PATH | <db_dir>/audit-key | Ed25519 signing key path for the audit chain |
SYSKNIFE_CHECKPOINT_DB | — | Postgres URL for audit checkpoint external anchoring (keeps DB credentials off the command line) |
SYSKNIFE_SOCKET | falls back to the same default as SYSKNIFE_LISTEN_URI | CLI / MCP daemon address |
SYSKNIFE_TOKEN | — | Vsock auth token (when daemon runs in a VM) |
XDG_CONFIG_HOME | ~/.config | Base path for sysknife/config.toml |
Provider API keys
Required when the corresponding provider is selected:
OPENAI_API_KEY— OpenAIANTHROPIC_API_KEY— AnthropicGEMINI_API_KEY— GeminiGROQ_API_KEY— GroqDEEPSEEK_API_KEY— DeepSeekMISTRAL_API_KEY— MistralXAI_API_KEY— xAI- none — Ollama (local, no key)
Daemon-only configuration
These environment variables are read only by sysknife-daemon, not by
the CLI / shell:
| Variable | Purpose |
|---|---|
SYSKNIFE_AUDIT_KEY_PATH | Ed25519 audit signing key path (default: alongside the database) |
Validating your config
sysknife doctor
Reports the resolved configuration (socket, host, provider, model, audit
backend) plus a quick chain-integrity check. A failing doctor is the
fastest way to catch a typo'd env var or a bad path.
Where each setting lives in the source
For maintainers — the canonical types are:
crates/sysknife-core/src/config.rs—LacsConfig,DaemonSection,LlmSection,PolicySection,AuditSection,StorageSection,StoragePoolSectioncrates/sysknife-brain/src/config.rs—BrainConfig,ProviderConfigcrates/sysknife-core/src/lib.rs—default_listen_uri,default_database_path,prefs_path
Adding a new config knob: add the field to LacsConfig, surface the env
var in apply_defaults_to_env, and update this document. A test in
crates/sysknife-core/src/config.rs should cover the new field.