GloriousFlywheel Tailnet Operator Identity 2026-04-16
Snapshot date: 2026-04-16
Purpose
Capture the first executable auth-model tightening for #172.
This note is about request identity and session handling. It does not claim the full dashboard auth redesign is complete.
Companion notes:
- gloriousflywheel-dashboard-control-plane-assumptions-2026-04-16.md
- gloriousflywheel-dashboard-control-authority-options-2026-04-16.md
- gloriousflywheel-dashboard-mutation-authority-hold-2026-04-16.md
- gloriousflywheel-program-surface-2026-04-15.md
- gloriousflywheel-milestone-execution-matrix-2026-04-15.md
Current Executed Contract
The repo now treats auth sources in this order:
- trusted proxy identity headers when
TRUST_PROXY_HEADERS=true - stored interactive session cookies
- development fallback in local dev mode only
That means tailnet and mTLS request identity is now authoritative when the dashboard is behind the trusted proxy path.
Executed Changes
1. Signed Dashboard Sessions
app/src/lib/server/auth/session.ts now signs session cookies with
SESSION_SECRET when it is configured.
Implications:
- production-style deployments no longer rely on unsigned base64 JSON cookies
- tampered or legacy unsigned cookies are rejected when a session secret is present
- local/dev environments without
SESSION_SECRETstill use the simpler unsigned cookie path for compatibility
2. Proxy Identity Takes Precedence
app/src/hooks.server.ts now resolves trusted proxy identity before stored
interactive sessions.
Implications:
- a tailnet or mTLS-authenticated request is no longer silently shadowed by an older OAuth or passkey cookie
- request auth matches the ingress trust boundary instead of whichever cookie happened to exist first
3. Proxy Roles Are No Longer Hard-Coded Viewer
Trusted proxy identities no longer default to viewer.
Current role contract:
- proxy-header auth defaults to
operator AUTH_ADMIN_IDENTITIES,AUTH_OPERATOR_IDENTITIES, andAUTH_VIEWER_IDENTITIEScan override the fallback role by username or emailPROXY_AUTH_DEFAULT_ROLEcan change the proxy fallback when needed
4. Interactive Auth Remains Compatibility
Interactive auth remains available, but it is now more clearly bounded:
- GitLab OAuth still backs the current compatibility login flow
- WebAuthn still provides interactive passwordless auth for registered users
- passkey registration still depends on the GitLab interactive compatibility path today
Why This Matters
Before this slice:
- proxy auth existed, but only as a thin helper behind cookie auth
- trusted proxy users were always mapped to
viewer - session cookies were not protected by the already-provisioned
SESSION_SECRET
After this slice:
- tailnet/mTLS operator identity is first-class at request time
- the hook logic now matches the intended operator-plane direction better
- interactive auth and mutation compatibility remain available without defining the strategic future too early
Remaining Gap
This does not finish #172.
The repo still needs:
- a final operator permission model tied to mutation authority
- a deliberate story for passkeys outside the GitLab interactive compatibility path
- a replacement mutation authority if the dashboard stops using GitLab-backed compatibility flows
Exit Condition
- request auth precedence is explicit and tailnet-first
- signed session handling is in place when a session secret exists
- trusted proxy identities can be treated as real operators instead of fallback viewers