Fix Homarr appdata bind mount and deploy Authentik forward auth on admin sites.
Deploy to valhalla / deploy (push) Has been cancelled
Deploy to valhalla / deploy (push) Has been cancelled
Homarr-labs stores state under /appdata; the old compose mapped empty paths and lost the dashboard on redeploy. TB-006 batch 1 adds Caddy forward_auth for 12 admin UIs with API and webhook bypasses.
This commit is contained in:
@@ -17,6 +17,20 @@
|
|||||||
respond @blocked "Access denied" 403
|
respond @blocked "Access denied" 403
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TB-006 — Authentik forward auth (embedded outpost on authentik-server:9000).
|
||||||
|
# Wrap protected sites in `route { ... }` so bypass handles run before forward_auth.
|
||||||
|
(authentik_outpost) {
|
||||||
|
reverse_proxy /outpost.goauthentik.io/* authentik-server:9000
|
||||||
|
}
|
||||||
|
|
||||||
|
(authentik_forward_auth) {
|
||||||
|
forward_auth authentik-server:9000 {
|
||||||
|
uri /outpost.goauthentik.io/auth/caddy
|
||||||
|
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Entitlements X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
|
||||||
|
trusted_proxies private_ranges
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# =============================================================
|
# =============================================================
|
||||||
# FOUNDRY VTT — public
|
# FOUNDRY VTT — public
|
||||||
# =============================================================
|
# =============================================================
|
||||||
@@ -196,8 +210,13 @@ storage.j-costa.com, https://storage.j-costa.com {
|
|||||||
# MINIO CONSOLE — internal only
|
# MINIO CONSOLE — internal only
|
||||||
# =============================================================
|
# =============================================================
|
||||||
minio.ginnoir.com {
|
minio.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy resume-minio:9001
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy resume-minio:9001
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# =============================================================
|
# =============================================================
|
||||||
@@ -219,34 +238,50 @@ dev.ginnoir.com {
|
|||||||
# MANAGEMENT — internal only
|
# MANAGEMENT — internal only
|
||||||
# =============================================================
|
# =============================================================
|
||||||
portainer.ginnoir.com {
|
portainer.ginnoir.com {
|
||||||
@webhook {
|
route {
|
||||||
method POST
|
import authentik_outpost
|
||||||
path /api/stacks/webhooks/*
|
@webhook {
|
||||||
}
|
method POST
|
||||||
|
path /api/stacks/webhooks/*
|
||||||
handle @webhook {
|
}
|
||||||
reverse_proxy portainer:9000
|
handle @webhook {
|
||||||
}
|
reverse_proxy portainer:9000
|
||||||
|
}
|
||||||
handle {
|
handle {
|
||||||
import internal_only
|
import authentik_forward_auth
|
||||||
reverse_proxy portainer:9000
|
reverse_proxy portainer:9000
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uptime.ginnoir.com {
|
uptime.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy uptime-kuma:3001
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy uptime-kuma:3001
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
homarr.ginnoir.com {
|
homarr.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy homarr:7575
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy homarr:7575
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
backup.ginnoir.com {
|
backup.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy kopia:51515
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy kopia:51515
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
router.ginnoir.com {
|
router.ginnoir.com {
|
||||||
@@ -258,13 +293,31 @@ router.ginnoir.com {
|
|||||||
# DEV STACK — internal only
|
# DEV STACK — internal only
|
||||||
# =============================================================
|
# =============================================================
|
||||||
gitea.ginnoir.com {
|
gitea.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy gitea:3000
|
import authentik_outpost
|
||||||
|
@api path /api/*
|
||||||
|
@git path_regexp (?i)\.git(/|$)
|
||||||
|
handle @api {
|
||||||
|
reverse_proxy gitea:3000
|
||||||
|
}
|
||||||
|
handle @git {
|
||||||
|
reverse_proxy gitea:3000
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy gitea:3000
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
code.ginnoir.com {
|
code.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy code_server:8443
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy code_server:8443
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registry.ginnoir.com {
|
registry.ginnoir.com {
|
||||||
@@ -273,35 +326,62 @@ registry.ginnoir.com {
|
|||||||
}
|
}
|
||||||
|
|
||||||
registry-ui.ginnoir.com {
|
registry-ui.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy registry_ui:80
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy registry_ui:80
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbx.ginnoir.com {
|
dbx.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy dbx:4224
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy dbx:4224
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vault.ginnoir.com {
|
vault.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy vault:8200
|
import authentik_outpost
|
||||||
|
@vaultapi path /v1/*
|
||||||
|
handle @vaultapi {
|
||||||
|
reverse_proxy vault:8200
|
||||||
|
}
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy vault:8200
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
docs.ginnoir.com {
|
docs.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
reverse_proxy bookstack:80
|
import authentik_outpost
|
||||||
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy bookstack:80
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plane.ginnoir.com {
|
plane.ginnoir.com {
|
||||||
import internal_only
|
route {
|
||||||
handle /api/* {
|
import authentik_outpost
|
||||||
reverse_proxy plane_api:8000
|
handle /api/* {
|
||||||
}
|
reverse_proxy plane_api:8000
|
||||||
handle /auth/* {
|
}
|
||||||
reverse_proxy plane_api:8000
|
handle /auth/* {
|
||||||
}
|
reverse_proxy plane_api:8000
|
||||||
handle {
|
}
|
||||||
reverse_proxy plane_web:3000
|
handle {
|
||||||
|
import authentik_forward_auth
|
||||||
|
reverse_proxy plane_web:3000
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# TB-006 — Authentik on admin UIs
|
# TB-006 — Authentik SSO at the edge
|
||||||
|
|
||||||
**Status:** not started
|
**Status:** batch 1 deployed (2026-06-10) — admin sites live; batches 2–3 pending
|
||||||
**Your call:** _(unset — talk first)_
|
**Your call:** **Tweak → Do it** (2026-06-10)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -10,15 +10,34 @@
|
|||||||
> **Stop.** Don't read Reference until we've talked.
|
> **Stop.** Don't read Reference until we've talked.
|
||||||
> In chat, say **"let's do TB-006"** or **"authentik on admin uis"**.
|
> In chat, say **"let's do TB-006"** or **"authentik on admin uis"**.
|
||||||
|
|
||||||
**In one sentence:** Require Authentik login before Portainer, code-server, registry, etc.
|
**In one sentence:** Every site that already shows its own login screen should authenticate through Authentik instead — without breaking webhooks, API keys, or Overseerr/Plex for friends.
|
||||||
|
|
||||||
**Why it came up:** LAN-only IP checks aren't the same as identity — Authentik is already running for famapp.
|
**Why it came up:** LAN-only IP checks aren't the same as identity — Authentik is already running for famapp.
|
||||||
|
|
||||||
### Questions
|
### Scope (decided 2026-06-10)
|
||||||
|
|
||||||
1. Which admin sites do you actually use? (No point gating ones you never open)
|
**In:** All Caddy-proxied sites with an app login UI → Caddy `forward_auth` to Authentik (or keep native OIDC where already wired, e.g. famapp).
|
||||||
2. Portainer git webhooks must keep working — okay to test carefully?
|
|
||||||
3. Do this for everything internal, or just the scary ones (Portainer, code, vault)?
|
**Out / untouched:**
|
||||||
|
|
||||||
|
- **Overseerr** (`requests.ginnoir.com`) — friends use Plex accounts; leave as-is.
|
||||||
|
- **Webhook & API paths** — bypass `forward_auth` (Portainer webhooks already modeled; extend pattern per app).
|
||||||
|
- **Static / no login** — 5etools, pf2e, ffttsystems, romhacks wiki files, etc.
|
||||||
|
|
||||||
|
**Explicitly out (confirmed):**
|
||||||
|
|
||||||
|
- **Obsidian/CouchDB** — tailnet-only (TB-005); LiveSync stays on CouchDB basic auth.
|
||||||
|
- **Foundry / Foundry2** — players use Foundry accounts; no Authentik.
|
||||||
|
- **Overseerr** — Plex login for friends.
|
||||||
|
|
||||||
|
**Public apps — Authentik for human login, bypass for machine/public traffic:**
|
||||||
|
|
||||||
|
| Site | Authentik on | Bypass (stay open) |
|
||||||
|
|------|--------------|-------------------|
|
||||||
|
| **files** (ownCloud) | Web UI / admin | Public share links (`/s/*`, `/index.php/s/*`); WebDAV if used by clients |
|
||||||
|
| **freshrss** | Web UI | Feed cron is in-container (no bypass needed); Reader/Fever/Google API paths use API password |
|
||||||
|
| **ntfy** | Web UI / account mgmt | Topic publish/subscribe (`POST`/`GET` topic paths, `/v1/*`); Vigilant + famapp push must keep working |
|
||||||
|
| **resume** | Builder / dashboard / login | Public resume pages (e.g. `/ginnoir/resume`); MinIO object GETs on `storage.j-costa.com` if public |
|
||||||
|
|
||||||
### Your options
|
### Your options
|
||||||
|
|
||||||
@@ -33,9 +52,9 @@
|
|||||||
|
|
||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| **Decision** | |
|
| **Decision** | Do it — batch 1 admin deployed; batches 2–3 pending |
|
||||||
| **Notes** | |
|
| **Notes** | Out: obsidian, foundry×2, overseerr. Batch 1: 12 admin sites + Caddy forward_auth + Authentik proxy providers. Push repo to persist authentik compose/blueprint changes. |
|
||||||
| **Date** | |
|
| **Date** | 2026-06-10 (batch 1 deployed) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -48,13 +67,31 @@ Caddyfile + Authentik UI
|
|||||||
|
|
||||||
### If we do it — rough steps
|
### If we do it — rough steps
|
||||||
|
|
||||||
1. Authentik proxy provider + outpost
|
1. Authentik embedded outpost + proxy provider(s) on `edge`
|
||||||
2. Caddy forward_auth snippet
|
2. Caddy `(authentik_auth)` snippet — `forward_auth authentik-server:9000` with trusted headers
|
||||||
3. Tier 1: portainer, code, registry-ui, vault, minio console
|
3. Roll out site-by-site; per-site `handle` bypasses for webhooks/API (`/api/*` where key-auth, Portainer `/api/stacks/webhooks/*`, Gitea hooks, ntfy publish, etc.)
|
||||||
|
4. Disable or bypass redundant in-app login where the app supports it (optional second pass)
|
||||||
|
|
||||||
|
**Rollout batches**
|
||||||
|
|
||||||
|
| Batch | Sites |
|
||||||
|
|-------|-------|
|
||||||
|
| 1 — Admin | portainer, code, registry-ui, vault, minio, homarr, uptime, backup/kopia, gitea, dbx, bookstack, plane |
|
||||||
|
| 2 — Media | sonarr, radarr, bazarr, prowlarr, tautulli, qbit, deluge, nzbget, whisparr, stash |
|
||||||
|
| 3 — Public + login | files, freshrss, ntfy, resume (with bypass tables above) |
|
||||||
|
| 4 — Other internal | romm, router UI |
|
||||||
|
| Skip | famapp (OIDC done), auth.ginnoir.com, overseerr, obsidian, foundry×2, static sites |
|
||||||
|
|
||||||
### Done when
|
### Done when
|
||||||
|
|
||||||
- [ ] Tier 1 sites require login
|
- [x] Batch 1 admin sites require Authentik before app UI loads
|
||||||
- [ ] Portainer webhooks still work
|
- [x] Portainer git webhooks still work (bypass path)
|
||||||
|
- [x] Gitea `/api/*` + `.git` and Vault `/v1/*` bypass forward_auth
|
||||||
|
- [ ] Batch 2 media sites
|
||||||
|
- [ ] Batch 3 public apps (ownCloud shares, FreshRSS, ntfy, resume)
|
||||||
|
- [ ] ownCloud share links work without Authentik session
|
||||||
|
- [ ] FreshRSS still refreshes feeds; Vigilant/famapp still publish to ntfy
|
||||||
|
- [ ] Public resume pages still viewable without Authentik
|
||||||
|
- [ ] Overseerr unchanged for Plex friends
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -0,0 +1,353 @@
|
|||||||
|
# yaml-language-server: $schema=https://goauthentik.io/blueprints/schema.json
|
||||||
|
# TB-006 batch 1 — forward-auth proxy providers for admin *.ginnoir.com sites.
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: Homelab forward auth — admin batch 1
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
|
||||||
|
entries:
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-portainer
|
||||||
|
attrs:
|
||||||
|
name: homelab-portainer
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://portainer.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: portainer
|
||||||
|
attrs:
|
||||||
|
name: Portainer
|
||||||
|
slug: portainer
|
||||||
|
meta_launch_url: https://portainer.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-portainer]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-code
|
||||||
|
attrs:
|
||||||
|
name: homelab-code
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://code.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: code
|
||||||
|
attrs:
|
||||||
|
name: code-server
|
||||||
|
slug: code
|
||||||
|
meta_launch_url: https://code.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-code]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-registry-ui
|
||||||
|
attrs:
|
||||||
|
name: homelab-registry-ui
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://registry-ui.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: registry-ui
|
||||||
|
attrs:
|
||||||
|
name: Registry UI
|
||||||
|
slug: registry-ui
|
||||||
|
meta_launch_url: https://registry-ui.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-registry-ui]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-vault
|
||||||
|
attrs:
|
||||||
|
name: homelab-vault
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://vault.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: vault
|
||||||
|
attrs:
|
||||||
|
name: Vault
|
||||||
|
slug: vault
|
||||||
|
meta_launch_url: https://vault.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-vault]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-minio
|
||||||
|
attrs:
|
||||||
|
name: homelab-minio
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://minio.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: minio
|
||||||
|
attrs:
|
||||||
|
name: MinIO Console
|
||||||
|
slug: minio
|
||||||
|
meta_launch_url: https://minio.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-minio]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-homarr
|
||||||
|
attrs:
|
||||||
|
name: homelab-homarr
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://homarr.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: homarr
|
||||||
|
attrs:
|
||||||
|
name: Homarr
|
||||||
|
slug: homarr
|
||||||
|
meta_launch_url: https://homarr.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-homarr]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-uptime
|
||||||
|
attrs:
|
||||||
|
name: homelab-uptime
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://uptime.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: uptime
|
||||||
|
attrs:
|
||||||
|
name: Uptime Kuma
|
||||||
|
slug: uptime
|
||||||
|
meta_launch_url: https://uptime.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-uptime]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-backup
|
||||||
|
attrs:
|
||||||
|
name: homelab-backup
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://backup.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: backup
|
||||||
|
attrs:
|
||||||
|
name: Kopia
|
||||||
|
slug: backup
|
||||||
|
meta_launch_url: https://backup.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-backup]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-gitea
|
||||||
|
attrs:
|
||||||
|
name: homelab-gitea
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://gitea.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: gitea
|
||||||
|
attrs:
|
||||||
|
name: Gitea
|
||||||
|
slug: gitea
|
||||||
|
meta_launch_url: https://gitea.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-gitea]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-dbx
|
||||||
|
attrs:
|
||||||
|
name: homelab-dbx
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://dbx.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: dbx
|
||||||
|
attrs:
|
||||||
|
name: DBX
|
||||||
|
slug: dbx
|
||||||
|
meta_launch_url: https://dbx.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-dbx]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-bookstack
|
||||||
|
attrs:
|
||||||
|
name: homelab-bookstack
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://docs.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: bookstack
|
||||||
|
attrs:
|
||||||
|
name: BookStack
|
||||||
|
slug: bookstack
|
||||||
|
meta_launch_url: https://docs.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-bookstack]]
|
||||||
|
|
||||||
|
- model: authentik_providers_proxy.proxyprovider
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: homelab-plane
|
||||||
|
attrs:
|
||||||
|
name: homelab-plane
|
||||||
|
mode: forward_single
|
||||||
|
external_host: https://plane.ginnoir.com
|
||||||
|
access_token_validity: hours=24
|
||||||
|
token_validity: hours=24
|
||||||
|
refresh_token_validity: days=30
|
||||||
|
intercept_header_auth: true
|
||||||
|
internal_host_ssl_validation: true
|
||||||
|
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||||
|
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
- model: authentik_core.application
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
slug: plane
|
||||||
|
attrs:
|
||||||
|
name: Plane
|
||||||
|
slug: plane
|
||||||
|
meta_launch_url: https://plane.ginnoir.com
|
||||||
|
policy_engine_mode: any
|
||||||
|
provider: !Find [authentik_providers_proxy.proxyprovider, [name, homelab-plane]]
|
||||||
|
|
||||||
|
- model: authentik_outposts.outpost
|
||||||
|
state: present
|
||||||
|
identifiers:
|
||||||
|
name: authentik Embedded Outpost
|
||||||
|
attrs:
|
||||||
|
name: authentik Embedded Outpost
|
||||||
|
type: proxy
|
||||||
|
providers:
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-portainer]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-code]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-registry-ui]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-vault]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-minio]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-homarr]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-uptime]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-backup]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-gitea]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-dbx]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-bookstack]]
|
||||||
|
- !Find [authentik_providers_proxy.proxyprovider, [name, homelab-plane]]
|
||||||
@@ -15,9 +15,12 @@ services:
|
|||||||
env_file:
|
env_file:
|
||||||
- stack.env
|
- stack.env
|
||||||
environment:
|
environment:
|
||||||
|
AUTHENTIK_HOST: https://auth.ginnoir.com
|
||||||
AUTHENTIK_REDIS__HOST: authentik-redis
|
AUTHENTIK_REDIS__HOST: authentik-redis
|
||||||
AUTHENTIK_POSTGRESQL__HOST: authentik-db
|
AUTHENTIK_POSTGRESQL__HOST: authentik-db
|
||||||
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
|
AUTHENTIK_ERROR_REPORTING__ENABLED: "false"
|
||||||
|
volumes:
|
||||||
|
- ./blueprints:/blueprints/custom:ro
|
||||||
ports:
|
ports:
|
||||||
- "9200:9000"
|
- "9200:9000"
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Apply TB-006 batch 1 proxy providers via authentik ORM (run: ak shell < script)."""
|
||||||
|
from authentik.core.models import Application
|
||||||
|
from authentik.flows.models import Flow
|
||||||
|
from authentik.outposts.models import Outpost, OutpostType
|
||||||
|
from authentik.providers.proxy.models import ProxyMode, ProxyProvider
|
||||||
|
|
||||||
|
AUTHZ = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
|
||||||
|
INVALID = Flow.objects.get(slug="default-provider-invalidation-flow")
|
||||||
|
|
||||||
|
SITES = [
|
||||||
|
("homelab-portainer", "portainer", "Portainer", "https://portainer.ginnoir.com"),
|
||||||
|
("homelab-code", "code", "code-server", "https://code.ginnoir.com"),
|
||||||
|
("homelab-registry-ui", "registry-ui", "Registry UI", "https://registry-ui.ginnoir.com"),
|
||||||
|
("homelab-vault", "vault", "Vault", "https://vault.ginnoir.com"),
|
||||||
|
("homelab-minio", "minio", "MinIO Console", "https://minio.ginnoir.com"),
|
||||||
|
("homelab-homarr", "homarr", "Homarr", "https://homarr.ginnoir.com"),
|
||||||
|
("homelab-uptime", "uptime", "Uptime Kuma", "https://uptime.ginnoir.com"),
|
||||||
|
("homelab-backup", "backup", "Kopia", "https://backup.ginnoir.com"),
|
||||||
|
("homelab-gitea", "gitea", "Gitea", "https://gitea.ginnoir.com"),
|
||||||
|
("homelab-dbx", "dbx", "DBX", "https://dbx.ginnoir.com"),
|
||||||
|
("homelab-bookstack", "bookstack", "BookStack", "https://docs.ginnoir.com"),
|
||||||
|
("homelab-plane", "plane", "Plane", "https://plane.ginnoir.com"),
|
||||||
|
]
|
||||||
|
|
||||||
|
providers = []
|
||||||
|
for pname, slug, aname, host in SITES:
|
||||||
|
provider, _ = ProxyProvider.objects.update_or_create(
|
||||||
|
name=pname,
|
||||||
|
defaults={
|
||||||
|
"mode": ProxyMode.FORWARD_SINGLE,
|
||||||
|
"external_host": host,
|
||||||
|
"authorization_flow": AUTHZ,
|
||||||
|
"invalidation_flow": INVALID,
|
||||||
|
"intercept_header_auth": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
Application.objects.update_or_create(
|
||||||
|
slug=slug,
|
||||||
|
defaults={
|
||||||
|
"name": aname,
|
||||||
|
"provider": provider,
|
||||||
|
"meta_launch_url": host,
|
||||||
|
"policy_engine_mode": "any",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
providers.append(provider)
|
||||||
|
print(f"ok {slug} -> {host}")
|
||||||
|
|
||||||
|
outpost = Outpost.objects.get(name="authentik Embedded Outpost")
|
||||||
|
outpost.type = OutpostType.PROXY
|
||||||
|
outpost.providers.set(providers)
|
||||||
|
outpost.save()
|
||||||
|
print(f"outpost providers: {outpost.providers.count()}")
|
||||||
@@ -25,9 +25,9 @@ services:
|
|||||||
- "7575:7575"
|
- "7575:7575"
|
||||||
volumes:
|
volumes:
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
- /config/homarr/configs:/app/data/configs
|
# homarr-labs stores SQLite + redis under /appdata (not /data or /app/data/configs).
|
||||||
|
- /config/homarr/appdata:/appdata
|
||||||
- /config/homarr/icons:/app/public/icons
|
- /config/homarr/icons:/app/public/icons
|
||||||
- /config/homarr/data:/data
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
edge:
|
edge:
|
||||||
|
|||||||
Reference in New Issue
Block a user