Auto-join SSO users to first shared search space on login#18
Conversation
| email, | ||
| ) | ||
|
|
||
| # SMB shared-space join runs in users.current_active_user so Bearer JWT |
There was a problem hiding this comment.
Let's remove the comments where another app is being referenced as the solution. This comment is not needed anymore.
Co-authored-by: Usama Sadiq <usama7274@gmail.com>
Security follow-up — per-request placement created an un-revokable membership pathHeads-up that the per-request placement here (
The per-request placement was deliberate per the function's docstring ("Safe when auth uses Bearer JWT only: runs from current_active_user as well."), to handle the JWT-only path where the proxy middleware doesn't fire. The trade-off (un-revokability) wasn't called out in the PR description. Fix#21 moves the call to
So new users are still auto-joined exactly once. Removed users stay removed. Trade-off acknowledgedThe original design intentionally caught the case "user's first auth is JWT, no Refs
cc @jawad-khan @UsamaSadiq for context — not a critique of the merge, the per-request choice was reasonable for the JWT-only-path concern, just an interaction with the DELETE endpoint that's worth documenting in the followup. 🤖 Generated with Claude Code |
* feat: Add user to default workspace on signin * fix: deleted unwanted file * fix: fixed sso workspace * fix: apply suggestions from code review Co-authored-by: Usama Sadiq <usama7274@gmail.com> --------- Co-authored-by: Usama Sadiq <usama.sadiq@arbisoft.com>
Regression-guard for SurfSense's architectural immunity to the cross-app stale-session-on-user-switch class of bug. SurfSense doesn't need an explicit Rule-2-style "compare upstream identity vs session identity → flush on mismatch" middleware (like Plane MODSetter#29, Outline #19, Penpot #18, Twenty #8 do) because `current_active_user` in app.users already resolves to the upstream identity (proxy_user) over the persisted session (jwt_user) whenever both are present. That precedence IS the contract. If a future refactor flips it (or removes the proxy_user check during a "simplify auth" pass) the stale-session bug class is silently re-introduced — and type-checks pass, so it would ship. These five tests pin the contract: 1. proxy_user wins when both proxy_user and jwt_user are present with different identities (the user-switch scenario) 2. Falls back to jwt_user when proxy_user is absent (header-absent is NOT a logout signal — internal calls, OPTIONS preflight, direct backend hits at 127.0.0.1 legitimately arrive without a proxy header) 3. Raises 401 when neither is present (sanity) 4. Same precedence for current_optional_user 5. current_optional_user returns None (does not raise) when neither is present Cross-app contract: awais786/sso-rules-moneta:openspec/specs/proxy-auth-middleware/spec.md SurfSense's architectural-immunity reasoning: awais786/sso-rules-moneta:surfsense-security.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat: Add user to default workspace on signin * fix: deleted unwanted file * fix: fixed sso workspace * fix: apply suggestions from code review Co-authored-by: Usama Sadiq <usama7274@gmail.com> --------- Co-authored-by: Usama Sadiq <usama.sadiq@arbisoft.com>
Regression-guard for SurfSense's architectural immunity to the cross-app stale-session-on-user-switch class of bug. SurfSense doesn't need an explicit Rule-2-style "compare upstream identity vs session identity → flush on mismatch" middleware (like Plane MODSetter#29, Outline #19, Penpot #18, Twenty #8 do) because `current_active_user` in app.users already resolves to the upstream identity (proxy_user) over the persisted session (jwt_user) whenever both are present. That precedence IS the contract. If a future refactor flips it (or removes the proxy_user check during a "simplify auth" pass) the stale-session bug class is silently re-introduced — and type-checks pass, so it would ship. These five tests pin the contract: 1. proxy_user wins when both proxy_user and jwt_user are present with different identities (the user-switch scenario) 2. Falls back to jwt_user when proxy_user is absent (header-absent is NOT a logout signal — internal calls, OPTIONS preflight, direct backend hits at 127.0.0.1 legitimately arrive without a proxy header) 3. Raises 401 when neither is present (sanity) 4. Same precedence for current_optional_user 5. current_optional_user returns None (does not raise) when neither is present Cross-app contract: awais786/sso-rules-moneta:openspec/specs/proxy-auth-middleware/spec.md SurfSense's architectural-immunity reasoning: awais786/sso-rules-moneta:surfsense-security.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Description
ProxyAuthMiddleware now checks whether the authenticated user has any non-owner search space membership. If not, they are added to the first shared search space (not owned by them) with the default role.
Motivation and Context
FIX #
Screenshots
API Changes
Change Type
Testing Performed
Checklist