# The management page `./web.sh` serves one page on `127.0.0.1:8140`: whether the bot is alive, what it is configured with, and the photo album's tagger. It replaces `tool/tagger.py`, which served the album half of this on the same port. ```sh ./web.sh # the configured pack ./web.sh --dir ~/pack --port 8140 ./web.sh --import ~/photos # dedup, strip and import, then serve ./web.sh --import ~/photos --dry-run # the report, changing nothing ./web.sh --untagged # only items with no tags yet ``` ## Why it is started by hand A systemd unit would be more convenient and is the wrong shape. This page can rewrite `.env` — the file that decides which groups the bot answers in and who may add it to one — and a unit would keep that writable on loopback all day for the sake of a bookmark. Started by hand, the window is the few minutes somebody is actually looking at it. It is also a **second process**, not more routes on the bot. The bot's own port already serves `POST /_selftest`, which posts for real into a real group; putting a configuration writer beside it would put both behind one mistake. ## Why loopback is not the whole defence Binding to `127.0.0.1` stops the network. It does not stop the browser already running on this machine, and two attacks reach a loopback port from an ordinary web page. `signal_bot/manage/guard.py` closes both, in about forty lines, with nothing to configure and no session to keep: - **Cross-origin form posts.** Any site can POST a `