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=true when 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=log so 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=false unless a private integration is required and isolated by infrastructure policy.
  • Keep TLS_SKIP_VERIFY=false.
  • Start with SESSION_IP_BINDING=log. Use strict only 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_URL to the browser-visible public URL.
  • Set USE_PROXY=true only when a trusted proxy terminates TLS.
  • Block direct access to the Windshift backend port when proxy mode is enabled.
  • Keep SSO_SECRET stable, 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_CONNECTIONS policy and test every affected integration.
  • Keep TLS_SKIP_VERIFY=false unless a temporary, documented exception is necessary.
  • Review SESSION_IP_BINDING logs before enabling strict mode.
  • 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=false

The equivalent command-line setting is:

./windshift --allow-local-connections=false

When 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:

  1. Confirm that every affected destination is on a trusted network.
  2. Record the reason and owner for the exception.
  3. Apply an egress rule that limits the reachable destinations.
  4. Replace the untrusted certificate.
  5. 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:

  1. Read the release notes for every version in the upgrade path.
  2. Stop writes or place the service in a maintenance window.
  3. Create a verified database and file backup.
  4. Pin the target release.
  5. Start one instance and watch migration logs.
  6. Check /healthz, /readyz, /api/version, and /api/setup/status.
  7. 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.