- 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
6.8 KiB
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., 7–30 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.
Secondary: SESSION_COOKIE_AGE = 86400 (24 hours)
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 validity —
hubris-forward-authhasaccess_token_validity = hours=24, which is reasonable for the forward-auth token. - Server-side session duration — The
user_loginstage hassession_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:
AUTHENTIK_SESSION_COOKIE_AGE= 604800 (7 days) — extends session cookie lifetime from 24h to 7 daysAUTHENTIK_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
- Login to Authentik at
auth.hubris.network - Close the browser completely
- Re-open browser, navigate to a forward-auth-gated service (e.g., paperless.hubris.network)
- Verify you're NOT redirected to login
- 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
- Config verification — Run Python snippet inside container to confirm Django settings changed
- Browser test — Close/reopen browser, verify session persists (Step 5 above)
- 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
- What environment variable name does Authentik use for Django session settings? Need to check
default.yml. The config layer may useAUTHENTIK_SESSION__COOKIE_AGE(double underscore) or the raw Django setting name. - Should we also extend the proxy token validity? The
hubris-forward-authprovider hasaccess_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. - 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.