- Adopt UserLoginStage (default-authentication-login) into Terraform and pin session_duration=weeks=4 so users stay logged in across browser restarts. There is no Brand.session_duration in 2026.2.x; UserLoginStage is the only correct lever. - Cap anonymous Django sessions at 2h via AUTHENTIK_SESSIONS__UNAUTHENTICATED_AGE on server + worker pods (default is days=1). Bots, healthcheckers, and partial flows now get reaped within 2h instead of accumulating for a day. Implementation note: the env var is injected via server.env / worker.env rather than authentik.sessions.unauthenticated_age, because authentik.existingSecret.secretName is set, which makes the chart skip rendering its own AUTHENTIK_* Secret. authentik.* values are therefore inert in this stack -- this is documented in .claude/reference/authentik-state.md so future edits use the right surface. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
110 lines
3.2 KiB
YAML
110 lines
3.2 KiB
YAML
authentik:
|
||
log_level: warning
|
||
# log_level: trace
|
||
secret_key: ""
|
||
existingSecret:
|
||
secretName: "goauthentik"
|
||
# This sends anonymous usage-data, stack traces on errors and
|
||
# performance data to authentik.error-reporting.a7k.io, and is fully opt-in
|
||
error_reporting:
|
||
enabled: false
|
||
postgresql:
|
||
# host: postgresql.dbaas
|
||
host: pgbouncer.authentik
|
||
port: 6432
|
||
user: authentik
|
||
password: ""
|
||
# Persistent client-side connections (safe with PgBouncer session mode;
|
||
# must be < pgbouncer server_idle_timeout=600s). Cuts Django connection
|
||
# setup overhead off the ~70 sequential ORM ops per flow stage.
|
||
conn_max_age: 60
|
||
conn_health_checks: true
|
||
cache:
|
||
# Cache flow plans for 30m and policy evaluations for 15m. Authentik 2026.2
|
||
# moved cache storage from Redis to Postgres, so a TTL hit is still a
|
||
# SELECT — but a single indexed lookup beats re-evaluating PolicyBindings.
|
||
timeout_flows: 1800
|
||
timeout_policies: 900
|
||
web:
|
||
# Gunicorn: 3 workers × 4 threads per server pod (default 2×4).
|
||
# Pairs with the server memory bump to 2Gi (each worker preloads Django ~500Mi).
|
||
workers: 3
|
||
threads: 4
|
||
worker:
|
||
# Celery-equivalent worker threads per pod (default 2, renamed from
|
||
# AUTHENTIK_WORKER__CONCURRENCY in 2025.8).
|
||
threads: 4
|
||
|
||
server:
|
||
replicas: 3
|
||
# Anonymous Django sessions (no completed login: bots, healthcheckers,
|
||
# partial flows) expire in 2h. Default is days=1. Once login completes,
|
||
# UserLoginStage.session_duration takes over via request.session.set_expiry.
|
||
# Injected via server.env (not authentik.sessions.*) because we use
|
||
# authentik.existingSecret.secretName, which makes the chart skip
|
||
# rendering the AUTHENTIK_* secret — so the values block doesn't reach env.
|
||
env:
|
||
- name: AUTHENTIK_SESSIONS__UNAUTHENTICATED_AGE
|
||
value: "hours=2"
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
maxSurge: 0
|
||
maxUnavailable: 1
|
||
resources:
|
||
requests:
|
||
cpu: 100m
|
||
memory: 1.5Gi
|
||
limits:
|
||
memory: 2Gi
|
||
topologySpreadConstraints:
|
||
- maxSkew: 1
|
||
topologyKey: kubernetes.io/hostname
|
||
whenUnsatisfiable: ScheduleAnyway
|
||
labelSelector:
|
||
matchLabels:
|
||
app.kubernetes.io/component: server
|
||
ingress:
|
||
enabled: false
|
||
# hosts:
|
||
# - authentik.viktorbarzin.me
|
||
podAnnotations:
|
||
diun.enable: true
|
||
diun.include_tags: "^202[0-9].[0-9]+.*$" # no need to annotate the worker as it uses the same image
|
||
pdb:
|
||
enabled: true
|
||
minAvailable: 2
|
||
global:
|
||
addPrometheusAnnotations: true
|
||
|
||
worker:
|
||
replicas: 3
|
||
# Same unauthenticated_age cap as server — both the server (Django session
|
||
# middleware) and worker (cleanup tasks) need to see the value.
|
||
env:
|
||
- name: AUTHENTIK_SESSIONS__UNAUTHENTICATED_AGE
|
||
value: "hours=2"
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
maxSurge: 0
|
||
maxUnavailable: 1
|
||
resources:
|
||
requests:
|
||
cpu: 100m
|
||
memory: 1.5Gi
|
||
limits:
|
||
memory: 2Gi
|
||
topologySpreadConstraints:
|
||
- maxSkew: 1
|
||
topologyKey: kubernetes.io/hostname
|
||
whenUnsatisfiable: ScheduleAnyway
|
||
labelSelector:
|
||
matchLabels:
|
||
app.kubernetes.io/component: worker
|
||
pdb:
|
||
enabled: true
|
||
maxUnavailable: 1
|
||
|
||
postgresql:
|
||
enabled: false
|