infra/ingress_factory: add auth = "app" mode for self-authed backends
Adds a fourth auth tier alongside required/public/none. "app" is
functionally identical to "none" — no Authentik middleware attached —
but the distinct name records intent at the call site: this backend
has its own user login (NextAuth, Django, OAuth, bearer-token API,
etc.) and Authentik would only break it.
Why the new tier: with only required/none, every "the app has its
own auth so drop Authentik" decision looked identical at the call
site to "this is an OAuth callback / webhook receiver / native-client
API". Future readers couldn't tell whether a stack was intentionally
unauthenticated or relying on backend auth. Now they can.
Migrates the 8 stacks flipped earlier this session (novelapp, immich,
linkwarden, tandoor, freshrss, affine, actualbudget, ebooks/audiobookshelf)
from "none" to "app". Confirmed no-op: `tg plan` on novelapp showed
"No changes" — same middleware chain, same live state.
The variable description and the .claude/CLAUDE.md Auth section now
spell out the anti-exposure rule: only pick "app" or "none" AFTER
verifying the app has its own user auth ("app") or the endpoint is
intentionally public ("none"). Default stays "required" so accidental
omission fails closed.
[ci skip]
This commit is contained in:
parent
dafd7a18bc
commit
459b00fa74
10 changed files with 73 additions and 37 deletions
|
|
@ -156,10 +156,10 @@ resource "kubernetes_service" "actualbudget" {
|
|||
|
||||
module "ingress" {
|
||||
source = "../../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": Actual Budget enforces a server password + per-user login
|
||||
# auth = "app": Actual Budget enforces a server password + per-user login
|
||||
# on its own sync API. Authentik forward-auth was 302-ing the mobile/web
|
||||
# sync clients; Actual's own auth gates users.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
namespace = "actualbudget"
|
||||
name = "budget-${var.name}"
|
||||
tls_secret_name = var.tls_secret_name
|
||||
|
|
|
|||
|
|
@ -359,10 +359,10 @@ resource "kubernetes_service" "affine" {
|
|||
|
||||
module "ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": AFFiNE has its own workspace auth + bearer-token API
|
||||
# auth = "app": AFFiNE has its own workspace auth + bearer-token API
|
||||
# used by desktop/mobile sync clients. Authentik forward-auth was 302-ing
|
||||
# those API callers; AFFiNE's own auth gates users.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
dns_type = "non-proxied"
|
||||
namespace = kubernetes_namespace.affine.metadata[0].name
|
||||
name = "affine"
|
||||
|
|
|
|||
|
|
@ -662,10 +662,10 @@ resource "kubernetes_service" "audiobookshelf" {
|
|||
|
||||
module "audiobookshelf_ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": Audiobookshelf has its own user/password login + API
|
||||
# auth = "app": Audiobookshelf has its own user/password login + API
|
||||
# tokens used by the iOS/Android Audiobookshelf app. Authentik forward-auth
|
||||
# was 302-ing the mobile clients; ABS's own auth gates users.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
dns_type = "non-proxied"
|
||||
namespace = kubernetes_namespace.ebooks.metadata[0].name
|
||||
name = "audiobookshelf"
|
||||
|
|
|
|||
|
|
@ -229,10 +229,10 @@ resource "kubernetes_service" "freshrss" {
|
|||
}
|
||||
module "ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": FreshRSS has built-in user login and exposes Fever +
|
||||
# auth = "app": FreshRSS has built-in user login and exposes Fever +
|
||||
# GReader APIs (/api/fever.php, /api/greader.php) used by mobile RSS
|
||||
# readers like Reeder/FeedMe. Authentik forward-auth was 302-ing those.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
dns_type = "proxied"
|
||||
namespace = "freshrss"
|
||||
name = "rss"
|
||||
|
|
|
|||
|
|
@ -738,10 +738,10 @@ resource "kubernetes_service" "immich-machine-learning" {
|
|||
|
||||
module "ingress-immich" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": Immich has its own user auth + bearer-token API. Authentik
|
||||
# auth = "app": Immich has its own user auth + bearer-token API. Authentik
|
||||
# forward-auth on `/api/*` was 302-ing the iOS/Android Immich app and any
|
||||
# external API consumer. App-level auth is the gate now.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
dns_type = "non-proxied"
|
||||
namespace = kubernetes_namespace.immich.metadata[0].name
|
||||
name = "immich"
|
||||
|
|
|
|||
|
|
@ -229,10 +229,10 @@ resource "kubernetes_service" "linkwarden" {
|
|||
|
||||
module "ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": Linkwarden uses NextAuth (NEXTAUTH_SECRET/URL set above)
|
||||
# auth = "app": Linkwarden uses NextAuth (NEXTAUTH_SECRET/URL set above)
|
||||
# and exposes /api/* for its mobile clients. Authentik forward-auth would
|
||||
# 302 those callers; app-level NextAuth gates users.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
dns_type = "proxied"
|
||||
namespace = kubernetes_namespace.linkwarden.metadata[0].name
|
||||
name = "linkwarden"
|
||||
|
|
|
|||
|
|
@ -224,11 +224,11 @@ resource "kubernetes_service" "novelapp" {
|
|||
|
||||
module "ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": novelapp handles its own auth via NextAuth + Google OAuth
|
||||
# auth = "app": novelapp handles its own auth via NextAuth + Google OAuth
|
||||
# (AUTH_URL/AUTH_SECRET/GOOGLE_CLIENT_{ID,SECRET} env vars above). Putting
|
||||
# Authentik forward-auth in front double-gates the app and breaks iOS/Android
|
||||
# webview clients that can't complete the Authentik 302/cookie dance.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
dns_type = "non-proxied"
|
||||
namespace = kubernetes_namespace.novelapp.metadata[0].name
|
||||
name = "novelapp"
|
||||
|
|
|
|||
|
|
@ -259,10 +259,10 @@ resource "kubernetes_service" "tandoor" {
|
|||
|
||||
module "ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": Tandoor uses Django auth (SECRET_KEY set above) and exposes
|
||||
# auth = "app": Tandoor uses Django auth (SECRET_KEY set above) and exposes
|
||||
# /api/* with token auth for its mobile clients. Authentik forward-auth was
|
||||
# 302-ing those callers; Django session/token auth gates users.
|
||||
auth = "none"
|
||||
auth = "app"
|
||||
dns_type = "proxied"
|
||||
namespace = kubernetes_namespace.tandoor.metadata[0].name
|
||||
name = "tandoor"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue