Security
gateway pairing
OTP authentication with brute force protection
flow
- gateway starts, prints 6-digit pairing code to terminal
- client sends code via
POST /pairwithX-Pairing-Codeheader - server validates with constant-time comparison (no timing leaks)
- server responds with bearer token (
bh_prefix) - all subsequent requests require
Authorization: Bearer bh_...
brute force protection
5 wrong attempts triggers a 5-minute lockout. this is enforced server-side, not client-side.
constant-time comparison
the pairing code comparison iterates max(a.len, b.len) and pads with zeros so timing is flat regardless of how many characters match. this prevents timing attacks that could leak the code one digit at a time.
network binding
- default:
127.0.0.1(localhost only) - refuses
0.0.0.0unless a tunnel is configured orallow_public_bind = true - when using cloudflare/tailscale/ngrok tunnel, public binding is safe because traffic is authenticated at the tunnel layer