From 20cf119dbdb85cbbc8c603974ad42f11de3f323a Mon Sep 17 00:00:00 2001 From: Ruben Hensen Date: Thu, 3 Sep 2026 15:21:07 +0200 Subject: [PATCH] Extend authentik + FreshRSS session lifetimes Authentik's default-authentication-login stage ships with session_duration: seconds=0, so the SSO session died with the browser. New blueprint raises it to 30 days for every app on that flow. FreshRSS runs OIDC through Apache mod_auth_openidc, whose defaults are a 5 minute inactivity timeout and a ~7.5 hour max duration in a non-persistent cookie. Bumped to a 30 day sliding inactivity window (refreshed on every request) with a 90 day hard cap, and made the cookie persistent so it survives a browser restart. --- apps/templates/authentik-helm.yaml | 12 ++++++++++ authentik/README.md | 16 ++++++++++++++ authentik/blueprint-session-duration.yaml | 27 +++++++++++++++++++++++ freshrss/freshrss-deployment.yaml | 14 ++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 authentik/blueprint-session-duration.yaml diff --git a/apps/templates/authentik-helm.yaml b/apps/templates/authentik-helm.yaml index 3c440c4..d3339b2 100644 --- a/apps/templates/authentik-helm.yaml +++ b/apps/templates/authentik-helm.yaml @@ -106,6 +106,9 @@ spec: - name: blueprint-actualbudget configMap: name: authentik-blueprint-actualbudget + - name: blueprint-session + configMap: + name: authentik-blueprint-session volumeMounts: - name: blueprint-vault mountPath: /blueprints/custom/vault-oidc.yaml @@ -125,6 +128,9 @@ spec: - name: blueprint-actualbudget mountPath: /blueprints/custom/actualbudget-proxy.yaml subPath: actualbudget-proxy.yaml + - name: blueprint-session + mountPath: /blueprints/custom/session-duration.yaml + subPath: session-duration.yaml ingress: enabled: true ingressClassName: nginx @@ -156,6 +162,9 @@ spec: - name: blueprint-actualbudget configMap: name: authentik-blueprint-actualbudget + - name: blueprint-session + configMap: + name: authentik-blueprint-session volumeMounts: - name: blueprint-vault mountPath: /blueprints/custom/vault-oidc.yaml @@ -175,6 +184,9 @@ spec: - name: blueprint-actualbudget mountPath: /blueprints/custom/actualbudget-proxy.yaml subPath: actualbudget-proxy.yaml + - name: blueprint-session + mountPath: /blueprints/custom/session-duration.yaml + subPath: session-duration.yaml postgresql: enabled: false redis: diff --git a/authentik/README.md b/authentik/README.md index cbf810a..89a27c4 100644 --- a/authentik/README.md +++ b/authentik/README.md @@ -11,6 +11,22 @@ Authentik is deployed as the central identity provider, providing OIDC and LDAP - `blueprint-ldap.yaml` — LDAP provider (base DN: `DC=ldap,DC=goauthentik,DC=io`) - `blueprint-mail-oidc.yaml` — OAuth2/OIDC provider for Stalwart mail - `blueprint-vault-oidc.yaml` — OIDC provider for Vault + - `blueprint-argocd-oidc.yaml` — OIDC provider for ArgoCD + - `blueprint-freshrss-oidc.yaml` — OIDC provider for FreshRSS + - `blueprint-actualbudget-proxy.yaml` — Proxy provider for Actual Budget + - `blueprint-session-duration.yaml` — Session lifetime of the default authentication flow + +## Session lifetime + +Authentik ships the login stage of `default-authentication-flow` with +`session_duration: seconds=0`, i.e. the SSO session dies when the browser closes. +`blueprint-session-duration.yaml` raises this to 30 days for every app that uses +that flow (FreshRSS, ArgoCD, Vault, Actual Budget, mail). + +The expiry is **absolute** — Authentik does not extend a session on activity. A +sliding window has to come from the application itself; FreshRSS does this via +`OIDC_SESSION_INACTIVITY_TIMEOUT` (see `freshrss/freshrss-deployment.yaml`), which +Apache mod_auth_openidc refreshes on every request. ## LDAP Outpost diff --git a/authentik/blueprint-session-duration.yaml b/authentik/blueprint-session-duration.yaml new file mode 100644 index 0000000..f7e3048 --- /dev/null +++ b/authentik/blueprint-session-duration.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: authentik-blueprint-session +data: + session-duration.yaml: | + version: 1 + metadata: + name: Session duration + entries: + # Overrides the login stage of the built-in `default-authentication-flow`, + # which every OIDC/proxy provider in this cluster authenticates against. + # authentik ships this stage with `session_duration: seconds=0`, which means + # "until the browser is closed" — that is why re-logins were so frequent. + # + # Note: authentik's session expiry is absolute (counted from login), it does + # not slide on activity. The sliding window lives in the applications, e.g. + # OIDC_SESSION_INACTIVITY_TIMEOUT in freshrss/freshrss-deployment.yaml. + - model: authentik_stages_user_login.userloginstage + state: present + identifiers: + name: default-authentication-login + attrs: + session_duration: days=30 + # Uncomment to show a "Remember me on this device" checkbox that adds + # this offset on top of session_duration when ticked (0 = hidden). + # remember_me_offset: days=60 diff --git a/freshrss/freshrss-deployment.yaml b/freshrss/freshrss-deployment.yaml index 6750388..2be5ff2 100644 --- a/freshrss/freshrss-deployment.yaml +++ b/freshrss/freshrss-deployment.yaml @@ -56,6 +56,20 @@ spec: value: "openid email profile" - name: OIDC_X_FORWARDED_HEADERS value: X-Forwarded-Port X-Forwarded-Proto X-Forwarded-Host + # Session handling for the Apache mod_auth_openidc layer that guards /i/. + # Defaults are 5 min inactivity / ~7.5 h max, which is what caused the + # constant bounces back to authentik. + # Sliding window: refreshed on every request, so any visit within the + # period extends it by another 30 days. + - name: OIDC_SESSION_INACTIVITY_TIMEOUT + value: "2592000" # 30 days + # Hard cap, counted from login and never extended. + - name: OIDC_SESSION_MAX_DURATION + value: "7776000" # 90 days + # ":persistent" makes the session cookie survive a browser restart + # (its expiry tracks OIDC_SESSION_INACTIVITY_TIMEOUT). + - name: OIDC_SESSION_TYPE + value: "server-cache:persistent" - name: TZ value: Europe/Amsterdam image: freshrss/freshrss:latest