Forgejo daily logout: 7d session TTL not rolled out + kubectl kai-server.local Bad Gateway #350
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/infrastructure#350
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Forgejo logs Kai out roughly once a day, per browser. The "once a day" cadence is the exact signature of Forgejo's default
[session] SESSION_LIFE_TIME = 86400(1 day) still being live, i.e. the 7-day fix from1da5986was committed but never rolled out to the running pod.This issue covers two distinct problems found while diagnosing:
1. Forgejo 7-day session TTL committed but (likely) not deployed
i_like_giteaweb session after the OAuth dance, so itsSESSION_LIFE_TIMEgoverns the daily bounce-back to the IdP.deploy/forgejo.yml:226setsFORGEJO__session__SESSION_LIFE_TIME = "604800"and pinsFORGEJO__session__PROVIDER = db. Landed in1da5986(2026-05-25, "fix(forgejo): pin session provider to postgres with 7d TTL", closing the old #127).coily ops kubectl -n forgejo get deploy forgejo -o yaml | grep -A1 -iE "SESSION_LIFE_TIME|session__PROVIDER"- empty or86400confirms the bug.coily ops kubectl apply -f deploy/forgejo.ymlthencoily ops kubectl -n forgejo rollout status deploy/forgejo.2. kubectl hits
Bad Gatewaybecause kai-server is sometimeskai-server.localcoily ops kubectl ...againsthttps://kai-server.local:6443/apireturnsBad Gatewayon every retry from kais-macbook-pro. Forgejo itself is up, so this is the control-plane API route, not the app.kai-server.local(mDNS) sometimes, which is flaky / lands on the wrong endpoint. Same class of bug already hit and fixed for Tailscale.ansible/roles/lan-hosts/defaults/main.ymlpins{ name: kai-server, ip: 192.168.0.194 }. The fix is to make the kubeconfig server use the stablekai-servername (or the LAN IP) rather than the.localmDNS name, mirroring the Tailscale resolution fix.Acceptance
SESSION_LIFE_TIME=604800withPROVIDER=db, verified via kubectl.coily ops kubectlreaches the cluster reliably from the macbook without.local-induced Bad Gateway.Update after restoring cluster access
Part 2 (kubectl Bad Gateway) - root-caused and fixed.
kai-server.localis mDNS (LAN-only) and was not resolving at all from off-LAN, while the kubeconfig pointed athttps://kai-server.local:6443- that is the failure.kai-serverresolves via Tailscale MagicDNS to the tailnet IP and is reachable when remote. On the home LAN that same tailnet IP is blackholed (infrastructure#294), so there the only reliable address is the LAN IP192.168.0.194.~/.kube/config:serverchanged fromhttps://kai-server.local:6443tohttps://kai-server:6443.tls-server-name: kai-serverwas already set, so the API cert validates with no--insecure-skip-tls-verify. Verified:kubectl get nodesreturnskai-server Readythrough the plain context.lan-hostsrole (commitb0e6846on main) so/etc/hostspinskai-server -> 192.168.0.194when home and falls back to MagicDNS away. One kubeconfig now works in both locations.Part 1 (daily logout) - my "not rolled out" theory was wrong.
FORGEJO__session__SESSION_LIFE_TIME=604800andFORGEJO__session__PROVIDER=db. The 7-day fix from1da5986is deployed.coily ops forgejo admin auth list) and check its session length /max_age.infrastructure#303 note. The
kai-server.local+--insecure-skip-tls-verifyworkaround infleet-readout.shcan be replaced withkai-server+tls-server-name=kai-server(cert-valid) oncelan-hostsconverges at home. The "add.localto the k3s tls-san" premise in #303 is now moot - use the cert-valid name instead.Part 1 (daily logout) - root cause found, it is an upstream Forgejo limitation
Not a misconfiguration. Two facts combine:
Max-Age- it is browser-session scoped. Confirmed live against the OAuth-start endpoint:set-cookie: session=...; Path=/; HttpOnly; SameSite=Lax(no Max-Age, no Expires).SESSION_LIFE_TIME=604800only sets how long the server keeps the session row (verified: thesessiontable holds rows whose last-activity is 27h+ old, so server retention is fine). It does not put an expiry on the cookie. See go-gitea/gitea#33403.gitea_incredible). That cookie - the only thing that survives a browser-session end and silently re-establishes login - is set solely by the username/password form with "Remember Me" ticked. The login page actively clears it (persistent=; Max-Age=0). Upstream bug: forgejo/forgejo#6007 (closed, no code fix; maintainer "not an easy fix"), go-gitea/gitea#28394.Net: server keeps the session 7 days, but the browser drops the session-scoped cookie when it ends its session (quit / overnight), and SSO gives no persistent cookie to fall back on -> re-auth ~daily, per browser. Exactly the reported symptom.
Fix options (a login-UX decision, not a pure config change)
gitea_incredibleforLOGIN_REMEMBER_DAYS. The GitHub link can stay for identity. Pair with pinningFORGEJO__security__LOGIN_REMEMBER_DAYS(currently unset -> default) indeploy/forgejo.ymlfor clarity.Max-Age/Expiresto the Forgejo sessionSet-Cookie, converting the session cookie to persistent. Keeps the SSO UX but means tampering with auth cookies at the proxy (SameSite/Secure care needed). More fragile.Also spotted while reading the running config
[session] COOKIE_SECURE = falseis still live (the runningapp.iniconfirms it), even though the public HTTPS ingress is up.docs/forgejo-deploy-plan.mdflags this env block as phase-1-only and says to remove it in phase 2. Worth droppingFORGEJO__session__COOKIE_SECURE=falsefromdeploy/forgejo.ymlnow that the public surface exists - separate from the logout issue, but a live cookie-security weakening.Resolution summary - closing
1. Daily logout (the original report) - root-caused to an upstream Forgejo limitation (forgejo/forgejo#6007, go-gitea/gitea#33403): the session cookie is browser-session scoped (no
Max-Age) and OAuth2/SSO logins never set the persistent remember-me cookie.SESSION_LIFE_TIME=604800is live and correct but only governs server-side retention. Decision: leave as-is (re-login is a one-click GitHub redirect), documented here. Not fixable by config; would need the upstream change or switching to local-password + Remember Me login.2. kubectl
Bad Gateway- fixed.~/.kube/confignow targetshttps://kai-server:6443(waskai-server.local, flaky mDNS) with the existingtls-server-name: kai-serverkeeping TLS valid.lan-hostsansible role enabled (b0e6846) so/etc/hostspinskai-server -> 192.168.0.194at home (bypassing the same-LAN tailnet blackhole, #294) and falls back to MagicDNS away. Verifiedkubectl get nodesworks from the macbook.3.
COOKIE_SECURE=falseleftover - fixed. The phase-1 env had been removed but the value persisted in the PVC-residentapp.ini(env-to-ini only upserts). SetFORGEJO__session__COOKIE_SECURE=autoexplicitly (1f755a9), applied + rolled out. Verified:app.ininowCOOKIE_SECURE = autoand the liveSet-Cookieover HTTPS now carriesSecure. Corrected the misleading phase-2 step indocs/forgejo-deploy-plan.md(a00889b).All three addressed. Closing.