Infrastructure/Caddy.md now owns the order of operations for exposing a vhost
(proxy provider + application + embedded-outpost claim, then the route, then the
name and the chain audit), because the IdP row is invisible state that nobody
recreates. Audiobookshelf's Internal-only row and law become Two doors, one app;
the homepage link and index.md follow.
The guard spec's GUARDED list is the lockstep with the Caddyfile; abs joins it
with the app's own SSO-button label as the leak marker - a string the Audiobookshelf
login renders and the IdP gate never prints.
ABS builds redirect_uri from the origin of the request, so a second door is a
second URI: ABS_EXTRA_BASES (default the guarded vhost) now contributes a
callback each, while the mobile-redirect URI stays on the LAN origin - the phone
is a non-browser client and cannot solve the guard's challenge, so it is
configured with the LAN address. Measured on the live provider: three URIs,
grants and scopes unchanged.
The tile carried the bare LAN IP. The probe stays the LAN host:port so the
homepage checker keeps measuring the app rather than the auth chain in front of
it.
Provider-first exposure: the IdP row (proxy provider abs-proxy + application
"Audiobookshelf Guard", claimed by the embedded outpost) already exists, so the
route can ship. The site block proxies everything to anubis:8923 like every other
guarded vhost, and the post-auth :8017 handler routes the host to
192.168.0.235:8000. The container carries ROUTER_BASE_PATH=/audiobookshelf, so
the app has no root: the bare / is redirected onto the base path inside the
post-auth handler, never pre-auth, so an anonymous client only ever meets the
gate.