Files
oikos/archive/hermes-plans/2026-06-06_232200-authentik-frequent-login-fix.md
dtoro 6b75f7302d db as source of truth: wiki→seeds, archive old artifacts, knowledge ingestion
- Migrations 010 (content_hash) + 011 (search tsvector column)
- new: internal/knowledge/seed.go — knowledge seed ingest engine
- new: internal/httpapi/knowledge.go — SearchKnowledge + GetEntityKnowledge
- wire knowledge ingest into oikos seed pipeline
- convert all 36 wiki docs + 6 investigations + 12 runbooks → seeds/knowledge.yaml
- archive: knowledge/wiki/→archive/, oikos/cards/→archive/, .hermes/plans/→archive/
- delete: 9 superseded Python kernel files, ledger/, mcp/build_host_files.py
- remove empty knowledge/ directory tree
2026-07-07 20:22:30 +02:00

6.8 KiB
Raw Blame History

Plan: Fix Frequent Authentik Login Prompts

Goal

Stop requiring repeated login to Authentik (several times per day) by fixing session and cookie expiry settings so the user stays logged in for longer periods (e.g., 730 days, or until explicit logout).

Current Context

Authentik runs on the VPS (82.165.190.79) in Docker Compose. Traffic flows:

Browser → Caddy (LXC 121) → VPS Traefik → Authentik

Caddy's forward_auth uses the (authentik) snippet which proxies to auth.hubris.network/outpost.goauthentik.io/auth/caddy. The Authentik server version is 2026.5.2.

Root Cause Found

Primary: SESSION_EXPIRE_AT_BROWSER_CLOSE = True

The Authentik Django session (authentik_session cookie) is configured to expire on browser close. Every time the user closes and reopens their browser, the session cookie is cleared. The next visit to a service that requires OAuth2 authorization (Gitea, Jellyfin, etc.) will redirect to the Authentik login page.

Even with the browser left open continuously, the session expires after 24 hours. Combined with SESSION_SAVE_EVERY_REQUEST = False, activity does NOT extend the session.

Session configuration (from Docker Python environment):

Setting Current Value Default in Django
SESSION_EXPIRE_AT_BROWSER_CLOSE True False
SESSION_COOKIE_AGE 86400 (24h) 1209600 (14d)
SESSION_SAVE_EVERY_REQUEST False False
SESSION_COOKIE_SAMESITE Lax Lax

What ISN'T the problem:

  • Proxy cookie validityhubris-forward-auth has access_token_validity = hours=24, which is reasonable for the forward-auth token.
  • Server-side session duration — The user_login stage has session_duration = seconds=0 (indefinite).
  • Refresh tokens — All OAuth2 providers have refresh_token_validity = days=30, which is fine.
  • Caddy configuration — The forward-auth chain is correctly set up.
  • Outpost health — All containers healthy, up for 6 days.

Proposed Approach

Change two Django session settings via Authentik environment variables:

  1. AUTHENTIK_SESSION_COOKIE_AGE = 604800 (7 days) — extends session cookie lifetime from 24h to 7 days
  2. AUTHENTIK_SESSION_EXPIRE_AT_BROWSER_CLOSE = false — prevents session cookie from being cleared on browser close

This keeps users logged in for up to 7 days with normal browser use (close/reopen, daily usage). The session still expires after 7 days of inactivity (SESSION_SAVE_EVERY_REQUEST stays False).

Step-by-step Plan

Step 1: Add environment variables to Docker compose

Edit /opt/docker-compose.yml on the VPS to add these env vars to the authentik-server service:

authentik-server:
  environment:
    # ... existing vars ...
    AUTHENTIK_SESSION_COOKIE_AGE: "604800"      # 7 days (was 86400 / 24h)
    AUTHENTIK_SESSION_EXPIRE_AT_BROWSER_CLOSE: "false"  # was true

Note: the Authentik config system uses __ (double underscore) for nesting. The env vars map to the Django settings via the config YAML path. The correct Authentik env var for SESSION_COOKIE_AGE would be AUTHENTIK_SESSION__COOKIE_AGE if it goes through the config system, or just SESSION_COOKIE_AGE if it's passed directly. Need to verify the exact variable name Authentik expects.

Step 2: Verify variable naming

Check the Authentik config YAML (/authentik/lib/default.yml inside the container) to confirm the exact env var name mapping. Authentik uses a custom config layer that maps env vars to settings.

Alternative if env vars don't work: Some Authentik settings need to be set via the admin UI (under System Settings or Tenant settings). The Django session settings might need to be configured differently in this version.

Step 3: Restart Authentik server

ssh root@82.165.190.79
docker compose -f /opt/docker-compose.yml restart authentik-server

Step 4: Verify the fix

# Check session settings took effect
ssh root@82.165.190.79 'docker exec -i authentik-server python3 << "PYEOF"
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
import django
django.setup()
from django.conf import settings
print("SESSION_EXPIRE_AT_BROWSER_CLOSE:", settings.SESSION_EXPIRE_AT_BROWSER_CLOSE)
print("SESSION_COOKIE_AGE:", settings.SESSION_COOKIE_AGE)
PYEOF'

Step 5: Functional test

  1. Login to Authentik at auth.hubris.network
  2. Close the browser completely
  3. Re-open browser, navigate to a forward-auth-gated service (e.g., paperless.hubris.network)
  4. Verify you're NOT redirected to login
  5. Verify OAuth2 services (Gitea) also maintain the session

Files Likely to Change

File Change
/opt/docker-compose.yml Add AUTHENTIK_SESSION_COOKIE_AGE and AUTHENTIK_SESSION_EXPIRE_AT_BROWSER_CLOSE env vars

Tests / Validation

  1. Config verification — Run Python snippet inside container to confirm Django settings changed
  2. Browser test — Close/reopen browser, verify session persists (Step 5 above)
  3. 24-hour test — Check session is still alive after 24h of normal use

Risks, Tradeoffs, and Open Questions

Risk Mitigation
Env var names don't match Authentik's config schema First verify in the container's default.yml config file
7-day persistent cookie is a security concern (stolen cookie = 7 days of access) This is the same risk as any "Remember Me" feature on any web app. The tradeoff is convenience vs. security.
The proxy cookie (authentik_proxy_*) may still have its own 24h limit That's managed separately via the OAuth2 provider's access_token_validity setting. If we also want to extend that, we can update hubris-forward-auth provider's access_token_validity from hours=24 to days=7.
SESSION_COOKIE_SECURE = False Should be True since Authentik is served behind HTTPS. However, the forward-auth subrequest from Caddy to the outpost is HTTP internally (http://127.0.0.1:8099), so False may be intentional for the outpost check.

Open Questions

  1. What environment variable name does Authentik use for Django session settings? Need to check default.yml. The config layer may use AUTHENTIK_SESSION__COOKIE_AGE (double underscore) or the raw Django setting name.
  2. Should we also extend the proxy token validity? The hubris-forward-auth provider has access_token_validity = hours=24. If we want users to not need re-login for more than 24h, we should also bump this to match the session cookie age.
  3. Which specific service triggers the most login prompts? The forward-auth (Caddy-gated) services use proxy cookies. OAuth2 services (Gitea, Jellyfin) use the Django session. Understanding which one the user is hitting most could narrow the fix scope.