Identify the bot's web callers by Discord id, and isolate the bot's network

authentik/vanguard-profile-scope-mapping.py (new, and the first time that mapping is version-controlled rather
than pasted from the docs) emits the Discord snowflake from the account's source connection alongside the
inherited groups, so the bot never has to match a name.

docker-compose.yml: discord-bot moves to its own network. It trusts the identity headers Caddy injects, and it
shared the default bridge with jellyfin, copyparty, syncthing, gitea, act_runner and cadvisor, any of which
could reach :8000 directly and forge them. It needs no sibling container: Caddy uses the published loopback
port and MariaDB is reached through host.docker.internal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-11-03 00:13:14 -06:00
parent 31bec6e770
commit ba110747b7
4 changed files with 59 additions and 2 deletions

View File

@@ -94,8 +94,11 @@ Rules:
3. Authorize by group, read from the header each time. Don't cache roles in your DB.
4. Serve under `/`; the proxy does no path rewriting for this host.
5. Build absolute links from `WEB_PUBLIC_URL`.
6. The Authentik username may differ from the Discord username. Use the header value as the user key;
if you need the Discord snowflake, resolve it through your gateway client and cache it in your DB.
6. **The Discord snowflake arrives in `X-Authentik-Jwt`** as the `discord_id` claim (a scope mapping on the
provider supplies it; Authentik takes it from the account's source connection). Decode the JWT payload and
use that as the user key. Do not match the Authentik username against Discord names: usernames are mutable
and reusable, and server nicknames are self-chosen and not unique, so name matching can mistake one member
for another. The signature needs no checking because the header can only come from the proxy.
Until the admin creates the matching Authentik application, the hostname returns an error, never an
open page. Test against `http://127.0.0.1:8000/` on the server with the headers set by hand.