Add Caddy bypasses so MCP can reach *arr and Uptime Kuma through Authentik.
Deploy to valhalla / deploy (push) Has been cancelled

TB-006 forward_auth blocks machine clients with HTML/302; route /api on *arr
sites and /api plus socket.io on uptime (LAN/tailnet only) before forward_auth.
Also add Cursor interview-first rule and small Authentik/FreshRSS debug helpers.
This commit is contained in:
ginnoir
2026-06-11 17:37:21 -05:00
parent 776478c035
commit e3bf11d18e
4 changed files with 66 additions and 0 deletions
@@ -0,0 +1,16 @@
---
description: Interview-first planning for ADHD — applies to plans/ and task briefs in this repo
globs: plans/**/*
alwaysApply: false
---
# Interview-first planning (this repo)
When working on files under `plans/`:
- Lead with conversation questions, not dense specs
- Each task brief's **Talk first** section is the real interface
- Record outcomes in **What we decided** after chatting with Matt
- Dropping a task is success — mark Decision: dropped
See also: user rule `interview-first-planning` (global, always apply).
+27
View File
@@ -31,6 +31,11 @@
} }
} }
# Clients on LAN, Docker, or tailnet (same ranges as internal_only).
(remote_internal) {
remote_ip 192.168.1.0/24 172.16.0.0/12 100.64.0.0/10 127.0.0.1
}
# ============================================================= # =============================================================
# FOUNDRY VTT — public # FOUNDRY VTT — public
# ============================================================= # =============================================================
@@ -87,6 +92,9 @@ sonarr.ginnoir.com {
import internal_only import internal_only
route { route {
import authentik_outpost import authentik_outpost
handle /api/* {
reverse_proxy sonarr:8989
}
handle { handle {
import authentik_forward_auth import authentik_forward_auth
reverse_proxy sonarr:8989 reverse_proxy sonarr:8989
@@ -98,6 +106,9 @@ radarr.ginnoir.com {
import internal_only import internal_only
route { route {
import authentik_outpost import authentik_outpost
handle /api/* {
reverse_proxy radarr:7878
}
handle { handle {
import authentik_forward_auth import authentik_forward_auth
reverse_proxy radarr:7878 reverse_proxy radarr:7878
@@ -109,6 +120,9 @@ bazarr.ginnoir.com {
import internal_only import internal_only
route { route {
import authentik_outpost import authentik_outpost
handle /api/* {
reverse_proxy bazarr:6767
}
handle { handle {
import authentik_forward_auth import authentik_forward_auth
reverse_proxy bazarr:6767 reverse_proxy bazarr:6767
@@ -120,6 +134,9 @@ prowlarr.ginnoir.com {
import internal_only import internal_only
route { route {
import authentik_outpost import authentik_outpost
handle /api/* {
reverse_proxy prowlarr:9696
}
handle { handle {
import authentik_forward_auth import authentik_forward_auth
reverse_proxy prowlarr:9696 reverse_proxy prowlarr:9696
@@ -178,6 +195,9 @@ whisparr.ginnoir.com {
import internal_only import internal_only
route { route {
import authentik_outpost import authentik_outpost
handle /api/* {
reverse_proxy whisparr:6969
}
handle { handle {
import authentik_forward_auth import authentik_forward_auth
reverse_proxy whisparr:6969 reverse_proxy whisparr:6969
@@ -324,6 +344,13 @@ portainer.ginnoir.com {
uptime.ginnoir.com { uptime.ginnoir.com {
route { route {
import authentik_outpost import authentik_outpost
@uptime_mcp {
path /api/* /socket.io/*
import remote_internal
}
handle @uptime_mcp {
reverse_proxy uptime-kuma:3001
}
handle { handle {
import authentik_forward_auth import authentik_forward_auth
reverse_proxy uptime-kuma:3001 reverse_proxy uptime-kuma:3001
+7
View File
@@ -0,0 +1,7 @@
<?php
header('Content-Type: text/plain');
foreach ($_SERVER as $k => $v) {
if (str_starts_with($k, 'HTTP_') || str_contains($k, 'REMOTE')) {
echo "$k=$v\n";
}
}
@@ -0,0 +1,16 @@
"""Print userinfo payload Portainer receives (ak shell: exec(open(...).read()))."""
from authentik.core.models import User
from authentik.providers.oauth2.models import OAuth2Provider, AccessToken
from authentik.providers.oauth2.views.userinfo import UserInfoView
from django.test import RequestFactory
u = User.objects.get(username="ginnoir")
p = OAuth2Provider.objects.get(name="portainer")
t = AccessToken.objects.create(user=u, provider=p, scope="openid email profile")
req = RequestFactory().get(
"/application/o/userinfo/",
HTTP_AUTHORIZATION=f"Bearer {t.token}",
)
resp = UserInfoView.as_view()(req)
print("status", resp.status_code)
print(resp.content.decode())