Configuration Options
Windshift can be configured with command-line flags and environment variables. Flags win over environment variables when both are present. The Docker image is usually configured with environment variables; the standalone binary can use either style.
Production checklist
For a self-hosted production deployment, set these first:
| Setting | Why it matters |
|---|---|
SSO_SECRET |
Required. Signs session cookies and SSO state. Generate once and keep it stable across restarts. |
BASE_URL |
Required for correct email links, SSO redirects, WebAuthn origins, calendar feeds, and runner callbacks. |
ALLOWED_HOSTS |
Restricts accepted hostnames and protects deployments behind proxies. |
USE_PROXY=true |
Required when TLS terminates at a reverse proxy. Only enable when Windshift is not directly internet-reachable. |
ATTACHMENT_PATH |
Required if users upload attachments and you want them persisted outside the database/container filesystem. |
POSTGRES_CONNECTION_STRING |
Recommended for multi-user production. SQLite is fine for small or single-node installs. |
Generate a secret with:
openssl rand -hex 32Keep the value. Changing SSO_SECRET invalidates existing sessions and can break encrypted SSO/provider credentials.
Configuration precedence
Windshift resolves configuration in this order:
- Explicit CLI flag
- Environment variable, where supported
- Built-in default
Example:
PORT=8080 ./windshift --port 3000Windshift listens on 3000, because the flag wins.
HTTP, proxy, and public URL
| Flag | Env var | Default | Description |
|---|---|---|---|
--port, -p |
PORT |
8080 |
HTTP server port. |
--base-url |
BASE_URL |
- | Public URL users access Windshift from, for example https://windshift.example.com. |
--context-path |
CONTEXT_PATH |
- | Optional subpath such as /windshift when served below a domain root. |
--allowed-hosts |
ALLOWED_HOSTS |
- | Comma-separated hostnames Windshift should accept, for example windshift.example.com. |
--allowed-port |
- | - | Extra port used for CORS and WebAuthn origin validation. |
--use-proxy |
USE_PROXY |
false |
Trust X-Forwarded-Proto and X-Forwarded-For from trusted proxies. |
--additional-proxies |
ADDITIONAL_PROXIES |
- | Comma-separated trusted proxy IPs in addition to private network ranges. |
--no-csrf |
- | false |
Disable CSRF protection. Development only. |
When USE_PROXY=true, Windshift trusts forwarded headers. Make sure only your reverse proxy can reach the Windshift port. Do not expose the backend port directly to the internet.
For subpath deployments, include the path in both BASE_URL and CONTEXT_PATH:
BASE_URL=https://example.com/windshift
CONTEXT_PATH=/windshiftSecrets and authentication
| Flag | Env var | Default | Description |
|---|---|---|---|
| - | SSO_SECRET |
required | Preferred session and SSO signing/encryption secret. |
| - | SESSION_SECRET |
- | Backward-compatible fallback when SSO_SECRET is unset. |
--enable-fallback |
ENABLE_ADMIN_FALLBACK |
false |
Enable password-based admin fallback for restrictive SSO setups. |
| - | RECOVER_USER |
- | Recovery helper for emergency user access flows. |
SSO_SECRET is required at startup. SESSION_SECRET is accepted only as a fallback for older deployments.
WebAuthn
| Flag | Env var | Default | Description |
|---|---|---|---|
| - | WEBAUTHN_RP_ID |
host name | WebAuthn relying-party ID, usually the public hostname. |
| - | WEBAUTHN_RP_NAME |
Windshift |
Display name shown by authenticators. |
Set BASE_URL and ALLOWED_HOSTS correctly before enabling passkeys/WebAuthn.
Database
| Flag | Env var | Default | Description |
|---|---|---|---|
--db |
DB_PATH |
windshift.db |
SQLite database file path. |
--postgres-connection-string, --pg-conn |
POSTGRES_CONNECTION_STRING |
- | PostgreSQL connection string. When set, PostgreSQL is used instead of SQLite. |
| - | DB_TYPE |
- | Set to postgres to build a connection string from POSTGRES_* variables. |
| - | POSTGRES_HOST |
postgres |
Host used when DB_TYPE=postgres and no connection string is supplied. |
| - | POSTGRES_PORT |
5432 |
PostgreSQL port for generated connection strings. |
| - | POSTGRES_USER |
windshift |
PostgreSQL user for generated connection strings. |
| - | POSTGRES_PASSWORD |
- | PostgreSQL password for generated connection strings. |
| - | POSTGRES_DB |
windshift |
PostgreSQL database for generated connection strings. |
--max-read-conns |
MAX_READ_CONNS |
120 |
SQLite read connection pool size. |
--max-write-conns |
MAX_WRITE_CONNS |
1 |
SQLite write connection pool size. |
Use POSTGRES_CONNECTION_STRING when possible; use the POSTGRES_* family when Docker Compose or secret managers make separate variables easier.
Files and attachments
| Flag | Env var | Default | Description |
|---|---|---|---|
--attachment-path |
ATTACHMENT_PATH |
- | Directory for uploaded attachments. |
In Docker, mount a persistent volume at /data and use /data/attachments.
TLS
| Flag | Env var | Default | Description |
|---|---|---|---|
--tls-cert |
- | - | TLS certificate path when Windshift terminates TLS directly. |
--tls-key |
- | - | TLS private key path when Windshift terminates TLS directly. |
Most deployments should terminate TLS at a reverse proxy and run Windshift over an internal network.
SSH TUI and MCP
| Flag | Env var | Default | Description |
|---|---|---|---|
--ssh |
SSH_ENABLED |
false |
Enable the SSH TUI server. |
--ssh-port |
SSH_PORT |
23234 |
SSH server port. |
--ssh-host |
SSH_HOST |
localhost |
SSH bind address. |
--ssh-key |
- | .ssh/windshift_host_key |
SSH host key path. |
--mcp |
MCP_ENABLED |
false |
Enable the MCP server at /mcp. |
Logging and rate limits
| Flag | Env var | Default | Description |
|---|---|---|---|
--log-level |
LOG_LEVEL |
info |
debug, info, warn, or error. |
--log-format |
LOG_FORMAT |
text |
text, json, or logfmt. |
--disable-ip-rate-limit |
DISABLE_IP_RATE_LIMIT |
false |
Disable IP-based rate limiting. Use only behind trusted controls. |
For container production logs, use:
LOG_FORMAT=json
LOG_LEVEL=infoPlugins
| Flag | Env var | Default | Description |
|---|---|---|---|
--disable-plugins |
DISABLE_PLUGINS |
false |
Disable the plugin system. |
| - | PLUGIN_DIR |
- | Primary plugin directory. |
| - | PLUGIN_DIRS |
- | Extra plugin directories, comma-separated. |
SSO and private identity providers
| Flag | Env var | Default | Description |
|---|---|---|---|
--oidc-allowed-private-cidrs |
OIDC_ALLOWED_PRIVATE_CIDRS |
- | Private/CGNAT CIDRs that OIDC discovery, JWKS, and token HTTP calls may dial. |
By default, OIDC HTTP clients block private, loopback, link-local, multicast, and CGNAT addresses to reduce SSRF risk. If your IdP is internal, allow only the exact CIDR(s) needed.
Examples:
# Internal IdP subnet
OIDC_ALLOWED_PRIVATE_CIDRS=10.20.30.0/24
# A single private IdP host
OIDC_ALLOWED_PRIVATE_CIDRS=10.20.30.15/32AI and LLM providers
AI features are configured in the Windshift admin UI after startup. Operators can customize the provider catalog and network policy here.
| Flag | Env var | Default | Description |
|---|---|---|---|
--llm-providers |
LLM_PROVIDERS_FILE |
- | Path to a custom LLM providers JSON file. Replaces the built-in provider catalog. |
--llm-allowed-private-cidrs |
LLM_ALLOWED_PRIVATE_CIDRS |
- | Private/loopback/CGNAT CIDRs that admin-configured LLM inference and model-list calls may dial. |
--ai-prompts-dir |
AI_PROMPTS_DIR |
/data/prompts in Docker |
Directory containing custom AI prompt override files. |
| - | LLM_ENDPOINT |
- | Legacy/fallback OpenAI-compatible inference endpoint. Prefer in-app AI connections for normal use. |
Windshift's built-in provider catalog includes Anthropic, OpenAI, Google Gemini, Z.AI, OpenRouter, and Local / Custom. OpenRouter includes a seed model list so admins can pick a model immediately; the Refresh button can still fetch the live catalog.
Local and internal LLM endpoints
LLM calls are SSRF-protected by default. Public provider endpoints work without extra configuration, but local or private models require an explicit allowlist. This applies to both inference requests and model-list refreshes.
For an Ollama or LM Studio server on the same host as the Windshift process:
LLM_ALLOWED_PRIVATE_CIDRS=127.0.0.1/32,::1/128For Windshift running in Docker and reaching a host service through Docker's bridge gateway:
LLM_ALLOWED_PRIVATE_CIDRS=172.17.0.1/32Then create a Local / Custom AI connection in the admin UI with a base URL such as:
http://host.docker.internal:11434/v1or:
http://172.17.0.1:11434/v1Only allow the exact host or subnet you need. Do not allow broad ranges such as 10.0.0.0/8 unless your network policy already prevents access to sensitive services.
Custom provider catalog
To add providers, change default models, or route a provider to a proxy, copy the built-in catalog and point Windshift at your copy:
internal/llm/llm_providers.json
Minimal OpenAI-compatible provider:
{
"providers": [
{
"type": "local",
"name": "Local / Custom",
"api_format": "openai",
"base_url": "http://127.0.0.1:11434/v1",
"models_endpoint": "/v1/models",
"models_auth_scheme": "bearer",
"models_response_format": "openai",
"models": [
{ "id": "llama3.1:8b", "name": "Llama 3.1 8B", "max_tokens": 4096 }
]
}
]
}Supported api_format values are:
| Value | Use for |
|---|---|
openai |
OpenAI-compatible chat completions APIs. |
anthropic |
Anthropic Messages API. |
Provider model-refresh settings:
| Field | Description |
|---|---|
models_endpoint |
Endpoint to fetch a model list, joined with the provider base URL. |
models_base_url |
Optional separate base URL for the model-list endpoint. |
models_auth_scheme |
bearer, anthropic, or google. |
models_response_format |
openai, anthropic, or google. |
chat_path |
Optional chat path override for OpenAI-compatible providers, for example /chat/completions. |
AI prompt overrides
Every AI feature uses an embedded system prompt. To override one prompt, place a <name>.txt file in AI_PROMPTS_DIR. Missing files keep the built-in default.
| Filename | Feature |
|---|---|
plan_my_day.txt |
Plan My Day |
catch_me_up.txt |
Catch Me Up |
find_similar.txt |
Find Similar |
decompose.txt |
Decompose |
release_notes.txt |
Release Notes |
dependency_analysis.txt |
Dependency Analysis |
ai_chat.txt |
AI Chat |
daily_briefing.txt |
Daily Briefing |
summarize_test_plan.txt |
Summarize Test Plan |
coding_agent_initial.txt |
Coding agent initial run prompt |
Default prompts are here:
Important:
ai_chat.txtcontains four runtime placeholders —%s(today's date),%s(current user's name),%d(user ID), and%d(assignee ID for "my items" lookups), in that order. Preserve all four in the same order when overriding this prompt.
Coding agent runner
See Coding Agent Runner for the full deployment guide.
| Env var | Default | Description |
|---|---|---|
CODING_AGENT_RUNNER_IMAGE |
- | Enables the local in-process coding-agent runner with this container image. |
CODING_AGENT_DOCKER_BINARY |
docker |
Docker executable path/name. |
CODING_AGENT_WORKTREE_ROOT |
- | Host path for prepared worktrees. Required when the runner image is set. |
CODING_AGENT_GLOBAL_CAP |
8 |
Max concurrent local agent runs. |
CODING_AGENT_WS_API_URL |
BASE_URL |
API URL agent containers use to reach Windshift. Override when BASE_URL is not reachable from containers. Must end in /api. |
CODING_AGENT_NETWORK |
coding-agent-egress |
Docker network for agent containers. |
CODING_AGENT_PIDS_LIMIT |
512 |
Container PID limit. |
CODING_AGENT_MEMORY |
4g |
Container memory and memory-swap limit. |
CODING_AGENT_CPUS |
2 |
Container CPU limit. |
CODING_AGENT_LLM_MODEL |
- | Fallback LLM model for agent containers. Usually configured per binding instead. |
Remote runner hosts use WSRUNNER_* variables in the runner process or runner
container, not in the Windshift server process. See Coding Agent Runner for the supported Docker runner compose file and the full remote-runner configuration table.
Notifications, Jira, and sidecars
| Env var | Default | Description |
|---|---|---|
NOTIFICATION_FLUSH_INTERVAL |
built-in | Notification write-batcher flush interval, Go duration such as 5s. |
NOTIFICATION_BATCH_SIZE |
built-in | Notification write-batcher batch size. |
NOTIFICATION_SYNC_INTERVAL |
built-in | Notification synchronization interval. |
WINDSHIFT_NOTIFICATION_BATCH_INTERVAL |
built-in | Email notification batch scheduler cadence. |
JIRA_CAPTURE_PAYLOADS |
- | Directory for Jira import request/response payload debugging. |
LOGBOOK_ENDPOINT |
- | URL of a Logbook sidecar service, if used. |
Examples
Minimal SQLite
SSO_SECRET=$(openssl rand -hex 32) \
BASE_URL=http://localhost:8080 \
./windshift --db /data/windshift.dbProduction behind a reverse proxy
./windshift \
--postgres-connection-string "postgres://windshift:secret@db:5432/windshift?sslmode=require" \
--use-proxy \
--allowed-hosts windshift.example.com \
--base-url https://windshift.example.com \
--attachment-path /data/attachments \
--log-level info \
--log-format jsonLocal LLM on the host
LLM_ALLOWED_PRIVATE_CIDRS=127.0.0.1/32,::1/128 \
./windshift --base-url http://localhost:8080Then add a Local / Custom AI connection in the UI with http://localhost:11434/v1.