Sweep through the 30+ stacks that predated the auth = "app" tier and were tagged auth = "none" without a comment explaining why they weren't behind Authentik. Each is now self-documenting at the call site, so the tg-level anti-exposure guard passes and future readers don't have to reverse-engineer the intent. Flipped 6 stacks from "none" to "app" — their backends have their own user auth and the new tier records that more accurately: - navidrome (Subsonic user/password) - ntfy (deny-all default + user.db tokens) - nextcloud (WebDAV/CalDAV/CardDAV app passwords) - vaultwarden (Bitwarden-compatible token auth) - headscale (OIDC + preauth keys for Tailscale nodes) - paperless-ngx (app-layer login + API tokens) Kept "none" with a comment on the rest — they're genuinely public, webhook receivers, native-protocol endpoints, OAuth callbacks, or Anubis-fronted: authentik (×2 + guest outpost), beads-server (dolt), claude-memory (bearer-token MCP), dawarich, ebooks/book-search-api, fire-planner /api, forgejo (git/OCI native clients), frigate (HA integration), immich/frame, insta2spotify /api, instagram-poster (meta fetcher), k8s-portal, matrix (native bearer), monitoring×2 (HA REST scrapes), n8n (webhooks), nvidia, onlyoffice (JWT), owntracks (HTTP Basic), postiz, privatebin (client-side enc), rybbit (analytics tracker), send (E2E file drop), tuya-bridge (API key), vault (own auth + CLI), webhook_handler, woodpecker (forgejo webhooks + OAuth), xray (×3 VPN transports). real-estate-crawler/main.tf:400 already had its comment from a prior edit — not touched here. No live state changes — auth = "app" produces the same middleware chain as auth = "none" (verified earlier this session). This commit is purely documentation + intent-tagging.
112 lines
3.8 KiB
HCL
112 lines
3.8 KiB
HCL
variable "tls_secret_name" {}
|
|
variable "secret_key" {}
|
|
variable "postgres_password" {}
|
|
variable "tier" { type = string }
|
|
variable "redis_host" { type = string }
|
|
variable "homepage_token" {
|
|
type = string
|
|
default = ""
|
|
sensitive = true
|
|
}
|
|
|
|
|
|
module "tls_secret" {
|
|
source = "../../../../modules/kubernetes/setup_tls_secret"
|
|
namespace = kubernetes_namespace.authentik.metadata[0].name
|
|
tls_secret_name = var.tls_secret_name
|
|
}
|
|
|
|
# The embedded outpost auto-creates an ingress expecting this secret name
|
|
module "tls_secret_outpost" {
|
|
source = "../../../../modules/kubernetes/setup_tls_secret"
|
|
namespace = kubernetes_namespace.authentik.metadata[0].name
|
|
tls_secret_name = "authentik-outpost-tls"
|
|
}
|
|
|
|
resource "kubernetes_namespace" "authentik" {
|
|
metadata {
|
|
name = "authentik"
|
|
labels = {
|
|
tier = var.tier
|
|
"resource-governance/custom-quota" = "true"
|
|
}
|
|
}
|
|
lifecycle {
|
|
# KYVERNO_LIFECYCLE_V1: goldilocks-vpa-auto-mode ClusterPolicy stamps this label on every namespace
|
|
ignore_changes = [metadata[0].labels["goldilocks.fairwinds.com/vpa-update-mode"]]
|
|
}
|
|
}
|
|
|
|
resource "kubernetes_resource_quota" "authentik" {
|
|
metadata {
|
|
name = "authentik-quota"
|
|
namespace = kubernetes_namespace.authentik.metadata[0].name
|
|
}
|
|
spec {
|
|
hard = {
|
|
"requests.cpu" = "16"
|
|
"requests.memory" = "16Gi"
|
|
"limits.memory" = "96Gi"
|
|
pods = "50"
|
|
}
|
|
}
|
|
}
|
|
|
|
resource "helm_release" "authentik" {
|
|
namespace = kubernetes_namespace.authentik.metadata[0].name
|
|
create_namespace = true
|
|
name = "goauthentik"
|
|
|
|
repository = "https://charts.goauthentik.io/"
|
|
chart = "authentik"
|
|
# version = "2025.10.3"
|
|
# version = "2025.12.4"
|
|
version = "2026.2.2"
|
|
atomic = true
|
|
timeout = 6000
|
|
|
|
values = [templatefile("${path.module}/values.yaml", { postgres_password = var.postgres_password, secret_key = var.secret_key })]
|
|
}
|
|
|
|
|
|
module "ingress" {
|
|
source = "../../../../modules/kubernetes/ingress_factory"
|
|
# Authentik's own UI cannot be gated by Authentik forward-auth — that
|
|
# creates a chicken-and-egg loop (users can't reach the login page).
|
|
# auth = "none": Authentik UI cannot be gated by Authentik forward-auth (chicken-and-egg loop prevents login).
|
|
auth = "none"
|
|
dns_type = "proxied"
|
|
namespace = kubernetes_namespace.authentik.metadata[0].name
|
|
name = "authentik"
|
|
service_name = "goauthentik-server"
|
|
tls_secret_name = var.tls_secret_name
|
|
anti_ai_scraping = false
|
|
extra_annotations = {
|
|
"gethomepage.dev/enabled" = "true"
|
|
"gethomepage.dev/name" = "Authentik"
|
|
"gethomepage.dev/description" = "Identity provider"
|
|
"gethomepage.dev/icon" = "authentik.png"
|
|
"gethomepage.dev/group" = "Identity & Security"
|
|
"gethomepage.dev/pod-selector" = ""
|
|
"gethomepage.dev/widget.type" = "authentik"
|
|
"gethomepage.dev/widget.url" = "http://goauthentik-server.authentik.svc.cluster.local"
|
|
"gethomepage.dev/widget.key" = var.homepage_token
|
|
}
|
|
}
|
|
|
|
module "ingress-outpost" {
|
|
source = "../../../../modules/kubernetes/ingress_factory"
|
|
# Authentik forward-auth outpost callback path — protecting this with
|
|
# forward-auth would loop the outpost back onto itself.
|
|
# auth = "none": Authentik outpost callback path for forward-auth flow; protecting with forward-auth creates circular dependency.
|
|
auth = "none"
|
|
namespace = kubernetes_namespace.authentik.metadata[0].name
|
|
name = "authentik-outpost"
|
|
host = "authentik"
|
|
service_name = "ak-outpost-authentik-embedded-outpost"
|
|
port = 9000
|
|
ingress_path = ["/outpost.goauthentik.io"]
|
|
tls_secret_name = var.tls_secret_name
|
|
anti_ai_scraping = false
|
|
exclude_crowdsec = true
|
|
}
|