Production-ready self-hosting
Use this guide to choose a production trust model and verify the controls around Windshift. It supplements the configuration reference.
Windshift supports private integrations by default. This is useful when one organization runs Windshift with internal SCM, Jira, identity, mail, model, webhook, plugin, or runner services. A public or multi-user installation usually needs tighter network controls.
Choose a deployment profile
Trusted organization network
Use this profile when one organization controls Windshift, its administrators, its integrations, and the network around them.
- Keep
ALLOW_LOCAL_CONNECTIONS=truewhen Windshift must reach private services. - Keep
TLS_SKIP_VERIFY=false. Install a trusted internal certificate authority instead of disabling verification. - Start with
SESSION_IP_BINDING=logso valid network changes do not end sessions. - Restrict administrator access and protect the Windshift host from unrelated internal networks.
- Apply host or network egress rules even when all configured integrations are trusted.
Hardened internet-exposed or multi-user deployment
Use this profile when less-trusted users or automation can influence integration destinations, or when Windshift runs in a public cloud network.
- Set
ALLOW_LOCAL_CONNECTIONS=falseunless a private integration is required and isolated by infrastructure policy. - Keep
TLS_SKIP_VERIFY=false. - Start with
SESSION_IP_BINDING=log. Usestrictonly after you verify proxy, mobile, and roaming-client behavior. - Deny egress to cloud metadata, host-local services, container control sockets, and unrelated private networks.
- Expose only the HTTPS reverse proxy. Do not expose the Windshift backend port.
- Run coding-agent runners on separate disposable hosts when possible.
Disabling local connections can break private SCM, Jira, LLM, webhook, OIDC, SMTP, IMAP, plugin, and runner-related endpoints. Test each configured integration after the change.
Minimum production checklist
- Pin a published Windshift version or immutable image digest.
- Back up the database and persistent files before each upgrade.
- Test database restore and attachment restore procedures.
- Serve Windshift through HTTPS.
- Set
BASE_URLto the browser-visible public URL. - Set
USE_PROXY=trueonly when a trusted proxy terminates TLS. - Block direct access to the Windshift backend port when proxy mode is enabled.
- Keep
SSO_SECRETstable, secret, and outside version control. - Configure SSO or another intended authentication method before broad access.
- Keep emergency administrator fallback disabled unless your recovery plan requires it.
- Review system-administrator and workspace-administrator membership.
- Choose an
ALLOW_LOCAL_CONNECTIONSpolicy and test every affected integration. - Keep
TLS_SKIP_VERIFY=falseunless a temporary, documented exception is necessary. - Review
SESSION_IP_BINDINGlogs before enablingstrictmode. - Apply network segmentation and outbound firewall rules.
- Persist
/data, attachments, plugins, and the selected database storage. - Send structured logs to monitored storage.
- Monitor
/healthz,/readyz, database capacity, memory, cache evictions, and failed background work. - Keep Windshift, the database, the reverse proxy, and runner hosts current.
- Run Windshift, PostgreSQL, and runners with only the permissions they need.
Outbound network boundary
Anyone who can configure an outbound destination can potentially use the network position of the Windshift server. This matters when a destination comes from a less-trusted user, imported data, a webhook, or automation.
ALLOW_LOCAL_CONNECTIONS=true permits supported server-side clients to reach loopback, link-local, and private-network destinations. The setting is global. It is not an allowlist for selected services.
Use this hardened setting to block private destinations:
ALLOW_LOCAL_CONNECTIONS=falseThe equivalent command-line setting is:
./windshift --allow-local-connections=falseWhen private destinations are required, keep the setting enabled and enforce the boundary outside Windshift. Block access to cloud metadata addresses, host management ports, Docker or Podman sockets, Kubernetes control planes, and unrelated internal subnets.
Application configuration does not replace network segmentation, metadata protection, secret management, tested backups, or timely security updates.
TLS and certificates
Terminate inbound TLS at a reverse proxy or with the Windshift --tls-cert and --tls-key settings. See Reverse Proxy.
TLS_SKIP_VERIFY=true disables certificate-chain and hostname verification for outbound HTTPS, SMTP, IMAP, and LDAP connections. This is a process-wide setting. Prefer a trusted internal certificate authority or service-specific certificate configuration.
If you must enable it temporarily:
- Confirm that every affected destination is on a trusted network.
- Record the reason and owner for the exception.
- Apply an egress rule that limits the reachable destinations.
- Replace the untrusted certificate.
- Restore
TLS_SKIP_VERIFY=false.
Sessions, proxies, and administrator access
Set SESSION_IP_BINDING=log first. Windshift records client-IP changes without ending sessions. After you verify the logs, use strict only where a fixed client address is expected. Use off when a trusted network layer already enforces the required session controls and client addresses change frequently.
When USE_PROXY=true, Windshift trusts forwarded client and protocol headers. Permit only the proxy to connect to the backend. Configure ADDITIONAL_PROXIES only for known proxy addresses.
Review administrator access regularly. Remove inactive accounts, protect identity-provider administrator roles, and keep recovery credentials in controlled secret storage.
Data durability and upgrades
For SQLite, back up the database file and persistent /data content while writes are stopped. For PostgreSQL, use tested PostgreSQL backup and restore procedures. Include attachments and plugins in both cases.
Before an upgrade:
- Read the release notes for every version in the upgrade path.
- Stop writes or place the service in a maintenance window.
- Create a verified database and file backup.
- Pin the target release.
- Start one instance and watch migration logs.
- Check
/healthz,/readyz,/api/version, and/api/setup/status. - Test authentication, item changes, integrations, and scheduled work.
Windshift 0.8.5 is a required upgrade bridge for older databases. See Windshift 0.8.5.
Monitoring and least privilege
Use JSON logs in production. Alert on startup failures, repeated authentication errors, failed webhooks, failed email delivery, database saturation, memory pressure, and runner failures.
The Docker socket on a runner grants control over its host. Prefer a dedicated runner host. Do not mount the Docker socket into the Windshift server. Keep agent networks and runner credentials separate from unrelated workloads.
Disable plugins when you do not use them. When plugins are enabled, install only reviewed packages and protect the plugin directory from untrusted writes.