The login-session lifetime (raised to days=7 on 2026-10-20) is owned by the default-authentication-login stage's session_duration, not a global setting and not SESSION_COOKIE_AGE. Authentik exposes no SESSION_SAVE_EVERY_REQUEST, so the window is absolute. session_duration is a STRING idiom; a timedelta stores a form timedelta_from_string rejects, crashing login. Add scripts/authentik-set-login-session-duration.sh that validates the form before writing (DB state, not repo-managed, re-run after a blueprint re-import). Trim the page back under the OKF 500-line cap. tests/run.sh green.
48 lines
2.1 KiB
Bash
Executable File
48 lines
2.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Set the authentik login-session TTL on Dankclaw.
|
|
#
|
|
# The login-session lifetime is governed by the `default-authentication-login`
|
|
# stage's `session_duration`, NOT a global setting and NOT SESSION_COOKIE_AGE
|
|
# (that is the pre-login session, sessions.unauthenticated_age). Authentik does
|
|
# not expose SESSION_SAVE_EVERY_REQUEST at all, so the session is an absolute
|
|
# window from login, not a sliding one.
|
|
#
|
|
# The field is a STRING in authentik's own idiom ("days=7", "seconds=30",
|
|
# "hours=12") — not a Python timedelta. Writing str(timedelta(days=7)) stores
|
|
# "7 days, 0:00:00", which authentik's timedelta_from_string parser REJECTS
|
|
# (ValueError), and login then crashes computing the session expiry. Always pass
|
|
# the "key=value" form; this script validates it before writing.
|
|
#
|
|
# Existing sessions keep their old expiry; the new TTL applies from the next
|
|
# login. This is DB state — it is NOT repo-managed and a blueprint re-import or
|
|
# rebuild-from-scratch reverts it. Run this again after such a rebuild.
|
|
#
|
|
# Usage: authentik-set-login-session-duration.sh ["days=7"] (default days=7)
|
|
set -euo pipefail
|
|
|
|
DUR="${1:-days=7}"
|
|
STAGE="default-authentication-login"
|
|
HOST="${AUTHENTIK_HOST:-dankclaw}"
|
|
|
|
# Refuse anything that is not the safe key=value duration idiom.
|
|
if ! printf '%s' "$DUR" | grep -Eq '^[A-Za-z]+=[0-9]+([ ]+[A-Za-z]+=[0-9]+)*$'; then
|
|
echo "invalid duration '$DUR' — use authentik form, e.g. 'days=7' or 'seconds=30'" >&2
|
|
exit 2
|
|
fi
|
|
|
|
ssh "$HOST" 'podman exec -i authentik-server ak shell' <<PYEOF
|
|
from django.apps import apps
|
|
from authentik.lib.utils.time import timedelta_from_string
|
|
dur = "$DUR"
|
|
timedelta_from_string(dur) # validate the form before touching the row
|
|
ULS = apps.get_model("authentik_stages_user_login", "UserLoginStage")
|
|
s = ULS.objects.get(name="$STAGE")
|
|
s.session_duration = dur
|
|
s.save(update_fields=["session_duration"])
|
|
back = ULS.objects.get(name="$STAGE").session_duration
|
|
assert back == dur, "persisted value mismatch: %r" % back
|
|
print("session_duration set to", repr(back), "->", timedelta_from_string(back))
|
|
PYEOF
|
|
|
|
echo "Login-session TTL for '$STAGE' is now $DUR (applies on next login)."
|