Repository navigation
Offer organization creation in the self-host switcher to root owners - #84
Merged
Merged
Conversation
A self-host database refused every sign-in, invitation and SSO login once it held a second organization, because each path required exactly one. Sessions now need a membership in any organization, an invitation admits into its own organization, and SSO signs in only people who already belong to one: it no longer adds a verified, approved address to the instance's organization. Setup records the organization it creates as the instance's root in a new selfHostRoot table. The private_self_host_migrations step 1_root_organization records an existing install's root when it has exactly one organization and leaves it unset otherwise. Organization creation remains disabled. Co-authored-by: Cursor <cursoragent@cursor.com>
Better Auth's create endpoint now asks whether the signed-in user owns the root organization that setup recorded. Admins, members, people outside the root, owners of other organizations, anonymous callers and bearer keys are refused, and an install with no root record refuses everyone. The creator becomes the new organization's owner. Co-authored-by: Cursor <cursoragent@cursor.com>
Self-host can now hold several organizations, so the scenarios proving that apps, accounts, connections, groups, grants, dashboard batches and PAT MCP calls stay inside their organization run there too. Self-host cannot remove organizations, so those scenarios remove theirs only on Cloud; each self-host scenario's server is discarded. The batch scenario's own organization is created by the root owner, who invites the member as an administrator. Co-authored-by: Cursor <cursoragent@cursor.com>
A signed-in user's GET /api/auth/self-host/capabilities answers whether they may create organizations, from the same root-owner check the create endpoint applies. The self-host switcher shows Create organization only when it says so; the server still refuses everyone else. Co-authored-by: Cursor <cursoragent@cursor.com>
shuv1337
changed the base branch from
feat/selfhost-multi-org-isolation
to
v2
November 9, 2026 04:38
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Self-host is getting real multi-organization support with owner-only creation. The dashboard's organization switcher should offer "Create organization" to exactly the people the server lets create, the root organization's owners, and switching should show each organization its own data. Stacked on #83. This is the top of the stack, so its selection below covers every layer.
What changed
GET /api/auth/self-host/capabilities(session only) returns{ createOrganization }from the sameownsRootcheck the create endpoint applies. Bearer callers and anonymous callers get401.organizationCreationAtom(browser only) reads it. The self-host org layout passesallowCreateOrganizationas true only on a successfultrue, and it stays false while loading, after a failure and during server rendering. The action sits inside the closed switcher menu, so nothing shifts when it appears.allowCreate={false}: on self-host, someone with no organization cannot hold a session.Verification
bun run check: exit 0.self-host-organization-switcher.spec.ts(new), passed:true. The owner creates "Second team" from the switcher and lands on/org/second-team/apps, which lists none of the root's apps. Switching back shows the root's app.false. The admin's switcher lists one organization and no create action.Negative check: forcing the action on makes the scenario fail on the admin (
[1, 1]instead of[1, 0]).Whole stack, run on this branch: 31/31 selected self-host scenarios passed. That covers every new or changed spec, the invitation, onboarding and password login scenarios, and the dashboard read-count and batch scenarios, which could see the new read. The fork CI security scenarios: 5/5 passed.