authentik: long-lived authenticated sessions, short-lived anonymous ones
- 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>
This commit is contained in:
parent
dfbf6faf3d
commit
40a6cd067b
3 changed files with 60 additions and 0 deletions
|
|
@ -57,3 +57,34 @@ resource "authentik_provider_proxy" "catchall" {
|
|||
ignore_changes = [property_mappings, jwt_federation_sources, skip_path_regex, internal_host, basic_auth_enabled, basic_auth_password_attribute, basic_auth_username_attribute, intercept_header_auth, access_token_validity]
|
||||
}
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Default User Login stage — bound to default-authentication-flow.
|
||||
# Adopted into Terraform 2026-05-01 to set session_duration=weeks=4 so users
|
||||
# stay logged in across browser restarts. There is no Brand.session_duration
|
||||
# in authentik 2026.2.x — UserLoginStage is the correct knob.
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
data "authentik_stage" "default_authentication_login" {
|
||||
name = "default-authentication-login"
|
||||
}
|
||||
|
||||
import {
|
||||
to = authentik_stage_user_login.default_login
|
||||
id = data.authentik_stage.default_authentication_login.id
|
||||
}
|
||||
|
||||
resource "authentik_stage_user_login" "default_login" {
|
||||
name = "default-authentication-login"
|
||||
session_duration = "weeks=4"
|
||||
lifecycle {
|
||||
# Pin only session_duration; everything else stays UI-managed so the
|
||||
# plan doesn't churn unrelated knobs (e.g. remember_me_offset toggles).
|
||||
ignore_changes = [
|
||||
remember_me_offset,
|
||||
terminate_other_sessions,
|
||||
geoip_binding,
|
||||
network_binding,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,15 @@ authentik:
|
|||
|
||||
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:
|
||||
|
|
@ -70,6 +79,11 @@ global:
|
|||
|
||||
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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue