Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ CGO_ENABLED=0 go build -ldflags="-s -w -X main.version=2026.3.0" -o gateway ./cm
| `GATEWAY_ID` | Stable gateway identifier (empty = generate ULID at startup) |
| `GATEWAY_PUBLIC_TERMINAL_URL_TEMPLATE` | Template for the public terminal WebSocket URL, e.g. `wss://{id}.gateway.example.com/terminal` |
| `GATEWAY_BOOTSTRAP_HOST` | Wildcard root hostname for agent bootstrap redirect, e.g. `gateway.example.com` |
| `GATEWAY_WEB_LISTEN_ADDR` | Listen address for the web TLS listener (terminal WebSocket), e.g. `:8443` |
| `GATEWAY_WEB_LISTEN_ADDR` | Listen address for the terminal-WebSocket HTTP listener (cleartext; Traefik terminates TLS upstream), e.g. `:8443` |
| `GATEWAY_LOG_LEVEL` | Log level: `debug`, `info`, `warn`, `error` (default `info`) |
| `GATEWAY_HEARTBEAT_INTERVAL` | Heartbeat cadence sent to agents (Go duration, 5s..5m; default `30s`) |
| `GATEWAY_TRAEFIK_TTY_CERT_RESOLVER` | Traefik cert resolver name for the per-replica TTY HTTP router (e.g. `letsencrypt`) |
Expand Down
2 changes: 1 addition & 1 deletion cmd/control/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export CONTROL_DATABASE_URL="postgres://powermanage:powermanage@localhost:5432/p
export CONTROL_JWT_SECRET="your-secret-key"
export CONTROL_CA_CERT="./dev/certs/ca.crt"
export CONTROL_CA_KEY="./dev/certs/ca.key"
export CONTROL_GATEWAY_URL="https://gateway.example.com:8080"
export CONTROL_GATEWAY_URL="https://gateway.example.com"
export CONTROL_ADMIN_EMAIL="admin@localhost.com"
export CONTROL_ADMIN_PASSWORD="admin"

Expand Down
20 changes: 17 additions & 3 deletions cmd/control/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,23 @@ func main() {

logger := logging.SetupLogger(cfg.LogLevel, cfg.LogFormat, os.Stderr)
slog.SetDefault(logger)
logger.Info("starting control server", "version", version, "listen_addr", cfg.ListenAddr, "gateway_url", cfg.GatewayURL, "dynamic_group_eval_interval", cfg.DynamicGroupEvalInterval)
if cfg.GatewayURL == "" {
logger.Warn("CONTROL_GATEWAY_URL is not set - agents will not receive a gateway URL during registration")
// Redact the gateway URL on the startup line too. If a bad shape
// slipped in (e.g. https://u:p@host/ despite the validator, or an
// operator paste-mistake), it shouldn't land in every boot log.
logger.Info("starting control server", "version", version, "listen_addr", cfg.ListenAddr, "gateway_url", api.RedactGatewayURL(cfg.GatewayURL), "dynamic_group_eval_interval", cfg.DynamicGroupEvalInterval)
// CONTROL_GATEWAY_URL is fatal when invalid: registration hands
// it back to the agent verbatim, so any invalid shape — empty
// string, bare hostname (parses as a relative path), http://
// (agents refuse h2c), userinfo, or non-https scheme — turns
// every successful enrollment into an agent that can never
// connect. api.ValidateGatewayURL is the shared validator
// (also invoked defensively in the registration handler).
if err := api.ValidateGatewayURL(cfg.GatewayURL); err != nil {
// Redact userinfo before logging — the validator rejects
// URLs that contain credentials, but those credentials
// shouldn't land in the startup error line regardless.
logger.Error("CONTROL_GATEWAY_URL is invalid", "gateway_url", api.RedactGatewayURL(cfg.GatewayURL), "error", err)
os.Exit(1)
}

// Setup signal handling
Expand Down
Loading
Loading