The app is the only process on this box accepting unauthenticated input from
the internet and it was running as root in a writable container. Now uid 10001,
read_only with a tmpfs /tmp, cap_drop ALL and no-new-privileges. Host-side
/srv/scout-website/data and the service account key are chowned to 10001.
Verified on a throwaway container: every route, the admin API, spam rejection,
and a real submission writing to both the jsonl and SQLite.
NPM proxies to scout-website:8000 over arrstack_arr_net, so the 0.0.0.0 publish
only provided a LAN path that bypassed the proxy, its exploit blocking and its
real-client-IP logging.
Three bot submissions landed 2026-08-30 with both selects carrying the
placeholder label "Select one..." - required= is browser-only and a direct
POST skips it. Adds a hidden honeypot (answers 303 so the bot sees success)
and server-side checks on name, email, children, interested_in and source.
Rejections are logged with the client IP and never touch any store.