Port 8000 — Loopback Bind (Public Exposure Closed)

Closed: 2026-08-07 on Dustin’s go (entirely-api af18957). The last audit-era security item from the 2026-08-05 Tailscale-session audit.

What was wrong

unlikely-api’s compose bind was 0.0.0.0:8000:8000; Docker NAT bypasses UFW (DOCKER-USER chain empty), so /docs, /openapi.json and /api/status answered unauthenticated from the public internet (verified via check-host.net probes from 3 countries, 2026-08-05).

The fix (two steps, two days)

  1. 2026-08-07 AM (prereq, fleet item 7): all 5 live Kilroy skill files moved off the Docker bridge IP 172.17.0.1:8000 → localhost:8000.
  2. 2026-08-07 (this change): compose bind → 127.0.0.1:8000:8000, container recreated (docker compose up -d unlikely-api — recreate, not restart), repo verified clean of other sessions’ dirty files first.

Verification

ss -tlnp shows docker-proxy on 127.0.0.1:8000 only; localhost /api/health 200; external TCP probes from PL/TR/IR all time out (https://check-host.net/check-report/46afa8f3kce6). Caddy (127.0.0.1 upstream), crontabs, /opt/scripts, Kilroy jobs all unaffected — nothing legitimate ever used the public bind.

Caveat

Rob/OpenClaw’s frozen configs still reference 172.17.0.1:8000 — if Rob is ever resurrected, the bridge-IP path is now dead; fix his config or add a DOCKER-USER allowance then. Memory: project_port_8000_exposure (RESOLVED).