[M3] Dev-test stack is served over plaintext HTTP to the LAN — put TLS on the transports (secret-unmask debug hook stays) #78
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
The dev-test stack has no TLS on any transport:
deploy/Caddyfile.fragmentis the intended TLS edge but was never merged into a running Caddy, so every request — including the API — travels as plaintext HTTP over the LAN. Given that this environment intentionally carries a debug hook that can return stored secrets in plaintext, the missing TLS is the actual defect.Scope change (2026-09-20, requested by owner)
/api/v1/settings" to "put SSL/TLS on the transports".SLAB_UAT_UNMASK_SECRETS=1(deploy/.env) is an intentional dev/test debugging hook — it is needed to inspect stored secrets on this box and it stays.allow_origins=["*"](backend/app.py:135-141, raised separately if wanted).Observed evidence
deploy/INVENTORY.md:deploy/override-m3.ymlbinds the frontend to0.0.0.0:10881; the frontend container's nginx (deploy/nginx-m1.conf) proxies/api/to FastAPI on the compose network.deploy/Caddyfile.fragmentis written as the TLS edge but is not in play:Checked on
ubudual5060: nocaddyprocess is running and thecaddyservice is inactive, so nothing terminates TLS for this stack. (The fragment's comment says "Merge into host Caddy" — that merge has not happened.)Consequence, probed read-only against the live container over that plaintext hop (values not printed):
Why this is the real issue
The hook is fine in dev/test. What turns a debugging convenience into a LAN-visible credential read is that the bytes are unencrypted and unauthenticated on the wire, on a shared
192.168.1.0/24. That applies to any future debug surface too, not just this one route. The Tailscale address (100.64.0.9) is already an encrypted transport; the LAN HTTP path is not.Acceptance
tls internal,/api/*handled before the frontend catch-all), or the0.0.0.0LAN bind dropped in favour of the encrypted Tailscale path only.curl -i http://192.168.1.202:10881/api/v1/settingsmust refuse or redirect tohttps://, never return 200 with the settings payload.backend/settings.py:62-65), and default-off behaviour unchanged (SETTINGS-75masking when unset).https://<host>/api/v1/settingswith the hook off and confirming{"configured": true}shapes rather than strings.Related
deploy/INVENTORY.md,deploy/Caddyfile.fragment,deploy/override-m3.yml,deploy/docker-compose.yml34ee7ef(temporary UAT secret-unmask gate),d614123(UAT secrets as plain text inputs)[M3] UAT deploy serves the Woo app password and inference key in plaintext over the LAN (SLAB_UAT_UNMASK_SECRETS=1)to [M3] Dev-test stack is served over plaintext HTTP to the LAN — put TLS on the transports (secret-unmask debug hook stays)Caddyfile.fragment exists with tls internal, not yet merged into running Caddy. Moving to post-M3.