Problem
On staging, GET /api/teams (listTeams) appears to return 200 with a teams payload even when the request's session cookie is missing/invalid, rather than returning 401. Clients use listTeams as their session-validity probe, so a permissive 200 lets a stale session look valid.
Impact on clients
The account/ app had to add defensive client-side validation to compensate:
- ACCT-029:
useAuth.initialize() cross-checks the cached pubkey against the returned teams' team_users. If the pubkey isn't a member of any team, it treats the session as stale and forces re-login.
- This validation then broke support/admin users, who legitimately access teams via JIT grant and never appear in
team_users — every reload logged them out.
- A follow-up fix (probe
/api/admin/status before logging out) was needed to exempt support users.
All of this client complexity exists only because the server can't be trusted to reject an invalid session with 401.
Expected behavior
GET /api/teams must return 401 Unauthorized when the session cookie is missing, expired, or invalid — on every environment, including staging. With proper enforcement, clients can treat a successful listTeams as authoritative proof of a valid session (matching the v1 approach) and drop the team_users membership heuristic entirely.
Notes
Problem
On staging,
GET /api/teams(listTeams) appears to return200with a teams payload even when the request's session cookie is missing/invalid, rather than returning401. Clients uselistTeamsas their session-validity probe, so a permissive200lets a stale session look valid.Impact on clients
The account/ app had to add defensive client-side validation to compensate:
useAuth.initialize()cross-checks the cached pubkey against the returned teams'team_users. If the pubkey isn't a member of any team, it treats the session as stale and forces re-login.team_users— every reload logged them out./api/admin/statusbefore logging out) was needed to exempt support users.All of this client complexity exists only because the server can't be trusted to reject an invalid session with
401.Expected behavior
GET /api/teamsmust return401 Unauthorizedwhen the session cookie is missing, expired, or invalid — on every environment, including staging. With proper enforcement, clients can treat a successfullistTeamsas authoritative proof of a valid session (matching the v1 approach) and drop theteam_usersmembership heuristic entirely.Notes
useAuth.initialize()by removing the ACCT-029 check and the admin-status probe.