Skip to main content
The control plane includes several optional proxy and service components that can be enabled in config.toml.

Reverse proxy

Routes HTTP traffic to apps by hostname. Each app gets <app-name>.<domain>.
[proxy]
  enabled = true
  domain = "example.com"
  http_port = 80
  https_port = 443
  request_timeout = "30s"
  api_forward = "127.0.0.1:8080"   # Forward root domain to API (optional)

TLS with Let’s Encrypt

[proxy.tls]
  enabled = true
  email = "[email protected]"
  cache_dir = "/var/lib/zwrm/certs"
  allowed_hosts = []               # Additional TLS hostnames
Certificates are automatically obtained and renewed via Let’s Encrypt. The cache directory stores certificates on disk.

Health checks

The proxy monitors backend health and removes unhealthy VMs from the rotation:
[proxy.health]
  interval = "10s"
  timeout = "2s"
  failure_threshold = 3            # Failures before marking unhealthy
  recovery_threshold = 2           # Successes before marking healthy
  startup_grace_period = "30s"     # Grace period before checks start

SSH proxy

Enables zwrm ssh access through NAT to VMs that don’t have public IPs. Uses certificate-based authentication.
[ssh_proxy]
  enabled = true
  port = 2222
  host_key_path = "/var/lib/zwrm/ssh_proxy_host_key"
  idle_timeout = "10m"

  [ssh_proxy.ca]
    ca_path = "/var/lib/zwrm/ssh_ca"
    certificate_ttl = "24h"
The SSH CA keypair is generated automatically on first start if it doesn’t exist.

PostgreSQL proxy

External PostgreSQL access via HAProxy with TLS. Allows developers to connect to managed databases from outside the cluster.
[postgres_proxy]
  enabled = true
  domain = "pg.example.com"
  port = 5432
  haproxy_config_path = "/etc/haproxy/haproxy.cfg"
  haproxy_map_path = "/etc/haproxy/postgres.map"
  haproxy_reload_command = "systemctl reload haproxy"
  connection_timeout = "10s"
  client_timeout = "1h"
  server_timeout = "1h"

  [postgres_proxy.tls]
    certbot_enabled = true
    certbot_email = "[email protected]"
    certbot_dns_plugin = "route53"
    certbot_credentials_path = "/etc/certbot/credentials"
The PostgreSQL proxy requires HAProxy to be installed separately. ZWRM generates the HAProxy config and reloads it when databases are created or destroyed.

Authentication service

ZWRM can run a Better Auth-based authentication service as a subprocess for multi-user setups.
[auth]
  database_url = "postgres://user:pass@localhost:5432/zwrm_auth"
  max_orgs_per_user = 5

  [auth.service]
    enabled = true
    internal_port = 3000
    auth_dir = "/usr/local/share/zwrmd/auth"
    routes = ["auth.example.com"]

    [auth.service.env]
      BETTER_AUTH_SECRET = ""       # JWT signing secret (openssl rand -base64 32)
      BETTER_AUTH_URL = "https://auth.example.com"
      RESEND_API_KEY = ""           # For transactional emails
      TRUSTED_ORIGINS = "https://dashboard.example.com"
      # Optional OAuth providers:
      # GITHUB_CLIENT_ID = ""
      # GITHUB_CLIENT_SECRET = ""
      # GOOGLE_CLIENT_ID = ""
      # GOOGLE_CLIENT_SECRET = ""
The auth service requires a separate PostgreSQL database and a Node.js runtime.
For single-user setups with localhost access only, you don’t need the auth service — localhost requests bypass authentication automatically.