Skip to content

[Decision] What is an authenticated session with NO active organization? Three subsystems answered it three contradictory ways in one shift (fail-open / fail-closed / permanently-invisible ledger rows) #8247

Description

@hotlong

Filed by the triage seat (scheduled fire, session session_01BJ9jjXsUuc4Mkiyzvv1xUW, 2026-08-12 ~22:47Z round). This decision has no single natural anchor — it sits upstream of three measured cards in three subsystems — so it gets a standalone card per the escalation protocol.

Background

One and the same state — an authenticated session whose activeOrganizationId is null — produced three different, mutually contradictory behaviors, all measured live on 2026-08-12:

CardSubsystemBehavior under the stateConsequence
#8158plugin-sharing adminOrgScopefell OPENorg-scoped manage_sharing read/wrote ALL tenants' sharing rules (fixed to reject, PR #8237)
#8208Layer 0 tenant wall + write stampingfalls CLOSED, silentlyHTTP-created record stamped organization_id: NULL, immediately invisible to its own creator
#8245audit ledgerwrites rows no reader can ever seeevery audit row from a user's FIRST session carries a NULL tenant, permanently invisible to RLS readers

None of the three implementations is individually wrong; the platform has never declared what the state means, so each layer improvised. The state is structurally guaranteed to occur: better-auth defers the ADR-0093 membership reconciler past the signup transaction, so every new user's first session predates their membership (ADR-0081 D1 defaultActiveOrg finds no sys_member row). It can also arise later (member removed from their org, etc.), so it cannot be defined away by fixing signup alone.

Premises (re-check before ruling)

The question

Is "authenticated, but no active organization" a legal session state with defined semantics, or an illegal intermediate to be eliminated at the mint point?

Options

Recommendation: C

Security/permission-boundary semantics ⇒ human floor; not auto-adjudicable.

Downstream

Disposition of findings #8208 and #8245 is gated on this ruling; #8158's fix stands either way. Related: #8241 (RLS policy-composition trap, same family but a different mechanism — not gated on this).

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions