add pid file for gateway running and auth token for /reload and pico channel#2134
add pid file for gateway running and auth token for /reload and pico channel#2134yinwm merged 6 commits intosipeed:mainfrom
Conversation
yinwm
left a comment
There was a problem hiding this comment.
Thanks for the PR! The PID file management design is solid and the config consolidation is a great cleanup. A few blocking issues before we can merge:
1. Security: Token leaked in logs (must fix)
In TryAutoStartGateway(), the line:
logger.Infof("pidData: %v", pidData)will print the auth token to logs since %v dumps all struct fields including Token. Please either remove this line or use a format that excludes the token, e.g.:
logger.Infof("pidData: PID=%d, Version=%s", pidData.PID, pidData.Version)2. Duplicated picoTokenPrefix constant (must fix)
picoTokenPrefix = "pico-" is defined in both pkg/gateway/gateway.go and web/backend/api/gateway.go. If one side changes and the other doesn't, token composition/validation will silently break. Please extract it to a shared location (e.g. pkg/pid or a dedicated constants file).
3. Breaking API changes not flagged (must fix)
This PR introduces breaking changes but is labeled as "non-breaking":
/healthno longer returns thepidfield/reloadnow requiresBearertoken authentication/pico/wsnow validates tokens before proxyingEnsurePicoChannelsignature changed fromerrorto(bool, error)
Please update the PR type checkbox accordingly and confirm the frontend is fully adapted to these changes.
Non-blocking suggestions:
web/backend/api/gateway.gois 870+ lines — consider splitting intogateway_pid.go/gateway_pico.gopicoComposedTokenuses plain string comparison for token validation; considersubtle.ConstantTimeComparefor consistency with the/reloadhandlergatewayStatusData()has 3 separate lock/unlock paths — worth simplifying the locking pattern- Unit test coverage for
picoComposedToken,extractBearerToken, and the/reloadauth flow would be valuable additions
yinwm
left a comment
There was a problem hiding this comment.
LGTM! Great addition — the centralized PID file management and config.GetHome() consolidation clean up a lot of scattered logic. Token auth for /reload and the pico channel is well-designed with proper constant-time comparison.
A few non-blocking suggestions for future consideration:
- In
overridePicoToken, the composite tokenpico-<pidToken><picoToken>lacks a delimiter — could cause parsing ambiguity downstream. generateToken's fallback totime.Now().UnixNano()is predictable — consider returning an error when the system CSPRNG is unavailable.- Removing
Pidfrom/healthresponse is technically breaking — worth confirming no external consumers depend on it. refreshPicoTokensLockedsilently swallows config load errors — a warning log would help debugging.gatewayStatusDatahas anattachToGatewayProcessLockedside effect despite its read-sounding name.
None of these block merging. Nice work!
add pid file for gateway running and auth token for /reload and pico channel
📝 Description
Add PID file management and auth tokens for gateway lifecycle and pico channel
This commit introduces centralized PID file management and token-based authentication for the gateway process. Key changes:
New pkg/pid package — Cross-platform PID file management (JSON format with PID, token, version, port, host). Supports singleton enforcement, atomic writes (temp + rename), stale PID cleanup, and platform-specific process liveness checks (Unix: signal(0), Windows: OpenProcess/GetExitCodeProcess). Comprehensive test coverage included.
Gateway singleton & auth token — The gateway writes a PID file on startup with a cryptographically random auth token. This token is used to authenticate the /reload endpoint (subtle.ConstantTimeCompare) and compose the Pico channel WebSocket token (pico-).
WebSocket reverse proxy — The web backend now proxies /pico/ws to the gateway, allowing the frontend to connect through a single port. Token validation distinguishes between gateway unavailability (503) and invalid credentials (403).
Config centralization — Consolidated scattered home directory resolution into config.GetHome() with PICOCLAW_HOME env support. Extracted env var keys into config.EnvHome, config.EnvConfig, config.EnvGatewayHost etc. as typed constants.
TUI gateway management — Replaced inline PID file parsing and platform-specific process checking with the shared pkg/pid package. Uses SIGTERM instead of SIGKILL for graceful shutdown.
Middleware fix — Added Hijack() to responseRecorder so WebSocket upgrades work correctly through the logging middleware layer.
🗣️ Type of Change
🤖 AI Code Generation
🔗 Related Issue
📚 Technical Context (Skip for Docs)
🧪 Test Environment
📸 Evidence (Optional)
Click to view Logs/Screenshots
☑️ Checklist