Episode 15: Pocket ID as identity provider, tinyauth gate, offboarding script
Pocket ID replaces Forgejo as the OIDC provider for Outline, Vaultwarden and NetBird; Forgejo logs in through it. Uptime Kuma sits behind tinyauth via Caddy forward_auth (group ops), the public status page stays public. offboarding/offboard.py switches one person off in every service with an API and prints what a human still has to do: the shared passwords they could read. Measured: SSO lock alone left 10 of 13 ways open for 45 minutes; the script leaves 1 of 14, the vault copy on their laptop. HARDENING.md: the ufw hairpin that broke Vaultwarden SSO and Kuma, the mesh route into the docker bridges, and a fail2ban exception for Pocket ID.
This commit is contained in:
parent
3edef38ba3
commit
12542ecb19
9 changed files with 490 additions and 21 deletions
34
Caddyfile
34
Caddyfile
|
|
@ -85,7 +85,25 @@ vault.{$DOMAIN} {
|
|||
status.{$DOMAIN} {
|
||||
import common
|
||||
import crowdsec
|
||||
reverse_proxy uptime-kuma:3001
|
||||
# episode 15: the Kuma UI only behind the login gate (tinyauth, group ops).
|
||||
# Status pages, badges and push heartbeats stay public.
|
||||
@public path /status/* /api/status-page/* /api/badge/* /api/push/* /assets/* /upload/* /icon.svg /favicon.ico /manifest.json
|
||||
handle @public {
|
||||
reverse_proxy uptime-kuma:3001
|
||||
}
|
||||
handle {
|
||||
forward_auth tinyauth:3000 {
|
||||
uri /api/auth/caddy
|
||||
copy_headers Remote-User Remote-Email Remote-Groups
|
||||
# tinyauth v5 answers 401 and names its login page in a header;
|
||||
# without this the browser only ever sees {"message":"Unauthorized"}
|
||||
@login status 401
|
||||
handle_response @login {
|
||||
redir {rp.header.X-Tinyauth-Location} 302
|
||||
}
|
||||
}
|
||||
reverse_proxy uptime-kuma:3001
|
||||
}
|
||||
}
|
||||
|
||||
# Push notifications (episode 6). Websockets and long polling pass through as-is.
|
||||
|
|
@ -125,3 +143,17 @@ vpn.{$DOMAIN} {
|
|||
# Dashboard (everything else)
|
||||
reverse_proxy /* netbird-dashboard:80
|
||||
}
|
||||
|
||||
# Identity provider (episode 15). Everyone logs in here, with a passkey.
|
||||
id.{$DOMAIN} {
|
||||
import common
|
||||
import crowdsec
|
||||
reverse_proxy pocket-id:1411
|
||||
}
|
||||
|
||||
# Login gate for services without their own SSO (episode 15), used by forward_auth.
|
||||
auth.{$DOMAIN} {
|
||||
import common
|
||||
import crowdsec
|
||||
reverse_proxy tinyauth:3000
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue