Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aac2599e5f | ||
|
|
45ca838f22 |
@@ -25,20 +25,13 @@ data:
|
||||
attrs:
|
||||
local: true
|
||||
|
||||
# Retired OIDC layer. Paperless's URL-level access is gated by the
|
||||
# paperless-gate ProxyProvider (below); user identity is forwarded
|
||||
# from the gate to paperless via the X-authentik-* request headers
|
||||
# and consumed by paperless via PAPERLESS_ENABLE_HTTP_REMOTE_USER
|
||||
# (see kubernetes/apps/paperless/paperless.yaml). One Authentik
|
||||
# Application, one Provider — the dual-OAuth2-flow setup with a
|
||||
# separate paperless OIDC client + django-allauth callback was
|
||||
# structurally fine but added a second consent screen on first
|
||||
# login for no real defense-in-depth gain.
|
||||
# Retired OIDC layer. Access is gated by the paperless-gate
|
||||
# ProxyProvider below, which forwards identity as X-authentik-* headers
|
||||
# consumed via PAPERLESS_ENABLE_HTTP_REMOTE_USER.
|
||||
#
|
||||
# Order matters: delete the Application BEFORE the OAuth2Provider
|
||||
# because Application.provider is on_delete=PROTECT, so the
|
||||
# OAuth2Provider can't be removed while the Application still
|
||||
# references it.
|
||||
# ORDER MATTERS: delete the Application BEFORE the OAuth2Provider.
|
||||
# Application.provider is on_delete=PROTECT, so the provider cannot be
|
||||
# removed while an Application still references it.
|
||||
- model: authentik_core.application
|
||||
identifiers:
|
||||
slug: paperless
|
||||
@@ -49,22 +42,15 @@ data:
|
||||
name: Paperless
|
||||
state: absent
|
||||
|
||||
# Also clean up the very-early orphan `paperless` ProxyProvider
|
||||
# left behind from this session's first attempts. It's not bound
|
||||
# to anything any more, just leftover state in the DB.
|
||||
# Orphan ProxyProvider, unbound — leftover DB state.
|
||||
- model: authentik_providers_proxy.proxyprovider
|
||||
identifiers:
|
||||
name: paperless
|
||||
state: absent
|
||||
|
||||
# Dedicated forward-auth gate for paperless. This is a SEPARATE
|
||||
# outpost (its own Deployment + Service `ak-outpost-paperless-
|
||||
# gate`) running in front of paperless so every request is
|
||||
# authenticated and authorized by Authentik before it reaches
|
||||
# paperless's own attack surface. The gate sits on top of, and
|
||||
# separate from, the OIDC OAuth2Provider above (which is what
|
||||
# paperless's django-allauth uses for SSO once a request makes
|
||||
# it through the gate).
|
||||
# Dedicated forward-auth gate for paperless: its own outpost
|
||||
# Deployment + Service, so every request is authenticated before it
|
||||
# reaches paperless.
|
||||
- id: paperless-gate-provider
|
||||
model: authentik_providers_proxy.proxyprovider
|
||||
identifiers:
|
||||
@@ -73,16 +59,13 @@ data:
|
||||
attrs:
|
||||
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
|
||||
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||
# Proxy (not forward_domain) so the outpost itself terminates
|
||||
# the request and forwards to paperless — moving the trust
|
||||
# boundary off ingress-nginx and onto paperless-gate. ingress-
|
||||
# nginx now only routes paperless.renner.uno to the outpost
|
||||
# service; it never talks to paperless directly. The outpost
|
||||
# is what populates X-Authentik-Username on the upstream
|
||||
# request, and the NetworkPolicy in the paperless namespace
|
||||
# only allows traffic to paperless from the gate outpost pod
|
||||
# itself, so ingress-nginx (or any other in-cluster workload)
|
||||
# cannot bypass the gate to inject headers.
|
||||
# Proxy, NOT forward_domain: the outpost terminates the request
|
||||
# itself, so the trust boundary sits here rather than at the ingress
|
||||
# controller, which only routes to the outpost Service and never
|
||||
# reaches paperless directly. The outpost populates
|
||||
# X-Authentik-Username, and the paperless NetworkPolicy admits
|
||||
# traffic only from this outpost — so nothing else in the cluster
|
||||
# can bypass the gate and inject those headers.
|
||||
mode: proxy
|
||||
internal_host: http://paperless.paperless.svc.cluster.local
|
||||
internal_host_ssl_validation: false
|
||||
@@ -91,19 +74,12 @@ data:
|
||||
access_token_validity: hours=24
|
||||
refresh_token_validity: days=30
|
||||
intercept_header_auth: true
|
||||
# Pass paperless's entire static-asset tree through anonymously.
|
||||
# Two reasons:
|
||||
# 1. <link rel="manifest"> is fetched with `credentials: 'omit'`
|
||||
# (W3C spec, no crossorigin attr) so the cookie is never sent
|
||||
# — every page load and every SPA navigation turned into a
|
||||
# 302 → auth.renner.uno round-trip with an orphan session JWT.
|
||||
# Same root cause as the retired music-assistant-gate (see
|
||||
# comment further below); paperless can't retire the gate so
|
||||
# it carves out the offending paths instead.
|
||||
# 2. Every CSS/JS/icon fetch otherwise validates the cookie at
|
||||
# the outpost — pure overhead on assets that carry no
|
||||
# authentication value. Django's STATIC tree is public by
|
||||
# design; MEDIA (under /api/documents/*) stays gated.
|
||||
# The static-asset tree passes anonymously, and must. A
|
||||
# <link rel="manifest"> is fetched with `credentials: 'omit'` per
|
||||
# the W3C spec, so the session cookie is never sent and every page
|
||||
# load turns into a redirect loop through the login origin. Django's
|
||||
# STATIC tree is public by design; MEDIA under /api/documents/*
|
||||
# stays gated.
|
||||
skip_path_regex: ^/static/.*
|
||||
|
||||
- model: authentik_core.application
|
||||
@@ -130,18 +106,14 @@ data:
|
||||
negate: false
|
||||
failure_result: false
|
||||
|
||||
# Retired: the music-assistant-gate ProxyProvider, Application,
|
||||
# and dedicated Outpost. The gate fundamentally conflicted with
|
||||
# MA's PWA model — Chrome fetches manifest.webmanifest / sw.js /
|
||||
# icons with `credentials: 'omit'` (per W3C spec, no crossorigin
|
||||
# attribute on MA's <link rel="manifest">), and the cached
|
||||
# service worker bypasses fresh navigations on PWA cold-start so
|
||||
# the Authentik cookie never lands in the WebAPK's cookie jar.
|
||||
# MA has its own auth (delegated to Home Assistant); the gate's
|
||||
# marginal value didn't justify the recurring breakage.
|
||||
# Order matters: Application before Provider before Outpost.
|
||||
# Application.provider is on_delete=PROTECT, so the Provider
|
||||
# can't be removed while the Application still references it.
|
||||
# Retired: the music-assistant gate. A forward-auth gate cannot work in
|
||||
# front of a PWA — the manifest and service worker are fetched with
|
||||
# `credentials: 'omit'`, and a cached service worker bypasses fresh
|
||||
# navigations, so the session cookie never reaches the installed app.
|
||||
# Do not reintroduce one there; MA delegates auth to Home Assistant.
|
||||
#
|
||||
# ORDER MATTERS: Application before Provider before Outpost, because
|
||||
# Application.provider is on_delete=PROTECT.
|
||||
- model: authentik_core.application
|
||||
identifiers:
|
||||
slug: music-assistant-gate
|
||||
@@ -157,18 +129,13 @@ data:
|
||||
name: music-assistant-gate
|
||||
state: absent
|
||||
|
||||
# Dedicated outpost: its ONLY job is to serve the in-cluster
|
||||
# /outpost.goauthentik.io/auth/nginx endpoint that nginx
|
||||
# auth_request hits for every request to paperless. The
|
||||
# browser-facing legs of the OAuth flow (/start, /callback, the
|
||||
# `/if/...` login UI, /application/o/authorize, /api, etc.) all
|
||||
# need to happen on auth.renner.uno because that's the origin
|
||||
# WebAuthn/FIDO/TOTP credentials are bound to. So we attach the
|
||||
# ProxyProvider to BOTH outposts (see embedded outpost below) and
|
||||
# set authentik_host_browser to auth.renner.uno here too — the
|
||||
# nginx auth_request happens server-to-server, but if the
|
||||
# dedicated outpost ever does emit a redirect URL, it points at
|
||||
# the right host.
|
||||
# Dedicated outpost, serving the in-cluster auth endpoint only.
|
||||
#
|
||||
# The browser-facing legs of the OAuth flow must happen on
|
||||
# auth.renner.uno, because that is the origin WebAuthn credentials are
|
||||
# bound to. Hence the ProxyProvider is attached to BOTH this outpost and
|
||||
# the embedded one, and authentik_host_browser points at auth.renner.uno
|
||||
# here too — so any redirect this outpost emits names the right host.
|
||||
- model: authentik_outposts.outpost
|
||||
identifiers:
|
||||
name: paperless-gate
|
||||
@@ -196,12 +163,7 @@ data:
|
||||
kubernetes_ingress_secret_name: "authentik-outpost-tls"
|
||||
kubernetes_json_patches: null
|
||||
|
||||
# Tear down the leftover paperless-proxy Application from an
|
||||
# earlier experiment. The orphan `paperless` ProxyProvider that
|
||||
# used to back paperless.app is left in place — it's PROTECTed
|
||||
# by Application.provider as long as anything references it, and
|
||||
# leftover orphans don't break anything. Delete via the Authentik
|
||||
# UI once everything's confirmed working.
|
||||
# Leftover Application from an earlier experiment.
|
||||
- model: authentik_policies.policybinding
|
||||
identifiers:
|
||||
target: !Find [authentik_core.application, [slug, paperless-proxy]]
|
||||
@@ -217,15 +179,11 @@ data:
|
||||
# ------------------------------------------------------------------
|
||||
# vscode config-editor gate
|
||||
#
|
||||
# code-server (the HA /config editor sidecar) runs with --auth=none,
|
||||
# as root, mounting the whole HA /config incl. plaintext secrets.yaml
|
||||
# and .storage. This gate moves it behind Authentik with a passkey
|
||||
# step-up, mirroring the paperless-gate proxy-outpost pattern above:
|
||||
# the dedicated ak-outpost-vscode-gate terminates the request,
|
||||
# enforces the session, and forwards to the code-server Service.
|
||||
# Traefik only ever routes vscode.home.renner.uno to the outpost; the
|
||||
# home-assistant CNP is tightened so ONLY the gate outpost may reach
|
||||
# :8080 (see home-assistant-ns.yaml + vscode-gate-egress.yaml).
|
||||
# code-server runs with --auth=none, as root, mounting the whole HA
|
||||
# /config including plaintext secrets.yaml and .storage. This gate is
|
||||
# the only thing in front of it: the outpost terminates the request and
|
||||
# enforces a passkey step-up, Traefik routes only to the outpost, and
|
||||
# the home-assistant CNP admits :8080 from the gate alone.
|
||||
# ------------------------------------------------------------------
|
||||
- id: vscode-config-editors-group
|
||||
model: authentik_core.group
|
||||
@@ -265,17 +223,14 @@ data:
|
||||
access_token_validity: hours=24
|
||||
refresh_token_validity: days=30
|
||||
intercept_header_auth: true
|
||||
# code-server is a service-worker app: <link rel="manifest"> and
|
||||
# the service worker are fetched with credentials:'omit', which
|
||||
# turned into a /authorize redirect loop and forced the RETIREMENT
|
||||
# of the music-assistant gate (see comment above). Carve its
|
||||
# static/manifest/SW tree out so those cookieless fetches pass
|
||||
# through instead of 302-looping; the editor's actual content
|
||||
# (the /config tree) is served over authenticated websocket/API
|
||||
# paths, which stay gated.
|
||||
# NOTE: the exact skip set is code-server-version-specific and
|
||||
# MUST be confirmed post-deploy against the real redirect-loop
|
||||
# behaviour (see the PR validation checklist).
|
||||
# code-server is a service-worker app, so its manifest and SW are
|
||||
# fetched with credentials:'omit' and 302-loop unless carved out.
|
||||
# The editor's actual content rides authenticated websocket/API
|
||||
# paths and stays gated.
|
||||
#
|
||||
# This skip set is version-specific: re-check it after a
|
||||
# code-server bump, because a renamed asset path reintroduces the
|
||||
# loop silently.
|
||||
skip_path_regex: ^/(_static/|manifest\.json|.*\.webmanifest|.*serviceWorker\.js).*
|
||||
|
||||
- model: authentik_core.application
|
||||
@@ -331,16 +286,11 @@ data:
|
||||
# ------------------------------------------------------------------
|
||||
# shelly-manager gate
|
||||
#
|
||||
# shelly-manager has no authentication of its own: anything that can
|
||||
# reach :8080 can rewrite Shelly device config, push scripts, and read
|
||||
# the stored per-device AdminPassword values. Until now the only
|
||||
# control was reachability of shelly-manager.home.renner.uno.
|
||||
#
|
||||
# Same shape as the vscode-gate above: a dedicated outpost terminates
|
||||
# the request, enforces a passkey step-up, and forwards to the
|
||||
# shelly-manager Service. Traefik only ever routes the hostname to the
|
||||
# outpost; the home-assistant CNP allows ONLY this outpost to reach
|
||||
# :8080 (see home-assistant-ns.yaml + shelly-manager-gate-egress.yaml).
|
||||
# shelly-manager has no authentication of its own: anything that reaches
|
||||
# :8080 can rewrite device config, push scripts and read the stored
|
||||
# per-device AdminPassword values. Same shape as the vscode gate — the
|
||||
# outpost is the only control, Traefik routes only to it, and the CNP
|
||||
# admits :8080 from this outpost alone.
|
||||
# ------------------------------------------------------------------
|
||||
- id: shelly-managers-group
|
||||
model: authentik_core.group
|
||||
|
||||
Reference in New Issue
Block a user