v2.4.0
Summary
First security layer for remotecmd-cli: relay shared secret + TLS env vars. Both are opt-in and backward compatible — existing deployments continue to work without any config changes.
Changes
Relay shared secret (RELAY_SECRET)
- If
RELAY_SECRETenv var is set on the relay, all WebSocket connections must includeAuthorization: Bearer <secret>header - If not set, relay accepts all connections (backward compatible)
- Clients/daemons send the header via
dialRelay()— reads fromconfig.json(relay.secret) orRELAY_SECRETenv var - Configure with
remotecmd-cli set-relay --url <u> --name <n> --secret <s>
TLS env vars
- Relay:
RCMD_TLS_CERTandRCMD_TLS_KEYenv vars as fallback for--tls-cert/--tls-keyflags - Client:
RCMD_TLS_SKIP_VERIFY=1to skip cert verification (self-signed certs) wss://URLs already worked viawsURL()— no client changes needed
Centralized relay dialing
- All 10 relay connection sites now use
dialRelay()which adds auth headers automatically relayAuthHeaders()returns nil when no secret configured (no overhead)
Migration path
- Deploy v2.4.0 to relay and all clients/daemons (self-update works)
- When ready, set
RELAY_SECRETon the relay and restart it - Add
--secret <value>toset-relayon each client/daemon (or setRELAY_SECRETenv var) - Until all peers are updated, the relay runs without the secret — no disruption
Test plan
- Unit tests: 5 new tests for relay secret (reject/accept/wrong/no-secret/helpers)
- Full test suite passes (27s)
- CI passes (tests + coverage gate)
- Deployed to dk1 relay — all 10 targets reconnected without config changes
- Exec verified on rbm21, dk2, vps1 through new relay
Generated with Devin